lvm.js

changeset 19
8c9c1752272b
parent 18
ae0b4ec242a3
child 20
977ae93f612c
equal deleted inserted replaced
18:ae0b4ec242a3 19:8c9c1752272b
292 var ret = f.apply(null, args.map(function (a) { return a.value; })); 292 var ret = f.apply(null, args.map(function (a) { return a.value; }));
293 } 293 }
294 else 294 else
295 { 295 {
296 // Lua function 296 // Lua function
297 this.frame = {f:f,pc:0,reg:args}; 297 this.frame = {f:f,pc:0,reg:args,
298 retAt:INS_A(instruction),retCount:INS_C(instruction)};
298 this.callstack.push(this.frame); 299 this.callstack.push(this.frame);
299 } 300 }
300 break; 301 break;
301 case OP_CLOSURE: 302 case OP_CLOSURE:
302 var prototype_id = INS_Bx(instruction); 303 var prototype_id = INS_Bx(instruction);
305 throw "Upvalues not yet implemented, sorry :)"; 306 throw "Upvalues not yet implemented, sorry :)";
306 var f = new LFunction(chunk, this.frame.f.environment); 307 var f = new LFunction(chunk, this.frame.f.environment);
307 this.frame.reg[INS_A(instruction)] = new LValue("function", f); 308 this.frame.reg[INS_A(instruction)] = new LValue("function", f);
308 break; 309 break;
309 case OP_RETURN: 310 case OP_RETURN:
310 this.callstack.pop(); 311 var oldFrame = this.callstack.pop();
311 this.frame = this.callstack[this.callstack.length-1]; 312 this.frame = this.callstack[this.callstack.length-1];
313 if(this.frame)
314 {
315 var rets;
316 if(INS_B(instruction) == 0)
317 rets = oldFrame.reg.slice(INS_A(instruction));
318 else
319 rets = oldFrame.reg.slice(INS_A(instruction),INS_A(instruction)+(INS_B(instruction)-1));
320 var i;
321 for(i=0;(oldFrame.retCount == 0||i<oldFrame.retCount)&&i<rets.length;i++)
322 this.frame.reg[oldFrame.retAt+i] = rets[i];
323 if(oldFrame.retAt+i<this.frame.reg.length)
324 this.frame.reg.splice(0,oldFrame.retAt+i);
325 }
312 break; 326 break;
313 default: 327 default:
314 throw "Unhandled opcode: "+INS_OPCODE(instruction); 328 throw "Unhandled opcode: "+INS_OPCODE(instruction);
315 } 329 }
316 } 330 }

mercurial