4 public function Context() : void {
5 this.lints = new Array();
6 this.lfloats = new Array();
7 this.lstrings = new Array();
8 this.lnamespaces = new Array();
9 this.lnssets = new Array();
10 this.lmtypes = new Array();
11 this.lnames = new Array();
12 this.lclasses = new Array();
13 this.lmethods = new Array();
14 this.hstrings = new Hash();
16 this.emptyString = this.string("");
17 this.nsPublic = this.namespace(HNamespace.NPublic(this.emptyString));
18 this.arrayProp = this.name(Name.NMultiNameLate(this.nsset([this.nsPublic])));
19 this.beginFunction({ args : [], ret : null});
20 this.ops([OpCode.OThis,OpCode.OScope]);
21 this.init = this.curMethod;
22 this.init.maxStack = 2;
23 this.init.maxScope = 2;
25 protected var lints : Array;
26 protected var lfloats : Array;
27 protected var lstrings : Array;
28 protected var lnamespaces : Array;
29 protected var lnssets : Array;
30 protected var lnames : Array;
31 protected var hstrings : Hash;
32 protected var lclasses : Array;
33 protected var lmtypes : Array;
34 protected var lmethods : Array;
35 protected var curClass : *;
36 protected var curMethod : *;
37 protected var init : *;
38 protected var fieldSlot : int;
39 protected var bytepos : int;
40 protected var registers : Array;
41 public var emptyString : Index;
42 public var nsPublic : Index;
43 public var arrayProp : Index;
44 public function _int(i : int) : Index {
45 return this.lookup(this.lints,i);
47 public function float(f : Number) : Index {
48 return this.lookup(this.lfloats,f);
50 public function string(s : String) : Index {
51 var n : * = this.hstrings.get(s);
53 this.lstrings.push(s);
54 n = this.lstrings.length;
55 this.hstrings.set(s,n);
59 public function namespace(n : HNamespace) : Index {
60 return this.elookup(this.lnamespaces,n);
62 public function nsset(ns : Array) : Index {
64 var _g1 : int = 0, _g : int = this.lnssets.length;
67 var s : Array = this.lnssets[i];
68 if(s.length != ns.length) continue;
69 var ok : Boolean = true;
71 var _g3 : int = 0, _g2 : int = s.length;
74 if(!Type.enumEq(s[j],ns[j])) {
80 if(ok) return Index.Idx(i + 1);
83 this.lnssets.push(ns);
84 return Index.Idx(this.lnssets.length);
86 public function name(n : Name) : Index {
87 return this.elookup(this.lnames,n);
89 public function type(path : String) : Index {
90 if(path == "*") return null;
91 var path1 : Array = path.split(".");
92 var cname : String = path1.pop();
93 var pid : Index = this.string(path1.join("."));
94 var nameid : Index = this.string(cname);
95 var pid1 : Index = this.namespace(HNamespace.NPublic(pid));
96 var tid : Index = this.name(Name.NName(nameid,pid1));
99 public function property(pname : String,ns : Index = null) : Index {
100 var pid : Index = this.string("");
101 var nameid : Index = this.string(pname);
102 var pid1 : Index = (ns == null?this.namespace(HNamespace.NPublic(pid)):ns);
103 var tid : Index = this.name(Name.NName(nameid,pid1));
106 public function methodType(m : *) : Index {
107 this.lmtypes.push(m);
108 return Index.Idx(this.lmtypes.length - 1);
110 protected function lookup(arr : Array,n : *) : Index {
112 var _g1 : int = 0, _g : int = arr.length;
115 if(arr[i] == n) return Index.Idx(i + 1);
119 return Index.Idx(arr.length);
121 protected function elookup(arr : Array,n : *) : Index {
123 var _g1 : int = 0, _g : int = arr.length;
126 if(Type.enumEq(arr[i],n)) return Index.Idx(i + 1);
130 return Index.Idx(arr.length);
132 public function getDatas() : * {
133 return { ints : this.lints, floats : this.lfloats, strings : this.lstrings, namespaces : this.lnamespaces, nssets : this.lnssets, names : this.lnames, mtypes : this.lmtypes, classes : this.lclasses, methods : this.lmethods, init : Index.Idx(0)}
135 protected function beginFunction(mt : *) : Index {
136 this.curMethod = { type : this.methodType(mt), nRegs : mt.args.length + 1, maxScope : 0, maxStack : 0, opcodes : []}
137 this.lmethods.push(this.curMethod);
138 this.registers = new Array();
140 var _g1 : int = 0, _g : int = this.curMethod.nRegs;
143 this.registers.push(true);
146 return Index.Idx(this.lmethods.length - 1);
148 public function allocRegister() : int {
150 var _g1 : int = 0, _g : int = this.registers.length;
153 if(!this.registers[i]) {
154 this.registers[i] = true;
159 this.registers.push(true);
160 this.curMethod.nRegs++;
161 return this.registers.length - 1;
163 public function freeRegister(i : int) : void {
164 this.registers[i] = false;
166 public function beginClass(path : String) : * {
168 var index : Index = Index.Idx(this.lclasses.length);
169 var tpath : Index = this.type(path);
170 var st : Index = this.beginFunction({ args : [], ret : null});
171 this.op(OpCode.ORetVoid);
172 var m : Index = this.beginFunction({ args : [], ret : null});
173 this.op(OpCode.ORetVoid);
175 this.curClass = { index : index, name : tpath, superclass : this.type("Object"), constructorType : this.curMethod.type, constructor : m, statics : st, fields : [], staticFields : []}
176 this.lclasses.push(this.curClass);
177 this.curMethod = null;
178 return this.curClass;
180 protected function endClass() : void {
181 if(this.curClass == null) return;
182 this.curMethod = this.init;
183 this.ops([OpCode.OGetGlobalScope,OpCode.OGetLex(this.type("Object")),OpCode.OScope,OpCode.OGetLex(this.curClass.superclass),OpCode.OClassDef(this.curClass.index),OpCode.OPopScope,OpCode.OInitProp(this.curClass.name)]);
184 this.curMethod = null;
185 this.curClass = null;
187 public function beginMethod(mname : String,targs : Array,tret : Index,isStatic : * = null,isOverride : * = null,isFinal : * = null) : * {
188 var m : Index = this.beginFunction({ args : targs, ret : tret});
189 var fl : Array = (isStatic?this.curClass.staticFields:this.curClass.fields);
190 fl.push({ name : this.property(mname), slot : 0, kind : FieldKind.FMethod(m,isFinal,isOverride)});
191 return this.curMethod;
193 public function defineField(fname : String,t : Index,isStatic : * = null) : int {
194 var fl : Array = (isStatic?this.curClass.staticFields:this.curClass.fields);
195 var slot : int = this.fieldSlot++;
196 fl.push({ name : this.property(fname), slot : slot, kind : FieldKind.FVar(t)});
199 public function op(o : OpCode) : void {
200 this.curMethod.opcodes.push(o);
201 var w : OpWriter = new OpWriter();
203 this.bytepos += w.getBytes().length;
205 public function ops(ops : Array) : void {
207 var _g1 : int = 0, _g : int = ops.length;
214 public function backwardJump() : Function {
215 var start : int = this.bytepos;
216 var me : Context = this;
217 this.op(OpCode.OLabel);
218 return function(jcond : JumpStyle) : void {
219 me.op(OpCode.OJump(jcond,start - me.bytepos - 4));
222 public function jump(jcond : JumpStyle) : Function {
223 var ops : Array = this.curMethod.opcodes;
224 var pos : int = ops.length;
225 this.op(OpCode.OJump(JumpStyle.JTrue,-1));
226 var start : int = this.bytepos;
227 var me : Context = this;
228 return function() : void {
229 ops[pos] = OpCode.OJump(jcond,me.bytepos - start);
232 public function finalize() : void {
234 this.curMethod = this.init;
235 this.op(OpCode.ORetVoid);
236 this.curMethod = null;
237 this.curClass = null;