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
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
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/>. */
27 #include <gpython/gpython.h>
28 #include <gpython/vectors.h>
29 #include <gpython/objects.h>
30 #include <gpython/runtime.h>
32 // Holds all runtime information to primitive types
33 gpy_vector_t
* __GPY_GLOBL_PRIMITIVES
;
35 // runtime stack for all module runtime data
38 NOTE on thread-saftey for future, this stack will need
39 Global Lock, and a per thread __CALL_STACK & __RET_ADDR
46 -> * maybe __CALL_STACK //TODO
47 -> * maybe __RET_ADDR //TODO
53 #define __GPY_INIT_LEN 3
54 static int __GPY_GLOBL_modOffs
= 0;
55 static int __GPY_GLOBAL_STACK_LEN
= 0;
56 static gpy_hash_tab_t stack_table
;
58 static bool __GPY_GLOBAL_RETURN
;
59 gpy_object_t
** __GPY_MODULE_RR_STACK
;
60 gpy_object_t
** __GPY_RR_STACK_PTR
;
62 #define GPY_MODULE_STACK_RET_ADDR \
63 (__GPY_MODULE_RR_STACK + 1)
64 #define GPY_MODULE_STACK_RET_VAL \
65 *(__GPY_MODULE_RR_STACK + 1)
68 void gpy_rr_init_primitives (void)
70 gpy_obj_func_mod_init (__GPY_GLOBL_PRIMITIVES
);
71 gpy_obj_integer_mod_init (__GPY_GLOBL_PRIMITIVES
);
72 gpy_obj_staticmethod_mod_init (__GPY_GLOBL_PRIMITIVES
);
73 gpy_obj_class_mod_init (__GPY_GLOBL_PRIMITIVES
);
74 gpy_obj_classmethod_mod_init (__GPY_GLOBL_PRIMITIVES
);
75 gpy_obj_list_mod_init (__GPY_GLOBL_PRIMITIVES
);
76 gpy_obj_module_mod_init (__GPY_GLOBL_PRIMITIVES
);
77 gpy_obj_string_mod_init (__GPY_GLOBL_PRIMITIVES
);
81 void gpy_rr_init_runtime_stack (void)
83 __GPY_GLOBAL_RETURN
= false;
84 gpy_dd_hash_init_table (&stack_table
);
86 __GPY_GLOBL_PRIMITIVES
= gpy_malloc (sizeof (gpy_vector_t
));
87 gpy_vec_init (__GPY_GLOBL_PRIMITIVES
);
88 gpy_rr_init_primitives ();
90 __GPY_MODULE_RR_STACK
= (gpy_object_t
**) gpy_calloc
91 (__GPY_INIT_LEN
, sizeof (gpy_object_t
*));
93 *__GPY_MODULE_RR_STACK
= gpy_rr_fold_integer (__GPY_INIT_LEN
);
94 __GPY_RR_STACK_PTR
= (__GPY_MODULE_RR_STACK
+ __GPY_INIT_LEN
);
96 __GPY_GLOBAL_STACK_LEN
+= __GPY_INIT_LEN
;
99 /* remember to update the stack pointer's and the stack size */
100 void gpy_rr_extend_runtime_stack (int nslots
)
102 // calculate the size of reallocation
103 size_t size
= sizeof (gpy_object_t
*) * (__GPY_INIT_LEN
+ nslots
);
104 __GPY_MODULE_RR_STACK
= gpy_realloc (__GPY_MODULE_RR_STACK
, size
);
105 __GPY_GLOBAL_STACK_LEN
+= nslots
;
107 // update the stack pointer to the begining of all modules
108 __GPY_RR_STACK_PTR
= __GPY_MODULE_RR_STACK
;
109 __GPY_RR_STACK_PTR
+= __GPY_GLOBAL_STACK_LEN
+ (nslots
- 1);
112 /* More of a helper function than trying to do this directly in GENERIC */
113 char ** gpy_rr_modAttribList (int n
, ...)
115 char ** retval
= NULL
;
119 gpy_calloc (n
+ 1, sizeof (char *));
125 for (i
= 0; i
< n
; ++i
)
127 char * y
= va_arg (ap
, char *);
128 retval
[i
] = strdup (y
);
138 * @slots is the length to which the stack needs extended
139 * @stack_id is the id of the module which is being loaded
140 * @elems is the _ordered_ list of attributes of the class
142 int gpy_rr_extendRRStack (int slots
,
143 const char * stack_id
,
147 /* Make sure it doesn't already exist! */
148 gpy_hashval_t h
= gpy_dd_hash_string (stack_id
);
149 gpy_hash_entry_t
* e
= gpy_dd_hash_lookup_table (&stack_table
, h
);
151 if (e
== NULL
|| e
->data
== NULL
)
153 /* extend the stack and setup the stack pointer for the callee' */
154 gpy_rr_extend_runtime_stack (slots
);
156 gpy_moduleInfo_t
* info
= (gpy_moduleInfo_t
*)
157 gpy_malloc (sizeof (gpy_moduleInfo_t
));
158 info
->offset
= __GPY_GLOBL_modOffs
;
159 info
->length
= slots
;
160 info
->modID
= strdup (stack_id
);
161 info
->idents
= elems
;
163 gpy_assert (!gpy_dd_hash_insert (h
, (void *) info
, &stack_table
));
164 retOffs
= info
->offset
;
166 // update the offset for next module load...
167 __GPY_GLOBL_modOffs
+= slots
;
170 fatal ("Stack id <%s> already exists!\n", stack_id
);
175 void gpy_rr_init_runtime (void)
177 gpy_rr_init_runtime_stack ();
180 void gpy_rr_cleanup_final (void)
183 Cleanup the runtime stack and all other object data
189 gpy_object_attrib_t
* gpy_rr_fold_attribute (const unsigned char * identifier
,
190 unsigned char * code_addr
,
191 unsigned int offset
, int nargs
)
193 gpy_object_attrib_t
* attrib
= gpy_malloc (sizeof (gpy_object_attrib_t
));
194 attrib
->identifier
= identifier
;
195 attrib
->T
= GPY_GCCPY
;
198 gpy_object_t
* f
= gpy_rr_fold_classmethod_decl (identifier
, code_addr
, nargs
);
204 attrib
->offset
= offset
;
208 gpy_object_attrib_t
** gpy_rr_fold_attrib_list (int n
, ...)
210 gpy_object_attrib_t
** retval
= NULL
;
213 /* +1 for the sentinal */
214 retval
= (gpy_object_attrib_t
**)
215 gpy_calloc (n
+1, sizeof (gpy_object_attrib_t
*));
220 for (idx
= 0; idx
< n
; ++idx
)
222 gpy_object_attrib_t
* i
= va_arg (ap
, gpy_object_attrib_t
*);
232 gpy_object_t
* gpy_rr_fold_encList (int n
, ...)
234 gpy_object_t
* retval
= NULL
;
238 gpy_object_t
** elems
= (gpy_object_t
**)
239 gpy_calloc (n
+ 1, sizeof (gpy_object_t
*));
242 for (i
= 0; i
< n
; ++i
)
244 gpy_object_t
* elem
= va_arg (ap
, gpy_object_t
*);
250 /* + 2 for first argument the length of elements and for sentinal */
251 gpy_object_t
** args
= (gpy_object_t
**)
252 gpy_calloc (3, sizeof (gpy_object_t
*));
255 num
.type
= TYPE_INTEGER
;
256 num
.literal
.integer
= n
;
258 gpy_literal_t elements
;
259 elements
.type
= TYPE_VEC
;
260 elements
.literal
.vec
= elems
;
262 gpy_object_t a1
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &num
};
263 gpy_object_t a2
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &elements
};
264 gpy_object_t a3
= { .T
= TYPE_NULL
, .o
.literal
= NULL
};
269 gpy_typedef_t
* def
= __gpy_list_type_node
;
270 retval
= def
->tp_new (def
, args
);
275 gpy_assert (retval
->T
== TYPE_OBJECT_STATE
);
279 gpy_object_t
* gpy_rr_fold_class_decl (gpy_object_attrib_t
** attribs
,
280 int size
, const char * identifier
)
282 gpy_object_t
* retval
= NULL_OBJECT
;
284 gpy_object_t
** args
= (gpy_object_t
**)
285 gpy_calloc (4, sizeof(gpy_object_t
*));
288 A
.type
= TYPE_ATTRIB_L
;
289 A
.literal
.attribs
= attribs
;
292 i
.type
= TYPE_INTEGER
;
293 i
.literal
.integer
= size
;
296 s
.type
= TYPE_STRING
;
297 s
.literal
.string
= (char *) identifier
;
299 gpy_object_t a1
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &A
};
300 gpy_object_t a2
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &i
};
301 gpy_object_t a3
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &s
};
302 gpy_object_t a4
= { .T
= TYPE_NULL
, .o
.literal
= NULL
};
309 gpy_typedef_t
* def
= __gpy_class_type_node
;
310 retval
= def
->tp_new (def
, args
);
313 gpy_assert (retval
->T
== TYPE_OBJECT_DECL
);
317 gpy_object_t
* gpy_rr_fold_staticmethod_decl (const char * identifier
,
318 unsigned char * code_addr
,
321 gpy_object_t
* retval
= NULL_OBJECT
;
323 gpy_object_t
** args
= (gpy_object_t
**)
324 gpy_calloc (4, sizeof(gpy_object_t
*));
327 i
.type
= TYPE_STRING
;
328 i
.literal
.string
= (char *)identifier
;
332 p
.literal
.addr
= code_addr
;
335 n
.type
= TYPE_INTEGER
;
336 n
.literal
.integer
= nargs
;
338 gpy_object_t a1
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &i
};
339 gpy_object_t a2
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &p
};
340 gpy_object_t a3
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &n
};
341 gpy_object_t a4
= { .T
= TYPE_NULL
, .o
.literal
= NULL
};
348 gpy_typedef_t
* def
= __gpy_staticmethod_type_node
;
349 retval
= def
->tp_new (def
, args
);
352 gpy_assert (retval
->T
== TYPE_OBJECT_DECL
);
357 gpy_object_t
* gpy_rr_fold_classmethod_decl (const char * identifier
,
358 unsigned char * code_addr
,
361 gpy_object_t
* retval
= NULL_OBJECT
;
363 gpy_object_t
** args
= (gpy_object_t
**)
364 gpy_calloc (4, sizeof(gpy_object_t
*));
367 s
.type
= TYPE_STRING
;
368 s
.literal
.string
= (char *)identifier
;
372 p
.literal
.addr
= code_addr
;
375 n
.type
= TYPE_INTEGER
;
376 n
.literal
.integer
= nargs
;
378 gpy_object_t a1
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &s
};
379 gpy_object_t a2
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &p
};
380 gpy_object_t a3
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &n
};
381 gpy_object_t a4
= { .T
= TYPE_NULL
, .o
.literal
= NULL
};
388 gpy_typedef_t
* def
= __gpy_classmethod_type_node
;
389 retval
= def
->tp_new (def
, args
);
392 gpy_assert (retval
->T
== TYPE_OBJECT_DECL
);
397 gpy_object_t
** gpy_rr_getRefSlice (gpy_object_t
* decl
, gpy_object_t
* slice
)
399 gpy_typedef_t
* type
= decl
->o
.object_state
->definition
;
402 return type
->tp_ref_slice (decl
, slice
);
404 fatal ("Object <%p> has no slice assign hook!\n", (void *) decl
);
409 gpy_object_t
* gpy_rr_getSlice (gpy_object_t
* decl
, gpy_object_t
* slice
)
411 gpy_typedef_t
* type
= decl
->o
.object_state
->definition
;
414 return type
->tp_slice (decl
, slice
);
416 fatal ("Object <%p> has no slice hook!\n", (void *) decl
);
421 void gpy_rr_foldImport (gpy_object_t
** decl
,
424 gpy_moduleInfo_t
* mod
= NULL
;
425 gpy_hashval_t h
= gpy_dd_hash_string (module
);
426 gpy_hash_entry_t
* e
= gpy_dd_hash_lookup_table (&stack_table
, h
);
429 gpy_assert (e
->data
);
430 mod
= (gpy_moduleInfo_t
*) e
->data
;
432 gpy_object_t
** args
= (gpy_object_t
**)
433 gpy_calloc (5, sizeof (gpy_object_t
*));
436 A
.type
= TYPE_INTEGER
;
437 A
.literal
.integer
= mod
->offset
;
440 i
.type
= TYPE_INTEGER
;
441 i
.literal
.integer
= mod
->length
;
444 s
.type
= TYPE_STRING
;
445 s
.literal
.string
= mod
->modID
;
448 S
.type
= TYPE_STR_ARRY
;
449 S
.literal
.sarray
= mod
->idents
;
451 gpy_object_t a0
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &A
};
452 gpy_object_t a1
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &i
};
453 gpy_object_t a2
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &s
};
454 gpy_object_t a3
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &S
};
455 gpy_object_t a4
= { .T
= TYPE_NULL
, .o
.literal
= NULL
};
463 gpy_typedef_t
* def
= __gpy_module_type_node
;
464 *decl
= def
->tp_new (def
, args
);
467 gpy_assert ((*decl
)->T
== TYPE_OBJECT_DECL
);
470 gpy_object_t
* gpy_rr_fold_call (gpy_object_t
* decl
, int nargs
, ...)
472 gpy_object_t
* retval
= NULL_OBJECT
;
474 gpy_assert (decl
->T
== TYPE_OBJECT_DECL
);
475 gpy_typedef_t
* type
= decl
->o
.object_state
->definition
;
477 /* + 1 for sentinal */
478 gpy_object_t
** args
= calloc (nargs
+ 1, sizeof (gpy_object_t
*));
483 va_start (ap
, nargs
);
484 for (idx
= 0; idx
< nargs
; ++idx
)
486 args
[idx
] = va_arg (ap
, gpy_object_t
*);
493 /* args length checks ... */
494 int nparms
= type
->tp_nparms (decl
);
496 // if its not a class method we can drop the first argument
497 // since we dont need the self reference, this will be NULL
498 // on normal calls outside of attrib references on modules
499 bool iscmeth
= false;
500 if (!strcmp ("classmethod", type
->identifier
) ||
501 !strcmp ("func", type
->identifier
))
507 retval
= type
->tp_call (decl
, args
);
510 fatal ("call takes %i arguments (%i given)!\n", nparms
, nargs
);
518 retval
= type
->tp_call (decl
, args
+ 1);
521 fatal ("call takes %i arguments (%i given)!\n", nparms
, nargs
);
527 fatal ("name is not callable!\n");
530 if (__GPY_GLOBAL_RETURN
)
532 retval
= GPY_MODULE_STACK_RET_VAL
;
533 __GPY_GLOBAL_RETURN
= false;
539 unsigned char * gpy_rr_eval_attrib_reference (gpy_object_t
* base
,
542 unsigned char * retval
= NULL
;
543 gpy_typedef_t
* type
= base
->o
.object_state
->definition
;
545 struct gpy_object_attrib_t
** members
= type
->members_defintion
;
546 gpy_object_state_t
* objs
= base
->o
.object_state
;
550 int idx
, offset
= -1;
551 for (idx
= 0; members
[idx
] != NULL
; ++idx
)
553 struct gpy_object_attrib_t
* it
= members
[idx
];
554 if (!strcmp (attrib
, it
->identifier
))
556 if (it
->T
== GPY_GCCPY
)
558 /* when part of the type we can access the instance from the state */
560 unsigned char * state
= (unsigned char *)objs
->state
;
561 retval
= state
+ offset
;
563 else if (it
->T
== GPY_MOD
)
565 /* when part of the type we can access the instance from the state */
567 unsigned char * state
= (unsigned char *)objs
->state
;
568 unsigned char * sref
= state
+ offset
;
570 void ** ref
= (void **) sref
;
571 retval
= (unsigned char *) *ref
;
575 // this is probably an internal C attribute to an object.
576 gpy_assert (it
->T
= GPY_CATTR
);
577 retval
= (unsigned char *) &(it
->addr
);
584 fatal ("object has no attribute <%s>\n", attrib
);
590 gpy_object_t
* gpy_rr_fold_string (char * string
)
592 gpy_object_t
* retval
= NULL_OBJECT
;
594 gpy_object_t
** args
= (gpy_object_t
**)
595 gpy_calloc (2, sizeof (gpy_object_t
*));
599 s
.type
= TYPE_STRING
;
600 s
.literal
.string
= string
;
602 gpy_object_t s1
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &s
};
603 gpy_object_t s2
= { .T
= TYPE_NULL
, .o
.literal
= NULL
};
608 gpy_typedef_t
* Str_def
= __gpy_string_type_node
;
609 retval
= Str_def
->tp_new (Str_def
, args
);
611 gpy_assert (retval
->T
== TYPE_OBJECT_STATE
);
616 gpy_object_t
* gpy_rr_fold_integer (const int x
)
618 gpy_object_t
* retval
= NULL_OBJECT
;
620 gpy_object_t
** args
= (gpy_object_t
**)
621 gpy_calloc (2, sizeof(gpy_object_t
*));
624 i
.type
= TYPE_INTEGER
;
625 i
.literal
.integer
= x
;
627 gpy_object_t a1
= { .T
= TYPE_OBJECT_LIT
, .o
.literal
= &i
};
628 gpy_object_t a2
= { .T
= TYPE_NULL
, .o
.literal
= NULL
};
633 gpy_typedef_t
* Int_def
= __gpy_integer_type_node
;
634 retval
= Int_def
->tp_new (Int_def
, args
);
636 gpy_assert (retval
->T
== TYPE_OBJECT_STATE
);
642 void * gpy_rr_get_object_state (gpy_object_t
* o
)
645 return o
->o
.object_state
->state
;
648 void gpy_rr_eval_return (gpy_object_t
* o
)
651 gpy_object_t
** addr
= GPY_MODULE_STACK_RET_ADDR
;
653 __GPY_GLOBAL_RETURN
= true;
657 * int fd: we could use bit masks to represent:
660 void gpy_rr_eval_print (int fd
, int count
, ...)
666 gpy_object_t
* it
= NULL
;
667 for (idx
= 0; idx
< count
; ++idx
)
669 it
= va_arg (vl
, gpy_object_t
*);
670 struct gpy_typedef_t
* definition
= it
->o
.object_state
->definition
;
675 definition
->tp_print (it
, stdout
, false);
679 definition
->tp_print (it
, stderr
, false);
683 fatal ("invalid print file-descriptor <%i>!\n", fd
);
688 fprintf (stdout
, "\n");
693 void gpy_rr_incr_ref_count (gpy_object_t
* x1
)
695 gpy_assert (x1
->T
== TYPE_OBJECT_STATE
);
696 gpy_object_state_t
* x
= x1
->o
.object_state
;
698 debug ("incrementing ref count on <%p>:<%i> to <%i>!\n",
699 (void*) x
, x
->ref_count
, (x
->ref_count
+ 1));
704 void gpy_rr_decr_ref_count (gpy_object_t
* x1
)
706 gpy_assert (x1
->T
== TYPE_OBJECT_STATE
);
707 gpy_object_state_t
* x
= x1
->o
.object_state
;
709 debug ("decrementing ref count on <%p>:<%i> to <%i>!\n",
710 (void*) x
, x
->ref_count
, (x
->ref_count
- 1));
714 bool gpy_rr_eval_boolean (gpy_object_t
* x
)
718 gpy_assert (x
->T
== TYPE_OBJECT_STATE
);
719 gpy_object_state_t
* state
= x
->o
.object_state
;
721 struct gpy_typedef_t
* def
= state
->definition
;
722 if (def
->tp_eval_boolean
)
723 retval
= def
->tp_eval_boolean (x
);
728 gpy_object_t
* gpy_rr_eval_expression (gpy_object_t
* x1
,
732 gpy_object_t
* retval
= NULL
;
734 gpy_assert (x1
->T
== TYPE_OBJECT_STATE
);
735 gpy_assert (y1
->T
== TYPE_OBJECT_STATE
);
736 gpy_object_state_t
* x
= x1
->o
.object_state
;
737 gpy_object_state_t
* y
= y1
->o
.object_state
;
739 struct gpy_typedef_t
* def
= x1
->o
.object_state
->definition
;
740 struct gpy_number_prot_t
* binops
= (*def
).binary_protocol
;
741 struct gpy_number_prot_t binops_l
= (*binops
);
791 fatal("unhandled binary operation <%x>!\n", op
);
798 fatal ("no binary protocol!\n");