Sat, 21 Sep 2013 14:02:16 +0100
Add math.frexp() and tests (many thanks to Florob and Link Mauve!)
0 | 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 | 3 | var OP_LOADK = 1; |
39 | 4 | var OP_LOADBOOL = 2; |
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
|
5 | 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
|
6 | var OP_GETUPVAL = 4; |
0 | 7 | var OP_GETGLOBAL = 5; |
28
d14b47c3870f
Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents:
27
diff
changeset
|
8 | var OP_GETTABLE = 6; |
6 | 9 | 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
|
10 | var OP_SETUPVAL = 8; |
28
d14b47c3870f
Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents:
27
diff
changeset
|
11 | var OP_SETTABLE = 9; |
d14b47c3870f
Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents:
27
diff
changeset
|
12 | var OP_NEWTABLE = 10; |
36 | 13 | var OP_SELF = 11; |
58
40d0b0429428
Implement OP_ADD, OP_SUB, OP_LT
Matthew Wild <mwild1@gmail.com>
parents:
56
diff
changeset
|
14 | var OP_ADD = 12; |
40d0b0429428
Implement OP_ADD, OP_SUB, OP_LT
Matthew Wild <mwild1@gmail.com>
parents:
56
diff
changeset
|
15 | var OP_SUB = 13; |
110
6a6e5ef39eaf
Implement OP_MUL (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
109
diff
changeset
|
16 | var OP_MUL = 14; |
99
633e414a496c
Implement OP_DIV (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
98
diff
changeset
|
17 | var OP_DIV = 15; |
112
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
18 | var OP_MOD = 16; |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
19 | var OP_POW = 17; |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
20 | var OP_UNM = 18; |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
21 | var OP_NOT = 19; |
116
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
22 | var OP_LEN = 20; |
101
f1247747f025
Implement OP_CONCAT (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
100
diff
changeset
|
23 | var OP_CONCAT = 21; |
40
3a074ec1790f
Implement OP_TEST and OP_JMP
Matthew Wild <mwild1@gmail.com>
parents:
39
diff
changeset
|
24 | var OP_JMP = 22; |
81 | 25 | var OP_EQ = 23; |
58
40d0b0429428
Implement OP_ADD, OP_SUB, OP_LT
Matthew Wild <mwild1@gmail.com>
parents:
56
diff
changeset
|
26 | var OP_LT = 24; |
90
40edbc05fbb9
Implement OP_LE (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
89
diff
changeset
|
27 | var OP_LE = 25; |
40
3a074ec1790f
Implement OP_TEST and OP_JMP
Matthew Wild <mwild1@gmail.com>
parents:
39
diff
changeset
|
28 | var OP_TEST = 26; |
59 | 29 | var OP_TESTSET = 27; |
0 | 30 | var OP_CALL = 28; |
127
9a4c549c7828
Implement OP_TAILCALL - the last opcode!
Matthew Wild <mwild1@gmail.com>
parents:
125
diff
changeset
|
31 | var OP_TAILCALL = 29; |
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
|
32 | var OP_RETURN = 30; |
34
2c3d73c76d0f
OP_FORPREP, OP_FORLOOP: Support for numerical for loops
Matthew Wild <mwild1@gmail.com>
parents:
33
diff
changeset
|
33 | var OP_FORLOOP = 31; |
2c3d73c76d0f
OP_FORPREP, OP_FORLOOP: Support for numerical for loops
Matthew Wild <mwild1@gmail.com>
parents:
33
diff
changeset
|
34 | var OP_FORPREP = 32; |
102 | 35 | var OP_TFORLOOP = 33; |
103 | 36 | var OP_SETLIST = 34; |
118 | 37 | var OP_CLOSE = 35; |
15
5240eaff785f
Implement basic OP_CLOSURE (no support for upvalues yet)
Matthew Wild <mwild1@gmail.com>
parents:
14
diff
changeset
|
38 | var OP_CLOSURE = 36; |
123 | 39 | var OP_VARARG = 37; |
0 | 40 | |
91
298efa276aff
Disable debugMode, accidentally committed
Matthew Wild <mwild1@gmail.com>
parents:
90
diff
changeset
|
41 | var debugMode = false; |
8 | 42 | |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
43 | function LValue(vm, type, value) |
0 | 44 | { |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
45 | this.vm = vm; |
0 | 46 | this.type = type||"nil"; |
37
62c1d9bf3000
Allow LValues with a value of 'false' to be create (it was converted to 'null')
Matthew Wild <mwild1@gmail.com>
parents:
36
diff
changeset
|
47 | this.value = value; |
0 | 48 | } |
49 | ||
50 | LValue.prototype = { | |
51 | call: function (args) | |
52 | { | |
128
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
53 | var ret = this.vm.call(this, args); |
49
052bd6e8daf6
Give LValue precall() and call() methods, give functions a vm property.
Matthew Wild <mwild1@gmail.com>
parents:
48
diff
changeset
|
54 | if(typeof(ret) == "undefined") |
052bd6e8daf6
Give LValue precall() and call() methods, give functions a vm property.
Matthew Wild <mwild1@gmail.com>
parents:
48
diff
changeset
|
55 | ret = []; |
052bd6e8daf6
Give LValue precall() and call() methods, give functions a vm property.
Matthew Wild <mwild1@gmail.com>
parents:
48
diff
changeset
|
56 | return ret; |
052bd6e8daf6
Give LValue precall() and call() methods, give functions a vm property.
Matthew Wild <mwild1@gmail.com>
parents:
48
diff
changeset
|
57 | }, |
052bd6e8daf6
Give LValue precall() and call() methods, give functions a vm property.
Matthew Wild <mwild1@gmail.com>
parents:
48
diff
changeset
|
58 | precall: function () |
052bd6e8daf6
Give LValue precall() and call() methods, give functions a vm property.
Matthew Wild <mwild1@gmail.com>
parents:
48
diff
changeset
|
59 | { |
3
6f338fbf0abc
Throw an error if trying to call a non-function
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
60 | if(this.type == "function") |
6f338fbf0abc
Throw an error if trying to call a non-function
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
61 | return this.value; |
6f338fbf0abc
Throw an error if trying to call a non-function
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
62 | else |
6f338fbf0abc
Throw an error if trying to call a non-function
Matthew Wild <mwild1@gmail.com>
parents:
2
diff
changeset
|
63 | throw "Attempt to call a " + this.type + " value"; |
0 | 64 | }, |
54
5e0bdf7f234f
Support for __index metamethod
Matthew Wild <mwild1@gmail.com>
parents:
53
diff
changeset
|
65 | index: function (key, raw) |
0 | 66 | { |
67 | if(this.type == "table") | |
68 | { | |
54
5e0bdf7f234f
Support for __index metamethod
Matthew Wild <mwild1@gmail.com>
parents:
53
diff
changeset
|
69 | var val; |
5e0bdf7f234f
Support for __index metamethod
Matthew Wild <mwild1@gmail.com>
parents:
53
diff
changeset
|
70 | if(key.value in this.value) |
5e0bdf7f234f
Support for __index metamethod
Matthew Wild <mwild1@gmail.com>
parents:
53
diff
changeset
|
71 | return this.value[key.value]; |
5e0bdf7f234f
Support for __index metamethod
Matthew Wild <mwild1@gmail.com>
parents:
53
diff
changeset
|
72 | else if(raw != true && this.metatable && this.metatable.type != "nil") |
5e0bdf7f234f
Support for __index metamethod
Matthew Wild <mwild1@gmail.com>
parents:
53
diff
changeset
|
73 | { |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
74 | var __index = this.metatable.index(this.vm.LValue("__index")); |
60
430a0b155703
Support for tables in __index
Matthew Wild <mwild1@gmail.com>
parents:
59
diff
changeset
|
75 | if(__index.type == "function") |
54
5e0bdf7f234f
Support for __index metamethod
Matthew Wild <mwild1@gmail.com>
parents:
53
diff
changeset
|
76 | { |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
77 | return this.vm.LValue(__index.call([this, key])[0]); |
54
5e0bdf7f234f
Support for __index metamethod
Matthew Wild <mwild1@gmail.com>
parents:
53
diff
changeset
|
78 | } |
60
430a0b155703
Support for tables in __index
Matthew Wild <mwild1@gmail.com>
parents:
59
diff
changeset
|
79 | else if(__index.type != "nil") |
430a0b155703
Support for tables in __index
Matthew Wild <mwild1@gmail.com>
parents:
59
diff
changeset
|
80 | return __index.index(key); |
54
5e0bdf7f234f
Support for __index metamethod
Matthew Wild <mwild1@gmail.com>
parents:
53
diff
changeset
|
81 | } |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
82 | return this.vm.LValue(null); |
0 | 83 | } |
7
00ec5f6e7579
Add errors for when trying to index non-tables
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
84 | else |
00ec5f6e7579
Add errors for when trying to index non-tables
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
85 | throw "Attempt to index a " + this.type + " value"; |
0 | 86 | }, |
87 | setIndex: function (key, value) | |
88 | { | |
89 | if(this.type == "table") | |
90 | { | |
91 | this.value[key.value] = value; | |
92 | } | |
7
00ec5f6e7579
Add errors for when trying to index non-tables
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
93 | else |
00ec5f6e7579
Add errors for when trying to index non-tables
Matthew Wild <mwild1@gmail.com>
parents:
6
diff
changeset
|
94 | throw "Attempt to index a " + this.type + " value"; |
53 | 95 | }, |
96 | setMetatable: function (metatable) | |
97 | { | |
98 | if(metatable.type == "table") | |
99 | this.metatable = metatable; | |
100 | else if(metatable.type == "nil") | |
101 | this.metatable = null; | |
102 | else | |
103 | throw "Attempt to set a "+metatable.type+" value as a metatable"; | |
61 | 104 | }, |
105 | toString: function () | |
106 | { | |
107 | switch(this.type) | |
108 | { | |
109 | case "nil": | |
110 | return "nil"; | |
111 | default: | |
112 | return this.value.toString(); | |
113 | } | |
72
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
114 | }, |
86
97678a1565d4
Add LValue.truth() to return whether a value is (not(false) and not(nil))
Matthew Wild <mwild1@gmail.com>
parents:
85
diff
changeset
|
115 | truth: function () |
97678a1565d4
Add LValue.truth() to return whether a value is (not(false) and not(nil))
Matthew Wild <mwild1@gmail.com>
parents:
85
diff
changeset
|
116 | { |
97678a1565d4
Add LValue.truth() to return whether a value is (not(false) and not(nil))
Matthew Wild <mwild1@gmail.com>
parents:
85
diff
changeset
|
117 | if(this.type == "nil" || (this.type == "boolean" && this.value == false)) |
97678a1565d4
Add LValue.truth() to return whether a value is (not(false) and not(nil))
Matthew Wild <mwild1@gmail.com>
parents:
85
diff
changeset
|
118 | return false; |
97678a1565d4
Add LValue.truth() to return whether a value is (not(false) and not(nil))
Matthew Wild <mwild1@gmail.com>
parents:
85
diff
changeset
|
119 | return true; |
97678a1565d4
Add LValue.truth() to return whether a value is (not(false) and not(nil))
Matthew Wild <mwild1@gmail.com>
parents:
85
diff
changeset
|
120 | }, |
72
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
121 | add: function (op2) |
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
122 | { |
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
123 | var metamethod; |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
124 | var __add = this.vm.LValue("__add"); |
72
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
125 | if(this.metatable) |
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
126 | metamethod = this.metatable.index(__add); |
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
127 | if((!metamethod || metamethod.type == "nil") && op2.metatable) |
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
128 | metamethod = op2.metatable.index(__add); |
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
129 | if(metamethod && metamethod.type != "nil") |
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
130 | { |
75
aaecd573ee30
Support for __add metamethod
Matthew Wild <mwild1@gmail.com>
parents:
74
diff
changeset
|
131 | return metamethod.call([this, op2]); |
72
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
132 | } |
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
133 | else if((this.type == "number" || this.type == "string") |
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
134 | && (op2.type == "number" || op2.type == "string")) |
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
135 | { |
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
136 | // Plain addition |
76
d7d7a6bb90cd
Fix OP_ADD code to use new LValue format
Matthew Wild <mwild1@gmail.com>
parents:
75
diff
changeset
|
137 | return this.vm.LValue(parseFloat(this.value, 10) + parseFloat(op2.value, 10)); |
72
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
138 | } |
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
139 | else |
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
140 | throw "Attempt to perform arithmetic on a "+this.type+" and "+op2.type; |
80
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
141 | }, |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
142 | equals: function (op2) |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
143 | { |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
144 | if(this.type != op2.type) |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
145 | return false; |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
146 | if(this.value == op2.value) |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
147 | return true; |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
148 | var __eq = this.vm.LValue("__eq"); |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
149 | if(this.metatable && op2.metatable) |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
150 | { |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
151 | var metamethod1 = this.metatable.index(__eq); |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
152 | var metamethod2 = op2.metatable.index(__eq); |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
153 | if(metamethod1.equals(metamethod2)) |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
154 | { |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
155 | var result = metamethod1.call([this, op2]); |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
156 | return (result[0].type != "nil" |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
157 | && (result[0].type != "boolean" || result[0].value == true) |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
158 | ); |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
159 | } |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
160 | } |
beb0bb936aca
Give LValue an equals() method, returns true/false if the value == the first argument (checks metamethod)
Matthew Wild <mwild1@gmail.com>
parents:
79
diff
changeset
|
161 | return false; |
116
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
162 | }, |
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
163 | len: function () |
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
164 | { |
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
165 | switch(this.type) |
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
166 | { |
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
167 | case "string": |
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
168 | case "table": |
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
169 | return this.value.length; |
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
170 | default: |
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
171 | throw "attempt to get length of a "+this.type+" value"; |
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
172 | } |
0 | 173 | } |
174 | }; | |
175 | ||
92
e9da9847121a
Pass sourceName to child chunks (in binary files it's only set in the top-level chunk)
Matthew Wild <mwild1@gmail.com>
parents:
91
diff
changeset
|
176 | function LBinaryChunk(vm, chunk, start, sourceName) |
0 | 177 | { |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
178 | 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
|
179 | this.pos = start||12; |
9
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 | this.sourceName = this.readString(); |
92
e9da9847121a
Pass sourceName to child chunks (in binary files it's only set in the top-level chunk)
Matthew Wild <mwild1@gmail.com>
parents:
91
diff
changeset
|
182 | if(sourceName) |
e9da9847121a
Pass sourceName to child chunks (in binary files it's only set in the top-level chunk)
Matthew Wild <mwild1@gmail.com>
parents:
91
diff
changeset
|
183 | this.sourceName = sourceName; |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
184 | this.lineDefined = this.readInt(); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
185 | this.lastLineDefined = this.readInt(); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
186 | this.numUpvalues = this.readByte(); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
187 | this.numParameters = this.readByte(); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
188 | this.isVararg = this.readByte(); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
189 | this.maxStackSize = this.readByte(); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
190 | |
0 | 191 | this.instructions = []; |
9
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 | this.numInstructions = this.readInt(); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
194 | for(var i=0;i<this.numInstructions;i++) |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
195 | { |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
196 | var ins = this.readInt(); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
197 | this.instructions.push([ |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
198 | ins&0x3F, // Opcode |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
199 | (ins>>6)&0xFF, // Field A |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
200 | (ins>>23)&0x1FF, // Field B |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
201 | (ins>>14)&0x1FF // Field C |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
202 | ]); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
203 | if(debugMode) |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
204 | { |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
205 | var pi = this.instructions[this.instructions.length-1]; |
128
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
206 | //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
|
207 | } |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
208 | } |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
209 | |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
210 | this.constants = []; |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
211 | |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
212 | this.numConstants = this.readInt(); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
213 | for(var i=0;i<this.numConstants;i++) |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
214 | { |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
215 | var type = this.readByte(); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
216 | switch(type) |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
217 | { |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
218 | case 0: // Nil |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
219 | this.constants.push(new LValue(vm, "nil", null)); |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
220 | break; |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
221 | case 1: // Boolean |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
222 | this.constants.push(new LValue(vm, "boolean", this.readByte())); // FIXME type |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
223 | break; |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
224 | case 3: // Number |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
225 | this.constants.push(new LValue(vm, "number", this.readNumber())); |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
226 | break; |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
227 | case 4: // String |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
228 | this.constants.push(new LValue(vm, "string", this.readString())); |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
229 | break; |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
230 | default: |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
231 | throw "Invalid constant type "+type+" in bytecode"; |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
232 | } |
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 | |
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
|
235 | 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
|
236 | |
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
|
237 | 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
|
238 | 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
|
239 | { |
92
e9da9847121a
Pass sourceName to child chunks (in binary files it's only set in the top-level chunk)
Matthew Wild <mwild1@gmail.com>
parents:
91
diff
changeset
|
240 | var p = new LBinaryChunk(vm, chunk, this.pos, this.sourceName); |
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
|
241 | 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
|
242 | 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
|
243 | } |
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
|
244 | |
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
|
245 | 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
|
246 | |
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
|
247 | 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
|
248 | 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
|
249 | { |
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
|
250 | 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
|
251 | } |
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
|
252 | |
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
|
253 | 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
|
254 | 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
|
255 | 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
|
256 | { |
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
|
257 | 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
|
258 | } |
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
|
259 | |
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
|
260 | 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
|
261 | 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
|
262 | 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
|
263 | { |
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
|
264 | 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
|
265 | } |
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
|
266 | |
0 | 267 | return this; |
268 | } | |
269 | ||
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
270 | LBinaryChunk.prototype = { |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
271 | readBytes: function (n) |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
272 | { |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
273 | return this.chunk.slice(this.pos, this.pos+=n); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
274 | }, |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
275 | readByte: function () |
0 | 276 | { |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
277 | return this.readBytes(1).charCodeAt(0); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
278 | }, |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
279 | readInt: function () |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
280 | { |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
281 | //FIXME: Endianness |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
282 | return this.readByte() | (this.readByte()<<8) |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
283 | | (this.readByte()<<16) | (this.readByte()<<24); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
284 | }, |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
285 | readString: function () |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
286 | { |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
287 | var len = this.readInt(); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
288 | return this.readBytes(len).substring(0,len-1); |
0 | 289 | }, |
12
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
290 | readNumber: function () |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
291 | { |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
292 | //FIXME: Endianness |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
293 | 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
|
294 | 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
|
295 | |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
296 | var sign = (bytes[0]>>7)&0x1; |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
297 | 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
|
298 | |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
299 | 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
|
300 | + (bytes[2] * Math.pow(2,40)) |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
301 | + (bytes[3] * Math.pow(2,32)) |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
302 | + (bytes[4] * Math.pow(2,24)) |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
303 | + (bytes[5] * Math.pow(2,16)) |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
304 | + (bytes[6] * Math.pow(2,8)) |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
305 | + bytes[7]; |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
306 | |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
307 | if(exp != 0x000 && exp != 0x7FF) |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
308 | { |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
309 | 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
|
310 | return n; |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
311 | } |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
312 | else if(exp == 0x000) |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
313 | { |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
314 | return sign*0; |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
315 | } |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
316 | else |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
317 | return frac==0?sign*Infinity:NaN; |
7d748aba47ab
Initial stab at reading Number constants from bytecode
Matthew Wild <mwild1@gmail.com>
parents:
11
diff
changeset
|
318 | } |
0 | 319 | }; |
320 | ||
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
321 | function INS_OPCODE(ins) |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
322 | { |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
323 | return ins[0]; |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
324 | } |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
325 | |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
326 | function INS_A(ins) |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
327 | { |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
328 | return ins[1]; |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
329 | } |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
330 | |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
331 | function INS_B(ins) |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
332 | { |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
333 | return ins[2]; |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
334 | } |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
335 | |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
336 | function INS_C(ins) |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
337 | { |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
338 | return ins[3]; |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
339 | } |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
340 | |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
341 | function INS_Bx(ins) |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
342 | { |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
343 | return ((INS_C(ins))|(INS_B(ins)<<9)); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
344 | } |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
345 | |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
346 | function INS_sBx(ins) |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
347 | { |
32
035aacc192d8
Fix off-by-one in calculating the value of sBx
Matthew Wild <mwild1@gmail.com>
parents:
31
diff
changeset
|
348 | return (INS_Bx(ins)-0x1FFFF); |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
349 | } |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
350 | |
77
ab8ff064d808
Add new RK() helper and fix OP_ADD to use it (so it loads constants properly)
Matthew Wild <mwild1@gmail.com>
parents:
76
diff
changeset
|
351 | function RK(frame, R) |
ab8ff064d808
Add new RK() helper and fix OP_ADD to use it (so it loads constants properly)
Matthew Wild <mwild1@gmail.com>
parents:
76
diff
changeset
|
352 | { |
ab8ff064d808
Add new RK() helper and fix OP_ADD to use it (so it loads constants properly)
Matthew Wild <mwild1@gmail.com>
parents:
76
diff
changeset
|
353 | var keysource = (R&0x100)?frame.f.constants:frame.reg; |
ab8ff064d808
Add new RK() helper and fix OP_ADD to use it (so it loads constants properly)
Matthew Wild <mwild1@gmail.com>
parents:
76
diff
changeset
|
354 | return keysource[R&0xff]; |
ab8ff064d808
Add new RK() helper and fix OP_ADD to use it (so it loads constants properly)
Matthew Wild <mwild1@gmail.com>
parents:
76
diff
changeset
|
355 | } |
ab8ff064d808
Add new RK() helper and fix OP_ADD to use it (so it loads constants properly)
Matthew Wild <mwild1@gmail.com>
parents:
76
diff
changeset
|
356 | |
43
ecfa7896af35
Give LFunctions a vm property
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
357 | function LFunction(vm, chunk, env) |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
358 | { |
131
cd1ba419c808
Create local function to use as chunk prototype
Matthew Wild <mwild1@gmail.com>
parents:
130
diff
changeset
|
359 | var F = function () {}; |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
360 | F.prototype = chunk; |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
361 | var o = new F(); |
43
ecfa7896af35
Give LFunctions a vm property
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
362 | o.vm = vm; |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
363 | 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
|
364 | 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
|
365 | o.upvalues = []; |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
366 | return o; |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
367 | } |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
368 | |
0 | 369 | function LVM() |
370 | { | |
371 | this.callstack = []; | |
372 | this.stack = []; | |
373 | return this; | |
374 | } | |
375 | ||
376 | LVM.prototype = { | |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
377 | LValue: function (value) |
0 | 378 | { |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
379 | switch(typeof(value)) |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
380 | { |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
381 | case "number": |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
382 | return new LValue(this, "number", value); |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
383 | case "string": |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
384 | return new LValue(this, "string", value); |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
385 | case "function": |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
386 | return new LValue(this, "function", value); |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
387 | case "object": |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
388 | if(value == null) |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
389 | return new LValue(this, "nil", value); |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
390 | else |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
391 | return new LValue(this, "table", value); |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
392 | case "undefined": |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
393 | return new LValue(this, "nil", null); |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
394 | default: |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
395 | throw "Not able to convert type " + |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
396 | typeof(value)+" from Javascript to Lua"; |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
397 | } |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
398 | }, |
128
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
399 | call: function (func, args) |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
400 | { |
128
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
401 | var f = func.precall(); |
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
402 | if(typeof(f) == "function") |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
403 | { |
128
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
404 | return f.apply(this, args); |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
405 | } |
130
88fa4df26e9d
Better verification of function validity in LVM.call()
Matthew Wild <mwild1@gmail.com>
parents:
129
diff
changeset
|
406 | else if(f.instructions) |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
407 | { |
128
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
408 | var frame = {f:f,pc:0,entry:true}; |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
409 | if(args) |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
410 | frame.reg = args.slice(0); |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
411 | else |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
412 | frame.reg = []; |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
413 | this.callstack.push(frame); |
128
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
414 | for(var i=frame.reg.length;i<f.maxStackSize;i++) |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
415 | frame.reg[i] = this.LValue(null); |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
416 | return this.run(frame); |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
417 | } |
130
88fa4df26e9d
Better verification of function validity in LVM.call()
Matthew Wild <mwild1@gmail.com>
parents:
129
diff
changeset
|
418 | else |
88fa4df26e9d
Better verification of function validity in LVM.call()
Matthew Wild <mwild1@gmail.com>
parents:
129
diff
changeset
|
419 | throw "Attempt to call invalid function object: "+f.toString(); |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
420 | }, |
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
421 | run: function(frame) |
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
422 | { |
0 | 423 | var instruction; |
424 | while(this.callstack.length>0) | |
425 | { | |
45
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
426 | instruction = frame.f.instructions[frame.pc++]; |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
427 | if(debugMode) |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
428 | { |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
429 | sys.puts("PC: "+(frame.pc-1)+" OP: "+instruction[0]); |
106
04eb68b0f3e3
Prettier stack printing in debugMode
Matthew Wild <mwild1@gmail.com>
parents:
105
diff
changeset
|
430 | for(var i = 0; i < frame.reg.length; i++) |
107
40b25248703b
Fix exception in stack printing for some tests when debug mode is enabled
Matthew Wild <mwild1@gmail.com>
parents:
106
diff
changeset
|
431 | { |
40b25248703b
Fix exception in stack printing for some tests when debug mode is enabled
Matthew Wild <mwild1@gmail.com>
parents:
106
diff
changeset
|
432 | var entry = frame.reg[i]; |
40b25248703b
Fix exception in stack printing for some tests when debug mode is enabled
Matthew Wild <mwild1@gmail.com>
parents:
106
diff
changeset
|
433 | if(entry && entry.type) |
40b25248703b
Fix exception in stack printing for some tests when debug mode is enabled
Matthew Wild <mwild1@gmail.com>
parents:
106
diff
changeset
|
434 | sys.puts("\t"+i+":\t("+entry.type+") "+entry.toString()); |
40b25248703b
Fix exception in stack printing for some tests when debug mode is enabled
Matthew Wild <mwild1@gmail.com>
parents:
106
diff
changeset
|
435 | else |
40b25248703b
Fix exception in stack printing for some tests when debug mode is enabled
Matthew Wild <mwild1@gmail.com>
parents:
106
diff
changeset
|
436 | sys.puts("\t"+i+": "+entry); |
40b25248703b
Fix exception in stack printing for some tests when debug mode is enabled
Matthew Wild <mwild1@gmail.com>
parents:
106
diff
changeset
|
437 | } |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
438 | } |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
439 | switch(INS_OPCODE(instruction)) |
0 | 440 | { |
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
|
441 | case OP_MOVE: |
45
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
442 | frame.reg[INS_A(instruction)] = 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
|
443 | 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
|
444 | case OP_LOADNIL: |
10
ce2f27fa25a4
Use new notation for accessing instruction fields
Matthew Wild <mwild1@gmail.com>
parents:
9
diff
changeset
|
445 | for(var i = INS_A(instruction);i<=INS_B(instruction);i++) |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
446 | frame.reg[i] = new LValue(this, "nil", null); |
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
|
447 | break; |
39 | 448 | case OP_LOADBOOL: |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
449 | frame.reg[INS_A(instruction)] = new LValue(this, "boolean", INS_B(instruction)!=0); |
39 | 450 | if(INS_C(instruction)!=0) |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
451 | frame.pc++; |
39 | 452 | 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
|
453 | case OP_GETUPVAL: |
132
5a928c1478ad
OP_GETUPVALUE: Clone original LValue
Matthew Wild <mwild1@gmail.com>
parents:
131
diff
changeset
|
454 | var upvalue = frame.f.upvalues[INS_B(instruction)]; |
5a928c1478ad
OP_GETUPVALUE: Clone original LValue
Matthew Wild <mwild1@gmail.com>
parents:
131
diff
changeset
|
455 | frame.reg[INS_A(instruction)] = new LValue(this, upvalue.type, upvalue.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
|
456 | break; |
0 | 457 | case OP_GETGLOBAL: |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
458 | var name = frame.f.constants[INS_Bx(instruction)]; |
45
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
459 | frame.reg[INS_A(instruction)] = frame.f.environment.index(name); |
0 | 460 | 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
|
461 | case OP_SETUPVAL: |
45
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
462 | var reg = frame.reg[INS_A(instruction)]; |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
463 | var upvalue = frame.f.upvalues[INS_B(instruction)]; |
26 | 464 | upvalue.type = reg.type; |
465 | 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
|
466 | break; |
6 | 467 | case OP_SETGLOBAL: |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
468 | var name = frame.f.constants[INS_Bx(instruction)]; |
45
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
469 | frame.f.environment.setIndex(name, frame.reg[instruction[1]]); |
6 | 470 | break; |
0 | 471 | case OP_LOADK: |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
472 | var constant = frame.f.constants[INS_Bx(instruction)]; |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
473 | frame.reg[INS_A(instruction)] = new LValue(this, constant.type, constant.value); |
0 | 474 | break; |
28
d14b47c3870f
Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents:
27
diff
changeset
|
475 | case OP_NEWTABLE: |
115
1555cb5a97b3
Switch to [] for representing tables (for now)
Matthew Wild <mwild1@gmail.com>
parents:
114
diff
changeset
|
476 | frame.reg[INS_A(instruction)] = new LValue(this, "table", []); |
28
d14b47c3870f
Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents:
27
diff
changeset
|
477 | break; |
d14b47c3870f
Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents:
27
diff
changeset
|
478 | case OP_GETTABLE: |
d14b47c3870f
Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents:
27
diff
changeset
|
479 | var C = INS_C(instruction); |
114
82d7b057d330
Don't use this.LValue() inside the VM - it's for JS types only
Matthew Wild <mwild1@gmail.com>
parents:
113
diff
changeset
|
480 | var value = frame.reg[INS_B(instruction)].index(RK(frame, C)); |
82d7b057d330
Don't use this.LValue() inside the VM - it's for JS types only
Matthew Wild <mwild1@gmail.com>
parents:
113
diff
changeset
|
481 | frame.reg[INS_A(instruction)] = new LValue(this, value.type, value.value); |
28
d14b47c3870f
Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents:
27
diff
changeset
|
482 | break; |
d14b47c3870f
Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents:
27
diff
changeset
|
483 | case OP_SETTABLE: |
d14b47c3870f
Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents:
27
diff
changeset
|
484 | var C = INS_C(instruction); |
d14b47c3870f
Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents:
27
diff
changeset
|
485 | var B = INS_B(instruction); |
85
25470393fe74
Fix OP_SETTABLE to use RK() helper
Matthew Wild <mwild1@gmail.com>
parents:
83
diff
changeset
|
486 | frame.reg[INS_A(instruction)].setIndex(RK(frame, B), RK(frame, C)); |
28
d14b47c3870f
Support for OP_NEWTABLE, OP_GETTABLE, OP_SETTABLE
Matthew Wild <mwild1@gmail.com>
parents:
27
diff
changeset
|
487 | break; |
123 | 488 | case OP_VARARG: |
489 | var A = INS_A(instruction); | |
490 | var prevframe = this.callstack[this.callstack.length-2]; | |
491 | var base = frame.retAt+frame.f.numParameters; | |
133 | 492 | var available = (prevframe.reg.length - base) - 1; |
123 | 493 | var wanted = INS_B(instruction)-1; |
494 | if(wanted < 0) | |
495 | wanted = available; | |
496 | for(var i = 0; i<wanted; i++) | |
497 | { | |
498 | if(i<available) | |
499 | frame.reg[A+i] = prevframe.reg[base+i+1]; | |
500 | else | |
501 | frame.reg[A+i] = new LValue(this, "nil", null); | |
502 | } | |
503 | break; | |
127
9a4c549c7828
Implement OP_TAILCALL - the last opcode!
Matthew Wild <mwild1@gmail.com>
parents:
125
diff
changeset
|
504 | case OP_TAILCALL: |
9a4c549c7828
Implement OP_TAILCALL - the last opcode!
Matthew Wild <mwild1@gmail.com>
parents:
125
diff
changeset
|
505 | var f = frame.reg[INS_A(instruction)].precall(); |
134
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
506 | if(typeof(f) != "function") // Can't tail-call native functions |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
507 | { |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
508 | var A = INS_A(instruction), B = INS_B(instruction); |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
509 | var undefined, args; |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
510 | if(B != 1) |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
511 | args = frame.reg.slice(A+1, B==0?undefined:(A+B)); |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
512 | else |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
513 | args = []; |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
514 | if(args.length > f.numParameters) |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
515 | args.length = f.numParameters; |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
516 | for(var i=args.length;i<f.maxStackSize;i++) |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
517 | args[i] = new LValue(this, "nil", null); // Patch frame for new function |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
518 | frame.f = f; frame.pc = 0; frame.reg = args; |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
519 | break; |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
520 | } |
2e2d08e3669c
OP_TAILCALL: Fall through to OP_CALL for native functions
Matthew Wild <mwild1@gmail.com>
parents:
133
diff
changeset
|
521 | // Fall through... |
0 | 522 | case OP_CALL: |
128
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
523 | var f = frame.reg[INS_A(instruction)].precall(); // return JS or LFunction |
63
be8bcd01409b
New interface for native Javascript functions called from Lua
Matthew Wild <mwild1@gmail.com>
parents:
62
diff
changeset
|
524 | var A = INS_A(instruction), B = INS_B(instruction), C = INS_C(instruction); |
be8bcd01409b
New interface for native Javascript functions called from Lua
Matthew Wild <mwild1@gmail.com>
parents:
62
diff
changeset
|
525 | var undefined; |
113
1e49dfb8ccdc
Fix OP_CALL to handle the case of B==1 (no parameters) and fix an off-by-one error that wouldn't fill the stack with nils properly
Matthew Wild <mwild1@gmail.com>
parents:
112
diff
changeset
|
526 | var args; |
1e49dfb8ccdc
Fix OP_CALL to handle the case of B==1 (no parameters) and fix an off-by-one error that wouldn't fill the stack with nils properly
Matthew Wild <mwild1@gmail.com>
parents:
112
diff
changeset
|
527 | if(B != 1) |
1e49dfb8ccdc
Fix OP_CALL to handle the case of B==1 (no parameters) and fix an off-by-one error that wouldn't fill the stack with nils properly
Matthew Wild <mwild1@gmail.com>
parents:
112
diff
changeset
|
528 | args = frame.reg.slice(A+1, B==0?undefined:(A+B)); |
1e49dfb8ccdc
Fix OP_CALL to handle the case of B==1 (no parameters) and fix an off-by-one error that wouldn't fill the stack with nils properly
Matthew Wild <mwild1@gmail.com>
parents:
112
diff
changeset
|
529 | else |
1e49dfb8ccdc
Fix OP_CALL to handle the case of B==1 (no parameters) and fix an off-by-one error that wouldn't fill the stack with nils properly
Matthew Wild <mwild1@gmail.com>
parents:
112
diff
changeset
|
530 | args = []; |
121
fe51bed4a718
OP_CALL: Don't push varargs into called function's stack
Matthew Wild <mwild1@gmail.com>
parents:
120
diff
changeset
|
531 | if(B != 0) |
fe51bed4a718
OP_CALL: Don't push varargs into called function's stack
Matthew Wild <mwild1@gmail.com>
parents:
120
diff
changeset
|
532 | frame.reg.length = 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
|
533 | 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
|
534 | { |
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
|
535 | // JS native function |
128
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
536 | var ret = this.call(frame.reg[INS_A(instruction)], args); |
79
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
537 | // Insert ret to reg starting at R(A), with C-1 limit |
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
538 | var nresults = ret.length; |
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
539 | var nexpected; |
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
540 | if(C == 0) |
63
be8bcd01409b
New interface for native Javascript functions called from Lua
Matthew Wild <mwild1@gmail.com>
parents:
62
diff
changeset
|
541 | { |
79
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
542 | nexpected = nresults; |
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
543 | frame.reg = frame.reg.slice(0, A+nexpected); |
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
544 | } |
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
545 | else |
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
546 | nexpected = C-1; |
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
547 | for(var i = 0;;i++) |
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
548 | { |
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
549 | if(i < nresults) |
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
550 | frame.reg[A+i] = ret[i]; |
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
551 | else if(i < nexpected) |
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
552 | frame.reg[A+i] = new LValue(this, "nil", null); |
63
be8bcd01409b
New interface for native Javascript functions called from Lua
Matthew Wild <mwild1@gmail.com>
parents:
62
diff
changeset
|
553 | else |
79
94c0441b7321
Fix native function return values for the new calling interface
Matthew Wild <mwild1@gmail.com>
parents:
78
diff
changeset
|
554 | break; |
63
be8bcd01409b
New interface for native Javascript functions called from Lua
Matthew Wild <mwild1@gmail.com>
parents:
62
diff
changeset
|
555 | } |
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
|
556 | } |
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
|
557 | 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
|
558 | { |
121
fe51bed4a718
OP_CALL: Don't push varargs into called function's stack
Matthew Wild <mwild1@gmail.com>
parents:
120
diff
changeset
|
559 | if(args.length > f.numParameters) |
fe51bed4a718
OP_CALL: Don't push varargs into called function's stack
Matthew Wild <mwild1@gmail.com>
parents:
120
diff
changeset
|
560 | args.length = f.numParameters; |
fe51bed4a718
OP_CALL: Don't push varargs into called function's stack
Matthew Wild <mwild1@gmail.com>
parents:
120
diff
changeset
|
561 | for(var i=args.length;i<f.maxStackSize;i++) |
fe51bed4a718
OP_CALL: Don't push varargs into called function's stack
Matthew Wild <mwild1@gmail.com>
parents:
120
diff
changeset
|
562 | args[i] = new LValue(this, "nil", null); |
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
|
563 | // Lua function |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
564 | frame = {f:f,pc:0,reg:args, |
51
b429e7a73de7
More reliable detection of when we're at a native/Lua call boundary
Matthew Wild <mwild1@gmail.com>
parents:
50
diff
changeset
|
565 | retAt:INS_A(instruction),retCount:INS_C(instruction), |
b429e7a73de7
More reliable detection of when we're at a native/Lua call boundary
Matthew Wild <mwild1@gmail.com>
parents:
50
diff
changeset
|
566 | entry:false}; |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
567 | this.callstack.push(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
|
568 | } |
0 | 569 | break; |
15
5240eaff785f
Implement basic OP_CLOSURE (no support for upvalues yet)
Matthew Wild <mwild1@gmail.com>
parents:
14
diff
changeset
|
570 | case OP_CLOSURE: |
5240eaff785f
Implement basic OP_CLOSURE (no support for upvalues yet)
Matthew Wild <mwild1@gmail.com>
parents:
14
diff
changeset
|
571 | var prototype_id = INS_Bx(instruction); |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
572 | var chunk = frame.f.chunk.prototypes[prototype_id]; |
43
ecfa7896af35
Give LFunctions a vm property
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
573 | var f = new LFunction(this, chunk, frame.f.environment); |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
574 | frame.reg[INS_A(instruction)] = new LValue(this, "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
|
575 | 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
|
576 | { |
45
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
577 | var upval_instruction = frame.f.instructions[frame.pc++]; |
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
|
578 | 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
|
579 | { |
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
|
580 | case OP_MOVE: |
45
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
581 | f.upvalues[i] = frame.reg[INS_B(upval_instruction)]; |
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
|
582 | 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
|
583 | case OP_GETUPVAL: |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
584 | f.upvalues[i] = frame.f.upvalues[INS_B(upval_instruction)]; |
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
|
585 | 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
|
586 | 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
|
587 | 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
|
588 | } |
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
|
589 | } |
15
5240eaff785f
Implement basic OP_CLOSURE (no support for upvalues yet)
Matthew Wild <mwild1@gmail.com>
parents:
14
diff
changeset
|
590 | break; |
0 | 591 | case OP_RETURN: |
19
8c9c1752272b
OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents:
18
diff
changeset
|
592 | var oldFrame = this.callstack.pop(); |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
593 | frame = this.callstack[this.callstack.length-1]; |
47
b8c4273edbbb
Support for return values from LVM.call()
Matthew Wild <mwild1@gmail.com>
parents:
46
diff
changeset
|
594 | var rets; |
b8c4273edbbb
Support for return values from LVM.call()
Matthew Wild <mwild1@gmail.com>
parents:
46
diff
changeset
|
595 | if(INS_B(instruction) == 0) |
b8c4273edbbb
Support for return values from LVM.call()
Matthew Wild <mwild1@gmail.com>
parents:
46
diff
changeset
|
596 | rets = oldFrame.reg.slice(INS_A(instruction)); |
b8c4273edbbb
Support for return values from LVM.call()
Matthew Wild <mwild1@gmail.com>
parents:
46
diff
changeset
|
597 | else |
b8c4273edbbb
Support for return values from LVM.call()
Matthew Wild <mwild1@gmail.com>
parents:
46
diff
changeset
|
598 | rets = oldFrame.reg.slice(INS_A(instruction),INS_A(instruction)+(INS_B(instruction)-1)); |
51
b429e7a73de7
More reliable detection of when we're at a native/Lua call boundary
Matthew Wild <mwild1@gmail.com>
parents:
50
diff
changeset
|
599 | if(!oldFrame.entry) |
19
8c9c1752272b
OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents:
18
diff
changeset
|
600 | { |
8c9c1752272b
OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents:
18
diff
changeset
|
601 | var i; |
64
77552f3c2c39
Correct off-by-one in return value limits
Matthew Wild <mwild1@gmail.com>
parents:
63
diff
changeset
|
602 | for(i=0;(oldFrame.retCount == 0||i<(oldFrame.retCount-1))&&i<rets.length;i++) |
45
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
603 | frame.reg[oldFrame.retAt+i] = rets[i]; |
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
604 | if(oldFrame.retAt+i<frame.reg.length) |
135
77022489338a
OP_RETURN: Pad out results with nils if we get less results than expected
Matthew Wild <mwild1@gmail.com>
parents:
134
diff
changeset
|
605 | frame.reg.length = (oldFrame.retAt+i); |
77022489338a
OP_RETURN: Pad out results with nils if we get less results than expected
Matthew Wild <mwild1@gmail.com>
parents:
134
diff
changeset
|
606 | if(i<oldFrame.retCount) |
77022489338a
OP_RETURN: Pad out results with nils if we get less results than expected
Matthew Wild <mwild1@gmail.com>
parents:
134
diff
changeset
|
607 | { |
77022489338a
OP_RETURN: Pad out results with nils if we get less results than expected
Matthew Wild <mwild1@gmail.com>
parents:
134
diff
changeset
|
608 | for(;i<oldFrame.retCount;i++) |
77022489338a
OP_RETURN: Pad out results with nils if we get less results than expected
Matthew Wild <mwild1@gmail.com>
parents:
134
diff
changeset
|
609 | frame.reg[oldFrame.retAt+i] = new LValue(this, "nil", null); |
77022489338a
OP_RETURN: Pad out results with nils if we get less results than expected
Matthew Wild <mwild1@gmail.com>
parents:
134
diff
changeset
|
610 | } |
19
8c9c1752272b
OP_RETURN: Support for return values from Lua functions \o/
Matthew Wild <mwild1@gmail.com>
parents:
18
diff
changeset
|
611 | } |
47
b8c4273edbbb
Support for return values from LVM.call()
Matthew Wild <mwild1@gmail.com>
parents:
46
diff
changeset
|
612 | else |
b8c4273edbbb
Support for return values from LVM.call()
Matthew Wild <mwild1@gmail.com>
parents:
46
diff
changeset
|
613 | return rets; |
0 | 614 | break; |
118 | 615 | case OP_CLOSE: |
616 | // No-op, since we leave upvalue management to the GC | |
617 | break; | |
36 | 618 | case OP_SELF: |
45
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
619 | var table = frame.reg[INS_B(instruction)]; |
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
620 | frame.reg[INS_A(instruction)+1] = table; |
36 | 621 | var C = INS_C(instruction); |
78
a856f1c3364f
Update all opcodes to use RK() that need it
Matthew Wild <mwild1@gmail.com>
parents:
77
diff
changeset
|
622 | frame.reg[INS_A(instruction)] = table.index(RK(frame, C)); |
36 | 623 | break; |
34
2c3d73c76d0f
OP_FORPREP, OP_FORLOOP: Support for numerical for loops
Matthew Wild <mwild1@gmail.com>
parents:
33
diff
changeset
|
624 | case OP_FORPREP: |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
625 | frame.pc+=(INS_sBx(instruction)); |
34
2c3d73c76d0f
OP_FORPREP, OP_FORLOOP: Support for numerical for loops
Matthew Wild <mwild1@gmail.com>
parents:
33
diff
changeset
|
626 | var A = INS_A(instruction); |
45
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
627 | frame.reg[A].value -= frame.reg[A+2].value; |
34
2c3d73c76d0f
OP_FORPREP, OP_FORLOOP: Support for numerical for loops
Matthew Wild <mwild1@gmail.com>
parents:
33
diff
changeset
|
628 | break; |
2c3d73c76d0f
OP_FORPREP, OP_FORLOOP: Support for numerical for loops
Matthew Wild <mwild1@gmail.com>
parents:
33
diff
changeset
|
629 | case OP_FORLOOP: |
2c3d73c76d0f
OP_FORPREP, OP_FORLOOP: Support for numerical for loops
Matthew Wild <mwild1@gmail.com>
parents:
33
diff
changeset
|
630 | var A = INS_A(instruction); |
45
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
631 | var RA = frame.reg[A]; |
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
632 | RA.value += frame.reg[A+2].value; |
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
633 | if(RA.value <= frame.reg[A+1].value) |
34
2c3d73c76d0f
OP_FORPREP, OP_FORLOOP: Support for numerical for loops
Matthew Wild <mwild1@gmail.com>
parents:
33
diff
changeset
|
634 | { |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
635 | frame.pc += INS_sBx(instruction); |
117
8f1045a7f1d6
Fix OP_FORLOOP to set the loop counter variable properly
Matthew Wild <mwild1@gmail.com>
parents:
116
diff
changeset
|
636 | frame.reg[A+3] = new LValue(this, "number", RA.value); |
34
2c3d73c76d0f
OP_FORPREP, OP_FORLOOP: Support for numerical for loops
Matthew Wild <mwild1@gmail.com>
parents:
33
diff
changeset
|
637 | } |
2c3d73c76d0f
OP_FORPREP, OP_FORLOOP: Support for numerical for loops
Matthew Wild <mwild1@gmail.com>
parents:
33
diff
changeset
|
638 | break; |
102 | 639 | case OP_TFORLOOP: |
640 | var A = INS_A(instruction); | |
641 | var C = INS_C(instruction); | |
128
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
642 | var RA = frame.reg[A]; // Iterator function |
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
643 | var rets = this.call(RA, [frame.reg[A+1], frame.reg[A+2]]); |
102 | 644 | frame.reg.length = A+3; |
645 | for(var i = 0; i<C; i++) | |
646 | frame.reg[A+3+i] = rets[i]; | |
647 | if(frame.reg[A+3].type != "nil") | |
648 | frame.reg[A+2] = frame.reg[A+3]; | |
649 | else | |
650 | frame.pc++; // Skip JMP to start | |
651 | continue; | |
40
3a074ec1790f
Implement OP_TEST and OP_JMP
Matthew Wild <mwild1@gmail.com>
parents:
39
diff
changeset
|
652 | case OP_TEST: |
45
4d2cf0b5235d
Backed out changeset 741b953fcc5f (premature optimisations == bad)
Matthew Wild <mwild1@gmail.com>
parents:
42
diff
changeset
|
653 | var RA = frame.reg[INS_A(instruction)]; |
40
3a074ec1790f
Implement OP_TEST and OP_JMP
Matthew Wild <mwild1@gmail.com>
parents:
39
diff
changeset
|
654 | var RA_bool = RA.type == "nil" || (RA.type == "boolean" && RA.value == false); |
3a074ec1790f
Implement OP_TEST and OP_JMP
Matthew Wild <mwild1@gmail.com>
parents:
39
diff
changeset
|
655 | if(RA_bool == (INS_C(instruction)!=0)) |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
656 | frame.pc++; |
40
3a074ec1790f
Implement OP_TEST and OP_JMP
Matthew Wild <mwild1@gmail.com>
parents:
39
diff
changeset
|
657 | break; |
59 | 658 | case OP_TESTSET: |
659 | var RB = frame.reg[INS_B(instruction)]; | |
660 | var RB_bool = RB.type == "nil" || (RB.type == "boolean" && RB.value == false); | |
661 | if(RB_bool == (INS_C(instruction)!=0)) | |
662 | frame.pc++; | |
663 | else | |
664 | frame.reg[INS_A(instruction)] = RB; | |
665 | break; | |
40
3a074ec1790f
Implement OP_TEST and OP_JMP
Matthew Wild <mwild1@gmail.com>
parents:
39
diff
changeset
|
666 | case OP_JMP: |
41
70eb0eb5e7e8
Split LVM.run() into LVM.call()/LVM.run()
Matthew Wild <mwild1@gmail.com>
parents:
40
diff
changeset
|
667 | frame.pc+=INS_sBx(instruction); |
40
3a074ec1790f
Implement OP_TEST and OP_JMP
Matthew Wild <mwild1@gmail.com>
parents:
39
diff
changeset
|
668 | break; |
101
f1247747f025
Implement OP_CONCAT (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
100
diff
changeset
|
669 | case OP_CONCAT: |
f1247747f025
Implement OP_CONCAT (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
100
diff
changeset
|
670 | var A = INS_A(instruction); |
f1247747f025
Implement OP_CONCAT (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
100
diff
changeset
|
671 | var B = INS_B(instruction); |
f1247747f025
Implement OP_CONCAT (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
100
diff
changeset
|
672 | var C = INS_C(instruction); |
f1247747f025
Implement OP_CONCAT (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
100
diff
changeset
|
673 | var values = []; |
f1247747f025
Implement OP_CONCAT (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
100
diff
changeset
|
674 | for(var i = B; i<=C; i++) |
f1247747f025
Implement OP_CONCAT (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
100
diff
changeset
|
675 | values.push(frame.reg[i].value); |
120
e058c18b9f85
Fix OP_CONCAT: missing break; and should supply empty separator to join()
Matthew Wild <mwild1@gmail.com>
parents:
119
diff
changeset
|
676 | frame.reg[A] = new LValue(this, "string", values.join('')); |
e058c18b9f85
Fix OP_CONCAT: missing break; and should supply empty separator to join()
Matthew Wild <mwild1@gmail.com>
parents:
119
diff
changeset
|
677 | break; |
58
40d0b0429428
Implement OP_ADD, OP_SUB, OP_LT
Matthew Wild <mwild1@gmail.com>
parents:
56
diff
changeset
|
678 | case OP_ADD: |
77
ab8ff064d808
Add new RK() helper and fix OP_ADD to use it (so it loads constants properly)
Matthew Wild <mwild1@gmail.com>
parents:
76
diff
changeset
|
679 | var RB = RK(frame, INS_B(instruction)); |
ab8ff064d808
Add new RK() helper and fix OP_ADD to use it (so it loads constants properly)
Matthew Wild <mwild1@gmail.com>
parents:
76
diff
changeset
|
680 | var RC = RK(frame, INS_C(instruction)); |
72
dc73a60b3c06
Give LValue an add() method, to eventually respect metamethods
Matthew Wild <mwild1@gmail.com>
parents:
71
diff
changeset
|
681 | frame.reg[INS_A(instruction)] = RB.add(RC); |
58
40d0b0429428
Implement OP_ADD, OP_SUB, OP_LT
Matthew Wild <mwild1@gmail.com>
parents:
56
diff
changeset
|
682 | break; |
40d0b0429428
Implement OP_ADD, OP_SUB, OP_LT
Matthew Wild <mwild1@gmail.com>
parents:
56
diff
changeset
|
683 | case OP_SUB: |
95
c461e20b609a
Fix OP_SUB to use RK() too...
Matthew Wild <mwild1@gmail.com>
parents:
93
diff
changeset
|
684 | var RB = RK(frame, INS_B(instruction)); |
c461e20b609a
Fix OP_SUB to use RK() too...
Matthew Wild <mwild1@gmail.com>
parents:
93
diff
changeset
|
685 | var RC = RK(frame, INS_C(instruction)); |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
686 | frame.reg[INS_A(instruction)] = new LValue(this, "number", RB.value - RC.value); |
58
40d0b0429428
Implement OP_ADD, OP_SUB, OP_LT
Matthew Wild <mwild1@gmail.com>
parents:
56
diff
changeset
|
687 | break; |
110
6a6e5ef39eaf
Implement OP_MUL (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
109
diff
changeset
|
688 | case OP_MUL: |
6a6e5ef39eaf
Implement OP_MUL (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
109
diff
changeset
|
689 | var RB = RK(frame, INS_B(instruction)); |
6a6e5ef39eaf
Implement OP_MUL (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
109
diff
changeset
|
690 | var RC = RK(frame, INS_C(instruction)); |
6a6e5ef39eaf
Implement OP_MUL (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
109
diff
changeset
|
691 | frame.reg[INS_A(instruction)] = new LValue(this, "number", RB.value * RC.value); |
6a6e5ef39eaf
Implement OP_MUL (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
109
diff
changeset
|
692 | break; |
99
633e414a496c
Implement OP_DIV (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
98
diff
changeset
|
693 | case OP_DIV: |
633e414a496c
Implement OP_DIV (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
98
diff
changeset
|
694 | var RB = RK(frame, INS_B(instruction)); |
633e414a496c
Implement OP_DIV (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
98
diff
changeset
|
695 | var RC = RK(frame, INS_C(instruction)); |
633e414a496c
Implement OP_DIV (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
98
diff
changeset
|
696 | frame.reg[INS_A(instruction)] = new LValue(this, "number", RB.value / RC.value); |
633e414a496c
Implement OP_DIV (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
98
diff
changeset
|
697 | break; |
112
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
698 | case OP_MOD: |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
699 | var RB = RK(frame, INS_B(instruction)); |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
700 | var RC = RK(frame, INS_C(instruction)); |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
701 | frame.reg[INS_A(instruction)] = new LValue(this, "number", RB.value % RC.value); |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
702 | break; |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
703 | case OP_POW: |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
704 | var RB = RK(frame, INS_B(instruction)); |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
705 | var RC = RK(frame, INS_C(instruction)); |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
706 | frame.reg[INS_A(instruction)] = new LValue(this, "number", Math.pow(RB.value, RC.value)); |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
707 | break; |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
708 | case OP_UNM: |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
709 | var RB = frame.reg[INS_B(instruction)]; |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
710 | frame.reg[INS_A(instruction)] = new LValue(this, "number", -RB.value); |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
711 | break; |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
712 | case OP_NOT: |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
713 | var RB = frame.reg[INS_B(instruction)]; |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
714 | frame.reg[INS_A(instruction)] = new LValue(this, "boolean", !RB.truth()); |
5318bb31b0ac
Implement OP_MOD, OP_POW, OP_UNM, OP_NOT (no metamethods yet)
Matthew Wild <mwild1@gmail.com>
parents:
110
diff
changeset
|
715 | break; |
116
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
716 | case OP_LEN: |
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
717 | var RB = frame.reg[INS_B(instruction)]; |
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
718 | frame.reg[INS_A(instruction)] = new LValue(this, "number", RB.len()); |
b78e86780939
Implement LValue.len() and OP_LEN (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
115
diff
changeset
|
719 | break; |
89
a9cef9e01154
Fix OP_LT to respect A, and move OP_EQ to live next to it in the switch() for readability
Matthew Wild <mwild1@gmail.com>
parents:
88
diff
changeset
|
720 | case OP_EQ: |
a9cef9e01154
Fix OP_LT to respect A, and move OP_EQ to live next to it in the switch() for readability
Matthew Wild <mwild1@gmail.com>
parents:
88
diff
changeset
|
721 | var A = INS_A(instruction); |
88 | 722 | var RB = RK(frame, INS_B(instruction)); |
723 | var RC = RK(frame, INS_C(instruction)); | |
89
a9cef9e01154
Fix OP_LT to respect A, and move OP_EQ to live next to it in the switch() for readability
Matthew Wild <mwild1@gmail.com>
parents:
88
diff
changeset
|
724 | if(RB.equals(RC) != (A!=0)) |
a9cef9e01154
Fix OP_LT to respect A, and move OP_EQ to live next to it in the switch() for readability
Matthew Wild <mwild1@gmail.com>
parents:
88
diff
changeset
|
725 | frame.pc++; |
a9cef9e01154
Fix OP_LT to respect A, and move OP_EQ to live next to it in the switch() for readability
Matthew Wild <mwild1@gmail.com>
parents:
88
diff
changeset
|
726 | break; |
a9cef9e01154
Fix OP_LT to respect A, and move OP_EQ to live next to it in the switch() for readability
Matthew Wild <mwild1@gmail.com>
parents:
88
diff
changeset
|
727 | case OP_LT: |
a9cef9e01154
Fix OP_LT to respect A, and move OP_EQ to live next to it in the switch() for readability
Matthew Wild <mwild1@gmail.com>
parents:
88
diff
changeset
|
728 | var A = INS_A(instruction); |
a9cef9e01154
Fix OP_LT to respect A, and move OP_EQ to live next to it in the switch() for readability
Matthew Wild <mwild1@gmail.com>
parents:
88
diff
changeset
|
729 | var RB = RK(frame, INS_B(instruction)); |
a9cef9e01154
Fix OP_LT to respect A, and move OP_EQ to live next to it in the switch() for readability
Matthew Wild <mwild1@gmail.com>
parents:
88
diff
changeset
|
730 | var RC = RK(frame, INS_C(instruction)); |
a9cef9e01154
Fix OP_LT to respect A, and move OP_EQ to live next to it in the switch() for readability
Matthew Wild <mwild1@gmail.com>
parents:
88
diff
changeset
|
731 | if(RB.value < RC.value != (A!=0)) |
58
40d0b0429428
Implement OP_ADD, OP_SUB, OP_LT
Matthew Wild <mwild1@gmail.com>
parents:
56
diff
changeset
|
732 | frame.pc++; |
40d0b0429428
Implement OP_ADD, OP_SUB, OP_LT
Matthew Wild <mwild1@gmail.com>
parents:
56
diff
changeset
|
733 | break; |
90
40edbc05fbb9
Implement OP_LE (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
89
diff
changeset
|
734 | case OP_LE: |
40edbc05fbb9
Implement OP_LE (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
89
diff
changeset
|
735 | var A = INS_A(instruction); |
40edbc05fbb9
Implement OP_LE (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
89
diff
changeset
|
736 | var RB = RK(frame, INS_B(instruction)); |
40edbc05fbb9
Implement OP_LE (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
89
diff
changeset
|
737 | var RC = RK(frame, INS_C(instruction)); |
40edbc05fbb9
Implement OP_LE (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
89
diff
changeset
|
738 | if(RB.value <= RC.value != (A!=0)) |
40edbc05fbb9
Implement OP_LE (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
89
diff
changeset
|
739 | frame.pc++; |
40edbc05fbb9
Implement OP_LE (no metamethod yet)
Matthew Wild <mwild1@gmail.com>
parents:
89
diff
changeset
|
740 | break; |
103 | 741 | case OP_SETLIST: |
742 | var A = INS_A(instruction); | |
743 | var RA = frame.reg[A]; | |
744 | var B = INS_B(instruction); | |
745 | var C = INS_C(instruction); | |
746 | if(C == 0) | |
747 | throw "Dynamic table construction not yet implemented"; | |
748 | // #define LFIELDS_PER_FLUSH 50 // Lua 5.1 | |
749 | var baseindex = (C-1)*50; | |
750 | var index = new LValue(this, "number", 1); | |
136
0b31998aad53
OP_SETLIST: Implement support for B==0 (to top of stack)
Matthew Wild <mwild1@gmail.com>
parents:
135
diff
changeset
|
751 | var lim = B>0?B:((frame.reg.length-baseindex)-2); |
0b31998aad53
OP_SETLIST: Implement support for B==0 (to top of stack)
Matthew Wild <mwild1@gmail.com>
parents:
135
diff
changeset
|
752 | for(var i = 1; i<=lim; index.value=(baseindex+(++i))) |
103 | 753 | RA.setIndex(index, frame.reg[A+i]); |
754 | break; | |
0 | 755 | default: |
11
1b3267149cbd
Throw error on unhandled opcodes
Matthew Wild <mwild1@gmail.com>
parents:
10
diff
changeset
|
756 | throw "Unhandled opcode: "+INS_OPCODE(instruction); |
0 | 757 | } |
758 | } | |
96
e4324d9a824c
Add LVM().registerLib(env, name, lib) to register a table of native functions to an environment.
Matthew Wild <mwild1@gmail.com>
parents:
95
diff
changeset
|
759 | }, |
e4324d9a824c
Add LVM().registerLib(env, name, lib) to register a table of native functions to an environment.
Matthew Wild <mwild1@gmail.com>
parents:
95
diff
changeset
|
760 | registerLib: function (env, name, lib) |
e4324d9a824c
Add LVM().registerLib(env, name, lib) to register a table of native functions to an environment.
Matthew Wild <mwild1@gmail.com>
parents:
95
diff
changeset
|
761 | { |
e4324d9a824c
Add LVM().registerLib(env, name, lib) to register a table of native functions to an environment.
Matthew Wild <mwild1@gmail.com>
parents:
95
diff
changeset
|
762 | var t; |
e4324d9a824c
Add LVM().registerLib(env, name, lib) to register a table of native functions to an environment.
Matthew Wild <mwild1@gmail.com>
parents:
95
diff
changeset
|
763 | if(name) |
e4324d9a824c
Add LVM().registerLib(env, name, lib) to register a table of native functions to an environment.
Matthew Wild <mwild1@gmail.com>
parents:
95
diff
changeset
|
764 | { |
115
1555cb5a97b3
Switch to [] for representing tables (for now)
Matthew Wild <mwild1@gmail.com>
parents:
114
diff
changeset
|
765 | t = this.LValue([]); // Create env[name] and put fns in there |
96
e4324d9a824c
Add LVM().registerLib(env, name, lib) to register a table of native functions to an environment.
Matthew Wild <mwild1@gmail.com>
parents:
95
diff
changeset
|
766 | env.setIndex(this.LValue(name), t); |
e4324d9a824c
Add LVM().registerLib(env, name, lib) to register a table of native functions to an environment.
Matthew Wild <mwild1@gmail.com>
parents:
95
diff
changeset
|
767 | } |
e4324d9a824c
Add LVM().registerLib(env, name, lib) to register a table of native functions to an environment.
Matthew Wild <mwild1@gmail.com>
parents:
95
diff
changeset
|
768 | else |
e4324d9a824c
Add LVM().registerLib(env, name, lib) to register a table of native functions to an environment.
Matthew Wild <mwild1@gmail.com>
parents:
95
diff
changeset
|
769 | t = env; // Import directly into env |
e4324d9a824c
Add LVM().registerLib(env, name, lib) to register a table of native functions to an environment.
Matthew Wild <mwild1@gmail.com>
parents:
95
diff
changeset
|
770 | |
e4324d9a824c
Add LVM().registerLib(env, name, lib) to register a table of native functions to an environment.
Matthew Wild <mwild1@gmail.com>
parents:
95
diff
changeset
|
771 | for(var k in lib) |
e4324d9a824c
Add LVM().registerLib(env, name, lib) to register a table of native functions to an environment.
Matthew Wild <mwild1@gmail.com>
parents:
95
diff
changeset
|
772 | t.setIndex(this.LValue(k), this.LValue(lib[k])); |
128
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
773 | }, |
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
774 | loadstring: function (chunk, env) |
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
775 | { |
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
776 | var c = new LBinaryChunk(this, chunk); |
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
777 | var f = new LFunction(this, c, env); |
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
778 | return new LValue(this, "function", f); |
137
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
779 | }, |
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
780 | traceback: function () |
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
781 | { |
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
782 | var trace = []; |
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
783 | for(var i=this.callstack.length-1; i>=0; i--) |
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
784 | { |
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
785 | var currframe = testvm.callstack[i]; |
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
786 | var currfunc = currframe.f; |
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
787 | var sourceName = (currfunc.sourceName||"=?").substr(1); |
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
788 | var line = "?"; |
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
789 | if(currfunc.sourceLines && currfunc.sourceLines[currframe.pc-1]) |
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
790 | line = currfunc.sourceLines[currframe.pc-1]; |
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
791 | trace.push({ sourceName: sourceName, line: line }); |
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
792 | } |
6872878601d9
Add LVM.traceback() function
Matthew Wild <mwild1@gmail.com>
parents:
136
diff
changeset
|
793 | return trace; |
0 | 794 | } |
795 | }; | |
796 | ||
56
d02c7932cbf2
Move try {} block so it covers more of the VM initialization
Matthew Wild <mwild1@gmail.com>
parents:
55
diff
changeset
|
797 | try{ |
0 | 798 | 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
|
799 | |
9
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
800 | var fs=require("fs"); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
801 | var sys=require("sys"); |
3f055c9ab80e
Add a bytecode interpreter \o/
Matthew Wild <mwild1@gmail.com>
parents:
8
diff
changeset
|
802 | |
115
1555cb5a97b3
Switch to [] for representing tables (for now)
Matthew Wild <mwild1@gmail.com>
parents:
114
diff
changeset
|
803 | var _G = testvm.LValue([]); |
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
|
804 | |
67
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
805 | // Standard library |
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
|
806 | |
67
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
807 | var baselib = { |
140
2286f9b970b7
baselib: Implement basic message-only error()
Matthew Wild <mwild1@gmail.com>
parents:
139
diff
changeset
|
808 | error: function (message) |
2286f9b970b7
baselib: Implement basic message-only error()
Matthew Wild <mwild1@gmail.com>
parents:
139
diff
changeset
|
809 | { |
2286f9b970b7
baselib: Implement basic message-only error()
Matthew Wild <mwild1@gmail.com>
parents:
139
diff
changeset
|
810 | throw message.toString(); |
2286f9b970b7
baselib: Implement basic message-only error()
Matthew Wild <mwild1@gmail.com>
parents:
139
diff
changeset
|
811 | }, |
74
a4a6adee1459
New Lua<->native function interface, simpler. Added type() to baselib.
Matthew Wild <mwild1@gmail.com>
parents:
73
diff
changeset
|
812 | print: function () |
67
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
813 | { |
74
a4a6adee1459
New Lua<->native function interface, simpler. Added type() to baselib.
Matthew Wild <mwild1@gmail.com>
parents:
73
diff
changeset
|
814 | var args = Array.prototype.slice.call(arguments); |
67
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
815 | sys.print(args[0].toString()); |
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
816 | for(var i = 1; i<args.length; i++) |
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
817 | sys.print("\t"+args[i].toString()); |
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
818 | sys.print("\n"); |
74
a4a6adee1459
New Lua<->native function interface, simpler. Added type() to baselib.
Matthew Wild <mwild1@gmail.com>
parents:
73
diff
changeset
|
819 | return []; |
67
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
820 | }, |
74
a4a6adee1459
New Lua<->native function interface, simpler. Added type() to baselib.
Matthew Wild <mwild1@gmail.com>
parents:
73
diff
changeset
|
821 | setmetatable: function (table, metatable) |
67
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
822 | { |
74
a4a6adee1459
New Lua<->native function interface, simpler. Added type() to baselib.
Matthew Wild <mwild1@gmail.com>
parents:
73
diff
changeset
|
823 | if(arguments.length!=2) |
a4a6adee1459
New Lua<->native function interface, simpler. Added type() to baselib.
Matthew Wild <mwild1@gmail.com>
parents:
73
diff
changeset
|
824 | throw "setmetatable expects 2 arguments, got "+arguments.length; |
a4a6adee1459
New Lua<->native function interface, simpler. Added type() to baselib.
Matthew Wild <mwild1@gmail.com>
parents:
73
diff
changeset
|
825 | |
a4a6adee1459
New Lua<->native function interface, simpler. Added type() to baselib.
Matthew Wild <mwild1@gmail.com>
parents:
73
diff
changeset
|
826 | table.setMetatable(metatable); |
a4a6adee1459
New Lua<->native function interface, simpler. Added type() to baselib.
Matthew Wild <mwild1@gmail.com>
parents:
73
diff
changeset
|
827 | return [table]; |
a4a6adee1459
New Lua<->native function interface, simpler. Added type() to baselib.
Matthew Wild <mwild1@gmail.com>
parents:
73
diff
changeset
|
828 | }, |
a4a6adee1459
New Lua<->native function interface, simpler. Added type() to baselib.
Matthew Wild <mwild1@gmail.com>
parents:
73
diff
changeset
|
829 | type: function (o) |
a4a6adee1459
New Lua<->native function interface, simpler. Added type() to baselib.
Matthew Wild <mwild1@gmail.com>
parents:
73
diff
changeset
|
830 | { |
83
0e6b19731508
Fix type() in baselib to return an LValue
Matthew Wild <mwild1@gmail.com>
parents:
82
diff
changeset
|
831 | return [this.LValue(o.type)]; |
87
07d19518e89a
Add assert() to baselib, real tests possible at last
Matthew Wild <mwild1@gmail.com>
parents:
86
diff
changeset
|
832 | }, |
07d19518e89a
Add assert() to baselib, real tests possible at last
Matthew Wild <mwild1@gmail.com>
parents:
86
diff
changeset
|
833 | assert: function (expr, message) |
07d19518e89a
Add assert() to baselib, real tests possible at last
Matthew Wild <mwild1@gmail.com>
parents:
86
diff
changeset
|
834 | { |
07d19518e89a
Add assert() to baselib, real tests possible at last
Matthew Wild <mwild1@gmail.com>
parents:
86
diff
changeset
|
835 | if(!expr.truth()) |
119
ad42e6dd7cbd
assert(): Throw "assertion failed" message when none supplied
Matthew Wild <mwild1@gmail.com>
parents:
118
diff
changeset
|
836 | if(message && message.truth()) |
ad42e6dd7cbd
assert(): Throw "assertion failed" message when none supplied
Matthew Wild <mwild1@gmail.com>
parents:
118
diff
changeset
|
837 | throw message; |
ad42e6dd7cbd
assert(): Throw "assertion failed" message when none supplied
Matthew Wild <mwild1@gmail.com>
parents:
118
diff
changeset
|
838 | else |
ad42e6dd7cbd
assert(): Throw "assertion failed" message when none supplied
Matthew Wild <mwild1@gmail.com>
parents:
118
diff
changeset
|
839 | throw "assertion failed"; |
87
07d19518e89a
Add assert() to baselib, real tests possible at last
Matthew Wild <mwild1@gmail.com>
parents:
86
diff
changeset
|
840 | return [expr]; |
67
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
841 | } |
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
842 | }; |
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
843 | |
97
80cc68dd8222
Rename default_environment to _G, use registerLib() for baselib and add math lib with 2 ldexp, floor
Matthew Wild <mwild1@gmail.com>
parents:
96
diff
changeset
|
844 | var math = { |
80cc68dd8222
Rename default_environment to _G, use registerLib() for baselib and add math lib with 2 ldexp, floor
Matthew Wild <mwild1@gmail.com>
parents:
96
diff
changeset
|
845 | ldexp: function (m, e) |
80cc68dd8222
Rename default_environment to _G, use registerLib() for baselib and add math lib with 2 ldexp, floor
Matthew Wild <mwild1@gmail.com>
parents:
96
diff
changeset
|
846 | { |
80cc68dd8222
Rename default_environment to _G, use registerLib() for baselib and add math lib with 2 ldexp, floor
Matthew Wild <mwild1@gmail.com>
parents:
96
diff
changeset
|
847 | return [this.LValue(m.value*Math.pow(2, e.value))]; |
80cc68dd8222
Rename default_environment to _G, use registerLib() for baselib and add math lib with 2 ldexp, floor
Matthew Wild <mwild1@gmail.com>
parents:
96
diff
changeset
|
848 | }, |
142
574e0baea136
Add math.frexp() and tests (many thanks to Florob and Link Mauve!)
Matthew Wild <mwild1@gmail.com>
parents:
141
diff
changeset
|
849 | frexp: function (x) |
574e0baea136
Add math.frexp() and tests (many thanks to Florob and Link Mauve!)
Matthew Wild <mwild1@gmail.com>
parents:
141
diff
changeset
|
850 | { |
574e0baea136
Add math.frexp() and tests (many thanks to Florob and Link Mauve!)
Matthew Wild <mwild1@gmail.com>
parents:
141
diff
changeset
|
851 | var m = x.value; |
574e0baea136
Add math.frexp() and tests (many thanks to Florob and Link Mauve!)
Matthew Wild <mwild1@gmail.com>
parents:
141
diff
changeset
|
852 | var e = 0; |
574e0baea136
Add math.frexp() and tests (many thanks to Florob and Link Mauve!)
Matthew Wild <mwild1@gmail.com>
parents:
141
diff
changeset
|
853 | while (Math.abs(m) >= 1) { |
574e0baea136
Add math.frexp() and tests (many thanks to Florob and Link Mauve!)
Matthew Wild <mwild1@gmail.com>
parents:
141
diff
changeset
|
854 | m = m / 2; |
574e0baea136
Add math.frexp() and tests (many thanks to Florob and Link Mauve!)
Matthew Wild <mwild1@gmail.com>
parents:
141
diff
changeset
|
855 | e = e + 1; |
574e0baea136
Add math.frexp() and tests (many thanks to Florob and Link Mauve!)
Matthew Wild <mwild1@gmail.com>
parents:
141
diff
changeset
|
856 | }; |
574e0baea136
Add math.frexp() and tests (many thanks to Florob and Link Mauve!)
Matthew Wild <mwild1@gmail.com>
parents:
141
diff
changeset
|
857 | return [this.LValue(m), this.LValue(e)]; |
574e0baea136
Add math.frexp() and tests (many thanks to Florob and Link Mauve!)
Matthew Wild <mwild1@gmail.com>
parents:
141
diff
changeset
|
858 | }, |
97
80cc68dd8222
Rename default_environment to _G, use registerLib() for baselib and add math lib with 2 ldexp, floor
Matthew Wild <mwild1@gmail.com>
parents:
96
diff
changeset
|
859 | floor: function (x) |
80cc68dd8222
Rename default_environment to _G, use registerLib() for baselib and add math lib with 2 ldexp, floor
Matthew Wild <mwild1@gmail.com>
parents:
96
diff
changeset
|
860 | { |
80cc68dd8222
Rename default_environment to _G, use registerLib() for baselib and add math lib with 2 ldexp, floor
Matthew Wild <mwild1@gmail.com>
parents:
96
diff
changeset
|
861 | return [this.LValue(Math.floor(x.value))]; |
80cc68dd8222
Rename default_environment to _G, use registerLib() for baselib and add math lib with 2 ldexp, floor
Matthew Wild <mwild1@gmail.com>
parents:
96
diff
changeset
|
862 | } |
80cc68dd8222
Rename default_environment to _G, use registerLib() for baselib and add math lib with 2 ldexp, floor
Matthew Wild <mwild1@gmail.com>
parents:
96
diff
changeset
|
863 | }; |
80cc68dd8222
Rename default_environment to _G, use registerLib() for baselib and add math lib with 2 ldexp, floor
Matthew Wild <mwild1@gmail.com>
parents:
96
diff
changeset
|
864 | |
104
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
865 | var _patternClasses = { |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
866 | "a": "[A-Za-z]", "A": "[^A-Za-z]", |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
867 | "p": "[\x21-\x2f\x3a-\x40\x5b-\x60\x7b-\x7e]", |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
868 | "P": "[^\x21-\x2f\x3a-\x40\x5b-\x60\x7b-\x7e]", |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
869 | "s": "[\x09-\x0d\x20]", "S": "[^\x09-\x0d\x20]", |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
870 | "u": "[A-Z]", "U": "[^A-Z]", |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
871 | "d": "[0-9]", "D": "[^0-9]", |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
872 | "w": "[0-9A-Za-z]", "W": "[^0-9A-Za-z]", |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
873 | "x": "[0-9A-Fa-f]", "X": "[^0-9A-Fa-f]", |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
874 | "z": "[\x00]", "Z": "[^\x00]", |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
875 | "l": "[a-z]", "L": "[^a-z]", |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
876 | "c": "[\x00-\x1f\x7f]", "C": "[^\x00-\x1f\x7f]", |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
877 | }; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
878 | |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
879 | var _patternToRegExp = function (patt) |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
880 | { |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
881 | var regexp = ""; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
882 | for(var i=0;i<patt.length;i++) |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
883 | { |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
884 | var c = patt[i]; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
885 | if(c == "%") |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
886 | { |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
887 | c = patt[++i]; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
888 | if(c == "b") |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
889 | { |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
890 | throw "%b not supported in patterns"; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
891 | } |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
892 | else if(c >= "0" && c <= "9") |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
893 | { |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
894 | regexp += ("\\"+c); |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
895 | continue; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
896 | } |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
897 | else |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
898 | { |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
899 | var cls = _patternClasses[c]; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
900 | if(cls) |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
901 | { |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
902 | regexp += cls; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
903 | continue; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
904 | } |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
905 | } |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
906 | } |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
907 | else if(c == "\\" || c == "/") |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
908 | regexp += "\\"; // Escape escapes |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
909 | regexp += c; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
910 | } |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
911 | return new RegExp(regexp, "g"); |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
912 | }; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
913 | |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
914 | var string = { |
139
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
915 | "char": function () |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
916 | { |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
917 | var nArgs = arguments.length; |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
918 | if(nArgs < 1) |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
919 | throw "string.char(): Expects at least 1 parameter"; |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
920 | var results = []; |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
921 | for(var i=0; i<nArgs; i++) |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
922 | { |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
923 | var code = arguments[i]; |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
924 | if(code.type != "number") |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
925 | throw "string.char(): Argument #"+(i+1)+" expected number, got "+code.type; |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
926 | results.push(String.fromCharCode(code.value)); |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
927 | } |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
928 | return [this.LValue(results.join(''))]; |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
929 | }, |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
930 | find: function (str, patt, init, plain) |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
931 | { |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
932 | if(arguments.length > 2) |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
933 | throw "string.find(): No more than the first 2 arguments supported"; |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
934 | var re = _patternToRegExp(patt.value); |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
935 | var result = re.exec(str); |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
936 | if(!result) |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
937 | return [this.LValue(null)]; |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
938 | var start = result.index+1; |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
939 | var end = start + result[0].length - 1; |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
940 | var ret = [this.LValue(start), this.LValue(end)]; |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
941 | for(var i=1; i<result.length; i++) |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
942 | ret.push(this.LValue(result[i])); |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
943 | return ret; |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
944 | }, |
141
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
945 | format: function (format_) |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
946 | { |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
947 | var format = format_.value, result = ""; |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
948 | var re = new RegExp("%([0-9. ]*)([a-zA-Z%])", "g"); |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
949 | var match, currpos = 0, currparam = 1; |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
950 | while(match = re.exec(format)) |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
951 | { |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
952 | result += format.substring(currpos, match.index); |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
953 | currpos = re.lastIndex; |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
954 | switch(match[2]) |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
955 | { |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
956 | case "f": case "d": |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
957 | if(match[1].length>0) |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
958 | throw "string.format(): Number format modifers not yet implemented"; |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
959 | case "s": |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
960 | result+=arguments[currparam++].value.toString(); |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
961 | case "%": |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
962 | break; |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
963 | default: |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
964 | throw "string.format(): Format %"+match[2]+" not implemented"; |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
965 | } |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
966 | } |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
967 | result += format.substring(currpos); |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
968 | return [this.LValue(result)]; |
16b833862ae2
Implement basic string.format() supporting %d/%s
Matthew Wild <mwild1@gmail.com>
parents:
140
diff
changeset
|
969 | }, |
104
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
970 | gmatch: function (str, patt) |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
971 | { |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
972 | var re = _patternToRegExp(patt.value); |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
973 | var matches = str.value.match(re)||[]; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
974 | var curr = 0; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
975 | var iter = function () |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
976 | { |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
977 | return [this.LValue(matches[curr++])]; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
978 | }; |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
979 | return [this.LValue(iter)]; |
139
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
980 | }, |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
981 | sub: function (str, from, to) |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
982 | { |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
983 | var result; |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
984 | switch(arguments.length) |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
985 | { |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
986 | case 0: |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
987 | case 1: |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
988 | throw "string.sub(): Expected 2 or more arguments"; |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
989 | case 2: |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
990 | result = str.value.substring(from.value); |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
991 | case 3: |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
992 | result = str.value.substring(from.value, to.value); |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
993 | } |
055fe658d0b2
Implement string.find (mostly) and string.sub
Matthew Wild <mwild1@gmail.com>
parents:
138
diff
changeset
|
994 | return [this.LValue(result)]; |
104
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
995 | } |
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
996 | }; |
97
80cc68dd8222
Rename default_environment to _G, use registerLib() for baselib and add math lib with 2 ldexp, floor
Matthew Wild <mwild1@gmail.com>
parents:
96
diff
changeset
|
997 | testvm.registerLib(_G, null, baselib); |
80cc68dd8222
Rename default_environment to _G, use registerLib() for baselib and add math lib with 2 ldexp, floor
Matthew Wild <mwild1@gmail.com>
parents:
96
diff
changeset
|
998 | testvm.registerLib(_G, "math", math); |
104
c481f6bfb19b
Add string lib, with gmatch function only for now
Matthew Wild <mwild1@gmail.com>
parents:
103
diff
changeset
|
999 | testvm.registerLib(_G, "string", string); |
67
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
1000 | |
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
1001 | // Metatable on environment to print out nil global accesses |
115
1555cb5a97b3
Switch to [] for representing tables (for now)
Matthew Wild <mwild1@gmail.com>
parents:
114
diff
changeset
|
1002 | var mt = testvm.LValue([]); |
55
89ecee2cbad1
Add test __index handler to catch use of nil globals
Matthew Wild <mwild1@gmail.com>
parents:
54
diff
changeset
|
1003 | mt.setIndex( |
73
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
1004 | testvm.LValue("__index"), |
6b43d68abc94
Large overhaul - every LValue (and LBinaryChunk) now has a valid 'vm' property, so we know in which LVM to call it or its metamethods
Matthew Wild <mwild1@gmail.com>
parents:
72
diff
changeset
|
1005 | testvm.LValue(function (t, k) { sys.puts("Access of nil global: "+k); }) |
55
89ecee2cbad1
Add test __index handler to catch use of nil globals
Matthew Wild <mwild1@gmail.com>
parents:
54
diff
changeset
|
1006 | ); |
97
80cc68dd8222
Rename default_environment to _G, use registerLib() for baselib and add math lib with 2 ldexp, floor
Matthew Wild <mwild1@gmail.com>
parents:
96
diff
changeset
|
1007 | _G.setMetatable(mt); |
67
782274d793ac
Formalise the beginnings of a baselib, add setmetatable.
Matthew Wild <mwild1@gmail.com>
parents:
66
diff
changeset
|
1008 | |
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
|
1009 | |
128
29c56996fa03
Change LVM.call() to take an LValue rather than the raw native/LFunction object. Also add LVM.loadstring(chunk, env) and use that for loading luac.out.
Matthew Wild <mwild1@gmail.com>
parents:
127
diff
changeset
|
1010 | var f = testvm.loadstring(fs.readFileSync("luac.out", "binary"), _G); |
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
|
1011 | |
129 | 1012 | var ret = testvm.call(f); |
1013 | if(ret) | |
1014 | sys.puts("Returned: "+sys.inspect(ret)); | |
1015 | ||
29
62f3df8ed204
Remove rawExceptions flag, always print exception's stack trace if it has one
Matthew Wild <mwild1@gmail.com>
parents:
28
diff
changeset
|
1016 | } |
62f3df8ed204
Remove rawExceptions flag, always print exception's stack trace if it has one
Matthew Wild <mwild1@gmail.com>
parents:
28
diff
changeset
|
1017 | 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
|
1018 | { |
138
f9bb0e212d28
Replace error reporting code with calls to LVM.traceback()
Matthew Wild <mwild1@gmail.com>
parents:
137
diff
changeset
|
1019 | var trace = testvm.traceback(); |
f9bb0e212d28
Replace error reporting code with calls to LVM.traceback()
Matthew Wild <mwild1@gmail.com>
parents:
137
diff
changeset
|
1020 | var currframe = trace[0]; |
98
14d2400ec059
Don't try and print current position in the Lua script with no valid frame
Matthew Wild <mwild1@gmail.com>
parents:
97
diff
changeset
|
1021 | if(currframe) |
14d2400ec059
Don't try and print current position in the Lua script with no valid frame
Matthew Wild <mwild1@gmail.com>
parents:
97
diff
changeset
|
1022 | { |
138
f9bb0e212d28
Replace error reporting code with calls to LVM.traceback()
Matthew Wild <mwild1@gmail.com>
parents:
137
diff
changeset
|
1023 | sys.print("lvm.js: "+currframe.sourceName+":"+currframe.line+": "); |
98
14d2400ec059
Don't try and print current position in the Lua script with no valid frame
Matthew Wild <mwild1@gmail.com>
parents:
97
diff
changeset
|
1024 | } |
93
748b51e8f0d6
Print out location at which errors occur, yay!
Matthew Wild <mwild1@gmail.com>
parents:
92
diff
changeset
|
1025 | sys.puts(e); |
35
3de1d63ffdf7
Fix for error handling to handle string exceptions
Matthew Wild <mwild1@gmail.com>
parents:
34
diff
changeset
|
1026 | if(typeof(e) == "object" && "stack" in e) |
68
5b815d3591e2
Switch to sys.puts for all output for now, leaving browser compatibility for the moment.
Matthew Wild <mwild1@gmail.com>
parents:
67
diff
changeset
|
1027 | sys.puts(e.stack); |
44
f5244bce28ce
Exit with failure code on error
Matthew Wild <mwild1@gmail.com>
parents:
43
diff
changeset
|
1028 | process.exit(1); |
5 | 1029 | } |