# HG changeset patch # User Mike Pavone # Date 1341894748 25200 # Node ID bf5e88f6419dfd396edc5a29c2b65cf6b3b351c5 # Parent a10f1b049193db2ce70b45bfcfceabda533e94b0 Use a function/method call strategy that actually works diff -r a10f1b049193 -r bf5e88f6419d cbackend.js --- a/cbackend.js Mon Jul 09 08:57:50 2012 -0700 +++ b/cbackend.js Mon Jul 09 21:32:28 2012 -0700 @@ -42,10 +42,7 @@ op.prototype.toC = function(isReceiver) { var optoMeth = {'+': 'ADD_', '-': 'SUB_', '*': 'MUL_', '/': 'DIV_', '=': 'EQ_', '!=': 'NEQ_', '<': 'LT_', '>': 'GT_', '>=': 'GEQ_', '<=': 'LEQ_'}; var method = optoMeth[this.op]; - var ret = '(params[0] = ' + this.left.toC() + ',\n'; - ret += 'params[1] = ' + this.right.toC() + ',\n'; - ret += 'mcall(' + getMethodId(method) + ', 2, params))\n'; - return ret; + return 'mcall(' + getMethodId(method) + ', 2, ' + this.left.toC() + ', ' + this.right.toC() + ')\n'; }; function escapeCName(name) @@ -65,7 +62,6 @@ throw new Error('symbol ' + name + ' not found'); } var pre = ''; - console.log('symbol', info); switch(info.type) { case 'self': pre = 'self->'; @@ -158,7 +154,7 @@ } } for (var i in args) { - args[i] = 'params[' + i + '] = ' + args[i].toC() + ',\n'; + args[i] = ', ' + args[i].toC(); } var callpart; if (method) { @@ -166,7 +162,7 @@ } else { callpart = 'ccall(' + escapeCName(name); } - return '(' + args.join('') + callpart + ', ' + args.length + ', ' + 'params))'; + return callpart + ', ' + args.length + args.join('') + ')'; } function cObject(name) { @@ -174,6 +170,7 @@ this.slots = {}; this.properties = []; this.values = []; + this.slotvars = {}; } cObject.prototype.addMessage = function(msgname, implementation) { @@ -190,13 +187,22 @@ this.properties.push([propname, type]); } else { var escaped = escapeCName(propname); - this.addMessage(propname, 'return self->' + escaped + ';'); - this.addMessage(propname + '!', 'self->' + escaped + ' = params[1]; return params[0];'); + this.addMessage(propname, 'va_end(args); return self->' + escaped + ';'); + this.addMessageVar(propname + '!', 'setval', 'object *'); + this.addMessage(propname + '!', 'setval = va_arg(args, object *); va_end(args); self->' + escaped + ' = setval; return (object *)self;'); this.properties.push(escaped); this.values.push(value); } } +cObject.prototype.addMessageVar = function(msgname, varname, type) { + var trunc = getMethodId(msgname) & 0xF; + if (!(trunc in this.slotvars)) { + this.slotvars[trunc] = {}; + } + this.slotvars[trunc][varname] = type; +} + cObject.prototype.toEarlyCDef = function() { var objdef = 'typedef struct {\n\tobject header;\n'; for (var i in this.properties) { @@ -218,20 +224,24 @@ metadef += ', '; } if (i in this.slots) { - slotdefs += 'object * ' + this.name + '_slot_' + i + '(uint32_t method_id, uint32_t num_params, object ** params) {\n\t' + - this.name + ' *self = (' + this.name + ' *)params[0];'; + slotdefs += 'object * ' + this.name + '_slot_' + i + '(uint32_t method_id, uint32_t num_params, object * oself, va_list args) {\n\t' + + this.name + ' *self = (' + this.name + ' *)oself;\n'; + for (var varname in this.slotvars[i]) { + slotdefs += '\t' + this.slotvars[i][varname] + ' ' + varname + ';\n'; + } if (this.slots[i].length == 1) { slotdefs += '\tif (method_id == ' + this.slots[i][0][0] + ') { /* ' + this.slots[i][0][2] + '*/\n' + '\t\t' + this.slots[i][0][1] + '\n' + '\t}\n' + - '\treturn no_impl(method_id, num_params, params);\n}\n'; + '\treturn no_impl(method_id, num_params, (object *)self, args);\n}\n'; } else { slotdefs += '\tswitch(method_id) {\n'; for (j in this.slots[i]) { slotdefs += '\t\tcase ' + this.slots[i][j][0] + ': /* ' + this.slots[i][j][2] + '*/\n' + '\t\t\t' + this.slots[i][j][1] + '\n'; } - slotdefs += '\t\tdefault:\n\treturn no_impl(method_id, num_params, params);\n}\n'; + slotdefs += '\t\tdefault:\n' + + '\treturn no_impl(method_id, num_params, params, args);\n}\n'; } metadef += this.name + '_slot_' + i; } else { @@ -285,9 +295,14 @@ { var int32 = new cObject('obj_int32'); int32.addProperty('num', null, 'int32_t'); - int32.addMessage('ADD_', 'params[0] = make_object(&obj_int32_meta, NULL, 0); ((obj_int32 *)params[0])->num = self->num + ((obj_int32 *)params[1])->num; return params[0];'); - int32.addMessage('SUB_', 'params[0] = make_object(&obj_int32_meta, NULL, 0); ((obj_int32 *)params[0])->num = self->num - ((obj_int32 *)params[1])->num; return params[0];'); - int32.addMessage('LT_', 'params[0] = main_module; if (self->num < ((obj_int32 *)params[1])->num) { return mcall(METHOD_ID_TRUE, 1, params); } return mcall(METHOD_ID_FALSE, 1, params);'); + int32.addMessageVar('ADD_', 'ret', 'obj_int32 *'); + int32.addMessageVar('ADD_', 'argb', 'obj_int32 *'); + int32.addMessage('ADD_', 'argb = va_arg(args, obj_int32 *); ret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0); ret->num = self->num + argb->num; return ret;'); + int32.addMessageVar('SUB_', 'ret', 'obj_int32 *'); + int32.addMessageVar('SUB_', 'argb', 'obj_int32 *'); + int32.addMessage('SUB_', 'argb = va_arg(args, obj_int32 *); ret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0); ret->num = self->num - argb->num; return ret;'); + int32.addMessageVar('LT_', 'argb', 'obj_int32 *'); + int32.addMessage('LT_', 'argb = va_arg(args, obj_int32 *); if (self->num < argb->num) { return mcall(METHOD_ID_TRUE, 1, main_module); } return mcall(METHOD_ID_FALSE, 1, main_module);'); forwarddec = toplevelcode = ''; forwarddec += int32.toEarlyCDef(); toplevelcode += int32.toCDef(); @@ -325,7 +340,7 @@ for (var i = 0; i < args.length; ++i) { var argname = args[i].toC(); - args[i] = (argname.indexOf('->') < 0 ? '\tobject * ' : '\t') + argname + ' = params[' + (offset + i) + '];\n'; + args[i] = (argname.indexOf('->') < 0 ? '\tobject * ' : '\t') + argname + ' = va_arg(args, object *);\n'; } var compiled = [] for (var i in exprs) { @@ -352,17 +367,17 @@ var myenvinit = ''; } - toplevelcode += 'object * lambda_' + mynum + ' (' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, object ** params) {\n' + myenvinit; + toplevelcode += 'object * lambda_' + mynum + ' (' + this.symbols.parentEnvType() + ' * env, uint32_t num_args, ...) {\n\tva_list args;\n' + myenvinit + '\tva_start(args, num_args);\n'; if (this.selftype) { var selfvar = (new symbol('self', this.symbols)).toC(); if (selfvar == 'self') { - toplevelcode += '\t' + this.selftype + ' * self = (' + this.selftype + ' *)params[0];\n'; + toplevelcode += '\t' + this.selftype + ' * self = va_arg(args, ' + this.selftype + ' *);\n'; } else { - toplevelcode += '\t' + selfvar + ' = (' + this.selftype + ' *)params[0];\n'; + toplevelcode += '\t' + selfvar + ' = va_arg(args, ' + this.selftype + ' *);\n'; } } - toplevelcode += args.join('') + exprs.join(';\n\t') + '\n}\n'; + toplevelcode += args.join('') + '\tva_end(args);\n' + exprs.join(';\n\t') + '\n}\n'; if (this.symbols.parentEnvType() != 'void') { if (this.symbols.passthruenv) { @@ -406,7 +421,17 @@ return; } if (this.expression instanceof lambda) { - cobj.addMessage(this.symbol.name, 'return ccall(' + val + ', num_params, params);'); + var params = ['((object *)self)']; + var paramget = ''; + for (var i in this.expression.args) { + var escaped = escapeCName(this.expression.args[i].cleanName()); + if (escaped != 'self') { + cobj.addMessageVar(this.symbol.name, escaped, 'object *'); + params.push(escaped); + paramget += escaped + ' = va_arg(args, object *); '; + } + } + cobj.addMessage(this.symbol.name, paramget + 'return ccall(' + val + ', ' + params.length + (params.length ? ', ' : '') + params.join(', ') + ');'); } else { cobj.addProperty(this.symbol.name, val); } diff -r a10f1b049193 -r bf5e88f6419d compiler.js --- a/compiler.js Mon Jul 09 08:57:50 2012 -0700 +++ b/compiler.js Mon Jul 09 21:32:28 2012 -0700 @@ -9,12 +9,10 @@ this.names = null; var self = this; get('/src/', function(data) { - console.log(data); self.names = {}; var fakeEl = newEl("div", { innerHTML: data.response }); - console.log(fakeEl); each(qall('a', fakeEl), function(idx, a) { var tpidx = a.textContent.indexOf('.tp'); if (tpidx > -1) { @@ -24,11 +22,9 @@ }); } topsymbols.prototype.find = function(name) { - console.log(this.names); if (!this.names) { throw new Error('data not ready'); } - console.log('toplevel', name); if (name in this.names) { return { type: 'toplevel', @@ -99,7 +95,6 @@ return curlist; } osymbols.prototype.getEnvType = function() { - console.log('osymbol parent', this.parent); return this.parent.getEnvType(); } @@ -113,7 +108,6 @@ this.envtype = 'void'; } lsymbols.prototype.find = function(name, nestedcall) { - console.log('find', name, nestedcall); if (name in this.names) { if (this.names[name] instanceof funcall && this.names[name].name == 'foreign:') { return { @@ -122,7 +116,6 @@ }; } if (nestedcall) { - console.log('closedover', name); this.closedover[name] = true; } if (name in this.closedover) { @@ -180,7 +173,6 @@ }; lsymbols.prototype.getEnvType = function() { if (this.passthruenv) { - console.log('lsymbol parent', this.parent); return this.parent.getEnvType(); } else { return this.envtype; diff -r a10f1b049193 -r bf5e88f6419d runtime/object.c --- a/runtime/object.c Mon Jul 09 08:57:50 2012 -0700 +++ b/runtime/object.c Mon Jul 09 21:32:28 2012 -0700 @@ -30,3 +30,12 @@ ret->func = func; return (object *) ret; } + +object * mcall(uint32_t method_id, uint32_t num_args, object * self, ...) +{ + va_list args; + va_start(args, self); + object * ret = self->meta->meth_lookup[method_id & 0xF](method_id, num_args, self, args); + va_end(args); + return ret; +} diff -r a10f1b049193 -r bf5e88f6419d runtime/object.h --- a/runtime/object.h Mon Jul 09 08:57:50 2012 -0700 +++ b/runtime/object.h Mon Jul 09 21:32:28 2012 -0700 @@ -2,6 +2,7 @@ #define OBJECT_H_ #include +#include typedef struct obj_meta obj_meta; @@ -11,9 +12,9 @@ struct object * parent; } object; -typedef object * (*method)(uint32_t method_id, uint32_t num_args, object **); +typedef object * (*method)(uint32_t method_id, uint32_t num_args, object * self, va_list args); -typedef object * (*closure_func)(void *, uint32_t, object **); +typedef object * (*closure_func)(void *, uint32_t, ...); typedef struct closure { @@ -30,8 +31,8 @@ extern obj_meta lambda_meta; -#define mcall(method_id, num_args, args) (args[0])->meta->meth_lookup[method_id & 0xF](method_id, num_args, args) -#define ccall(clos, num_args, args) (((closure *)clos)->func(((closure *)clos)->env, num_args, args)) +object * mcall(uint32_t method_id, uint32_t num_args, object * self, ...); +#define ccall(clos, num_args, ...) (((closure *)clos)->func(((closure *)clos)->env, num_args,##__VA_ARGS__)) object * make_object(obj_meta * meta, void * parent, int num_props, ...); object * make_closure(void * env, closure_func func); diff -r a10f1b049193 -r bf5e88f6419d runtime/progfoot.inc --- a/runtime/progfoot.inc Mon Jul 09 08:57:50 2012 -0700 +++ b/runtime/progfoot.inc Mon Jul 09 21:32:28 2012 -0700 @@ -1,10 +1,7 @@ int main(int argc, char ** argv) { - object * params[64]; - params[0] = mainModule(); - object * ret = mcall(METHOD_ID_MAIN, 1, params); - printf("%p:%p\n", ret->meta, &obj_int32_meta); + object * ret = mcall(METHOD_ID_MAIN, 1, mainModule()); if (ret->meta == &obj_int32_meta) { obj_int32 * reti32 = (obj_int32 *) ret; printf("%d\n", reti32->num); diff -r a10f1b049193 -r bf5e88f6419d runtime/proghead.inc --- a/runtime/proghead.inc Mon Jul 09 08:57:50 2012 -0700 +++ b/runtime/proghead.inc Mon Jul 09 21:32:28 2012 -0700 @@ -5,9 +5,9 @@ object * main_module; -object * no_impl(uint32_t method_id, uint32_t num_args, object ** params) +object * no_impl(uint32_t method_id, uint32_t num_args, object * self, va_list args) { - printf("method %d is not implemented on object %p\n", method_id, params[0]); + printf("method %d is not implemented on object %p\n", method_id, self); printf("main_module %p\n", main_module); exit(0); return NULL;