diff --git a/lang/boolean.c b/lang/boolean.c index eab6ca0..b031635 100644 --- a/lang/boolean.c +++ b/lang/boolean.c @@ -33,7 +33,7 @@ return boolean->value; } -static void boolean_invert(VmState state, Object obj, void *priv) { +static void boolean_invert(VmState state, Object obj, int priv) { (void)priv; int arg_count = vm_stack_depth(state); vm_abort_if(state, arg_count != 1, @@ -44,7 +44,7 @@ } static struct object_call calls[] = { - {.name = "Invert", .handler = boolean_invert, .priv = NULL}, + {.name = "Invert", .handler = boolean_invert, .priv = 0}, {.name = NULL, /* end */}}; static struct object_class boolean_class = { diff --git a/lang/compile.py b/lang/compile.py index fc19ad9..2f9f388 100755 --- a/lang/compile.py +++ b/lang/compile.py @@ -980,30 +980,38 @@ static void CLASSNAME_cleanup(VmState state, Object obj) { struct object_list **args = (struct object_list **)object_priv(state, obj, &CLASSNAME_class); free_args(state, args); -} - -static void CLASSNAME_call_bytecode(VmState state, Object obj, void *priv) { - struct object_list **args = (struct object_list **)object_priv(state, obj, &CLASSNAME_class); - bytecode_run(state, obj, (const unsigned char *)priv, *args); }""" -def generate_class_call(class_name, func_name): - call = '{.name = "%s", .handler = CLASSNAME_call_bytecode, ' % (func_name) - call += '\n\t\t.priv = (void *)bytecode_%s_%s },\n\t' % (class_name, func_name) +def generate_class_call(class_name, func_name, index): + call = '{.name = "%s", .handler = CLASSNAME_call_bytecode, .priv = %s },\n\t' % (func_name, index) return call def generate_class_structs(class_ir): calls = "" + bytecodes = "" + index = 0 for func in class_ir.functions: - calls += generate_class_call(class_ir.name, func) - return """static struct object_call CLASSNAME_calls[] = { + calls += generate_class_call(class_ir.name, func, index) + bytecodes += "bytecode_%s_%s,\n\t" % (class_ir.name, func) + index += 1 + return """static const unsigned char *CLASSNAME_bytecodes[] = { + %sNULL, +}; + +static void CLASSNAME_call_bytecode(VmState state, Object obj, int priv) { + struct object_list **args = (struct object_list **)object_priv(state, obj, &CLASSNAME_class); + const unsigned char *bytecode = CLASSNAME_bytecodes[priv]; + bytecode_run(state, obj, bytecode, *args); +} + +static struct object_call CLASSNAME_calls[] = { %s{.name = NULL, /* end */ }, }; static struct object_class CLASSNAME_class = { .cleanup = CLASSNAME_cleanup, .calls = &CLASSNAME_calls[0], -};""" % (calls) +};""" % (bytecodes, calls) def generate_c_class(class_ir): functions = [] diff --git a/lang/object.h b/lang/object.h index ebc16a2..1ff70bf 100644 --- a/lang/object.h +++ b/lang/object.h @@ -9,8 +9,8 @@ // Dispatchable object call struct object_call { const char *name; - void (*handler)(VmState state, Object obj, void *priv); - void *priv; + void (*handler)(VmState state, Object obj, int priv); + int priv; }; // Object class shared between objects diff --git a/lang/rational.c b/lang/rational.c index 47247eb..9c27d60 100644 --- a/lang/rational.c +++ b/lang/rational.c @@ -57,12 +57,12 @@ return &ratio->value; } -#define OP_ADD (void *)1 -#define OP_SUBTRACT (void *)2 -#define OP_DIVIDE (void *)3 -#define OP_MULTIPLY (void *)4 +#define OP_ADD 1 +#define OP_SUBTRACT 2 +#define OP_DIVIDE 3 +#define OP_MULTIPLY 4 -static void rational_math(VmState state, Object obj, void *priv) { +static void rational_math(VmState state, Object obj, int priv) { int arg_count = vm_stack_depth(state); vm_abort_if(state, arg_count != 2, "rational_math called without 2 arguments"); @@ -87,7 +87,7 @@ mpq_clear(result); } -static void rational_equals(VmState state, Object obj, void *priv) { +static void rational_equals(VmState state, Object obj, int priv) { (void)priv; int arg_count = vm_stack_depth(state); vm_abort_if(state, arg_count != 2, @@ -105,7 +105,7 @@ {.name = "Subtract", .handler = rational_math, .priv = OP_SUBTRACT}, {.name = "Divide", .handler = rational_math, .priv = OP_DIVIDE}, {.name = "Multiply", .handler = rational_math, .priv = OP_MULTIPLY}, - {.name = "Equals", .handler = rational_equals, .priv = NULL}, + {.name = "Equals", .handler = rational_equals, .priv = 0}, {.name = NULL, /* end */}}; static struct object_class ratio_class = {