lvm.js

Sun, 23 May 2010 13:28:23 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Sun, 23 May 2010 13:28:23 +0100
changeset 33
6cc1b0a8dd97
parent 32
035aacc192d8
child 34
2c3d73c76d0f
permissions
-rw-r--r--

Instantiate a new LValue in OP_LOADK, otherwise "constants" aren't so constant...

0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
2 var OP_MOVE = 0;
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 var OP_LOADK = 1;
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
4 var OP_LOADNIL = 3;
20
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
5 var OP_GETUPVAL = 4;
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 var OP_GETGLOBAL = 5;
28
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
7 var OP_GETTABLE = 6;
6
418fd175eaed Implement OP_SETGLOBAL
Matthew Wild <mwild1@gmail.com>
parents: 5
diff changeset
8 var OP_SETGLOBAL = 7;
20
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
9 var OP_SETUPVAL = 8;
28
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
10 var OP_SETTABLE = 9;
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
11 var OP_NEWTABLE = 10;
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 var OP_CALL = 28;
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
13 var OP_RETURN = 30;
15
5240eaff785f Implement basic OP_CLOSURE (no support for upvalues yet)
Matthew Wild <mwild1@gmail.com>
parents: 14
diff changeset
14 var OP_CLOSURE = 36;
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15
8
e7de6d1fee96 Add debugMode switch
Matthew Wild <mwild1@gmail.com>
parents: 7
diff changeset
16 var debugMode = false;
e7de6d1fee96 Add debugMode switch
Matthew Wild <mwild1@gmail.com>
parents: 7
diff changeset
17
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 function LValue(type, value)
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 {
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 this.type = type||"nil";
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 this.value = value||null;
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 }
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 LValue.prototype = {
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 call: function (args)
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 {
3
6f338fbf0abc Throw an error if trying to call a non-function
Matthew Wild <mwild1@gmail.com>
parents: 2
diff changeset
27 if(this.type == "function")
6f338fbf0abc Throw an error if trying to call a non-function
Matthew Wild <mwild1@gmail.com>
parents: 2
diff changeset
28 return this.value;
6f338fbf0abc Throw an error if trying to call a non-function
Matthew Wild <mwild1@gmail.com>
parents: 2
diff changeset
29 else
6f338fbf0abc Throw an error if trying to call a non-function
Matthew Wild <mwild1@gmail.com>
parents: 2
diff changeset
30 throw "Attempt to call a " + this.type + " value";
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 },
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 index: function (key)
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 {
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34 if(this.type == "table")
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 {
4
0eda73eda4ae Return nil for non-existent table keys
Matthew Wild <mwild1@gmail.com>
parents: 3
diff changeset
36 var val = this.value[key.value];
0eda73eda4ae Return nil for non-existent table keys
Matthew Wild <mwild1@gmail.com>
parents: 3
diff changeset
37 if(typeof(val) == "undefined")
0eda73eda4ae Return nil for non-existent table keys
Matthew Wild <mwild1@gmail.com>
parents: 3
diff changeset
38 return new LValue("nil", null);
0eda73eda4ae Return nil for non-existent table keys
Matthew Wild <mwild1@gmail.com>
parents: 3
diff changeset
39 return val;
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 }
7
00ec5f6e7579 Add errors for when trying to index non-tables
Matthew Wild <mwild1@gmail.com>
parents: 6
diff changeset
41 else
00ec5f6e7579 Add errors for when trying to index non-tables
Matthew Wild <mwild1@gmail.com>
parents: 6
diff changeset
42 throw "Attempt to index a " + this.type + " value";
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 },
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 setIndex: function (key, value)
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 {
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 if(this.type == "table")
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 {
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 this.value[key.value] = value;
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 }
7
00ec5f6e7579 Add errors for when trying to index non-tables
Matthew Wild <mwild1@gmail.com>
parents: 6
diff changeset
50 else
00ec5f6e7579 Add errors for when trying to index non-tables
Matthew Wild <mwild1@gmail.com>
parents: 6
diff changeset
51 throw "Attempt to index a " + this.type + " value";
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 }
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 };
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 function LValueFromString(string)
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 {
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 return new LValue("string", string);
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 }
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 function LValueFromFunction(func)
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 {
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 return new LValue("function", func);
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 }
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64
27
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
65 function LValueFromValue(value)
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
66 {
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
67 switch(typeof(value))
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
68 {
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
69 case "string":
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
70 return new LValueFromString(value);
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
71 case "function":
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
72 return new LValueFromFunction(value);
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
73 case "object":
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
74 if(value == null)
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
75 return new LValue("nil", value);
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
76 default:
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
77 sys.puts( "Not able to convert type " +
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
78 typeof(value)+" from Javascript to Lua: "+sys.inspect(value));
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
79 throw "Not able to convert type " +
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
80 typeof(value)+" from Javascript to Lua";
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
81 }
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
82 }
35a2203253a6 New LValueFromValue() to convert from any Javascript value (almost) to a LValue
Matthew Wild <mwild1@gmail.com>
parents: 26
diff changeset
83
13
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
84 function LBinaryChunk(chunk, start)
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 {
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
86 this.chunk = chunk;
13
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
87 this.pos = start||12;
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
88
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
89 this.sourceName = this.readString();
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
90 this.lineDefined = this.readInt();
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
91 this.lastLineDefined = this.readInt();
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
92 this.numUpvalues = this.readByte();
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
93 this.numParameters = this.readByte();
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
94 this.isVararg = this.readByte();
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
95 this.maxStackSize = this.readByte();
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
96
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 this.instructions = [];
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
98
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
99 this.numInstructions = this.readInt();
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
100 for(var i=0;i<this.numInstructions;i++)
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
101 {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
102 var ins = this.readInt();
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
103 this.instructions.push([
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
104 ins&0x3F, // Opcode
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
105 (ins>>6)&0xFF, // Field A
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
106 (ins>>23)&0x1FF, // Field B
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
107 (ins>>14)&0x1FF // Field C
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
108 ]);
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
109 if(debugMode)
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
110 {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
111 var pi = this.instructions[this.instructions.length-1];
31
bc58527bac34 Print sBx field in bytecode dump (for debugging)
Matthew Wild <mwild1@gmail.com>
parents: 30
diff changeset
112 sys.puts("Pos: "+(this.pos-4)+" Ins: "+ins+" OP: "+INS_OPCODE(pi)+" A: "+INS_A(pi)+" B: "+INS_B(pi)+" C: "+INS_C(pi)+" Bx: "+INS_Bx(pi)+" sBx: "+(INS_Bx(pi)-0x1FFFE));
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
113 }
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
114 }
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
115
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
116 this.constants = [];
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
117
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
118 this.numConstants = this.readInt();
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
119 for(var i=0;i<this.numConstants;i++)
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
120 {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
121 var type = this.readByte();
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
122 switch(type)
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
123 {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
124 case 0: // Nil
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
125 this.constants.push(new LValue("nil", null));
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
126 break;
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
127 case 1: // Boolean
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
128 this.constants.push(new LValue("boolean", this.readByte()));
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
129 break;
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
130 case 3: // Number
12
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
131 this.constants.push(new LValue("number", this.readNumber()));
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
132 break;
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
133 case 4: // String
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
134 this.constants.push(LValueFromString(this.readString()));
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
135 break;
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
136 default:
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
137 throw "Invalid constant type "+type+" in bytecode";
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
138 }
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
139 }
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
140
13
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
141 this.prototypes = [];
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
142
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
143 this.numPrototypes = this.readInt();
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
144 for(var i=0;i<this.numPrototypes;i++)
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
145 {
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
146 var p = new LBinaryChunk(chunk, this.pos);
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
147 this.pos = p.pos;
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
148 this.prototypes.push(p);
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
149 }
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
150
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
151 this.sourceLines = [];
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
152
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
153 this.numSourceLines = this.readInt();
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
154 for(var i=0;i<this.numSourceLines;i++)
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
155 {
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
156 this.sourceLines.push(this.readInt());
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
157 }
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
158
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
159 this.localList = [];
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
160 this.numLocalList = this.readInt();
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
161 for(var i=0;i<this.numLocalList;i++)
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
162 {
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
163 this.localList.push([this.readString(),this.readInt(),this.readInt()]);
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
164 }
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
165
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
166 this.upvalueList = [];
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
167 this.numUpvalueList = this.readInt();
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
168 for(var i=0;i<this.numUpvalueList;i++)
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
169 {
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
170 this.upvalueList.push(this.readString());
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
171 }
f259da6951e8 Support for reading all fields in the chunk (including function prototypes, required for OP_CLOSURE)
Matthew Wild <mwild1@gmail.com>
parents: 12
diff changeset
172
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 return this;
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
174 }
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
176 LBinaryChunk.prototype = {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
177 readBytes: function (n)
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
178 {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
179 return this.chunk.slice(this.pos, this.pos+=n);
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
180 },
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
181 readByte: function ()
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
182 {
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
183 return this.readBytes(1).charCodeAt(0);
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
184 },
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
185 readInt: function ()
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
186 {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
187 //FIXME: Endianness
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
188 return this.readByte() | (this.readByte()<<8)
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
189 | (this.readByte()<<16) | (this.readByte()<<24);
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
190 },
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
191 readString: function ()
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
192 {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
193 var len = this.readInt();
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
194 return this.readBytes(len).substring(0,len-1);
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
195 },
12
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
196 readNumber: function ()
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
197 {
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
198 //FIXME: Endianness
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
199 var bytes = [this.readByte(),this.readByte(),this.readByte(),this.readByte(),
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
200 this.readByte(),this.readByte(),this.readByte(),this.readByte()].reverse();
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
201
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
202 var sign = (bytes[0]>>7)&0x1;
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
203 var exp = (bytes[0]&0x7F)<<4 | (bytes[1]&0xf0)>>4;
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
204
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
205 var frac = ((bytes[1] & 0x0f) * Math.pow(2,48))
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
206 + (bytes[2] * Math.pow(2,40))
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
207 + (bytes[3] * Math.pow(2,32))
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
208 + (bytes[4] * Math.pow(2,24))
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
209 + (bytes[5] * Math.pow(2,16))
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
210 + (bytes[6] * Math.pow(2,8))
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
211 + bytes[7];
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
212
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
213 if(exp != 0x000 && exp != 0x7FF)
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
214 {
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
215 var n = (sign==1?-1:1)*Math.pow(2,exp-1023)*(1+(frac/0x10000000000000));
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
216 return n;
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
217 }
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
218 else if(exp == 0x000)
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
219 {
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
220 return sign*0;
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
221 }
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
222 else
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
223 return frac==0?sign*Infinity:NaN;
7d748aba47ab Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents: 11
diff changeset
224 }
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
225 };
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
226
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
227 function INS_OPCODE(ins)
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
228 {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
229 return ins[0];
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
230 }
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
231
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
232 function INS_A(ins)
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
233 {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
234 return ins[1];
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
235 }
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
236
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
237 function INS_B(ins)
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
238 {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
239 return ins[2];
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
240 }
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
241
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
242 function INS_C(ins)
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
243 {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
244 return ins[3];
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
245 }
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
246
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
247 function INS_Bx(ins)
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
248 {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
249 return ((INS_C(ins))|(INS_B(ins)<<9));
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
250 }
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
251
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
252 function INS_sBx(ins)
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
253 {
32
035aacc192d8 Fix off-by-one in calculating the value of sBx
Matthew Wild <mwild1@gmail.com>
parents: 31
diff changeset
254 return (INS_Bx(ins)-0x1FFFF);
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
255 }
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
256
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
257 function LFunction(chunk, env)
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
258 {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
259 function F() {};
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
260 F.prototype = chunk;
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
261 var o = new F();
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
262 o.environment = env;
14
21a2fce50931 Add chunk property to LFunction to show which chunk it came from
Matthew Wild <mwild1@gmail.com>
parents: 13
diff changeset
263 o.chunk = chunk;
20
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
264 o.upvalues = [];
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
265 return o;
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
266 }
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
267
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
268 function LVM()
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
269 {
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
270 this.callstack = [];
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
271 this.stack = [];
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
272 return this;
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
273 }
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
274
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
275 LVM.prototype = {
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
276 run: function (lfFunction)
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
277 {
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
278 this.frame = {f:lfFunction,pc:0,reg:[]};
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
279 this.callstack.push(this.frame);
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
280 var instruction;
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
281 while(this.callstack.length>0)
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
282 {
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
283 instruction = this.frame.f.instructions[this.frame.pc++];
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
284 if(debugMode)
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
285 {
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
286 sys.puts("PC: "+(this.frame.pc-1)+" OP: "+instruction[0]);
21
9b5cc503bc31 Switch from JSON.stringify for debug output to sys.inspect which doesn't bail out on circular references
Matthew Wild <mwild1@gmail.com>
parents: 20
diff changeset
287 sys.puts("STACK: "+sys.inspect(this.frame.reg));
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
288 }
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
289 switch(INS_OPCODE(instruction))
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
290 {
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
291 case OP_MOVE:
10
ce2f27fa25a4 Use new notation for accessing instruction fields
Matthew Wild <mwild1@gmail.com>
parents: 9
diff changeset
292 this.frame.reg[INS_A(instruction)] = this.frame.reg[INS_B(instruction)];
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
293 break;
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
294 case OP_LOADNIL:
10
ce2f27fa25a4 Use new notation for accessing instruction fields
Matthew Wild <mwild1@gmail.com>
parents: 9
diff changeset
295 for(var i = INS_A(instruction);i<=INS_B(instruction);i++)
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
296 this.frame.reg[i] = new LValue("nil", null);
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
297 break;
20
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
298 case OP_GETUPVAL:
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
299 this.frame.reg[INS_A(instruction)] = this.frame.f.upvalues[INS_B(instruction)];
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
300 break;
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
301 case OP_GETGLOBAL:
10
ce2f27fa25a4 Use new notation for accessing instruction fields
Matthew Wild <mwild1@gmail.com>
parents: 9
diff changeset
302 var name = this.frame.f.constants[INS_Bx(instruction)];
ce2f27fa25a4 Use new notation for accessing instruction fields
Matthew Wild <mwild1@gmail.com>
parents: 9
diff changeset
303 this.frame.reg[INS_A(instruction)] = this.frame.f.environment.index(name);
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
304 break;
20
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
305 case OP_SETUPVAL:
26
5c7eafb47830 Implement OP_SETUPVALUE \o/
Matthew Wild <mwild1@gmail.com>
parents: 25
diff changeset
306 var reg = this.frame.reg[INS_A(instruction)];
5c7eafb47830 Implement OP_SETUPVALUE \o/
Matthew Wild <mwild1@gmail.com>
parents: 25
diff changeset
307 var upvalue = this.frame.f.upvalues[INS_B(instruction)];
5c7eafb47830 Implement OP_SETUPVALUE \o/
Matthew Wild <mwild1@gmail.com>
parents: 25
diff changeset
308 upvalue.type = reg.type;
5c7eafb47830 Implement OP_SETUPVALUE \o/
Matthew Wild <mwild1@gmail.com>
parents: 25
diff changeset
309 upvalue.value = reg.value;
20
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
310 break;
6
418fd175eaed Implement OP_SETGLOBAL
Matthew Wild <mwild1@gmail.com>
parents: 5
diff changeset
311 case OP_SETGLOBAL:
10
ce2f27fa25a4 Use new notation for accessing instruction fields
Matthew Wild <mwild1@gmail.com>
parents: 9
diff changeset
312 var name = this.frame.f.constants[INS_Bx(instruction)];
6
418fd175eaed Implement OP_SETGLOBAL
Matthew Wild <mwild1@gmail.com>
parents: 5
diff changeset
313 this.frame.f.environment.setIndex(name, this.frame.reg[instruction[1]]);
418fd175eaed Implement OP_SETGLOBAL
Matthew Wild <mwild1@gmail.com>
parents: 5
diff changeset
314 break;
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
315 case OP_LOADK:
33
6cc1b0a8dd97 Instantiate a new LValue in OP_LOADK, otherwise "constants" aren't so constant...
Matthew Wild <mwild1@gmail.com>
parents: 32
diff changeset
316 var constant = this.frame.f.constants[INS_Bx(instruction)];
6cc1b0a8dd97 Instantiate a new LValue in OP_LOADK, otherwise "constants" aren't so constant...
Matthew Wild <mwild1@gmail.com>
parents: 32
diff changeset
317 this.frame.reg[INS_A(instruction)] = new LValue(constant.type, constant.value);
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
318 break;
28
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
319 case OP_NEWTABLE:
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
320 this.frame.reg[INS_A(instruction)] = new LValue("table", {});
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
321 break;
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
322 case OP_GETTABLE:
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
323 var C = INS_C(instruction);
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
324 var keysource = (C&256)?this.frame.f.constants:this.frame.reg;
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
325 var key = keysource[C&0xff];
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
326 var value = this.frame.reg[INS_B(instruction)].index(key).value;
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
327 this.frame.reg[INS_A(instruction)] = new LValueFromValue(value);
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
328 break;
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
329 case OP_SETTABLE:
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
330 var C = INS_C(instruction);
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
331 var valuesource = (C&256)?this.frame.f.constants:this.frame.reg;
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
332 var value = valuesource[C&0xff];
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
333
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
334 var B = INS_B(instruction);
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
335 var keysource = (B&256)?this.frame.f.constants:this.frame.reg;
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
336 var key = keysource[B&0xff];
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
337 this.frame.reg[INS_A(instruction)].setIndex(key, value);
d14b47c3870f Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents: 27
diff changeset
338 break;
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
339 case OP_CALL:
10
ce2f27fa25a4 Use new notation for accessing instruction fields
Matthew Wild <mwild1@gmail.com>
parents: 9
diff changeset
340 var f = this.frame.reg[INS_A(instruction)].call(); // return JS or LValue
18
ae0b4ec242a3 Support for B==0 in OP_CALL (signifies params are to top of the stack)
Matthew Wild <mwild1@gmail.com>
parents: 17
diff changeset
341 var A = INS_A(instruction), B = INS_B(instruction), undefined;
ae0b4ec242a3 Support for B==0 in OP_CALL (signifies params are to top of the stack)
Matthew Wild <mwild1@gmail.com>
parents: 17
diff changeset
342 var args = this.frame.reg.slice(A+1, B==0?undefined:(A+B));
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
343 if(typeof(f) == "function")
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
344 {
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
345 // JS native function
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
346 var ret = f.apply(null, args.map(function (a) { return a.value; }));
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
347 }
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
348 else
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
349 {
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
350 // Lua function
19
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
351 this.frame = {f:f,pc:0,reg:args,
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
352 retAt:INS_A(instruction),retCount:INS_C(instruction)};
16
9c8710ea2a5a Implement OP_CALL for Lua functions (no return values yet)
Matthew Wild <mwild1@gmail.com>
parents: 15
diff changeset
353 this.callstack.push(this.frame);
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
354 }
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
355 break;
15
5240eaff785f Implement basic OP_CLOSURE (no support for upvalues yet)
Matthew Wild <mwild1@gmail.com>
parents: 14
diff changeset
356 case OP_CLOSURE:
5240eaff785f Implement basic OP_CLOSURE (no support for upvalues yet)
Matthew Wild <mwild1@gmail.com>
parents: 14
diff changeset
357 var prototype_id = INS_Bx(instruction);
5240eaff785f Implement basic OP_CLOSURE (no support for upvalues yet)
Matthew Wild <mwild1@gmail.com>
parents: 14
diff changeset
358 var chunk = this.frame.f.chunk.prototypes[prototype_id];
5240eaff785f Implement basic OP_CLOSURE (no support for upvalues yet)
Matthew Wild <mwild1@gmail.com>
parents: 14
diff changeset
359 var f = new LFunction(chunk, this.frame.f.environment);
24
5c9d8a65c87d It's required to insert the new function into the stack before processing its upvalue instructions, in case it refers to itself.
Matthew Wild <mwild1@gmail.com>
parents: 23
diff changeset
360 this.frame.reg[INS_A(instruction)] = new LValue("function", f);
20
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
361 for(var i=0;i<chunk.numUpvalues;i++)
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
362 {
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
363 var upval_instruction = this.frame.f.instructions[this.frame.pc++];
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
364 switch(INS_OPCODE(upval_instruction))
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
365 {
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
366 case OP_MOVE:
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
367 f.upvalues[i] = this.frame.reg[INS_B(upval_instruction)];
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
368 break;
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
369 case OP_GETUPVAL:
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
370 f.upvalues[i] = this.frame.f.upvalues[INS_B(upval_instruction)];
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
371 break;
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
372 default:
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
373 throw "Invalid upvalue opcode following OP_CLOSURE";
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
374 }
977ae93f612c Support for upvalues in functions \o/ implemented OP_GETUPVAL, and a stub for OP_SETUPVAL.
Matthew Wild <mwild1@gmail.com>
parents: 19
diff changeset
375 }
15
5240eaff785f Implement basic OP_CLOSURE (no support for upvalues yet)
Matthew Wild <mwild1@gmail.com>
parents: 14
diff changeset
376 break;
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
377 case OP_RETURN:
19
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
378 var oldFrame = this.callstack.pop();
17
ac02246fc1d1 Fix OP_RETURN to update this.frame
Matthew Wild <mwild1@gmail.com>
parents: 16
diff changeset
379 this.frame = this.callstack[this.callstack.length-1];
19
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
380 if(this.frame)
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
381 {
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
382 var rets;
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
383 if(INS_B(instruction) == 0)
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
384 rets = oldFrame.reg.slice(INS_A(instruction));
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
385 else
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
386 rets = oldFrame.reg.slice(INS_A(instruction),INS_A(instruction)+(INS_B(instruction)-1));
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
387 var i;
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
388 for(i=0;(oldFrame.retCount == 0||i<oldFrame.retCount)&&i<rets.length;i++)
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
389 this.frame.reg[oldFrame.retAt+i] = rets[i];
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
390 if(oldFrame.retAt+i<this.frame.reg.length)
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
391 this.frame.reg.splice(0,oldFrame.retAt+i);
8c9c1752272b OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents: 18
diff changeset
392 }
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
393 break;
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
394 default:
11
1b3267149cbd Throw error on unhandled opcodes
Matthew Wild <mwild1@gmail.com>
parents: 10
diff changeset
395 throw "Unhandled opcode: "+INS_OPCODE(instruction);
0
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
396 }
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
397 }
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
398 }
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
399 };
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
400
2fcdf7f16d71 Initial commit
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
401 var testvm = new LVM();
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
402
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
403 var fs=require("fs");
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
404 var sys=require("sys");
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
405 var c = new LBinaryChunk(fs.readFileSync("luac.out", "binary"));
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
406
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
407 var default_environment = new LValue("table", {});
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
408
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
409 var print;
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
410 if(typeof(document) == "object")
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
411 print = function (a) { document.write(a+"<br/>") }; // Browser
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
412 else
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
413 print = require("sys").puts; // Nodejs
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
414
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
415 default_environment.setIndex(LValueFromString("print"), LValueFromFunction(print));
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
416
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
417 var f = new LFunction(c, default_environment);
2
253863ece36f Implement OP_MOVE, OP_LOADNIL and OP_RETURN. Also change the way OP_CALL is implemented, and update the test code with a more complicated (kind of) sample.
Matthew Wild <mwild1@gmail.com>
parents: 1
diff changeset
418
29
62f3df8ed204 Remove rawExceptions flag, always print exception's stack trace if it has one
Matthew Wild <mwild1@gmail.com>
parents: 28
diff changeset
419 try{
9
3f055c9ab80e Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents: 8
diff changeset
420 testvm.run(f);
29
62f3df8ed204 Remove rawExceptions flag, always print exception's stack trace if it has one
Matthew Wild <mwild1@gmail.com>
parents: 28
diff changeset
421 }
62f3df8ed204 Remove rawExceptions flag, always print exception's stack trace if it has one
Matthew Wild <mwild1@gmail.com>
parents: 28
diff changeset
422 catch(e)
25
9e62bc13b30d Add new debug option - rawExceptions - to prevent catching exceptions thrown by the VM, use for debugging the VM.
Matthew Wild <mwild1@gmail.com>
parents: 24
diff changeset
423 {
29
62f3df8ed204 Remove rawExceptions flag, always print exception's stack trace if it has one
Matthew Wild <mwild1@gmail.com>
parents: 28
diff changeset
424 print("Error: " + e);
30
10fd886c4e8a Couple of fixes for last commit
Matthew Wild <mwild1@gmail.com>
parents: 29
diff changeset
425 if("stack" in e)
29
62f3df8ed204 Remove rawExceptions flag, always print exception's stack trace if it has one
Matthew Wild <mwild1@gmail.com>
parents: 28
diff changeset
426 print(e.stack);
5
c5c9c4f2d1d3 Print error on error
Matthew Wild <mwild1@gmail.com>
parents: 4
diff changeset
427 }

mercurial