# HG changeset patch # User Mike Pavone # Date 1342255183 25200 # Node ID 0fd06e077afebce6b0170a3f7c383bc7e71ebda2 # Parent 7b454d100dc8afd97465c29357296e958eedb522 Fix object parent diff -r 7b454d100dc8 -r 0fd06e077afe cbackend.js --- a/cbackend.js Sat Jul 14 00:35:50 2012 -0700 +++ b/cbackend.js Sat Jul 14 01:39:43 2012 -0700 @@ -42,7 +42,7 @@ op.prototype.toC = function(isReceiver) { var optoMeth = {'+': 'ADD_', '-': 'SUB_', '*': 'MUL_', '/': 'DIV_', '=': 'EQ_', '!=': 'NEQ_', '<': 'LT_', '>': 'GT_', '>=': 'GEQ_', '<=': 'LEQ_', '.': 'CAT_'}; var method = optoMeth[this.op]; - return 'mcall(' + getMethodId(method) + ', 2, (object *)' + this.left.toC() + ', ' + this.right.toC() + ')\n'; + return 'mcall(' + getMethodId(method) + '/* ' + method + ' */, 2, (object *)' + this.left.toC() + ', ' + this.right.toC() + ')\n'; }; function escapeCName(name) @@ -188,7 +188,7 @@ } var callpart; if (method) { - callpart = 'mcall(' + getMethodId(name); + callpart = 'mcall(' + getMethodId(name) + '/* ' + name + ' */'; } else { callpart = 'ccall(' + (new symbol(name, this.symbols)).toC(); } @@ -202,6 +202,9 @@ this.values = []; this.slotvars = {}; this.includes = {}; + this.parent = 'NULL'; + this.init = []; + this.initmsgadded = false; } cObject.prototype.addInclude = function(includefile) { @@ -234,15 +237,12 @@ this.addMessage(propname, { vars: {}, lines: [ - 'va_end(args);', 'return self->' + escaped + ';' ]}); this.addMessage(propname + '!', { - vars: {setval: 'object *'}, + vars: {}, lines: [ - 'setval = va_arg(args, object *);', - 'va_end(args);', - 'self->' + escaped + ' = setval;', + 'self->' + escaped + ' = va_arg(args, object *);', 'return (object *)self;' ]}); this.properties.push(escaped); @@ -250,7 +250,25 @@ } } +cObject.prototype.addInit = function(statement) { + this.init.push(statement); +} + +cObject.prototype.checkInitMsg = function() { + if (!this.initmsgadded && this.init.length) { + var init = this.init.slice(0, this.init.length); + init.push('return (object *)self;'); + this.addMessage('_init', { + vars: {}, + lines: init + }); + this.initmsgadded = true; + } +} + + cObject.prototype.toEarlyCDef = function() { + this.checkInitMsg(); var includes = ''; for (var file in this.includes) { includes += '#include ' + file + '\n'; @@ -268,6 +286,7 @@ } cObject.prototype.toCDef = function() { + this.checkInitMsg(); var slotdefs = ''; var metadef = 'obj_meta ' + this.name + '_meta = {sizeof(' + this.name +'), {'; for (var i = 0; i < 16; i++) { @@ -305,7 +324,12 @@ } cObject.prototype.toCInstance = function() { - return 'make_object(&' + this.name + '_meta, NULL, ' + this.values.length + (this.values.length ? ', ' : '') + this.values.join(', ') + ')'; + this.checkInitMsg(); + var ret = 'make_object(&' + this.name + '_meta, ' + this.parent + ', ' + this.values.length + (this.values.length ? ', ' : '') + this.values.join(', ') + ')'; + if (this.initmsgadded) { + ret = 'mcall(' + getMethodId('_init') + ', 1, ' + ret + ')' + } + return ret; } cObject.prototype.toC = function() { @@ -326,6 +350,9 @@ me.addProperty('env', this.symbols.envVar(), 'struct ' + this.symbols.getEnvType() + ' * '); me.hasenv = true; } + if (this.symbols.needsparent && !(this.symbols.parent instanceof osymbols)) { + me.parent = '(object *)(' + (new symbol('self', this.symbols.parent)).toC() + ')'; + } for (var i in messages) { if (messages[i] instanceof funcall) { if (messages[i].name == 'import:' && messages[i].args.length == 1) { @@ -465,9 +492,9 @@ array.addMessage('length', { vars: {intret: 'obj_int32 *'}, lines: [ - 'intret = make_object(&obj_int32_meta, NULL, 0);', + 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', 'intret->num = self->size;', - 'return intret;' + 'return &(intret->header);' ] }); return array; @@ -587,9 +614,9 @@ lines: [ 'filedes = va_arg(args, obj_int32 *);', 'str = va_arg(args, string *);', - 'intret = make_object(&obj_int32_meta, NULL, 0);', + 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', 'intret->num = write(filedes->num, str->data, str->bytes);', - 'return intret;' + 'return &(intret->header);' ] }); os.addMessage('read', { @@ -597,12 +624,12 @@ lines: [ 'filedes = va_arg(args, obj_int32 *);', 'size = va_arg(args, obj_int32 *);', - 'str = make_object(&string_meta, NULL, 0);', + 'str = (string *)make_object(&string_meta, NULL, 0);', 'str->data = malloc(size->num + 1);', 'str->length = str->bytes = read(filedes->num, str->data, size->num);', 'if (str->bytes < 0) { str->bytes = str->length = 0; }', 'str->data[str->bytes] = 0;', - 'return str;' + 'return &(str->header);' ] }); os.addMessage('open', { @@ -610,7 +637,7 @@ lines: [ 'str = va_arg(args, string *);', 'flags = va_arg(args, obj_int32 *);', - 'filedes = make_object(&obj_int32_meta, NULL, 0);', + 'filedes = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', 'if (num_params == 3) {', ' filedes->num = open(str->data, flags->num);', '} else if (num_params == 4) {', @@ -619,64 +646,64 @@ '} else {', ' filedes->num = -1;', '}', - 'return filedes;' + 'return &(filedes->header);' ] }); os.addMessage('close', { vars: {filedes: 'obj_int32 *', intret: 'obj_int32 *'}, lines: [ 'filedes = va_arg(args, obj_int32 *);', - 'intret = make_object(&obj_int32_meta, NULL, 0);', + 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', 'intret->num = close(filedes->num);', - 'return intret;' + 'return &(intret->header);' ] }); os.addMessage('O_RDONLY', { vars: {intret: 'obj_int32 *'}, lines: [ - 'intret = make_object(&obj_int32_meta, NULL, 0);', + 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', 'intret->num = O_RDONLY;', - 'return intret;' + 'return &(intret->header);' ] }); os.addMessage('O_WRONLY', { vars: {intret: 'obj_int32 *'}, lines: [ - 'intret = make_object(&obj_int32_meta, NULL, 0);', + 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', 'intret->num = O_WRONLY;', - 'return intret;' + 'return &(intret->header);' ] }); os.addMessage('O_RDWR', { vars: {intret: 'obj_int32 *'}, lines: [ - 'intret = make_object(&obj_int32_meta, NULL, 0);', + 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', 'intret->num = O_RDWR;', - 'return intret;' + 'return &(intret->header);' ] }); os.addMessage('O_CREAT', { vars: {intret: 'obj_int32 *'}, lines: [ - 'intret = make_object(&obj_int32_meta, NULL, 0);', + 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', 'intret->num = O_CREAT;', - 'return intret;' + 'return &(intret->header);' ] }); os.addMessage('O_APPEND', { vars: {intret: 'obj_int32 *'}, lines: [ - 'intret = make_object(&obj_int32_meta, NULL, 0);', + 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', 'intret->num = O_APPEND;', - 'return intret;' + 'return &(intret->header);' ] }); os.addMessage('O_TRUNC', { vars: {intret: 'obj_int32 *'}, lines: [ - 'intret = make_object(&obj_int32_meta, NULL, 0);', + 'intret = (obj_int32 *)make_object(&obj_int32_meta, NULL, 0);', 'intret->num = O_TRUNC;', - 'return intret;' + 'return &(intret->header);' ] }); toplevel.names['os'] = os; @@ -858,5 +885,8 @@ }); } else { cobj.addProperty(this.symbol.name, val); + if (this.expression instanceof object && this.expression.symbols.needsparent) { + cobj.addInit('self->' + escapeCName(this.symbol.name) + '->parent = self;'); + } } }; diff -r 7b454d100dc8 -r 0fd06e077afe compiler.js --- a/compiler.js Sat Jul 14 00:35:50 2012 -0700 +++ b/compiler.js Sat Jul 14 01:39:43 2012 -0700 @@ -67,6 +67,7 @@ this.names = {}; this.needsenv = false; this.typename = null; + this.needsparent = false; } osymbols.prototype.find = function(name, nestedcall) { debugprint('//osymbols.find', name + ', exists?:', name in this.names, ', nested?:', nestedcall); @@ -88,7 +89,9 @@ if(ret.type == 'self') { ret.type = 'parent'; ret.depth = 1; + this.needsparent = true; } else if(ret.type == 'parent') { + this.needsparent = true; ret.depth++; } else if(ret.type == 'closedover' || ret.type == 'upvar') { this.needsenv = true;