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)
33 (:if-nlt
((offset ofs24
)) #x0c
2 0)
34 (:if-nle
((offset ofs24
)) #x0d
2 0)
35 (:if-ngt
((offset ofs24
)) #x0e
2 0)
36 (:if-nge
((offset ofs24
)) #x0f
2 0)
37 (:jump
((offset ofs24
)) #x10
0 0)
38 (:if-true
((offset ofs24
)) #x11
1 0)
39 (:if-false
((offset ofs24
)) #x12
1 0)
40 (:if-eq
((offset ofs24
)) #x13
2 0)
41 (:if-ne
((offset ofs24
)) #x14
2 0)
42 (:if-lt
((offset ofs24
)) #x15
2 0)
43 (:if-le
((offset ofs24
)) #x16
2 0)
44 (:if-gt
((offset ofs24
)) #x17
2 0)
45 (:if-ge
((offset ofs24
)) #x18
2 0)
46 (:if-strict-eq
((offset ofs24
)) #x19
2 0)
47 (:if-strict-ne
((offset ofs24
)) #x1a
2 0)
48 (:lookup-switch
((default-offset ofs24
) (offsets counted-ofs24
)) #x1b
1 0)
49 (:push-with
() #x1c
1 0 0 1)
50 (:pop-scope
() #x1d
0 0 1 0)
51 (:next-name
() #x1e
2 1)
52 (:has-next
() #x1f
2 1)
53 (:push-null
() #x20
0 1)
54 (:push-undefined
() #x21
0 1)
55 ;; (:push-constant ? #x22 ? ?) -- fp10 = illegal opcode
56 (:next-value
() #x23
2 1)
57 (:push-byte
((byte u8
)) #x24
0 1)
58 (:push-short
((value u30
)) #x25
0 1)
59 (:push-true
() #x26
0 1)
60 (:push-false
() #x27
0 1)
61 (:push-nan
() #x28
0 1)
65 (:push-string
((string string-u30
)) #x2c
0 1)
66 (:push-int
((integer int-u30
)) #x2d
0 1)
67 (:push-uint
((uinteger uint-u30
)) #x2e
0 1)
68 (:push-double
((double double-u30
)) #x2f
0 1)
69 (:push-scope
() #x30
1 0 0 1)
70 (:push-namespace
((namespace namespace-q30
)) #x31
0 1)
71 (:has-next-2
((object-local-reg u30
) (index-local-reg u30
)) #x32
0 1 0 0 (max object-local-reg index-local-reg
))
72 ;; #x35-#x3e: flash 10/alchemy instrs
73 ;; see http://ncannasse.fr/blog/adobe_alchemy
74 (:store-int-8
() #x35
2 0) ;; stack=value,addr -> .
75 (:store-int-16
() #x36
2 0) ;; stack=value,addr -> .
76 (:store-int-32
() #x37
2 0) ;; stack=value,addr -> .
77 (:store-float-32
() #x38
2 0) ;; stack=value,addr -> .
78 (:store-float-64
() #x39
2 0) ;; stack=value,addr -> .
79 (:load-int-8
() #x3a
1 1) ;; stack=addr -> value
80 (:load-int-16
() #x3b
1 1) ;; stack=addr -> value
81 (:load-int-32
() #x3c
1 1) ;; stack=addr -> value
82 (:load-float-32
() #x3d
1 1) ;; stack=addr -> value
83 (:load-float-64
() #x3e
1 1) ;; stack=addr -> value
85 (:new-function
((method-index u30
)) #x40
0 1)
86 (:call
((arg-count u30
)) #x41
(+ 2 arg-count
) 1)
87 (:construct
((arg-count u30
)) #x42
(1+ arg-count
) 1)
88 (:call-method
((method-index u30
) (arg-count u30
)) #x43
(+ 1 arg-count
) 1)
89 (:call-static
((method-index u30
) (arg-count u30
)) #x44
(+ 1 arg-count
) 1)
90 (:call-super
((multiname multiname-q30
) (arg-count u30
)) #x45
(+ 1 arg-count
(runtime-name-count multiname
)) 1)
91 (:call-property
((multiname multiname-q30
) (arg-count u30
)) #x46
(+ 1 arg-count
(runtime-name-count multiname
)) 1)
92 (:return-void
() #x47
0 0)
93 (:return-value
() #x48
1 0)
94 (:construct-super
((arg-count u30
)) #x49
(1+ arg-count
) 0)
95 (:construct-prop
((multiname multiname-q30
) (arg-count u30
)) #x4a
(+ 1 arg-count
(runtime-name-count multiname
)) 1)
96 ;;(:call-super-id ? #x4b ? ?)
97 (:call-prop-lex
((multiname multiname-q30
) (arg-count u30
)) #x4c
(+ 1 arg-count
(runtime-name-count multiname
)) 1)
98 ;;(:call-interface ? #x4d ? ?)
99 (:call-super-void
((multiname multiname-q30
) (arg-count u30
)) #x4e
(+ 1 arg-count
(runtime-name-count multiname
)) 0)
100 (:call-prop-void
((multiname multiname-q30
) (arg-count u30
)) #x4f
(+ 1 arg-count
(runtime-name-count multiname
)) 0)
101 ;; #50-#x52: flash 10/alchemy instructions
102 (:sign-extend-1to32
() #x50
1 1) ;; stack=value,value
103 (:sign-extend-8to32
() #x51
1 1) ;; stack=value,value
104 (:sign-extend-16to32
() #x52
1 1) ;; stack=value,value
107 (:new-object
((arg-count u32
)) #x55
(* 2 arg-count
) 1)
108 (:new-array
((arg-count u30
)) #x56 arg-count
1)
109 (:new-activation
() #x57
0 1 0 0 0 +need-activation
+)
110 (:new-class
((class-index u30
)) #x58
1 1) ;; 2->1 ? also see docs about scope stuff
111 (:get-descendants
((multiname multiname-q30
)) #x59
(1+ (runtime-name-count multiname
)) 1)
112 (:new-catch
((exception-index u30
)) #x5a
0 1)
113 (:find-property-strict
((multiname multiname-q30
)) #x5d
(runtime-name-count multiname
) 1)
114 (:find-property
((multiname multiname-q30
)) #x5e
(runtime-name-count multiname
) 1)
115 (:find-def
((string string-u30
)) #x5f
0 1) ;; ??
116 (:get-lex
((multiname multiname-q30
)) #x60
0 1)
117 (:set-property
((multiname multiname-q30
)) #x61
(+ 2 (runtime-name-count multiname
)) 0)
118 (:get-local
((local-index u30
)) #x62
0 1 0 0 local-index
)
119 (:set-local
((local-index u30
)) #x63
1 0 0 0 local-index
)
120 (:get-global-scope
() #x64
0 1)
121 (:get-scope-object
((scope-index u8
)) #x65
0 1)
122 (:get-property
((multiname multiname-q30
)) #x66
(1+ (runtime-name-count multiname
)) 1)
123 (:init-property
((multiname multiname-q30
)) #x68
(+ 2 (runtime-name-count multiname
)) 0)
124 (:delete-property
((multiname multiname-q30
)) #x6a
(1+ (runtime-name-count multiname
)) 1)
125 (:get-slot
((slot-index u30
)) #x6c
1 1)
126 (:set-slot
((slot-index u30
)) #x6d
2 0)
127 (:get-global-slot
((slot-index u30
)) #x6e
0 1) ;; deprecated?
128 (:set-global-slot
((slot-index u30
)) #x6f
1 0) ;; deprecated?
129 (:convert-string
() #x70
1 1)
130 (:esc_xelem
() #x71
1 1)
131 (:esc_xattr
() #x72
1 1)
132 (:convert-integer
() #x73
1 1)
133 (:convert-unsigned
() #x74
1 1)
134 (:convert-double
() #x75
1 1)
135 (:convert-boolean
() #x76
1 1)
136 (:convert-object
() #x77
1 1)
137 (:check-filter
() #x78
1 1)
138 (:coerce
((multiname multiname-q30
)) #x80
1 1)
139 (:coerce-b
() #x81
1 1) ;; deprecated?
140 (:coerce-any
() #x82
1 1)
141 (:coerce-i
() #x83
1 1) ;; deprecated?
142 (:coerce-d
() #x84
1 1) ;; deprecated?
143 (:coerce-string
() #x85
1 1)
144 (:as-type
((multiname multiname-q30
)) #x86
1 1)
145 (:as-type-late
() #x87
2 1)
146 (:coerce-u
() #x88
1 1) ;; deprecated?
147 (:coerce-object
() #x89
1 1)
148 (:negate
() #x90
1 1)
149 (:increment
() #x91
1 1)
150 (:inc-local
((local-index u30
)) #x92
0 0 0 0 local-index
)
151 (:decrement
() #x93
1 1)
152 (:dec-local
((local-index u30
)) #x94
0 0 0 0 local-index
)
153 (:type-of
() #x95
1 1)
155 (:bit-not
() #x97
1 1)
156 ;; (:concat ? #x9a ? ?)
157 ;; (:add_d ? #x9b ? ?)
159 (:subtract
() #xa1
2 1)
160 (:multiply
() #xa2
2 1)
161 (:divide
() #xa3
2 1)
162 (:modulo
() #xa4
2 1)
163 (:lshift
() #xa5
2 1)
164 (:rshift
() #xa6
2 1)
165 (:unsigned-rshift
() #xa7
2 1)
166 (:bit-and
() #xa8
2 1)
167 (:bit-or
() #xa9
2 1)
168 (:bit-xor
() #xaa
2 1)
169 (:equals
() #xab
2 1)
170 (:strict-equals
() #xac
2 1)
171 (:less-than
() #xad
2 1)
172 (:less-equals
() #xae
2 1)
173 (:greater-than
() #xaf
2 1)
174 (:greater-equals
() #xb0
2 1)
175 (:instance-of
() #xb1
2 1)
176 ;; :is-type seems broken (in player 10), unpredictably changes type
177 ;; of things on stack or scope stack causing verifier errors
178 (:is-type
((multiname multiname-q30
)) #xb2
1 1)
179 (:is-type-late
() #xb3
2 1)
181 (:increment-i
() #xc0
1 1)
182 (:decrement-i
() #xc1
1 1)
183 (:inc-local-i
((local-index u30
)) #xc2
0 0 0 0 local-index
)
184 (:dec-local-i
((local-index u30
)) #xc3
0 0 0 0 local-index
)
185 (:negate-i
() #xc4
1 1)
187 (:subtract-i
() #xc6
2 1)
188 (:multiply-i
() #xc7
2 1)
189 (:get-local-0
() #xd0
0 1 0 0 0)
190 (:get-local-1
() #xd1
0 1 0 0 1)
191 (:get-local-2
() #xd2
0 1 0 0 2)
192 (:get-local-3
() #xd3
0 1 0 0 3)
193 (:set-local-0
() #xd4
1 0 0 0 0)
194 (:set-local-1
() #xd5
1 0 0 0 1)
195 (:set-local-2
() #xd6
1 0 0 0 2)
196 (:set-local-3
() #xd7
1 0 0 0 3)
197 (:debug
((debug-type u8
) (string string-u30
) (register u8
) (extra u30
)) #xef
0 0)
198 (:debug-line
((line-number u30
)) #xf0
0 0)
199 (:debug-file
((string string-u30
)) #xf1
0 0)
200 #+ (or) (:breakpoint-line
((line ?
) #xf2
))
201 (:timestamp
() #xf3
0 0)
202 ;;(:verify-pass ? #xf5 ? ?)
203 ;;(:alloc ? #xf6 ? ?)
206 ;;(:prologue ? #xf9 ? ?)
207 ;;(:send-enter ? #xfa ? ?)
208 ;;(:double-to-atom ? #xfb ? ?)
209 ;;(:sweep ? #xfc ? ?)
210 ;;(:codegen-op ? #xfd ? ?)
211 ;;(:verify-op ? #xfe ? ?)
212 ;;(:decode ? #xff ? ?)
218 #+nil
(format t
"~{ ~x ~}~% "
219 (avm2-asm:assemble
'((get-local-0)
226 (let ((*assembler-context
* (make-instance 'assembler-context
)))
227 ;; intern some names so the code compiles
235 (format t
"~{ ~2,'0x~}~% "
236 (assemble '((:get-local-0
)
240 (:find-property-strict
3)
241 (:construct-prop
3 0)
249 (:find-property-strict
5)
251 (:call-prop-void
5 1)
253 ;; 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
254 ;; 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
259 (let ((*assembler-context
* (make-instance 'assembler-context
)))
260 ;; intern some names so the code compiles
268 (format t
"~{ ~2,'0x~}~% "
269 (assemble '((:get-local-0
)
273 (:find-property-strict
3)
274 (:construct-prop
3 0)
284 (:find-property-strict
5)
286 (:call-prop-void
5 1)
290 (let ((*assembler-context
* (make-instance 'assembler-context
)))
291 ;; intern some names so the code compiles
299 (format t
"~{ ~s~%~}~% "
301 (assemble '((:get-local-0
)
305 (:find-property-strict
(:id
3))
306 (:construct-prop
(:id
3) 0)
312 (:push-string
"string1")
313 (:push-string
"string2")
315 (:set-property
"foo:bar")
316 (:set-property
(:qname
"foo" "baz"))
317 (:set-property
(:id
3))
318 (:find-property-strict
"string1")
320 (:call-prop-void
(:id
5) 1)
324 (format t
"~{ ~s~%~}"
325 (avm2-disassemble #(#xD0
#x30
#xD0
#x49
#x00
#x5D
#x03
#x4A
#x03
#x00
326 #x80
#x03
#xD5
#xD1
#x2C
#x07
#x2C
#x07
#xA0
#x61
327 #x04
#x5D
#x05
#xD1
#x4F
#x05
#x01
#x47
)))
330 (format t
"~{ #x~2,'0x~}~%"
331 (assemble '( (:GET-LOCAL-0
)
335 (:FIND-PROPERTY-STRICT
(:QNAME
"flash.text" ":TextField"))
336 (:CONSTRUCT-PROP
(:QNAME
"flash.text" ":TextField") 0)
337 (:COERCE
(:QNAME
"flash.text" ":TextField"))
340 (:PUSH-STRING
"TextField")
341 (:PUSH-STRING
"TextField")
343 (:SET-PROPERTY
(:QNAME
"" "foo"))
344 (:FIND-PROPERTY-STRICT
(:QNAME
"flash.text" "TextField"))
346 (:CALL-PROP-VOID
(:QNAME
"flash.text" "TextField") 1)
350 (format t
"~{ ~s~%~}"
352 #( #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
)