5 ((string-id :initform nil
:initarg string-id
:accessor string-id
)
6 (namespace-id :initform nil
:initarg namespace-id
:accessor namespace-id
)
7 (method-id :initform nil
:initarg method-id
:accessor method-id
)
8 (class-id :initform nil
:initarg class-id
:accessor class-id
)))
10 (defclass assembler-context
()
11 ;; avm2 constant pools are 1 based, so we start them at 1 here, and
12 ;; skip the first entry on write
13 ((ints :initform
(make-array 32 :fill-pointer
1 :adjustable t
) :reader ints
)
14 (uints :initform
(make-array 32 :fill-pointer
1 :adjustable t
) :reader uints
)
15 (doubles :initform
(make-array 32 :fill-pointer
1 :adjustable t
) :reader doubles
)
16 (strings :initform
(make-array 32 :fill-pointer
1 :adjustable t
) :reader strings
)
17 (namespaces :initform
(make-array 32 :fill-pointer
1 :adjustable t
) :reader namespaces
)
18 (ns-sets :initform
(make-array 32 :fill-pointer
1 :adjustable t
) :reader ns-sets
)
19 (multinames :initform
(make-array 32 :fill-pointer
1 :adjustable t
) :reader multinames
)
21 (method-infos :initform
(make-array 32 :fill-pointer
0 :adjustable t
) :reader method-infos
)
22 (metadata :initform
(make-array 32 :fill-pointer
0 :adjustable t
) :reader metadata
)
23 ;; possibly should store classes and instances together, or
24 ;; otherwise enforce them being the same length...
25 (classes :initform
(make-array 32 :fill-pointer
0 :adjustable t
) :reader classes
)
26 (instances :initform
(make-array 32 :fill-pointer
0 :adjustable t
) :reader instances
)
27 (scripts :initform
(make-array 32 :fill-pointer
0 :adjustable t
) :reader scripts
)
28 (method-bodies :initform
(make-array 32 :fill-pointer
0 :adjustable t
) :reader method-bodies
)
30 ;; strings seem immutable, so combining all string literals
32 ;; probably should eventually do this for all constants
33 (string-intern-hash :initform
(make-hash-table :test
'equal
) :reader string-intern-hash
)
34 (multiname-hash :initform
(make-hash-table :test
'equalp
) :reader multiname-hash
)
35 (ns-set-hash :initform
(make-hash-table :test
'equalp
) :reader ns-set-hash
)))
38 (defparameter *assembler-context
* (make-instance 'assembler-context
))
39 (defparameter *empty-sym
* (make-instance 'avm2sym
'string-id
1 'namespace-id
1
40 'method-id
1 'class-id
1))
41 (defun avm2-intern (string-designator)
42 (let ((string (and string-designator
(string string-designator
))))
43 (if (or (not string
) #+()(string= string
""))
45 (let ((i (gethash string
(string-intern-hash *assembler-context
*)))
46 (j (length (strings *assembler-context
*))))
49 ;;(format t "used interned string ~a = ~d ~%" string i)
52 ;;(format t "interning ~a = ~d ~%" string j)
53 (vector-push-extend string
(strings *assembler-context
*))
54 (setf (gethash string
(string-intern-hash *assembler-context
*))
55 (make-instance 'avm2sym
'string-id j
))))))))
56 (defun avm2-string (s)
57 (string-id (avm2-intern s
)))
59 (defun avm2-intern-int (int)
60 ;;fixme: write a real version of this
61 ;;(format t "intern int ~a ~%" int)
62 (loop with a
= (ints *assembler-context
*)
63 for i from
1 below
(length a
)
64 when
(= int
(aref a i
))
66 finally
(return (prog1
68 (vector-push-extend int a
)))))
70 (defun avm2-intern-uint (int)
71 ;;fixme: write a real version of this
72 (loop with a
= (uints *assembler-context
*)
73 for i from
1 below
(length a
)
74 when
(= int
(aref a i
))
76 finally
(return (prog1
78 (vector-push-extend int a
)))))
80 (defun avm2-intern-double (double)
81 ;;fixme: write a real version of this
82 (loop with a
= (doubles *assembler-context
*)
83 with d
= (float double
1d0
)
84 for i from
1 below
(length a
)
87 finally
(return (prog1
89 (vector-push-extend d a
)))))
92 ;;;;;; namespace.kind values
93 (defparameter +namespace
+ #x08
)
94 (defparameter +package-namespace
+ #x16
)
95 (defparameter +package-internal-ns
+ #x17
)
96 (defparameter +protected-namespace
+ #x18
)
97 (defparameter +explicit-namespace
+ #x19
)
98 (defparameter +static-protected-ns
+ #x1a
)
99 (defparameter +private-ns
+ #x05
)
101 (defun avm2-ns-intern (string-designator &key
(kind +package-namespace
+))
102 (let ((sym (avm2-intern string-designator
)))
103 (if (namespace-id sym
)
106 (setf (namespace-id sym
) (length (namespaces *assembler-context
*)))
107 (vector-push-extend (list kind
(string-id sym
))
108 (namespaces *assembler-context
*))))))
110 (defun avm2-ns-set-intern (namespaces)
111 (let* ((ns-ids (loop for i in namespaces
115 collect
(avm2-ns-intern i
)))
116 (id (gethash ns-ids
(ns-set-hash *assembler-context
*))))
120 (setf (gethash ns-ids
(ns-set-hash *assembler-context
*))
121 (length (ns-sets *assembler-context
*)))
122 (vector-push-extend ns-ids
(ns-sets *assembler-context
*))))))
125 ;;; multiname.kind values
126 (defparameter +qname
+ #x07
)
127 (defparameter +qname-a
+ #x0d
)
128 (defparameter +rt-qname
+ #x0f
)
129 (defparameter +rt-qname-a
+ #x10
)
130 (defparameter +rt-qname-l
+ #x11
)
131 (defparameter +rt-qname-la
+ #x12
)
132 (defparameter +multiname
+ #x09
)
133 (defparameter +multiname-a
+ #x0e
)
134 (defparameter +multiname-l
+ #x1b
)
135 (defparameter +multiname-la
+ #x1c
)
137 (defun intern-multiname (kind ns name
)
138 (let* ((ns (avm2-ns-intern ns
))
139 (name (avm2-string name
))
140 (mn (list kind ns name
))
141 (id (gethash mn
(multiname-hash *assembler-context
*))))
145 (vector-push-extend mn
(multinames *assembler-context
*))
146 (setf (gethash mn
(multiname-hash *assembler-context
*))
147 (1- (length (multinames *assembler-context
*))))))))
149 (defun intern-multiname-l (kind &rest ns-list
)
150 (let* ((ns-set (avm2-ns-set-intern ns-list
))
151 (mn (list kind ns-set
))
152 (id (gethash mn
(multiname-hash *assembler-context
*))))
156 (vector-push-extend mn
(multinames *assembler-context
*))
157 (setf (gethash mn
(multiname-hash *assembler-context
*))
158 (1- (length (multinames *assembler-context
*))))))))
160 (defun qname (ns name
)
161 (intern-multiname +qname
+ ns name
))
164 (defun parsed-qname (name)
165 (let ((p (position #\
: name
:test
'char
=)))
167 (qname (subseq name
0 p
) (subseq name
(position #\
: name
:start p
:test-not
'char
=)))
170 ;;; instance_info.flags values
172 (defparameter +class-sealed
+ #x01
)
173 (defparameter +class-final
+ #x02
)
174 (defparameter +class-interface
+ #x04
)
175 (defparameter +class-protected-ns
+ #x08
)
178 ;;; fixme: probably should make an effort to avoid duplicates or something?
179 (defun avm2-class (name-mn super-mn flags interfaces instance-init traits class-init
&key protected-ns class-traits
)
180 (let ((class-id (length (classes *assembler-context
*))))
181 (vector-push-extend (list name-mn super-mn flags interfaces
182 instance-init traits protected-ns
)
183 (instances *assembler-context
*))
184 (vector-push-extend (cons class-init class-traits
)
185 (classes *assembler-context
*))
188 (defun avm2-method (name param-types return-type flags
&key option-params pnames body
)
189 (let ((method-id (length (method-infos *assembler-context
*))))
190 (when body
(setf flags
(logior flags
(flags body
))))
191 (vector-push-extend (list name param-types return-type flags option-params pnames
)
192 (method-infos *assembler-context
*))
193 (setf (method-id body
) method-id
)
194 (vector-push-extend body
(method-bodies *assembler-context
*))
198 (defclass trait-info
()
199 ((name :initarg name
:accessor name
)
200 (trait-data :initarg trait-data
:accessor trait-data
)
201 (metadata :initarg metadata
:accessor metadata
)))
203 (defclass trait-data-slot
/const
()
204 ((kind :initform
0 :initarg kind
:accessor kind
) ;; 0 or 6
205 (slot-id :initarg slot-id
:accessor slot-id
)
206 (type-name :initarg type-name
:accessor type-name
)
207 (vindex :initarg vindex
:accessor vindex
)
208 (vkind :initarg vkind
:accessor vkind
)))
210 (defclass trait-data-class
()
211 ((kind :initform
4 :initarg kind
:accessor kind
)
212 (slot-id :initarg slot-id
:accessor slot-id
)
213 (classi :initarg classi
:accessor classi
)))
216 (defclass trait-data-function
()
217 ((kind :initform
5 :initarg kind
:accessor kind
)
218 (slot-id :initarg slot-id
:accessor slot-id
)
219 (fn :initarg function
:accessor fn
)))
222 (defclass trait-data-method
/get
/set
()
223 ((kind :initform
1 :initarg kind
:accessor kind
) ;;1 2 3
224 (slot-id :initarg slot-id
:accessor slot-id
)
225 (method-id :initarg method
:accessor method-id
)))
228 (defclass exception-info
()
229 ((from :initarg from
:accessor from
)
230 (to :initarg to
:accessor to
)
231 (target :initarg target
:accessor target
)
232 (exc-type :initarg exc-type
:accessor exc-type
)
233 (var-name :initarg var-name
:accessor var-name
)))
236 (defun qname-string (mn-id)
237 (let* ((mn (aref (multinames *assembler-context
*) mn-id
))
240 (setf name
(if name
(aref (strings *assembler-context
*) name
) ""))
242 (aref (strings *assembler-context
*)
243 (second (aref (namespaces *assembler-context
*) ns
)))
247 (format nil
"~a:~a" ns name
))))
249 #+(or)(let ((*assembler-context
* (make-instance 'assembler-context
)))
250 (qname "baz baz" "bleh")
251 (format t
"~s ~%" (multinames *assembler-context
*))
252 (format t
"--~a = ~a ~%" (qname "foo" "bar")
253 (qname-string (qname "foo" "bar")))
255 for j across
(multinames *assembler-context
*)
256 do
(format t
" mn ~a = ~a ~%" i j
))
259 for j across
(strings *assembler-context
*)
260 do
(format t
" string ~a = ~a ~%" i j
))
263 for j across
(namespaces *assembler-context
*)
264 do
(format t
" ns ~a = ~a ~%" i j
))
266 (format t
"--~a = ~a ~%" (qname "" "bar") (qname-string (qname "" "bar"))))