aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorredbrain <redbrain@gcc.gnu.org>2012-04-21 19:12:19 +0100
committerredbrain <redbrain@gcc.gnu.org>2012-04-21 19:12:19 +0100
commit6bb2994a691ee688ac538c2ac9d382804aad5abe (patch)
tree9bf8e9a3e0886c75383b07c144be6a157b285c11
parent30903ba9eb9e6b3f3d926041cfc438c71377d6f6 (diff)
lots of argument passing work finished and we can compile python nowalpha-v0.1
-rw-r--r--gcc/python/py-dot-pass-genericify.c217
-rw-r--r--gcc/python/py-parser.y4
-rw-r--r--gcc/python/py-runtime.c20
-rw-r--r--gcc/python/py-runtime.def12
-rw-r--r--gcc/python/py-runtime.h3
-rw-r--r--gcc/python/py-runtime.tpl2
-rw-r--r--libgpython/include/gpython/objects.h5
-rw-r--r--libgpython/include/gpython/runtime.h17
-rw-r--r--libgpython/runtime/py-obj_class.c88
-rw-r--r--libgpython/runtime/py-obj_classmethod.c17
-rw-r--r--libgpython/runtime/py-obj_staticmethod.c6
-rw-r--r--libgpython/runtime/py-runtime.c63
-rw-r--r--libgpython/runtime/py-type-utils.c15
13 files changed, 325 insertions, 144 deletions
diff --git a/gcc/python/py-dot-pass-genericify.c b/gcc/python/py-dot-pass-genericify.c
index 4546363c240..671b28605c0 100644
--- a/gcc/python/py-dot-pass-genericify.c
+++ b/gcc/python/py-dot-pass-genericify.c
@@ -195,6 +195,42 @@ void gpy_dot_pass_genericify_class_type (tree type, tree self,
}
static
+void gpy_dot_pass_genericify_arguments_to_context (gpy_context_t context,
+ gpy_dot_tree_t * parameters,
+ tree argdecl, tree * block)
+{
+ gpy_dot_tree_t *pnode = parameters;
+ if (pnode)
+ {
+ int offset = 0;
+ for (; pnode != NULL_DOT; pnode = DOT_CHAIN (pnode))
+ {
+ const char * parmid = DOT_IDENTIFIER_POINTER (pnode);
+ debug ("folding parameter <%s>!\n", parmid);
+
+ tree vardecl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (parmid),
+ gpy_object_type_ptr);
+
+ tree element_size = TYPE_SIZE_UNIT (gpy_object_type_ptr_ptr);
+ tree offs = fold_build2_loc (UNKNOWN_LOCATION, MULT_EXPR, sizetype,
+ build_int_cst (sizetype, offset),
+ element_size);
+ tree addr = fold_build2_loc (UNKNOWN_LOCATION, POINTER_PLUS_EXPR,
+ gpy_object_type_ptr_ptr,
+ argdecl, offs);
+
+ append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
+ vardecl,
+ build_fold_indirect_ref (addr)),
+ block);
+ gcc_assert (!gpy_dd_hash_insert (gpy_dd_hash_string (parmid), vardecl,
+ context));
+ offset++;
+ }
+ }
+}
+
+static
tree gpy_dot_pass_genericify_find_addr (const char * id,
const char * parent_ident,
VEC(tree,gc) * decls)
@@ -240,7 +276,8 @@ void gpy_dot_pass_genericify_walk_class (tree * block, tree type,
tree offs = fold_build2_loc (UNKNOWN_LOCATION, MULT_EXPR, sizetype,
build_int_cst (sizetype, offset),
element_size);
- tree a = GPY_RR_fold_attrib (gpy_dot_type_const_string_tree (ident),
+ tree str = gpy_dot_type_const_string_tree (ident);
+ tree a = GPY_RR_fold_attrib (build_fold_addr_expr (str),
gpy_dot_pass_genericify_find_addr (ident, type_name, ldecls),
offs);
VEC_safe_push (tree, gc, attribs, a);
@@ -257,8 +294,9 @@ void gpy_dot_pass_genericify_walk_class (tree * block, tree type,
attribs_decl,
GPY_RR_fold_attrib_list (args)),
block);
+ tree class_str = gpy_dot_type_const_string_tree (type_name);
tree fold_class = GPY_RR_fold_class_decl (attribs_decl, TYPE_SIZE_UNIT (type),
- gpy_dot_type_const_string_tree (type_name));
+ build_fold_addr_expr (class_str));
switch (TREE_CODE (decl))
{
@@ -492,10 +530,11 @@ tree gpy_dot_pass_genericify_modify (gpy_dot_tree_t * decl, tree * block,
tree lhs_tree = gpy_dot_pass_lower_expr (xlhs, block, context);
char * attrib_ident = DOT_IDENTIFIER_POINTER (xrhs);
+ tree str = gpy_dot_type_const_string_tree (attrib_ident);
append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr_ptr,
addr_1,
GPY_RR_fold_attrib_ref (lhs_tree,
- gpy_dot_type_const_string_tree (attrib_ident))),
+ build_fold_addr_expr (str))),
block);
tree refer = build_fold_indirect_ref (addr_1);
append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr_ptr,
@@ -606,9 +645,10 @@ tree gpy_dot_pass_lower_expr (gpy_dot_tree_t * decl, tree * block,
tree lhs_tree = gpy_dot_pass_lower_expr (xlhs, block, context);
char * attrib_ident = DOT_IDENTIFIER_POINTER (xrhs);
+ tree str = gpy_dot_type_const_string_tree (attrib_ident);
tree attrib_ref = build2 (MODIFY_EXPR, gpy_object_type_ptr_ptr, addr_1,
GPY_RR_fold_attrib_ref (lhs_tree,
- gpy_dot_type_const_string_tree (attrib_ident))
+ build_fold_addr_expr (str))
);
append_to_statement_list (attrib_ref, block);
retval = build_fold_indirect_ref (addr_1);
@@ -618,27 +658,66 @@ tree gpy_dot_pass_lower_expr (gpy_dot_tree_t * decl, tree * block,
case D_CALL_EXPR:
{
gpy_dot_tree_t * callid = DOT_lhs_TT (decl);
- tree call_decl = gpy_dot_pass_lower_expr (callid, block, context);
- gcc_assert (call_decl != error_mark_node);
+ if (DOT_TYPE (callid) == D_ATTRIB_REF)
+ {
+ tree call_decl = gpy_dot_pass_lower_expr (callid, block, context);
+ gcc_assert (call_decl != error_mark_node);
- gpy_dot_tree_t * argslist;
- VEC(tree,gc) * argsvec = VEC_alloc (tree,gc,0);
- for (argslist = DOT_rhs_TT (decl); argslist != NULL_DOT; argslist = DOT_CHAIN (argslist))
+ /* now we need to find the base of the attribute reference so we can pass self */
+ /* lets just assume we only handle x.y for now */
+ gpy_dot_tree_t * xlhs = DOT_lhs_TT (callid);
+ gpy_dot_tree_t * xrhs = DOT_rhs_TT (callid);
+
+ gcc_assert (DOT_TYPE (xlhs) == D_IDENTIFIER);
+ gcc_assert (DOT_TYPE (xrhs) == D_IDENTIFIER);
+
+ tree basetree = gpy_dot_pass_lower_expr (xlhs, block, context);
+
+ gpy_dot_tree_t * argslist;
+ VEC(tree,gc) * argsvec = VEC_alloc (tree,gc,0);
+ VEC_safe_push (tree, gc, argsvec, basetree);
+
+ for (argslist = DOT_rhs_TT (decl); argslist != NULL_DOT; argslist = DOT_CHAIN (argslist))
+ {
+ tree lexpr = gpy_dot_pass_lower_expr (argslist, block, context);
+ VEC_safe_push (tree, gc, argsvec, lexpr);
+ }
+ VEC(tree,gc) * args = VEC_alloc (tree,gc,0);
+ VEC_safe_push (tree, gc, args, call_decl);
+ VEC_safe_push (tree, gc, args, build_int_cst (integer_type_node, VEC_length (tree, argsvec)));
+ GPY_VEC_stmts_append (tree, args, argsvec);
+
+ tree retaddr = build_decl (UNKNOWN_LOCATION, VAR_DECL, create_tmp_var_name ("R"),
+ gpy_object_type_ptr);
+ append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr, retaddr,
+ GPY_RR_fold_call (args)),
+ block);
+ retval = retaddr;
+ }
+ else
{
- tree lexpr = gpy_dot_pass_lower_expr (argslist, block, context);
- VEC_safe_push (tree, gc, argsvec, lexpr);
+ tree call_decl = gpy_dot_pass_lower_expr (callid, block, context);
+ gcc_assert (call_decl != error_mark_node);
+
+ gpy_dot_tree_t * argslist;
+ VEC(tree,gc) * argsvec = VEC_alloc (tree,gc,0);
+ for (argslist = DOT_rhs_TT (decl); argslist != NULL_DOT; argslist = DOT_CHAIN (argslist))
+ {
+ tree lexpr = gpy_dot_pass_lower_expr (argslist, block, context);
+ VEC_safe_push (tree, gc, argsvec, lexpr);
+ }
+ VEC(tree,gc) * args = VEC_alloc (tree,gc,0);
+ VEC_safe_push (tree, gc, args, call_decl);
+ VEC_safe_push (tree, gc, args, build_int_cst (integer_type_node, VEC_length (tree, argsvec)));
+ GPY_VEC_stmts_append (tree, args, argsvec);
+
+ tree retaddr = build_decl (UNKNOWN_LOCATION, VAR_DECL, create_tmp_var_name ("R"),
+ gpy_object_type_ptr);
+ append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr, retaddr,
+ GPY_RR_fold_call (args)),
+ block);
+ retval = retaddr;
}
- VEC(tree,gc) * args = VEC_alloc (tree,gc,0);
- VEC_safe_push (tree, gc, args, call_decl);
- VEC_safe_push (tree, gc, args, build_int_cst (integer_type_node, VEC_length (tree, argsvec)));
- GPY_VEC_stmts_append (tree, args, argsvec);
-
- tree retaddr = build_decl (UNKNOWN_LOCATION, VAR_DECL, create_tmp_var_name ("R"),
- gpy_object_type_ptr);
- append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr, retaddr,
- GPY_RR_fold_call (args)),
- block);
- retval = retaddr;
}
break;
@@ -672,7 +751,7 @@ tree gpy_dot_pass_genericify_toplevl_functor_decl (gpy_dot_tree_t * decl,
VEC(gpy_context_t, gc) * context)
{
tree fntype = build_function_type_list (void_type_node,
- /* Arguments .. */
+ gpy_object_type_ptr_ptr,
NULL_TREE);
tree ident = GPY_dot_pass_genericify_gen_concat_identifier (GPY_current_module_name,
DOT_IDENTIFIER_POINTER (DOT_FIELD (decl))
@@ -686,6 +765,19 @@ tree gpy_dot_pass_genericify_toplevl_functor_decl (gpy_dot_tree_t * decl,
DECL_ARTIFICIAL(fndecl) = 1;
TREE_PUBLIC(fndecl) = 1;
+ tree arglist = NULL_TREE;
+ tree self_parm_decl = build_decl (BUILTINS_LOCATION, PARM_DECL,
+ get_identifier ("__arguments__"),
+ gpy_object_type_ptr_ptr);
+
+ DECL_CONTEXT (self_parm_decl) = fndecl;
+ DECL_ARG_TYPE (self_parm_decl) = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
+ TREE_READONLY (self_parm_decl) = 1;
+ arglist = chainon (arglist, self_parm_decl);
+
+ TREE_USED (self_parm_decl) = 1;
+ DECL_ARGUMENTS (fndecl) = arglist;
+
/* Define the return type (represented by RESULT_DECL) for the main functin */
tree resdecl = build_decl(BUILTINS_LOCATION, RESULT_DECL,
NULL_TREE, TREE_TYPE(fntype));
@@ -700,8 +792,12 @@ tree gpy_dot_pass_genericify_toplevl_functor_decl (gpy_dot_tree_t * decl,
DECL_INITIAL (fndecl) = block;
tree stmts = alloc_stmt_list ();
+
gpy_hash_tab_t ctx;
gpy_dd_hash_init_table (&ctx);
+ gpy_dot_tree_t * pnode = DOT_lhs_TT (decl);
+
+ gpy_dot_pass_genericify_arguments_to_context (&ctx, pnode, self_parm_decl, &stmts);
VEC_safe_push (gpy_context_t, gc, context, &ctx);
gpy_dot_tree_t * node = decl->opb.t;
@@ -757,12 +853,10 @@ tree gpy_dot_pass_genericify_class_method_attrib (gpy_dot_tree_t * decl,
const char * parent_ident,
VEC(gpy_context_t,gc) * context)
{
- tree params = NULL_TREE;
- gpy_dot_tree_t * pnode;
- for (pnode = DOT_lhs_TT (decl); pnode != NULL_DOT; pnode = DOT_CHAIN (pnode))
- chainon (params, tree_cons (NULL_TREE, gpy_object_type_ptr, NULL_TREE));
-
- tree fntype = build_function_type (void_type_node, params);
+ tree fntype = build_function_type_list (void_type_node,
+ gpy_object_type_ptr,
+ gpy_object_type_ptr_ptr,
+ NULL_TREE);
tree ident = GPY_dot_pass_genericify_gen_concat_identifier (GPY_current_module_name,
parent_ident);
ident = GPY_dot_pass_genericify_gen_concat_identifier (IDENTIFIER_POINTER (ident),
@@ -776,36 +870,29 @@ tree gpy_dot_pass_genericify_class_method_attrib (gpy_dot_tree_t * decl,
DECL_ARTIFICIAL(fndecl) = 1;
TREE_PUBLIC(fndecl) = 1;
- gpy_hash_tab_t ctx;
- gpy_dd_hash_init_table (&ctx);
-
- tree arglist = NULL_TREE;
- tree parm_decl = NULL_TREE;
tree self_parm_decl = NULL_TREE;
- for (pnode = DOT_lhs_TT (decl); pnode != NULL_DOT; pnode = DOT_CHAIN (pnode))
- {
- gcc_assert (DOT_TYPE(pnode) == D_IDENTIFIER);
- debug ("processing parameter <%s>!\n", DOT_IDENTIFIER_POINTER (pnode));
+ tree arglist = NULL_TREE;
+ tree parm_decl = build_decl (BUILTINS_LOCATION, PARM_DECL,
+ get_identifier ("self"),
+ gpy_object_type_ptr);
+
+ DECL_CONTEXT (parm_decl) = fndecl;
+ DECL_ARG_TYPE (parm_decl) = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
+ TREE_READONLY (parm_decl) = 1;
+ arglist = chainon (arglist, parm_decl);
+ TREE_USED (parm_decl) = 1;
+ self_parm_decl = parm_decl;
+
+ parm_decl = build_decl (BUILTINS_LOCATION, PARM_DECL,
+ get_identifier ("__arguments__"),
+ gpy_object_type_ptr_ptr);
+
+ DECL_CONTEXT (parm_decl) = fndecl;
+ DECL_ARG_TYPE (parm_decl) = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
+ TREE_READONLY (parm_decl) = 1;
+ arglist = chainon (arglist, parm_decl);
+ TREE_USED (parm_decl) = 1;
- parm_decl = build_decl (BUILTINS_LOCATION, PARM_DECL,
- get_identifier (DOT_IDENTIFIER_POINTER (pnode)),
- gpy_object_type_ptr);
-
- DECL_CONTEXT (parm_decl) = fndecl;
- DECL_ARG_TYPE (parm_decl) = gpy_object_type_ptr;
- TREE_READONLY (parm_decl) = 1;
- arglist = chainon (arglist, parm_decl);
-
- TREE_USED (parm_decl) = 1;
- if (!strcmp ("self", DOT_IDENTIFIER_POINTER (pnode)))
- self_parm_decl = parm_decl;
- else
- {
- gcc_assert (!gpy_dd_hash_insert (gpy_dd_hash_string (DOT_IDENTIFIER_POINTER (pnode)),
- parm_decl,
- &ctx));
- }
- }
DECL_ARGUMENTS (fndecl) = arglist;
/* Define the return type (represented by RESULT_DECL) for the main functin */
@@ -821,15 +908,22 @@ tree gpy_dot_pass_genericify_class_method_attrib (gpy_dot_tree_t * decl,
tree block = build_block (NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE);
DECL_INITIAL (fndecl) = block;
+ tree stmts = alloc_stmt_list ();
+
+ gpy_hash_tab_t ctx;
+ gpy_dd_hash_init_table (&ctx);
+
+ gpy_dot_tree_t * pnode = DOT_lhs_TT (decl);
+ // we dont care about self...
+ pnode = DOT_CHAIN (pnode);
+
+ gpy_dot_pass_genericify_arguments_to_context (&ctx, pnode, parm_decl, &stmts);
if (self_parm_decl)
gcc_assert (!gpy_dd_hash_insert (gpy_dd_hash_string ("self"), self_parm_decl,
&ctx));
else
warning(0, "No self parameter declared!\n");
-
VEC_safe_push (gpy_context_t, gc, context, &ctx);
-
- tree stmts = alloc_stmt_list ();
/*
lower the function suite here and append all initilization
*/
@@ -1088,9 +1182,10 @@ VEC(tree,gc) * gpy_dot_pass_genericify_TU (gpy_hash_tab_t * modules,
/* assign the function to the decl */
const char * funcid = DOT_IDENTIFIER_POINTER (DOT_FIELD (idtx));
tree funcdecl = gpy_dot_pass_decl_lookup (context, funcid);
+ tree str = gpy_dot_type_const_string_tree (funcid);
append_to_statement_list (build2 (MODIFY_EXPR, gpy_object_type_ptr,
funcdecl,
- GPY_RR_fold_func_decl (gpy_dot_type_const_string_tree (funcid),
+ GPY_RR_fold_func_decl (build_fold_addr_expr (str),
t)),
&stmts);
}
diff --git a/gcc/python/py-parser.y b/gcc/python/py-parser.y
index a518fb2501a..eb2f411de97 100644
--- a/gcc/python/py-parser.y
+++ b/gcc/python/py-parser.y
@@ -222,12 +222,12 @@ parameter_list_stmt:
{ $$ = VEC_pop (gpydot, gpy_symbol_stack); }
;
-parameter_list: parameter_list ',' target
+parameter_list: parameter_list ',' ident
{
DOT_CHAIN($1) = $3;
$$ = $3;
}
- | target
+ | ident
{
VEC_safe_push (gpydot, gc,
gpy_symbol_stack, $1);
diff --git a/gcc/python/py-runtime.c b/gcc/python/py-runtime.c
index c9213fac8b5..64834471d4f 100644
--- a/gcc/python/py-runtime.c
+++ b/gcc/python/py-runtime.c
@@ -315,6 +315,26 @@ tree GPY_RR_fold_call (VEC(tree,gc) * arguments)
return build_call_expr_loc_vec (BUILTINS_LOCATION, fndecl, arguments);
}
+tree GPY_RR_fold_argument (tree args, tree offset)
+{
+ tree fntype = build_function_type_list (gpy_object_type_ptr,
+ gpy_object_type_ptr_ptr,
+ integer_type_node,
+ NULL_TREE);
+ tree fndecl = build_decl (BUILTINS_LOCATION, FUNCTION_DECL,
+ get_identifier ("gpy_rr_fold_argument"),
+ fntype);
+ tree restype = TREE_TYPE (fndecl);
+ tree resdecl = build_decl (BUILTINS_LOCATION, RESULT_DECL, NULL_TREE,
+ restype);
+ DECL_CONTEXT (resdecl) = fndecl;
+ DECL_RESULT (fndecl) = resdecl;
+ DECL_EXTERNAL (fndecl) = 1;
+ TREE_PUBLIC (fndecl) = 1;
+
+ return build_call_expr (fndecl, 2, args, offset);
+}
+
static
tree gpy_build_py_vector_type (void)
diff --git a/gcc/python/py-runtime.def b/gcc/python/py-runtime.def
index 81484017119..696ba90a901 100644
--- a/gcc/python/py-runtime.def
+++ b/gcc/python/py-runtime.def
@@ -172,3 +172,15 @@ py-runtime = { code = GPY_RR_fold_call;
build_call = build_call_expr_loc_vec;
build_call_args = "BUILTINS_LOCATION, fndecl, arguments";
};
+py-runtime = { code = GPY_RR_fold_argument;
+ arguments = "tree args, tree offset";
+ proto = "tree, tree";
+ comment = "/* Eval arg */";
+ function_identifier = "gpy_rr_fold_argument";
+ fntype = "gpy_object_type_ptr,
+ gpy_object_type_ptr_ptr,
+ integer_type_node,
+ NULL_TREE";
+ build_call = build_call_expr;
+ build_call_args = "fndecl, 2, args, offset";
+ }; \ No newline at end of file
diff --git a/gcc/python/py-runtime.h b/gcc/python/py-runtime.h
index 02a6165a76c..6c8ab6a1460 100644
--- a/gcc/python/py-runtime.h
+++ b/gcc/python/py-runtime.h
@@ -75,5 +75,8 @@ extern tree GPY_RR_fold_attrib_ref (tree, tree);
/* Eval call */
extern tree GPY_RR_fold_call (VEC(tree,gc) *);
+/* Eval arg */
+extern tree GPY_RR_fold_argument (tree, tree);
+
#endif //__GCC_PY_RUNTIME_H__
diff --git a/gcc/python/py-runtime.tpl b/gcc/python/py-runtime.tpl
index eb4a9a43b62..75e4f119d51 100644
--- a/gcc/python/py-runtime.tpl
+++ b/gcc/python/py-runtime.tpl
@@ -288,7 +288,7 @@ void gpy_dot_types_init (void)
{
gpy_builtin_types_vec = VEC_alloc (tree,gc,0);
- tree const_char_type = build_qualified_type (char_type_node,
+ tree const_char_type = build_qualified_type (unsigned_char_type_node,
TYPE_QUAL_CONST);
tree ctype = build_pointer_type (const_char_type);
diff --git a/libgpython/include/gpython/objects.h b/libgpython/include/gpython/objects.h
index 114a551c676..ecc8d72d8a8 100644
--- a/libgpython/include/gpython/objects.h
+++ b/libgpython/include/gpython/objects.h
@@ -67,7 +67,8 @@ typedef struct gpy_object_t {
} o ;
} gpy_object_t ;
-typedef void (*fndecl)(gpy_object_t **);
+typedef void (*staticmethod_fndecl)(gpy_object_t **);
+typedef void (*classmethod_fndecl) (gpy_object_t *, gpy_object_t **);
typedef gpy_object_t * (*binary_op)(gpy_object_t *, gpy_object_t *);
typedef struct gpy_number_prot_t
{
@@ -119,8 +120,10 @@ extern gpy_object_attrib_t ** gpy_args_lit_parse_attrib_table (gpy_object_t *);
extern gpy_object_t * gpy_create_object_state (gpy_typedef_t *, void *);
extern gpy_object_t * gpy_create_object_decl (gpy_typedef_t *, void *);
extern unsigned char * gpy_object_staticmethod_getaddr (gpy_object_t *);
+extern unsigned char * gpy_object_classmethod_getaddr (gpy_object_t *);
extern void gpy_obj_integer_mod_init (gpy_vector_t * const);
extern void gpy_obj_staticmethod_mod_init (gpy_vector_t * const);
+extern void gpy_object_classmethod_inherit_self (gpy_object_t *, gpy_object_t *);
#endif //__GCC_OBJECTS_H__
diff --git a/libgpython/include/gpython/runtime.h b/libgpython/include/gpython/runtime.h
index cf049237667..11ecfd3597e 100644
--- a/libgpython/include/gpython/runtime.h
+++ b/libgpython/include/gpython/runtime.h
@@ -17,7 +17,22 @@ along with GCC; see the file COPYING3. If not see
#ifndef __GCC_RUNTIME_H__
#define __GCC_RUNTIME_H__
-extern gpy_object_t * gpy_rr_fold_functor_decl (const char *, unsigned char *);
+/*
+ accesors to the internal types...
+ */
+#define __gpy_integer_type_node \
+ (gpy_typedef_t *) __GPY_GLOBL_PRIMITIVES->vector[0]
+#define __gpy_staticmethod_type_node \
+ (gpy_typedef_t *) __GPY_GLOBL_PRIMITIVES->vector[1]
+#define __gpy_class_type_node \
+ (gpy_typedef_t *) __GPY_GLOBL_PRIMITIVES->vector[2]
+#define __gpy_classmethod_type_node \
+ (gpy_typedef_t *) __GPY_GLOBL_PRIMITIVES->vector[3]
+
+extern gpy_object_t * gpy_rr_fold_staticmethod_decl (const char *, unsigned char *);
+extern gpy_object_t * gpy_rr_fold_classmethod_decl (const char *, unsigned char *);
extern unsigned char * gpy_rr_eval_attrib_reference (gpy_object_t *, const char *);
+extern void gpy_rr_eval_print (int, int, ...);
+
#endif //__GCC_RUNTIME_H__
diff --git a/libgpython/runtime/py-obj_class.c b/libgpython/runtime/py-obj_class.c
index d002f8b2739..ab501809867 100644
--- a/libgpython/runtime/py-obj_class.c
+++ b/libgpython/runtime/py-obj_class.c
@@ -42,8 +42,32 @@ void gpy_object_classobj_init_decl_attribs (const void * self,
for (idx = 0; attribs[idx] != NULL; ++idx)
{
gpy_object_attrib_t * i = attribs[idx];
- unsigned char * x = selfptr + (i->offset);
- x = (unsigned char *) &(i->addr);
+ unsigned char * typeoffs = selfptr + (i->offset);
+
+ gpy_object_t ** offs = (gpy_object_t **) typeoffs;
+ if (i->addr)
+ {
+ gpy_object_t * attrib = (gpy_object_t *)i->addr;
+ *offs = i->addr;
+ }
+ else
+ *offs = NULL;
+ }
+}
+
+static
+void gpy_object_classobj_methodattribs_addself (gpy_object_attrib_t ** attribs,
+ gpy_object_t * self)
+{
+ int idx;
+ for (idx = 0; attribs[idx] != NULL; ++idx)
+ {
+ gpy_object_attrib_t * i = attribs[idx];
+ if (i->addr)
+ {
+ gpy_object_t * att = (gpy_object_t *) i->addr;
+ gpy_object_classmethod_inherit_self (att, self);
+ }
}
}
@@ -78,10 +102,9 @@ gpy_object_t * gpy_object_classobj_new (gpy_typedef_t * type,
/* we need to walk though the field_init here */
unsigned char * __field_init__ = gpy_rr_eval_attrib_reference (retval, "__field_init__");
gpy_object_t * field_init = *((gpy_object_t **) __field_init__);
- unsigned char * codeaddr = gpy_object_staticmethod_getaddr (field_init);
+ unsigned char * codeaddr = gpy_object_classmethod_getaddr (field_init);
gpy_assert (codeaddr);
- debug ("calling the __init__!\n");
__field_init_ptr c = (__field_init_ptr)codeaddr;
c (self);
@@ -117,25 +140,58 @@ void gpy_object_classobj_print (gpy_object_t * self, FILE *fd, bool newline)
fprintf (fd, "\n");
}
+static
+gpy_object_t ** gpy_object_classobj_setupargs (gpy_object_t ** args,
+ gpy_object_t * self)
+{
+ int idx = 0;
+ gpy_object_t ** ptr;
+ for (ptr = args; *ptr != NULL; ++ptr)
+ idx ++;
+
+ gpy_object_t ** newargs = calloc (idx+2, sizeof (gpy_object_t *));
+ *newargs = self;
+ gpy_object_t ** newargsptr = newargs;
+ newargsptr++;
+
+ for (ptr = args; *ptr != NULL; ++ptr)
+ {
+ *newargsptr = *ptr;
+ newargsptr++;
+ }
+ *newargsptr = NULL;
+
+ return newargs;
+}
+
gpy_object_t * gpy_object_classobj_call (gpy_object_t * self,
gpy_object_t ** args)
{
- gpy_object_t * retval = NULL_OBJECT;
- gpy_assert (self->T == TYPE_OBJECT_DECL);
+ gpy_object_t * retval = NULL_OBJECT;
+ gpy_assert (self->T == TYPE_OBJECT_DECL);
+
+ gpy_typedef_t * type = self->o.object_state->definition;
+ void * oldstate = self->o.object_state->state;
- gpy_typedef_t * type = self->o.object_state->definition;
- void * state = self->o.object_state->state;
- retval = gpy_create_object_state (type, state);
- gpy_assert (retval);
+ void * newstate = malloc (type->state_size);
+ memcpy (newstate, oldstate, type->state_size);
+ retval = gpy_create_object_state (type, newstate);
+ gpy_assert (retval);
- unsigned char * __init__ = gpy_rr_eval_attrib_reference (retval, "__init__");
- gpy_object_t * init = *((gpy_object_t **)__init__);
- unsigned char * codeaddr = gpy_object_staticmethod_getaddr (init);
- gpy_assert (codeaddr);
+ unsigned char * __init__ = gpy_rr_eval_attrib_reference (retval, "__init__");
+ gpy_object_t * init = *((gpy_object_t **) __init__);
-
+ gpy_assert (init->T == TYPE_OBJECT_DECL);
+ gpy_typedef_t * calltype = init->o.object_state->definition;
+ if (type->tp_call)
+ {
+ gpy_object_t ** arguments = gpy_object_classobj_setupargs (args, retval);
+ calltype->tp_call (init, arguments);
+ }
+ else
+ fatal ("name is not callable!\n");
- return retval;
+ return retval;
}
static struct gpy_typedef_t class_obj = {
diff --git a/libgpython/runtime/py-obj_classmethod.c b/libgpython/runtime/py-obj_classmethod.c
index 815c017b886..b2a80cad1bd 100644
--- a/libgpython/runtime/py-obj_classmethod.c
+++ b/libgpython/runtime/py-obj_classmethod.c
@@ -31,13 +31,13 @@ along with GCC; see the file COPYING3. If not see
#include <gpython/objects.h>
struct gpy_object_classmethod_t {
- const unsigned char * code;
- const char * identifier;
+ unsigned char * code;
+ char * identifier;
unsigned int nargs;
};
gpy_object_t * gpy_object_classmethod_new (gpy_typedef_t * type,
- gpy_object_t ** args)
+ gpy_object_t ** args)
{
gpy_object_t * retval = NULL_OBJECT;
@@ -76,16 +76,19 @@ void gpy_object_classmethod_print (gpy_object_t * self, FILE *fd, bool newline)
}
gpy_object_t * gpy_object_classmethod_call (gpy_object_t * self,
- gpy_object_t ** args)
+ gpy_object_t ** args)
{
gpy_object_t * retval = NULL_OBJECT;
gpy_assert (self->T == TYPE_OBJECT_DECL);
struct gpy_object_classmethod_t * state = self->o.object_state->state;
- if (!state->code)
+ if (state->code)
{
- fndecl fnptr = (fndecl)state->code;
- fnptr (args);
+ classmethod_fndecl fnptr = (classmethod_fndecl)state->code;
+ gpy_object_t ** ptr = args;
+ gpy_object_t * class = *ptr;
+ ptr++;
+ fnptr (class, ptr);
}
return retval;
}
diff --git a/libgpython/runtime/py-obj_staticmethod.c b/libgpython/runtime/py-obj_staticmethod.c
index 0f287e18f9e..c7f791466ad 100644
--- a/libgpython/runtime/py-obj_staticmethod.c
+++ b/libgpython/runtime/py-obj_staticmethod.c
@@ -31,8 +31,8 @@ along with GCC; see the file COPYING3. If not see
#include <gpython/objects.h>
struct gpy_object_staticmethod_t {
- const unsigned char * code;
- const char * identifier;
+ unsigned char * code;
+ char * identifier;
unsigned int nargs;
};
@@ -85,7 +85,7 @@ gpy_object_t * gpy_object_staticmethod_call (gpy_object_t * self,
struct gpy_object_staticmethod_t * state = self->o.object_state->state;
if (!state->code)
{
- fndecl fnptr = (fndecl)state->code;
+ staticmethod_fndecl fnptr = (staticmethod_fndecl)state->code;
fnptr (args);
}
return retval;
diff --git a/libgpython/runtime/py-runtime.c b/libgpython/runtime/py-runtime.c
index a518ba9db69..6dfcd55f001 100644
--- a/libgpython/runtime/py-runtime.c
+++ b/libgpython/runtime/py-runtime.c
@@ -81,7 +81,7 @@ void gpy_rr_extend_runtime_stack (int nslots)
__GPY_GLOBL_RR_STACK = gpy_realloc (__GPY_GLOBL_RR_STACK, size);
__GPY_GLOBL_RR_STACK_POINTER = __GPY_GLOBL_RR_STACK;
- __GPY_GLOBL_RR_STACK2_POINTER += 3+nslots;
+ __GPY_GLOBL_RR_STACK_POINTER += 3 + nslots;
}
void gpy_rr_init_runtime (void)
@@ -97,7 +97,7 @@ void gpy_rr_cleanup_final (void)
mpfr_free_cache ();
}
-gpy_object_attrib_t * gpy_rr_fold_attribute (const char * identifier,
+gpy_object_attrib_t * gpy_rr_fold_attribute (const unsigned char * identifier,
unsigned char * code_addr,
unsigned int offset)
{
@@ -168,15 +168,10 @@ gpy_object_t * gpy_rr_fold_class_decl (gpy_object_attrib_t ** attribs,
args[2] = &a3;
args[3] = &a4;
- gpy_typedef_t * def = (gpy_typedef_t *)
- __GPY_GLOBL_PRIMITIVES->vector[2];
- gpy_assert (def);
-
+ gpy_typedef_t * def = __gpy_class_type_node;
retval = def->tp_new (def, args);
gpy_free (args);
- debug ("initilized class object <%p> to <%s>!\n",
- (void*)retval, identifier);
gpy_assert (retval->T == TYPE_OBJECT_DECL);
return retval;
@@ -212,15 +207,10 @@ gpy_object_t * gpy_rr_fold_staticmethod_decl (const char * identifier,
args[2] = &a3;
args[3] = &a4;
- gpy_typedef_t * def = (gpy_typedef_t *)
- __GPY_GLOBL_PRIMITIVES->vector[1];
- gpy_assert (def);
-
+ gpy_typedef_t * def = __gpy_staticmethod_type_node;
retval = def->tp_new (def, args);
gpy_free (args);
- debug ("initilized staticmethod object <%p> to <%s>!\n",
- (void*)retval, identifier);
gpy_assert (retval->T == TYPE_OBJECT_DECL);
return retval;
@@ -234,9 +224,9 @@ gpy_object_t * gpy_rr_fold_classmethod_decl (const char * identifier,
gpy_object_t ** args = (gpy_object_t **)
gpy_calloc (4, sizeof(gpy_object_t*));
- gpy_literal_t i;
- i.type = TYPE_STRING;
- i.literal.string = (char *)identifier;
+ gpy_literal_t s;
+ s.type = TYPE_STRING;
+ s.literal.string = (char *)identifier;
gpy_literal_t p;
p.type = TYPE_ADDR;
@@ -246,7 +236,7 @@ gpy_object_t * gpy_rr_fold_classmethod_decl (const char * identifier,
n.type = TYPE_INTEGER;
n.literal.integer = 0;
- gpy_object_t a1 = { .T = TYPE_OBJECT_LIT, .o.literal = &i };
+ gpy_object_t a1 = { .T = TYPE_OBJECT_LIT, .o.literal = &s };
gpy_object_t a2 = { .T = TYPE_OBJECT_LIT, .o.literal = &p };
gpy_object_t a3 = { .T = TYPE_OBJECT_LIT, .o.literal = &n };
gpy_object_t a4 = { .T = TYPE_NULL, .o.literal = NULL };
@@ -256,15 +246,10 @@ gpy_object_t * gpy_rr_fold_classmethod_decl (const char * identifier,
args[2] = &a3;
args[3] = &a4;
- gpy_typedef_t * def = (gpy_typedef_t *)
- __GPY_GLOBL_PRIMITIVES->vector[1];
- gpy_assert (def);
-
+ gpy_typedef_t * def = __gpy_classmethod_type_node;
retval = def->tp_new (def, args);
gpy_free (args);
- debug ("initilized classmethod object <%p> to <%s>!\n",
- (void*)retval, identifier);
gpy_assert (retval->T == TYPE_OBJECT_DECL);
return retval;
@@ -277,11 +262,21 @@ gpy_object_t * gpy_rr_fold_call (gpy_object_t * decl, int nargs, ...)
gpy_assert (decl->T == TYPE_OBJECT_DECL);
gpy_typedef_t * type = decl->o.object_state->definition;
- gpy_assert (type->members_defintion);
+
+ /* + 1 for sentinal */
+ gpy_object_t ** args = calloc (nargs + 1, sizeof (gpy_object_t *));
+ va_list ap;
+ int idx;
+ va_start (ap, nargs);
+ for (idx = 0; idx < nargs; ++idx)
+ {
+ args[idx] = va_arg (ap, gpy_object_t *);
+ }
+ args[idx] = NULL;
if (type->tp_call)
{
- retval = type->tp_call (decl, NULL);
+ retval = type->tp_call (decl, args);
}
else
fatal ("name is not callable!\n");
@@ -289,17 +284,12 @@ gpy_object_t * gpy_rr_fold_call (gpy_object_t * decl, int nargs, ...)
return retval;
}
-
-
unsigned char * gpy_rr_eval_attrib_reference (gpy_object_t * base,
const char * attrib)
{
unsigned char * retval = NULL;
- gpy_assert (base->T == TYPE_OBJECT_STATE);
-
gpy_typedef_t * type = base->o.object_state->definition;
- gpy_assert (type->members_defintion);
-
+
struct gpy_object_attrib_t ** members = type->members_defintion;
gpy_object_state_t * objs = base->o.object_state;
@@ -336,15 +326,9 @@ gpy_object_t * gpy_rr_fold_integer (const int x)
args[0] = &a1;
args[1] = &a2;
- gpy_typedef_t * Int_def = (gpy_typedef_t *)
- __GPY_GLOBL_PRIMITIVES->vector[0];
- gpy_assert (Int_def);
-
+ gpy_typedef_t * Int_def = __gpy_integer_type_node;
retval = Int_def->tp_new (Int_def, args);
gpy_free(args);
-
- debug ("initilized integer object <%p> to <%i>!\n",
- (void*)retval, x );
gpy_assert (retval->T == TYPE_OBJECT_STATE);
return retval;
@@ -370,7 +354,6 @@ void gpy_rr_eval_print (int fd, int count, ...)
for (idx = 0; idx<count; ++idx)
{
it = va_arg (vl, gpy_object_t *);
- gpy_assert (it->T == TYPE_OBJECT_STATE);
struct gpy_typedef_t * definition = it->o.object_state->definition;
switch (fd)
diff --git a/libgpython/runtime/py-type-utils.c b/libgpython/runtime/py-type-utils.c
index e11923e9a05..dfa4ca54f7a 100644
--- a/libgpython/runtime/py-type-utils.c
+++ b/libgpython/runtime/py-type-utils.c
@@ -32,7 +32,8 @@ along with GCC; see the file COPYING3. If not see
#define GPY_ARG_LIT_CHECK(A,I,X) \
gpy_assert (A[I]->T == TYPE_OBJECT_LIT); \
- gpy_assert (A[I]->o.literal->type == X);
+ gpy_assert (A[I]->o.literal->type == X); \
+ ++I;
bool gpy_args_check_fmt (gpy_object_t ** args, const char * fmt)
{
@@ -53,27 +54,24 @@ bool gpy_args_check_fmt (gpy_object_t ** args, const char * fmt)
case 'i':
{
GPY_ARG_LIT_CHECK (args, idx, TYPE_INTEGER);
- debug ("integer check pass!\n");
}
break;
case 's':
{
GPY_ARG_LIT_CHECK (args, idx, TYPE_STRING);
- debug ("string check pass!\n");
}
+ break;
case 'p':
{
GPY_ARG_LIT_CHECK (args, idx, TYPE_ADDR);
- debug ("pointer check pass!\n");
}
break;
case 'A':
{
GPY_ARG_LIT_CHECK (args, idx, TYPE_ATTRIB_L);
- debug ("pointer check pass!\n");
}
break;
@@ -84,9 +82,6 @@ bool gpy_args_check_fmt (gpy_object_t ** args, const char * fmt)
}
break;
}
- if (!retval)
- break;
- idx++;
}
return retval;
}
@@ -99,7 +94,6 @@ int gpy_args_lit_parse_int (gpy_object_t * arg)
gpy_assert (arg->o.literal->type == TYPE_INTEGER);
retval = arg->o.literal->literal.integer;
- debug ("parsed int <%i>!\n", retval);
return retval;
}
@@ -111,7 +105,6 @@ char * gpy_args_lit_parse_string (gpy_object_t * arg)
gpy_assert (arg->o.literal->type == TYPE_STRING);
retval = arg->o.literal->literal.string;
- debug ("parsed string <%s>!\n", retval);
return retval;
}
@@ -123,7 +116,6 @@ unsigned char * gpy_args_lit_parse_pointer (gpy_object_t * arg)
gpy_assert (arg->o.literal->type == TYPE_ADDR);
retval = arg->o.literal->literal.addr;
- debug ("parsed pointer <%p>!\n", (void*) retval);
return retval;
}
@@ -135,7 +127,6 @@ gpy_object_attrib_t ** gpy_args_lit_parse_attrib_table (gpy_object_t * arg)
gpy_assert (arg->o.literal->type == TYPE_ATTRIB_L);
retval = arg->o.literal->literal.attribs;
- debug ("parsed attribute table <%p>!\n", (void*) retval);
return retval;
}