Bug 623379: runtests: Check for java binary before asc invokes (r=fklockii)
[tamarin-stm.git] / eval / eval-cogen.h
blob22b97cf1ad4b5184481c856ddcd94e7b359fafbe
1 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2 /* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is [Open Source Virtual Machine.].
18 * The Initial Developer of the Original Code is
19 * Adobe System Incorporated.
20 * Portions created by the Initial Developer are Copyright (C) 2008
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
24 * Adobe AS3 Team
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 // This file is included into eval.h
41 namespace avmplus {
42 namespace RTC {
44 class Label {
45 public:
46 Label() : address(~0U), backpatches(NULL) {}
47 uint32_t address; // either ~0U or the address of the label
48 Seq<uint32_t>* backpatches; // not a SeqBuilder so that we don't have to spend space on storing an allocator in every label object
51 class DefaultValue {
52 public:
53 DefaultValue(uint32_t tag, uint32_t index) : tag(tag), index(index) {}
54 const uint32_t tag;
55 const uint32_t index;
59 // Context management
61 enum CtxType {
62 CTX_Activation,
63 CTX_Break,
64 CTX_Catch,
65 CTX_Continue,
66 CTX_Finally,
67 CTX_Function,
68 CTX_ClassMethod,
69 CTX_Program,
70 CTX_With
73 class Ctx {
74 public:
75 Ctx(CtxType tag, Ctx* next)
76 : tag(tag)
77 , next(next)
81 const CtxType tag;
82 Ctx * const next;
84 bool mustPushThis(); // context requires a 'this' value to be pushed onto the scope chain
85 bool mustPushScopeReg(); // context requires a scope object stored in a scope register to be pushed onto the scope chain
87 VarScopeCtx * findVarScope(); // Should never be NULL
90 class ControlFlowCtx : public Ctx {
91 public:
92 ControlFlowCtx(CtxType tag, Label* label, Ctx* ctx0)
93 : Ctx(tag, ctx0)
94 , label(label)
97 Label * const label;
100 class BreakCtx : public ControlFlowCtx {
101 public:
102 BreakCtx(Label* label, Ctx* ctx0, Str* label_name=NULL)
103 : ControlFlowCtx(CTX_Break, label, ctx0)
104 , label_name(label_name)
107 Str * const label_name;
110 class ContinueCtx : public ControlFlowCtx {
111 public:
112 ContinueCtx(Label* label, Seq<Str*>* label_names, Ctx* ctx0)
113 : ControlFlowCtx(CTX_Continue, label, ctx0)
114 , label_names(label_names)
117 Seq<Str*>* const label_names;
120 // Represents a scope to restore to the scope chain, pushed by 'with'
121 // or 'catch' or reified activation objects, see subclasses.
123 class ScopeCtx : public Ctx {
124 public:
125 ScopeCtx(CtxType tag, uint32_t scope_reg, Ctx* ctx0)
126 : Ctx(tag, ctx0)
127 , scope_reg(scope_reg)
130 const uint32_t scope_reg;
133 class WithCtx : public ScopeCtx {
134 public:
135 WithCtx(uint32_t scope_reg, Ctx* ctx0)
136 : ScopeCtx(CTX_With, scope_reg, ctx0)
141 struct CatchCtx : public ScopeCtx {
142 CatchCtx(uint32_t scope_reg, Ctx* ctx0)
143 : ScopeCtx(CTX_Catch, scope_reg, ctx0)
148 class ActivationCtx : public ScopeCtx {
149 public:
150 ActivationCtx(uint32_t scope_reg, Ctx* ctx0)
151 : ScopeCtx(CTX_Activation, scope_reg, ctx0)
156 class FinallyCtx : public Ctx {
157 public:
158 FinallyCtx(Allocator* allocator, Label* Lfinally, uint32_t returnreg, Ctx* ctx0)
159 : Ctx(CTX_Finally, ctx0)
160 , Lfinally(Lfinally)
161 , returnreg(returnreg)
162 , nextLabel(0)
163 , returnLabels(allocator)
167 uint32_t addReturnLabel(Label* l);
169 Label * const Lfinally;
170 const uint32_t returnreg;
171 uint32_t nextLabel;
172 SeqBuilder<Label*> returnLabels;
175 class VarScopeCtx : public Ctx {
176 public:
177 VarScopeCtx(CtxType tag, uint32_t nsset, Seq<Namespace*>* openNamespaces, Allocator* allocator, Ctx* prev)
178 : Ctx(tag, prev)
179 , nsset(nsset)
180 , openNamespaces(openNamespaces)
182 (void)allocator;
184 const uint32_t nsset; // Will be something other than 0 if this variable scope has a multiname qualifier (namespace set)
185 Seq<Namespace*>* const openNamespaces; // Not including ""
188 class FunctionCtx : public VarScopeCtx {
189 public:
190 FunctionCtx(Allocator* allocator, uint32_t nsset, Seq<Namespace*>* openNamespaces, Ctx* prev)
191 : VarScopeCtx(CTX_Function, nsset, openNamespaces, allocator, prev)
196 class ProgramCtx : public VarScopeCtx {
197 public:
198 ProgramCtx(Allocator* allocator, uint32_t nsset, Seq<Namespace*>* openNamespaces, uint32_t capture_reg)
199 : VarScopeCtx(CTX_Program, nsset, openNamespaces, allocator, NULL)
200 , capture_reg(capture_reg)
203 const uint32_t capture_reg;
207 * Instruction and value emitter.
209 * A 'cogen' abstracts away the details of emitting bytecodes and constant
210 * values.
212 class Cogen {
213 public:
214 Cogen(Compiler* compiler, ABCFile* abc, ABCTraitsTable* traits, ABCMethodBodyInfo* body, uint32_t first_temp=1);
216 /* Instruction emitters. Most of these are trivially expanded
217 * inline to other calls; some have more complex logic. For
218 * example, I_getlocal(0) expands to OP_getlocal0, the
219 * dxns instructions set the uses_dxns flag, and the debug
220 * instructions check whether debugging is enabled. All methods
221 * help compute the heights of the value and scope stacks.
223 * Please maintain an alphabetical list.
225 void I_add();
226 void I_add_i();
227 void I_astype(uint32_t index);
228 void I_astypelate();
229 void I_bitand();
230 void I_bitnot();
231 void I_bitor();
232 void I_bitxor();
233 void I_call(uint32_t argc);
234 void I_callmethod(uint32_t index, uint32_t nargs);
235 void I_callproperty(uint32_t index, uint32_t nargs);
236 void I_callproplex(uint32_t index, uint32_t nargs);
237 void I_callpropvoid(uint32_t index, uint32_t nargs);
238 void I_callstatic(uint32_t index, uint32_t nargs);
239 void I_callsuper(uint32_t index, uint32_t nargs);
240 void I_callsupervoid(uint32_t index, uint32_t nargs);
241 void I_construct(uint32_t argc);
242 void I_constructprop(uint32_t index, uint32_t nargs);
243 void I_constructsuper(uint32_t argc);
244 void I_checkfilter();
245 void I_coerce(uint32_t index);
246 void I_coerce_a();
247 void I_coerce_s();
248 void I_coerce_b();
249 void I_coerce_d();
250 void I_coerce_i();
251 void I_coerce_u();
252 void I_convert_o();
253 void I_convert_s();
254 void I_debug(uint8_t debug_type, uint32_t index, uint8_t reg, uint32_t extra=0);
255 void I_debugfile(uint32_t index);
256 void I_debugline(uint32_t linenum);
257 void I_declocal(uint32_t reg);
258 void I_declocal_i(uint32_t reg);
259 void I_decrement();
260 void I_decrement_i();
261 void I_deleteproperty(uint32_t index);
262 void I_divide();
263 void I_dxns(uint32_t index);
264 void I_dxnslate();
265 void I_dup();
266 void I_equals();
267 void I_esc_xattr();
268 void I_esc_xelem();
269 void I_findproperty(uint32_t index);
270 void I_findpropstrict(uint32_t index);
271 void I_getdescendants(uint32_t index);
272 void I_getglobalscope();
273 void I_getglobalslot(uint32_t index);
274 void I_getlex(uint32_t index);
275 void I_getlocal(uint32_t index);
276 void I_getouterscope(uint32_t index);
277 void I_getproperty(uint32_t index);
278 void I_getscopeobject(uint32_t index);
279 void I_getslot(uint32_t index);
280 void I_getsuper(uint32_t index);
281 void I_greaterequals();
282 void I_greaterthan();
283 void I_hasnext();
284 void I_hasnext2(uint32_t object_reg, uint32_t index_reg);
285 void I_ifeq(Label* label);
286 void I_iffalse(Label* label);
287 void I_ifge(Label* label);
288 void I_ifgt(Label* label);
289 void I_ifle(Label* label);
290 void I_iflt(Label* label);
291 void I_ifne(Label* label);
292 void I_ifnge(Label* label);
293 void I_ifngt(Label* label);
294 void I_ifnle(Label* label);
295 void I_ifnlt(Label* label);
296 void I_ifstricteq(Label* label);
297 void I_ifstrictne(Label* label);
298 void I_iftrue(Label* label);
299 void I_in();
300 void I_inclocal(uint32_t reg);
301 void I_inclocal_i(uint32_t reg);
302 void I_increment();
303 void I_increment_i();
304 void I_initproperty(uint32_t index);
305 void I_instanceof();
306 void I_istype(uint32_t index);
307 void I_istypelate();
308 void I_jump(Label* label);
309 void I_kill(uint32_t index);
310 void I_label(Label* label);
311 void I_lessequals();
312 void I_lessthan();
313 void I_lookupswitch(Label* default_label, Label** case_labels, uint32_t ncases);
314 void I_lshift();
315 void I_modulo();
316 void I_multiply();
317 void I_multiply_i();
318 void I_negate();
319 void I_negate_i();
320 void I_newactivation();
321 void I_newarray(uint32_t nvalues);
322 void I_newcatch(uint32_t index);
323 void I_newclass(uint32_t index);
324 void I_newfunction(uint32_t index);
325 void I_newobject(uint32_t npairs);
326 void I_newvoid(uint32_t index);
327 void I_nextname();
328 void I_nextvalue();
329 void I_nop();
330 void I_not();
331 void I_pop();
332 void I_popscope();
333 void I_pushbyte(int8_t b);
334 void I_pushfalse();
335 void I_pushdouble(uint32_t index);
336 void I_pushint(uint32_t index);
337 void I_pushnamespace(uint32_t index);
338 void I_pushnan();
339 void I_pushnull();
340 void I_pushscope();
341 void I_pushshort(int16_t v);
342 void I_pushstring(uint32_t index);
343 void I_pushtrue();
344 void I_pushuint(uint32_t index);
345 void I_pushundefined();
346 void I_pushwith();
347 void I_returnvalue();
348 void I_returnvoid();
349 void I_rshift();
350 void I_setglobalslot(uint32_t index);
351 void I_setlocal(uint32_t index);
352 void I_setproperty(uint32_t index);
353 void I_setslot(uint32_t index);
354 void I_setsuper(uint32_t index);
355 void I_strictequals();
356 void I_subtract();
357 void I_subtract_i();
358 void I_swap();
359 void I_throw();
360 void I_typeof();
361 void I_urshift();
362 void I_opcode(AbcOpcode opcode);
364 uint32_t emitString(Str* value); // cpool index
365 uint32_t emitInt(int32_t value); // cpool index
366 uint32_t emitUInt(uint32_t value); // cpool index
367 uint32_t emitDouble(double value); // cpool index
368 uint32_t emitNamespace(uint32_t name);
369 uint32_t emitSlotTrait(uint32_t name, uint32_t type);
370 uint32_t emitConstTrait(uint32_t name, uint32_t type);
371 uint32_t emitMethodTrait(uint32_t name, uint32_t method);
372 uint32_t emitException(uint32_t from, uint32_t to, uint32_t target, uint32_t type, uint32_t name_index);
374 static uint32_t emitTypeName(Compiler* abc, QualifiedName* t);
376 Label* newLabel();
377 uint32_t getTemp();
378 void unstructuredControlFlow(Ctx* ctx, bool (hit)(Ctx*,void*), void* package, bool jump, SyntaxError msg, uint32_t pos=0);
379 void standardMethod(bool is_function, Seq<Str*>* params, Seq<FunctionDefn*>* functions, Seq<Str*>* vars, Seq<Stmt*>* stmts);
380 uint32_t arguments(Seq<Expr*>* args, Ctx* ctx);
381 void startCatch();
383 AbcOpcode binopToOpcode(Binop op, bool* isNegated);
384 uint32_t buildNssetWithPublic(Seq<Namespace*>* ns);
386 Compiler* const compiler;
387 ABCFile* const abc;
388 Allocator * const allocator;
390 uint32_t getMaxStack() const;
391 uint32_t getMaxScope() const;
392 uint32_t getLocalCount() const;
393 uint32_t getCodeLength() const;
394 uint8_t getFlags() const;
395 uint8_t* serializeCodeBytes(uint8_t* b) const;
397 private:
398 void callMN(AbcOpcode op, uint32_t index, uint32_t nargs);
399 void propU30(AbcOpcode op, uint32_t index);
400 void emitOp(AbcOpcode op);
401 void emitOpU30(AbcOpcode op, uint32_t u30);
402 void emitOpU30Special(AbcOpcode op, uint32_t u30, uint32_t stack_adjust);
403 void emitOpU30U30(AbcOpcode op, uint32_t u30_1, uint32_t u30_2);
404 void emitOpU8(AbcOpcode op, uint8_t b);
405 void emitOpS8(AbcOpcode op, int8_t b);
406 void emitOpS16(AbcOpcode op, uint16_t s);
407 void emitJump(AbcOpcode op, Label* label);
408 void fixupBackpatches(uint8_t* b) const;
409 void stackMovement(AbcOpcode opcode);
410 void stackMovement(AbcOpcode opcode, bool hasRTNS, bool hasRTName, uint32_t argc);
412 // Mapping from subset of tokens to attributes and operator values
413 static const struct BinopMapping {
414 unsigned isNegated:1;
415 unsigned abcOpcode:8;
416 } binopMapping[];
418 ByteBuffer code;
420 SeqBuilder<Label*> labels;
421 ABCTraitsTable * const traits;
422 ABCMethodBodyInfo * const body;
423 uint32_t last_linenum;
424 uint32_t label_counter;
425 uint32_t temp_counter;
426 bool sets_dxns;
427 bool need_activation;
428 uint32_t stack_depth;
429 uint32_t max_stack_depth;
430 uint32_t scope_depth;