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
)))
37 (defparameter *assembler-context
* (make-instance 'assembler-context
))
38 (defparameter *empty-sym
* (make-instance 'avm2sym
'string-id
1 'namespace-id
1
39 'method-id
1 'class-id
1))
40 (defun avm2-intern (string-designator)
41 (let ((string (and string-designator
(string string-designator
))))
42 (if (or (not string
) #+()(string= string
""))
44 (let ((i (gethash string
(string-intern-hash *assembler-context
*)))
45 (j (length (strings *assembler-context
*))))
48 ;;(format t "used interned string ~a = ~d ~%" string i)
51 ;;(format t "interning ~a = ~d ~%" string j)
52 (vector-push-extend string
(strings *assembler-context
*))
53 (setf (gethash string
(string-intern-hash *assembler-context
*))
54 (make-instance 'avm2sym
'string-id j
))))))))
55 (defun avm2-string (s)
56 (string-id (avm2-intern s
)))
58 (defun avm2-intern-int (int)
59 ;;fixme: write a real version of this
60 ;;(format t "intern int ~a ~%" int)
61 (loop with a
= (ints *assembler-context
*)
62 for i from
1 below
(length a
)
63 when
(= int
(aref a i
))
65 finally
(return (prog1
67 (vector-push-extend int a
)))))
69 (defun avm2-intern-uint (int)
70 ;;fixme: write a real version of this
71 (loop with a
= (uints *assembler-context
*)
72 for i from
1 below
(length a
)
73 when
(= int
(aref a i
))
75 finally
(return (prog1
77 (vector-push-extend int a
)))))
79 (defun avm2-intern-double (double)
80 ;;fixme: write a real version of this
81 (loop with a
= (doubles *assembler-context
*)
82 with d
= (float double
1d0
)
83 for i from
1 below
(length a
)
86 finally
(return (prog1
88 (vector-push-extend d a
)))))
91 ;;;;;; namespace.kind values
92 (defparameter +namespace
+ #x08
)
93 (defparameter +package-namespace
+ #x16
)
94 (defparameter +package-internal-ns
+ #x17
)
95 (defparameter +protected-namespace
+ #x18
)
96 (defparameter +explicit-namespace
+ #x19
)
97 (defparameter +static-protected-ns
+ #x1a
)
98 (defparameter +private-ns
+ #x05
)
100 (defun avm2-ns-intern (string-designator &key
(kind +package-namespace
+))
101 (let ((sym (avm2-intern string-designator
)))
102 (if (namespace-id sym
)
105 (setf (namespace-id sym
) (length (namespaces *assembler-context
*)))
106 (vector-push-extend (list kind
(string-id sym
))
107 (namespaces *assembler-context
*))))))
110 ;;; multiname.kind values
111 (defparameter +qname
+ #x07
)
112 (defparameter +qname-a
+ #x0d
)
113 (defparameter +rt-qname
+ #x0f
)
114 (defparameter +rt-qname-a
+ #x10
)
115 (defparameter +rt-qname-l
+ #x11
)
116 (defparameter +rt-qname-la
+ #x12
)
117 (defparameter +multiname
+ #x09
)
118 (defparameter +multiname-a
+ #x0e
)
119 (defparameter +multiname-l
+ #x1b
)
120 (defparameter +multiname-la
+ #x1c
)
122 (defun intern-multiname (kind ns name
)
123 (let* ((ns (avm2-ns-intern ns
))
124 (name (avm2-string name
))
125 (mn (list kind ns name
))
126 (id (gethash mn
(multiname-hash *assembler-context
*))))
130 (vector-push-extend mn
(multinames *assembler-context
*))
131 (setf (gethash mn
(multiname-hash *assembler-context
*))
132 (1- (length (multinames *assembler-context
*))))))))
134 (defun qname (ns name
)
135 (intern-multiname +qname
+ ns name
))
138 (defun parsed-qname (name)
139 (let ((p (position #\
: name
:test
'char
=)))
141 (qname (subseq name
0 p
) (subseq name
(position #\
: name
:start p
:test-not
'char
=)))
144 ;;; instance_info.flags values
146 (defparameter +class-sealed
+ #x01
)
147 (defparameter +class-final
+ #x02
)
148 (defparameter +class-interface
+ #x04
)
149 (defparameter +class-protected-ns
+ #x08
)
152 ;;; fixme: probably should make an effort to avoid duplicates or something?
153 (defun avm2-class (name-mn super-mn flags interfaces instance-init traits class-init
&key protected-ns class-traits
)
154 (let ((class-id (length (classes *assembler-context
*))))
155 (vector-push-extend (list name-mn super-mn flags interfaces
156 instance-init traits protected-ns
)
157 (instances *assembler-context
*))
158 (vector-push-extend (cons class-init class-traits
)
159 (classes *assembler-context
*))
162 (defun avm2-method (name param-types return-type flags
&key option-params pnames body
)
163 (let ((method-id (length (method-infos *assembler-context
*))))
164 (when body
(setf flags
(logior flags
(flags body
))))
165 (vector-push-extend (list name param-types return-type flags option-params pnames
)
166 (method-infos *assembler-context
*))
167 (setf (method-id body
) method-id
)
168 (vector-push-extend body
(method-bodies *assembler-context
*))
172 (defclass trait-info
()
173 ((name :initarg name
:accessor name
)
174 (trait-data :initarg trait-data
:accessor trait-data
)
175 (metadata :initarg metadata
:accessor metadata
)))
177 (defclass trait-data-slot
/const
()
178 ((kind :initform
0 :initarg kind
:accessor kind
) ;; 0 or 6
179 (slot-id :initarg slot-id
:accessor slot-id
)
180 (type-name :initarg type-name
:accessor type-name
)
181 (vindex :initarg vindex
:accessor vindex
)
182 (vkind :initarg vkind
:accessor vkind
)))
184 (defclass trait-data-class
()
185 ((kind :initform
4 :initarg kind
:accessor kind
)
186 (slot-id :initarg slot-id
:accessor slot-id
)
187 (classi :initarg classi
:accessor classi
)))
190 (defclass trait-data-function
()
191 ((kind :initform
5 :initarg kind
:accessor kind
)
192 (slot-id :initarg slot-id
:accessor slot-id
)
193 (fn :initarg function
:accessor fn
)))
196 (defclass trait-data-method
/get
/set
()
197 ((kind :initform
1 :initarg kind
:accessor kind
) ;;1 2 3
198 (slot-id :initarg slot-id
:accessor slot-id
)
199 (method-id :initarg method
:accessor method-id
)))
202 (defclass exception-info
()
203 ((from :initarg from
:accessor from
)
204 (to :initarg to
:accessor to
)
205 (target :initarg target
:accessor target
)
206 (exc-type :initarg exc-type
:accessor exc-type
)
207 (var-name :initarg var-name
:accessor var-name
)))
210 (defun qname-string (mn-id)
211 (let* ((mn (aref (multinames *assembler-context
*) mn-id
))
214 (setf name
(if name
(aref (strings *assembler-context
*) name
) ""))
216 (aref (strings *assembler-context
*)
217 (second (aref (namespaces *assembler-context
*) ns
)))
221 (format nil
"~a:~a" ns name
))))
223 #+(or)(let ((*assembler-context
* (make-instance 'assembler-context
)))
224 (qname "baz baz" "bleh")
225 (format t
"~s ~%" (multinames *assembler-context
*))
226 (format t
"--~a = ~a ~%" (qname "foo" "bar")
227 (qname-string (qname "foo" "bar")))
229 for j across
(multinames *assembler-context
*)
230 do
(format t
" mn ~a = ~a ~%" i j
))
233 for j across
(strings *assembler-context
*)
234 do
(format t
" string ~a = ~a ~%" i j
))
237 for j across
(namespaces *assembler-context
*)
238 do
(format t
" ns ~a = ~a ~%" i j
))
240 (format t
"--~a = ~a ~%" (qname "" "bar") (qname-string (qname "" "bar"))))