rename as3 -> avm2 since we don't actually deal with actionscript anywhere
[swf2.git] / asm / opcodes.lisp
blobe96e31d0e1dc681568cf0f68ea39f961b0e7d574
1 (in-package :avm2-asm)
3 (defun runtime-name-count (index)
4 "some opcodes need extra args when passed a runtime multiname, check
5 for that here and return count of extra args"
6 (let* ((mn (aref (avm2-asm::multinames avm2-asm::*assembler-context*) index))
7 (kind (car mn)))
8 (cond
9 ((or (= kind avm2-asm::+rt-qname+)
10 (= kind avm2-asm::+rt-qname-a+))
12 ((or (= kind avm2-asm::+rt-qname-l+)
13 (= kind avm2-asm::+rt-qname-la+))
15 (t 0))))
18 (define-ops
19 ;; name (args) opcode pop push pop-scope push-scope local flags
20 (:breakpoint () #x01 0 0) ;
21 (:nop () #x02 0 0) ;
22 (:throw () #x03 1 0) ;
23 (:get-super ((multiname multiname-q30)) #x04 (1+ (runtime-name-count multiname)) 1)
24 (:set-super ((multiname multiname-q30)) #x05 (+ 2 (runtime-name-count multiname)))
25 (:dxns ((string string-u30)) #x06 0 0 0 0 0 +set-dxns+)
26 (:dxnslate () #x07 1 0 0 0 0 +set-dxns+)
27 (:kill ((local-index u30)) #x08 0 0)
28 (:label () #x09 0 0)
29 (:if-nlt ((offset ofs24)) #x0c 2 0)
30 (:if-nle ((offset ofs24)) #x0d 2 0)
31 (:if-ngt ((offset ofs24)) #x0e 2 0)
32 (:if-nge ((offset ofs24)) #x0f 2 0)
33 (:jump ((offset ofs24)) #x10 0 0)
34 (:if-true ((offset ofs24)) #x11 1 0)
35 (:if-false ((offset ofs24)) #x12 1 0)
36 (:if-eq ((offset ofs24)) #x13 2 0)
37 (:if-ne ((offset ofs24)) #x14 2 0)
38 (:if-lt ((offset ofs24)) #x15 2 0)
39 (:if-le ((offset ofs24)) #x16 2 0)
40 (:if-gt ((offset ofs24)) #x17 2 0)
41 (:if-ge ((offset ofs24)) #x18 2 0)
42 (:if-strict-eq ((offset ofs24)) #x19 2 0)
43 (:if-strict-ne ((offset ofs24)) #x1a 2 0)
44 (:lookup-switch ((default-offset ofs24) (offsets counted-ofs24)) #x1b 1 0)
45 (:push-with () #x1c 1 0 0 1)
46 (:pop-scope () #x1d 0 0 1 0)
47 (:next-name () #x1e 2 1)
48 (:has-next () #x1f 2 1)
49 (:push-null () #x20 0 1)
50 (:push-undefined () #x21 0 1)
51 (:next-value () #x23 2 1)
52 (:push-byte ((byte u8)) #x24 0 1)
53 (:push-short ((value u30)) #x25 0 1)
54 (:push-true () #x26 0 1)
55 (:push-false () #x27 0 1)
56 (:push-nan () #x28 0 1)
57 (:pop () #x29 1 0)
58 (:dup () #x2a 1 2)
59 (:swap () #x2b 2 2)
60 (:push-string ((string string-u30)) #x2c 0 1)
61 (:push-int ((integer int-u30)) #x2d 0 1)
62 (:push-uint ((uinteger uint-u30)) #x2e 0 1)
63 (:push-double ((double double-u30)) #x2f 0 1)
64 (:push-scope () #x30 1 0 0 1)
65 (:push-namespace ((namespace namespace-q30)) #x31 0 1)
66 (:has-next-2 ((object-local-reg u30) (index-local-reg u30)) #x32 0 1 0 0 (max object-local-reg index-local-reg))
67 (:new-function ((method-index u30)) #x40 0 1)
68 (:call ((arg-count u30)) #x41 (+ 2 arg-count) 1)
69 (:construct ((arg-count u30)) #x42 (1+ arg-count) 1)
70 (:call-method ((method-index u30) (arg-count u30)) #x43 (+ 1 arg-count) 1)
71 (:call-static ((method-index u30) (arg-count u30)) #x44 (+ 1 arg-count) 1)
72 (:call-super ((multiname multiname-q30) (arg-count u30)) #x45 (+ 1 arg-count (runtime-name-count multiname)) 1)
73 (:call-property ((multiname multiname-q30) (arg-count u30)) #x46 (+ 1 arg-count (runtime-name-count multiname)) 1)
74 (:return-void () #x47 0 0)
75 (:return-value () #x48 1 0)
76 (:construct-super ((arg-count u30)) #x49 (1+ arg-count) 0)
77 (:construct-prop ((multiname multiname-q30) (arg-count u30)) #x4a (+ 1 arg-count (runtime-name-count multiname)) 1)
78 (:call-prop-lex ((multiname multiname-q30) (arg-count u30)) #x4c (+ 1 arg-count (runtime-name-count multiname)) 1)
79 (:call-super-void ((multiname multiname-q30) (arg-count u30)) #x4e (+ 1 arg-count (runtime-name-count multiname)) 0)
80 (:call-prop-void ((multiname multiname-q30) (arg-count u30)) #x4f (+ 1 arg-count (runtime-name-count multiname)) 0)
81 (:new-object ((arg-count u32)) #x55 (* 2 arg-count) 1)
82 (:new-array ((arg-count u30)) #x56 arg-count 1)
83 (:new-activation () #x57 0 1 0 0 0 +need-activation+)
84 (:new-class ((class-index u30)) #x58 1 1) ;; 2->1 ? also see docs about scope stuff
85 (:get-descendants ((multiname multiname-q30)) #x59 (1+ (runtime-name-count multiname)) 1)
86 (:new-catch ((exception-index u30)) #x5a 0 1)
87 (:find-property-strict ((multiname multiname-q30)) #x5d (runtime-name-count multiname) 1)
88 (:find-property ((multiname multiname-q30)) #x5e (runtime-name-count multiname) 1)
89 (:find-def ((string string-u30)) #x5f 0 1) ;; ??
90 (:get-lex ((multiname multiname-q30)) #x60 0 1)
91 (:set-property ((multiname multiname-q30)) #x61 (+ 2 (runtime-name-count multiname)) 0)
92 (:get-local ((local-index u30)) #x62 0 1 0 0 local-index)
93 (:set-local ((local-index u30)) #x63 1 0 0 0 local-index)
94 (:get-global-scope () #x64 0 1)
95 (:get-scope-object ((scope-index u8)) #x65 0 1)
96 (:get-property ((multiname multiname-q30)) #x66 (1+ (runtime-name-count multiname)) 1)
97 (:init-property ((multiname multiname-q30)) #x68 (+ 2 (runtime-name-count multiname)) 0)
98 (:delete-property ((multiname multiname-q30)) #x6a (1+ (runtime-name-count multiname)) 1)
99 (:get-slot ((slot-index u30)) #x6c 1 1)
100 (:set-slot ((slot-index u30)) #x6d 2 0)
101 (:get-global-slot ((slot-index u30)) #x6e 0 1) ;; deprecated?
102 (:set-global-slot ((slot-index u30)) #x6f 1 0) ;; deprecated?
103 (:convert-string () #x70 1 1)
104 (:esc_xattr () #x72 1 1)
105 (:esc_xelem () #x71 1 1)
106 (:convert-integer () #x73 1 1)
107 (:convert-unsigned () #x74 1 1)
108 (:convert-double () #x75 1 1)
109 (:convert-boolean () #x76 1 1)
110 (:convert-object () #x77 1 1)
111 (:check-filter () #x78 1 1)
112 (:coerce ((multiname multiname-q30)) #x80 1 1)
113 (:coerce-b () #x81 1 1) ;; deprecated?
114 (:coerce-any () #x82 1 1)
115 (:coerce-i () #x83 1 1) ;; deprecated?
116 (:coerce-d () #x84 1 1) ;; deprecated?
117 (:coerce-string () #x85 1 1)
118 (:as-type ((multiname multiname-q30)) #x86 1 1)
119 (:as-type-late () #x87 2 1)
120 (:coerce-u () #x88 1 1) ;; deprecated?
121 (:coerce-object () #x89 1 1)
122 (:negate () #x90 1 1)
123 (:increment () #x91 1 1)
124 (:inc-local ((local-index u30)) #x92 0 0 0 0 local-index)
125 (:decrement () #x93 1 1)
126 (:dec-local ((local-index u30)) #x94 0 0 0 0 local-index)
127 (:type-of () #x95 1 1)
128 (:not () #x96 1 1)
129 (:bit-not () #x97 1 1)
130 (:add () #xa0 2 1)
131 (:multiply () #xa2 2 1)
132 (:divide () #xa3 2 1)
133 (:modulo () #xa4 2 1)
134 (:lshift () #xa5 2 1)
135 (:rshift () #xa6 2 1)
136 (:unsigned-rshift () #xa7 2 1)
137 (:bit-and () #xa8 2 1)
138 (:bit-or () #xa9 2 1)
139 (:bit-xor () #xaa 2 1)
140 (:subtract () #xa1 2 1)
141 (:equals () #xab 2 1)
142 (:strict-equals () #xac 2 1)
143 (:less-than () #xad 2 1)
144 (:less-equals () #xae 2 1)
145 (:greater-than () #xaf 2 1)
146 (:greater-equals () #xb0 2 1)
147 (:instance-of () #xb1 2 1)
148 (:is-type ((multiname multiname-q30)) #xb2 1 1)
149 (:is-type-late () #xb3 2 1)
150 (:in () #xb4 2 1)
151 (:increment-i () #xc0 1 1)
152 (:decrement-i () #xc1 1 1)
153 (:inc-local-i ((local-index u30)) #xc2 0 0 0 0 local-index)
154 (:dec-local-i ((local-index u30)) #xc3 0 0 0 0 local-index)
155 (:negate-i () #xc4 1 1)
156 (:add-i () #xc5 2 1)
157 (:subtract-i () #xc6 2 1)
158 (:multiply-i () #xc7 2 1)
159 (:get-local-0 () #xd0 0 1 0 0 0)
160 (:get-local-1 () #xd1 0 1 0 0 1)
161 (:get-local-2 () #xd2 0 1 0 0 2)
162 (:get-local-3 () #xd3 0 1 0 0 3)
163 (:set-local-0 () #xd4 1 0 0 0 0)
164 (:set-local-1 () #xd5 1 0 0 0 1)
165 (:set-local-2 () #xd6 1 0 0 0 2)
166 (:set-local-3 () #xd7 1 0 0 0 3)
167 (:debug ((debug-type u8) (string string-u30) (register u8) (extra u30)) #xef 0 0)
168 (:debug-line ((line-number u30)) #xf0 0 0)
169 (:debug-file ((string string-u30)) #xf1 0 0)
170 #+ (or) (:breakpoint-line ((line ?) #xf2))
171 (:timestamp () #xf3 0 0))
176 #+nil(format t "~{ ~x ~}~% "
177 (avm2-asm:assemble '((get-local-0)
178 (push-scope)
179 (return-void))))
180 ;; D0 30 47
183 #+nil
184 (let ((*assembler-context* (make-instance 'assembler-context)))
185 ;; intern some names so the code compiles
186 (avm2-intern "")
187 (avm2-ns-intern "")
188 (qname "a" "b")
189 (qname "b" "b")
190 (qname "c" "b")
191 (qname "d" "b")
192 (qname "e" "b")
193 (format t "~{ ~2,'0x~}~% "
194 (assemble '((:get-local-0)
195 (:push-scope)
196 (:get-local-0)
197 (:construct-super 0)
198 (:find-property-strict 3)
199 (:construct-prop 3 0)
200 (:coerce 3)
201 (:set-local-1)
202 (:get-local-1)
203 (:push-string 7)
204 (:push-string 7)
205 (:add)
206 (:set-property 4)
207 (:find-property-strict 5)
208 (:get-local-1)
209 (:call-prop-void 5 1)
210 (:return-void)))))
211 ;; D0 30 D0 49 00 5D 03 4A 03 00 80 03 D5 D1 2C 07 2C 07 A0 61 04 5D 05 D1 4F 05 01 47
212 ;; D0 30 D0 49 00 5D 03 4A 03 00 80 03 D5 D1 2C 07 2C 07 A0 61 04 5D 05 D1 4F 05 01 47
216 #+nil
217 (let ((*assembler-context* (make-instance 'assembler-context)))
218 ;; intern some names so the code compiles
219 (avm2-intern "")
220 (avm2-ns-intern "")
221 (qname "a" "b")
222 (qname "b" "b")
223 (qname "c" "b")
224 (qname "d" "b")
225 (qname "e" "b")
226 (format t "~{ ~2,'0x~}~% "
227 (assemble '((:get-local-0)
228 (:push-scope)
229 (:get-local-0)
230 (:construct-super 0)
231 (:find-property-strict 3)
232 (:construct-prop 3 0)
233 (:coerce 3)
234 (:push-null)
235 (:pop)
236 (:set-local-1)
237 (:get-local-1)
238 (:push-string 7)
239 (:push-string 7)
240 (:add)
241 (:set-property 4)
242 (:find-property-strict 5)
243 (:get-local-1)
244 (:call-prop-void 5 1)
245 (:return-void)))))
247 #+nil
248 (let ((*assembler-context* (make-instance 'assembler-context)))
249 ;; intern some names so the code compiles
250 (avm2-intern "")
251 (avm2-ns-intern "")
252 (qname "a" "b")
253 (qname "b" "b")
254 (qname "c" "b")
255 (qname "d" "b")
256 (qname "e" "b")
257 (format t "~{ ~s~%~}~% "
258 (avm2-disassemble
259 (assemble '((:get-local-0)
260 (:push-scope)
261 (:get-local-0)
262 (:construct-super 0)
263 (:find-property-strict (:id 3))
264 (:construct-prop (:id 3) 0)
265 (:coerce (:id 3))
266 (:push-null)
267 (:pop)
268 (:set-local-1)
269 (:get-local-1)
270 (:push-string "string1")
271 (:push-string "string2")
272 (:add)
273 (:set-property "foo:bar")
274 (:set-property (:qname "foo" "baz"))
275 (:set-property (:id 3))
276 (:find-property-strict "string1")
277 (:get-local-1)
278 (:call-prop-void (:id 5) 1)
279 (:return-void))))))
281 #+nil
282 (format t "~{ ~s~%~}"
283 (avm2-disassemble #(#xD0 #x30 #xD0 #x49 #x00 #x5D #x03 #x4A #x03 #x00
284 #x80 #x03 #xD5 #xD1 #x2C #x07 #x2C #x07 #xA0 #x61
285 #x04 #x5D #x05 #xD1 #x4F #x05 #x01 #x47)))
287 #+nil
288 (format t "~{ #x~2,'0x~}~%"
289 (assemble '( (:GET-LOCAL-0)
290 (:PUSH-SCOPE)
291 (:GET-LOCAL-0)
292 (:CONSTRUCT-SUPER 0)
293 (:FIND-PROPERTY-STRICT (:QNAME "flash.text" ":TextField"))
294 (:CONSTRUCT-PROP (:QNAME "flash.text" ":TextField") 0)
295 (:COERCE (:QNAME "flash.text" ":TextField"))
296 (:SET-LOCAL-1)
297 (:GET-LOCAL-1)
298 (:PUSH-STRING "TextField")
299 (:PUSH-STRING "TextField")
300 (:ADD)
301 (:SET-PROPERTY (:QNAME "" "foo"))
302 (:FIND-PROPERTY-STRICT (:QNAME "flash.text" "TextField"))
303 (:GET-LOCAL-1)
304 (:CALL-PROP-VOID (:QNAME "flash.text" "TextField") 1)
305 (:RETURN-VOID))))
307 #+nil
308 (format t "~{ ~s~%~}"
309 (avm2-disassemble
310 #( #xD0 #x30 #xD0 #x49 #x00 #x5D #x03 #x4A #x03 #x00 #x80 #x03 #xD5 #xD1 #x2C #x07 #x2C #x07 #xA0 #x61 #x04 #x5D #x05 #xD1 #x4F #x05 #x01 #x47)