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
))
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
+))
18 ;;; http://ncannasse.fr/blog/adobe_alchemy
19 ;;;-- missing some from this one:
20 ;;; http://www.libspark.org/svn/as3/ByteCodeDisassembler/org/libspark/disassemble/abc/AbcParser.as
23 ;; name (args) opcode pop push pop-scope push-scope local flags
24 (:breakpoint
() #x01
0 0) ;
26 (:throw
() #x03
1 0) ;
27 (:get-super
((multiname multiname-q30
)) #x04
(1+ (runtime-name-count multiname
)) 1)
28 (:set-super
((multiname multiname-q30
)) #x05
(+ 2 (runtime-name-count multiname
)))
29 (:dxns
((string string-u30
)) #x06
0 0 0 0 0 +set-dxns
+)
30 (:dxnslate
() #x07
1 0 0 0 0 +set-dxns
+)
31 (:kill
((local-index u30
)) #x08
0 0)
35 (:if-nlt
((offset ofs24
)) #x0c
2 0)
36 (:if-nle
((offset ofs24
)) #x0d
2 0)
37 (:if-ngt
((offset ofs24
)) #x0e
2 0)
38 (:if-nge
((offset ofs24
)) #x0f
2 0)
39 (:jump
((offset ofs24
)) #x10
0 0)
40 (:if-true
((offset ofs24
)) #x11
1 0)
41 (:if-false
((offset ofs24
)) #x12
1 0)
42 (:if-eq
((offset ofs24
)) #x13
2 0)
43 (:if-ne
((offset ofs24
)) #x14
2 0)
44 (:if-lt
((offset ofs24
)) #x15
2 0)
45 (:if-le
((offset ofs24
)) #x16
2 0)
46 (:if-gt
((offset ofs24
)) #x17
2 0)
47 (:if-ge
((offset ofs24
)) #x18
2 0)
48 (:if-strict-eq
((offset ofs24
)) #x19
2 0)
49 (:if-strict-ne
((offset ofs24
)) #x1a
2 0)
50 (:lookup-switch
((default-offset ofs24
) (offsets counted-ofs24
)) #x1b
1 0)
51 (:push-with
() #x1c
1 0 0 1)
52 (:pop-scope
() #x1d
0 0 1 0)
53 (:next-name
() #x1e
2 1)
54 (:has-next
() #x1f
2 1)
55 (:push-null
() #x20
0 1)
56 (:push-undefined
() #x21
0 1)
57 ;; (:push-constant ? #x22 ? ?) -- fp10 = illegal opcode
58 (:next-value
() #x23
2 1)
59 (:push-byte
((byte u8
)) #x24
0 1)
60 (:push-short
((value u30
)) #x25
0 1)
61 (:push-true
() #x26
0 1)
62 (:push-false
() #x27
0 1)
63 (:push-nan
() #x28
0 1)
67 (:push-string
((string string-u30
)) #x2c
0 1)
68 (:push-int
((integer int-u30
)) #x2d
0 1)
69 (:push-uint
((uinteger uint-u30
)) #x2e
0 1)
70 (:push-double
((double double-u30
)) #x2f
0 1)
71 (:push-scope
() #x30
1 0 0 1)
72 (:push-namespace
((namespace namespace-q30
)) #x31
0 1)
73 (:has-next-2
((object-local-reg u30
) (index-local-reg u30
)) #x32
0 1 0 0 (max object-local-reg index-local-reg
))
76 ;; #x35-#x3e: flash 10/alchemy instrs
77 ;; see http://ncannasse.fr/blog/adobe_alchemy
78 ;; (are these backwards? tamarin has li*/lf* then si*/sf*
79 (:store-int-8
() #x35
2 0) ;; stack=value,addr -> .
80 (:store-int-16
() #x36
2 0) ;; stack=value,addr -> .
81 (:store-int-32
() #x37
2 0) ;; stack=value,addr -> .
82 (:store-float-32
() #x38
2 0) ;; stack=value,addr -> .
83 (:store-float-64
() #x39
2 0) ;; stack=value,addr -> .
84 (:load-int-8
() #x3a
1 1) ;; stack=addr -> value
85 (:load-int-16
() #x3b
1 1) ;; stack=addr -> value
86 (:load-int-32
() #x3c
1 1) ;; stack=addr -> value
87 (:load-float-32
() #x3d
1 1) ;; stack=addr -> value
88 (:load-float-64
() #x3e
1 1) ;; stack=addr -> value
90 (:new-function
((method-index method-u30
)) #x40
0 1)
91 (:call
((arg-count u30
)) #x41
(+ 2 arg-count
) 1)
92 (:construct
((arg-count u30
)) #x42
(1+ arg-count
) 1)
93 (:call-method
((method-index method-u30
) (arg-count u30
)) #x43
(+ 1 arg-count
) 1)
94 (:call-static
((method-index method-u30
) (arg-count u30
)) #x44
(+ 1 arg-count
) 1)
95 (:call-super
((multiname multiname-q30
) (arg-count u30
)) #x45
(+ 1 arg-count
(runtime-name-count multiname
)) 1)
96 (:call-property
((multiname multiname-q30
) (arg-count u30
)) #x46
(+ 1 arg-count
(runtime-name-count multiname
)) 1)
97 (:return-void
() #x47
0 0)
98 (:return-value
() #x48
1 0)
99 (:construct-super
((arg-count u30
)) #x49
(1+ arg-count
) 0)
100 (:construct-prop
((multiname multiname-q30
) (arg-count u30
)) #x4a
(+ 1 arg-count
(runtime-name-count multiname
)) 1)
101 ;;(:call-super-id ? #x4b ? ?)
102 (:call-prop-lex
((multiname multiname-q30
) (arg-count u30
)) #x4c
(+ 1 arg-count
(runtime-name-count multiname
)) 1)
103 ;;(:call-interface ? #x4d ? ?)
104 (:call-super-void
((multiname multiname-q30
) (arg-count u30
)) #x4e
(+ 1 arg-count
(runtime-name-count multiname
)) 0)
105 (:call-prop-void
((multiname multiname-q30
) (arg-count u30
)) #x4f
(+ 1 arg-count
(runtime-name-count multiname
)) 0)
106 ;; #50-#x52: flash 10/alchemy instructions
107 (:sign-extend-1to32
() #x50
1 1) ;; stack=value,value
108 (:sign-extend-8to32
() #x51
1 1) ;; stack=value,value
109 (:sign-extend-16to32
() #x52
1 1) ;; stack=value,value
110 ;; (:apply-type (?) #x53 1 1) ??
112 (:new-object
((arg-count u32
)) #x55
(* 2 arg-count
) 1)
113 (:new-array
((arg-count u30
)) #x56 arg-count
1)
114 (:new-activation
() #x57
0 1 0 0 0 +need-activation
+)
115 (:new-class
((class-index u30
)) #x58
1 1) ;; 2->1 ? also see docs about scope stuff
116 (:get-descendants
((multiname multiname-q30
)) #x59
(1+ (runtime-name-count multiname
)) 1)
117 (:new-catch
((exception-index u30
)) #x5a
0 1)
120 (:find-property-strict
((multiname multiname-q30
)) #x5d
(runtime-name-count multiname
) 1)
121 (:find-property
((multiname multiname-q30
)) #x5e
(runtime-name-count multiname
) 1)
122 (:find-def
((string string-u30
)) #x5f
0 1) ;; ??
123 (:get-lex
((multiname multiname-q30
)) #x60
0 1)
124 (:set-property
((multiname multiname-q30
)) #x61
(+ 2 (runtime-name-count multiname
)) 0)
125 (:get-local
((local-index u30
)) #x62
0 1 0 0 local-index
)
126 (:set-local
((local-index u30
)) #x63
1 0 0 0 local-index
)
127 (:get-global-scope
() #x64
0 1)
128 (:get-scope-object
((scope-index u8
)) #x65
0 1)
129 (:get-property
((multiname multiname-q30
)) #x66
(1+ (runtime-name-count multiname
)) 1)
130 ;;(:get-outer-scope (?) #x67 0 1) ??
131 (:init-property
((multiname multiname-q30
)) #x68
(+ 2 (runtime-name-count multiname
)) 0)
133 (:delete-property
((multiname multiname-q30
)) #x6a
(1+ (runtime-name-count multiname
)) 1)
135 (:get-slot
((slot-index u30
)) #x6c
1 1)
136 (:set-slot
((slot-index u30
)) #x6d
2 0)
137 (:get-global-slot
((slot-index u30
)) #x6e
0 1) ;; deprecated?
138 (:set-global-slot
((slot-index u30
)) #x6f
1 0) ;; deprecated?
139 (:convert-string
() #x70
1 1)
140 (:esc_xelem
() #x71
1 1)
141 (:esc_xattr
() #x72
1 1)
142 (:convert-integer
() #x73
1 1)
143 (:convert-unsigned
() #x74
1 1)
144 (:convert-double
() #x75
1 1)
145 (:convert-boolean
() #x76
1 1)
146 (:convert-object
() #x77
1 1)
147 (:check-filter
() #x78
1 1)
155 (:coerce
((multiname multiname-q30
)) #x80
1 1)
156 (:coerce-b
() #x81
1 1) ;; deprecated?
157 (:coerce-any
() #x82
1 1)
158 (:coerce-i
() #x83
1 1) ;; deprecated?
159 (:coerce-d
() #x84
1 1) ;; deprecated?
160 (:coerce-string
() #x85
1 1)
161 (:as-type
((multiname multiname-q30
)) #x86
1 1)
162 (:as-type-late
() #x87
2 1)
163 (:coerce-u
() #x88
1 1) ;; deprecated?
164 (:coerce-object
() #x89
1 1)
171 (:negate
() #x90
1 1)
172 (:increment
() #x91
1 1)
173 (:inc-local
((local-index u30
)) #x92
0 0 0 0 local-index
)
174 (:decrement
() #x93
1 1)
175 (:dec-local
((local-index u30
)) #x94
0 0 0 0 local-index
)
176 (:type-of
() #x95
1 1)
178 (:bit-not
() #x97
1 1)
179 ;; (:concat ? #x9a ? ?)
180 ;; (:add_d ? #x9b ? ?)
186 (:subtract
() #xa1
2 1)
187 (:multiply
() #xa2
2 1)
188 (:divide
() #xa3
2 1)
189 (:modulo
() #xa4
2 1)
190 (:lshift
() #xa5
2 1)
191 (:rshift
() #xa6
2 1)
192 (:unsigned-rshift
() #xa7
2 1)
193 (:bit-and
() #xa8
2 1)
194 (:bit-or
() #xa9
2 1)
195 (:bit-xor
() #xaa
2 1)
196 (:equals
() #xab
2 1)
197 (:strict-equals
() #xac
2 1)
198 (:less-than
() #xad
2 1)
199 (:less-equals
() #xae
2 1)
200 (:greater-than
() #xaf
2 1)
201 (:greater-equals
() #xb0
2 1)
202 (:instance-of
() #xb1
2 1)
203 ;; :is-type seems broken (in player 10), unpredictably changes type
204 ;; of things on stack or scope stack causing verifier errors
205 (:is-type
((multiname multiname-q30
)) #xb2
1 1)
206 (:is-type-late
() #xb3
2 1)
219 (:increment-i
() #xc0
1 1)
220 (:decrement-i
() #xc1
1 1)
221 (:inc-local-i
((local-index u30
)) #xc2
0 0 0 0 local-index
)
222 (:dec-local-i
((local-index u30
)) #xc3
0 0 0 0 local-index
)
223 (:negate-i
() #xc4
1 1)
225 (:subtract-i
() #xc6
2 1)
226 (:multiply-i
() #xc7
2 1)
235 (:get-local-0
() #xd0
0 1 0 0 0)
236 (:get-local-1
() #xd1
0 1 0 0 1)
237 (:get-local-2
() #xd2
0 1 0 0 2)
238 (:get-local-3
() #xd3
0 1 0 0 3)
239 (:set-local-0
() #xd4
1 0 0 0 0)
240 (:set-local-1
() #xd5
1 0 0 0 1)
241 (:set-local-2
() #xd6
1 0 0 0 2)
242 (:set-local-3
() #xd7
1 0 0 0 3)
265 ;; (:abs-jump () #xee 0 0) ?
266 (:debug
((debug-type u8
) (string string-u30
) (register u8
) (extra u30
)) #xef
0 0)
267 (:debug-line
((line-number u30
)) #xf0
0 0)
268 (:debug-file
((string string-u30
)) #xf1
0 0)
269 #+ (or) (:breakpoint-line
((line ?
) #xf2
))
270 (:timestamp
() #xf3
0 0)
271 ;;(:verify-pass ? #xf5 ? ?)
272 ;;(:alloc ? #xf6 ? ?)
275 ;;(:prologue ? #xf9 ? ?)
276 ;;(:send-enter ? #xfa ? ?)
277 ;;(:double-to-atom ? #xfb ? ?)
278 ;;(:sweep ? #xfc ? ?)
279 ;;(:codegen-op ? #xfd ? ?)
280 ;;(:verify-op ? #xfe ? ?)
281 ;;(:decode ? #xff ? ?)
287 #+nil
(format t
"~{ ~x ~}~% "
288 (avm2-asm:assemble
'((get-local-0)
295 (let ((*assembler-context
* (make-instance 'assembler-context
)))
296 ;; intern some names so the code compiles
304 (format t
"~{ ~2,'0x~}~% "
305 (assemble '((:get-local-0
)
309 (:find-property-strict
3)
310 (:construct-prop
3 0)
318 (:find-property-strict
5)
320 (:call-prop-void
5 1)
322 ;; 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
323 ;; 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
328 (let ((*assembler-context
* (make-instance 'assembler-context
)))
329 ;; intern some names so the code compiles
337 (format t
"~{ ~2,'0x~}~% "
338 (assemble '((:get-local-0
)
342 (:find-property-strict
3)
343 (:construct-prop
3 0)
353 (:find-property-strict
5)
355 (:call-prop-void
5 1)
359 (let ((*assembler-context
* (make-instance 'assembler-context
)))
360 ;; intern some names so the code compiles
368 (format t
"~{ ~s~%~}~% "
370 (assemble '((:get-local-0
)
374 (:find-property-strict
(:id
3))
375 (:construct-prop
(:id
3) 0)
381 (:push-string
"string1")
382 (:push-string
"string2")
384 (:set-property
"foo:bar")
385 (:set-property
(:qname
"foo" "baz"))
386 (:set-property
(:id
3))
387 (:find-property-strict
"string1")
389 (:call-prop-void
(:id
5) 1)
393 (format t
"~{ ~s~%~}"
394 (avm2-disassemble #(#xD0
#x30
#xD0
#x49
#x00
#x5D
#x03
#x4A
#x03
#x00
395 #x80
#x03
#xD5
#xD1
#x2C
#x07
#x2C
#x07
#xA0
#x61
396 #x04
#x5D
#x05
#xD1
#x4F
#x05
#x01
#x47
)))
399 (format t
"~{ #x~2,'0x~}~%"
400 (assemble '( (:GET-LOCAL-0
)
404 (:FIND-PROPERTY-STRICT
(:QNAME
"flash.text" ":TextField"))
405 (:CONSTRUCT-PROP
(:QNAME
"flash.text" ":TextField") 0)
406 (:COERCE
(:QNAME
"flash.text" ":TextField"))
409 (:PUSH-STRING
"TextField")
410 (:PUSH-STRING
"TextField")
412 (:SET-PROPERTY
(:QNAME
"" "foo"))
413 (:FIND-PROPERTY-STRICT
(:QNAME
"flash.text" "TextField"))
415 (:CALL-PROP-VOID
(:QNAME
"flash.text" "TextField") 1)
419 (format t
"~{ ~s~%~}"
421 #( #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
)