GCCPY:
[official-gcc.git] / libgpython / runtime / gpy-object-class.c
blobd175b8c108f7a8060e6858fa0f84e73810032621
1 /* This file is part of GCC.
3 GCC is free software; you can redistribute it and/or modify it under
4 the terms of the GNU General Public License as published by the Free
5 Software Foundation; either version 3, or (at your option) any later
6 version.
8 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
9 WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11 for more details.
13 You should have received a copy of the GNU General Public License
14 along with GCC; see the file COPYING3. If not see
15 <http://www.gnu.org/licenses/>. */
17 #ifdef HAVE_CONFIG_H
18 # include "config.h"
19 #endif
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <stdbool.h>
26 #ifdef USE_LIBFFI
27 # include <ffi.h>
28 #endif
30 #include <gpython/gpython.h>
31 #include <gpython/vectors.h>
32 #include <gpython/objects.h>
33 #include <gpython/runtime.h>
35 static
36 void gpy_object_classobj_init_decl_attribs (const void * self,
37 gpy_object_attrib_t ** attribs)
39 int idx;
40 unsigned char * selfptr = (unsigned char *)self;
41 for (idx = 0; attribs[idx] != NULL; ++idx)
43 gpy_object_attrib_t * i = attribs[idx];
44 unsigned char * typeoffs = selfptr + (i->offset);
46 gpy_object_t ** offs = (gpy_object_t **) typeoffs;
47 if (i->addr)
49 gpy_object_t * attrib = (gpy_object_t *)i->addr;
50 *offs = i->addr;
52 else
53 *offs = NULL;
57 /* Class's internal type is generated by the compiler ...*/
58 gpy_object_t * gpy_object_classobj_new (gpy_typedef_t * type,
59 gpy_object_t * args)
61 gpy_object_t * retval = NULL_OBJECT;
63 bool check = gpy_args_check_fmt (args, "A,i,s.");
64 gpy_assert (check);
66 gpy_object_attrib_t ** attribs = gpy_args_lit_parse_attrib_table (&args [0]);
67 int size = gpy_args_lit_parse_int (&args[1]);
68 char * ident = gpy_args_lit_parse_string (&args[2]);
70 void * self = gpy_malloc (size);
71 memset (self, 0, size);
72 gpy_object_classobj_init_decl_attribs (self, attribs);
74 gpy_typedef_t * ctype = gpy_malloc (sizeof (gpy_typedef_t));
75 ctype->identifier = ident;
76 ctype->state_size = size;
77 ctype->tp_new = type->tp_new;
78 ctype->tp_dealloc = type->tp_dealloc;
79 ctype->tp_print = type->tp_print;
80 ctype->tp_call = type->tp_call;
81 ctype->tp_nparms = type->tp_nparms;
82 ctype->binary_protocol = type->binary_protocol;
83 ctype->members_defintion = attribs;
85 retval = gpy_create_object_decl (ctype, self);
87 /* we need to walk though the field_init here */
88 gpy_object_t ** __field_init__ = gpy_rr_eval_attrib_reference (retval,
89 "__field_init__");
90 gpy_object_t * field_init = *__field_init__;
91 unsigned char * codeaddr = gpy_object_classmethod_getaddr (field_init);
93 ffi_cif cif;
94 ffi_type *argsdecl[1];
95 void *values[1];
96 argsdecl[0] = &ffi_type_pointer;
97 values[0] = (void *)&self;
99 gpy_assert (ffi_prep_cif (&cif, FFI_DEFAULT_ABI, 1,
100 &ffi_type_void, argsdecl)
101 == FFI_OK);
102 ffi_call (&cif, FFI_FN (codeaddr), NULL, values);
104 return retval;
107 void gpy_object_classobj_dealloc (gpy_object_t * self)
109 gpy_assert (self->T == TYPE_OBJECT_DECL);
110 gpy_object_state_t object_state = OBJECT_STATE (self);
112 gpy_free (object_state.state);
113 object_state.state = NULL;
116 void gpy_object_classobj_print (gpy_object_t * self, FILE *fd, bool newline)
118 switch (self->T)
120 case TYPE_OBJECT_STATE:
121 fprintf (fd, "class object instance <%p> ", (void *)self);
122 break;
124 case TYPE_OBJECT_DECL:
125 fprintf (fd, "class object decl <%p> ", (void *)self);
126 break;
128 default:
129 fatal ("something went very wrong here!\n");
130 break;
132 if (newline)
133 fprintf (fd, "\n");
136 static
137 gpy_object_t ** gpy_object_classobj_setupargs (gpy_object_t ** args,
138 gpy_object_t * self)
140 int idx = 0;
141 gpy_object_t ** ptr;
142 for (ptr = args; *ptr != NULL; ++ptr)
143 idx ++;
145 /* +1 for self +1 for NULL sentinal */
146 gpy_object_t ** newargs = calloc (idx+2, sizeof (gpy_object_t *));
147 *newargs = self;
148 gpy_object_t ** newargsptr = newargs;
149 newargsptr++;
151 for (ptr = args; *ptr != NULL; ++ptr)
153 *newargsptr = *ptr;
154 newargsptr++;
156 *newargsptr = NULL;
158 return newargs;
161 gpy_object_t * gpy_object_classobj_call (gpy_object_t * self,
162 gpy_object_t ** args)
164 gpy_object_t * retval = NULL_OBJECT;
165 gpy_assert (self->T == TYPE_OBJECT_DECL);
167 gpy_typedef_t * type = OBJECT_DEFINITION (self);
168 void * oldstate = OBJECT_STATE(self).state;
171 When a class is defined we run through the field initilizer and
172 create an OBJECT_CLASS_DECL
174 when we create an instance like x = myclass ()
175 we must create the 'self' which is the new instance object state
176 which holds the same data in the class_decl so we memcpy and need to incr
177 the ref_count on each object until we overwrite whats in self.
179 void * newstate = gpy_malloc (type->state_size);
180 memcpy (newstate, oldstate, type->state_size);
181 retval = gpy_create_object_state (type, newstate);
182 gpy_assert (retval);
184 gpy_object_t ** __init__ = gpy_rr_eval_attrib_reference (retval, "__init__");
185 gpy_object_t * init = *__init__;
187 gpy_assert (init->T == TYPE_OBJECT_DECL);
188 gpy_typedef_t * calltype = OBJECT_DEFINITION (init);
189 if (type->tp_call)
191 gpy_object_t ** arguments = gpy_object_classobj_setupargs (args, retval);
192 calltype->tp_call (init, arguments);
194 else
195 fatal ("name is not callable!\n");
197 return retval;
200 int gpy_object_classobj_nparms (gpy_object_t * self)
202 int retval = 0;
203 gpy_object_t ** __init__ = gpy_rr_eval_attrib_reference (self, "__init__");
204 gpy_object_t * init = *__init__;
206 gpy_assert (init->T == TYPE_OBJECT_DECL);
207 gpy_typedef_t * calltype = OBJECT_DEFINITION (init);
208 if (calltype->tp_call)
210 retval = calltype->tp_nparms (init);
212 we -1 to the arguments here for the arguments check to pass
213 since when we call __init__ (self)
214 we are creating the self argument in the call... so it isn't
215 directly passed
217 retval--;
219 return retval;
222 static struct gpy_typedef_t class_obj = {
223 "classobj",
225 &gpy_object_classobj_new,
226 &gpy_object_classobj_dealloc,
227 &gpy_object_classobj_print,
228 &gpy_object_classobj_call,
229 &gpy_object_classobj_nparms,
230 NULL,
231 NULL,
232 NULL
235 void gpy_obj_class_mod_init (gpy_vector_t * const vec)
237 gpy_vec_push (vec, &class_obj);