OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
11 // with the distribution. | 11 // with the distribution. |
(...skipping 18 matching lines...) Expand all Loading... |
30 | 30 |
31 #include "ast.h" | 31 #include "ast.h" |
32 #include "code-stubs-arm.h" | 32 #include "code-stubs-arm.h" |
33 #include "ic-inl.h" | 33 #include "ic-inl.h" |
34 | 34 |
35 namespace v8 { | 35 namespace v8 { |
36 namespace internal { | 36 namespace internal { |
37 | 37 |
38 // Forward declarations | 38 // Forward declarations |
39 class CompilationInfo; | 39 class CompilationInfo; |
40 class DeferredCode; | |
41 class JumpTarget; | |
42 class RegisterAllocator; | |
43 class RegisterFile; | |
44 | 40 |
45 enum InitState { CONST_INIT, NOT_CONST_INIT }; | |
46 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; | 41 enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; |
47 enum GenerateInlineSmi { DONT_GENERATE_INLINE_SMI, GENERATE_INLINE_SMI }; | |
48 enum WriteBarrierCharacter { UNLIKELY_SMI, LIKELY_SMI, NEVER_NEWSPACE }; | |
49 | |
50 | |
51 // ------------------------------------------------------------------------- | |
52 // Reference support | |
53 | |
54 // A reference is a C++ stack-allocated object that puts a | |
55 // reference on the virtual frame. The reference may be consumed | |
56 // by GetValue, TakeValue, SetValue, and Codegen::UnloadReference. | |
57 // When the lifetime (scope) of a valid reference ends, it must have | |
58 // been consumed, and be in state UNLOADED. | |
59 class Reference BASE_EMBEDDED { | |
60 public: | |
61 // The values of the types is important, see size(). | |
62 enum Type { UNLOADED = -2, ILLEGAL = -1, SLOT = 0, NAMED = 1, KEYED = 2 }; | |
63 Reference(CodeGenerator* cgen, | |
64 Expression* expression, | |
65 bool persist_after_get = false); | |
66 ~Reference(); | |
67 | |
68 Expression* expression() const { return expression_; } | |
69 Type type() const { return type_; } | |
70 void set_type(Type value) { | |
71 ASSERT_EQ(ILLEGAL, type_); | |
72 type_ = value; | |
73 } | |
74 | |
75 void set_unloaded() { | |
76 ASSERT_NE(ILLEGAL, type_); | |
77 ASSERT_NE(UNLOADED, type_); | |
78 type_ = UNLOADED; | |
79 } | |
80 // The size the reference takes up on the stack. | |
81 int size() const { | |
82 return (type_ < SLOT) ? 0 : type_; | |
83 } | |
84 | |
85 bool is_illegal() const { return type_ == ILLEGAL; } | |
86 bool is_slot() const { return type_ == SLOT; } | |
87 bool is_property() const { return type_ == NAMED || type_ == KEYED; } | |
88 bool is_unloaded() const { return type_ == UNLOADED; } | |
89 | |
90 // Return the name. Only valid for named property references. | |
91 Handle<String> GetName(); | |
92 | |
93 // Generate code to push the value of the reference on top of the | |
94 // expression stack. The reference is expected to be already on top of | |
95 // the expression stack, and it is consumed by the call unless the | |
96 // reference is for a compound assignment. | |
97 // If the reference is not consumed, it is left in place under its value. | |
98 void GetValue(); | |
99 | |
100 // Generate code to store the value on top of the expression stack in the | |
101 // reference. The reference is expected to be immediately below the value | |
102 // on the expression stack. The value is stored in the location specified | |
103 // by the reference, and is left on top of the stack, after the reference | |
104 // is popped from beneath it (unloaded). | |
105 void SetValue(InitState init_state, WriteBarrierCharacter wb); | |
106 | |
107 // This is in preparation for something that uses the reference on the stack. | |
108 // If we need this reference afterwards get then dup it now. Otherwise mark | |
109 // it as used. | |
110 inline void DupIfPersist(); | |
111 | |
112 private: | |
113 CodeGenerator* cgen_; | |
114 Expression* expression_; | |
115 Type type_; | |
116 // Keep the reference on the stack after get, so it can be used by set later. | |
117 bool persist_after_get_; | |
118 }; | |
119 | |
120 | |
121 // ------------------------------------------------------------------------- | |
122 // Code generation state | |
123 | |
124 // The state is passed down the AST by the code generator (and back up, in | |
125 // the form of the state of the label pair). It is threaded through the | |
126 // call stack. Constructing a state implicitly pushes it on the owning code | |
127 // generator's stack of states, and destroying one implicitly pops it. | |
128 | |
129 class CodeGenState BASE_EMBEDDED { | |
130 public: | |
131 // Create an initial code generator state. Destroying the initial state | |
132 // leaves the code generator with a NULL state. | |
133 explicit CodeGenState(CodeGenerator* owner); | |
134 | |
135 // Destroy a code generator state and restore the owning code generator's | |
136 // previous state. | |
137 virtual ~CodeGenState(); | |
138 | |
139 virtual JumpTarget* true_target() const { return NULL; } | |
140 virtual JumpTarget* false_target() const { return NULL; } | |
141 | |
142 protected: | |
143 inline CodeGenerator* owner() { return owner_; } | |
144 inline CodeGenState* previous() const { return previous_; } | |
145 | |
146 private: | |
147 CodeGenerator* owner_; | |
148 CodeGenState* previous_; | |
149 }; | |
150 | |
151 | |
152 class ConditionCodeGenState : public CodeGenState { | |
153 public: | |
154 // Create a code generator state based on a code generator's current | |
155 // state. The new state has its own pair of branch labels. | |
156 ConditionCodeGenState(CodeGenerator* owner, | |
157 JumpTarget* true_target, | |
158 JumpTarget* false_target); | |
159 | |
160 virtual JumpTarget* true_target() const { return true_target_; } | |
161 virtual JumpTarget* false_target() const { return false_target_; } | |
162 | |
163 private: | |
164 JumpTarget* true_target_; | |
165 JumpTarget* false_target_; | |
166 }; | |
167 | |
168 | |
169 class TypeInfoCodeGenState : public CodeGenState { | |
170 public: | |
171 TypeInfoCodeGenState(CodeGenerator* owner, | |
172 Slot* slot_number, | |
173 TypeInfo info); | |
174 ~TypeInfoCodeGenState(); | |
175 | |
176 virtual JumpTarget* true_target() const { return previous()->true_target(); } | |
177 virtual JumpTarget* false_target() const { | |
178 return previous()->false_target(); | |
179 } | |
180 | |
181 private: | |
182 Slot* slot_; | |
183 TypeInfo old_type_info_; | |
184 }; | |
185 | |
186 | |
187 // ------------------------------------------------------------------------- | |
188 // Arguments allocation mode | |
189 | |
190 enum ArgumentsAllocationMode { | |
191 NO_ARGUMENTS_ALLOCATION, | |
192 EAGER_ARGUMENTS_ALLOCATION, | |
193 LAZY_ARGUMENTS_ALLOCATION | |
194 }; | |
195 | |
196 | 42 |
197 // ------------------------------------------------------------------------- | 43 // ------------------------------------------------------------------------- |
198 // CodeGenerator | 44 // CodeGenerator |
199 | 45 |
200 class CodeGenerator: public AstVisitor { | 46 class CodeGenerator: public AstVisitor { |
201 public: | 47 public: |
202 static bool MakeCode(CompilationInfo* info); | 48 static bool MakeCode(CompilationInfo* info); |
203 | 49 |
204 // Printing of AST, etc. as requested by flags. | 50 // Printing of AST, etc. as requested by flags. |
205 static void MakeCodePrologue(CompilationInfo* info); | 51 static void MakeCodePrologue(CompilationInfo* info); |
(...skipping 12 matching lines...) Expand all Loading... |
218 | 64 |
219 static void SetFunctionInfo(Handle<JSFunction> fun, | 65 static void SetFunctionInfo(Handle<JSFunction> fun, |
220 FunctionLiteral* lit, | 66 FunctionLiteral* lit, |
221 bool is_toplevel, | 67 bool is_toplevel, |
222 Handle<Script> script); | 68 Handle<Script> script); |
223 | 69 |
224 static bool RecordPositions(MacroAssembler* masm, | 70 static bool RecordPositions(MacroAssembler* masm, |
225 int pos, | 71 int pos, |
226 bool right_here = false); | 72 bool right_here = false); |
227 | 73 |
228 // Accessors | |
229 MacroAssembler* masm() { return masm_; } | |
230 VirtualFrame* frame() const { return frame_; } | |
231 inline Handle<Script> script(); | |
232 | |
233 bool has_valid_frame() const { return frame_ != NULL; } | |
234 | |
235 // Set the virtual frame to be new_frame, with non-frame register | |
236 // reference counts given by non_frame_registers. The non-frame | |
237 // register reference counts of the old frame are returned in | |
238 // non_frame_registers. | |
239 void SetFrame(VirtualFrame* new_frame, RegisterFile* non_frame_registers); | |
240 | |
241 void DeleteFrame(); | |
242 | |
243 RegisterAllocator* allocator() const { return allocator_; } | |
244 | |
245 CodeGenState* state() { return state_; } | |
246 void set_state(CodeGenState* state) { state_ = state; } | |
247 | |
248 TypeInfo type_info(Slot* slot) { | |
249 int index = NumberOfSlot(slot); | |
250 if (index == kInvalidSlotNumber) return TypeInfo::Unknown(); | |
251 return (*type_info_)[index]; | |
252 } | |
253 | |
254 TypeInfo set_type_info(Slot* slot, TypeInfo info) { | |
255 int index = NumberOfSlot(slot); | |
256 ASSERT(index >= kInvalidSlotNumber); | |
257 if (index != kInvalidSlotNumber) { | |
258 TypeInfo previous_value = (*type_info_)[index]; | |
259 (*type_info_)[index] = info; | |
260 return previous_value; | |
261 } | |
262 return TypeInfo::Unknown(); | |
263 } | |
264 | |
265 void AddDeferred(DeferredCode* code) { deferred_.Add(code); } | |
266 | |
267 // Constants related to patching of inlined load/store. | 74 // Constants related to patching of inlined load/store. |
268 static int GetInlinedKeyedLoadInstructionsAfterPatch() { | 75 static int GetInlinedKeyedLoadInstructionsAfterPatch() { |
269 return FLAG_debug_code ? 32 : 13; | 76 return FLAG_debug_code ? 32 : 13; |
270 } | 77 } |
271 static const int kInlinedKeyedStoreInstructionsAfterPatch = 8; | 78 static const int kInlinedKeyedStoreInstructionsAfterPatch = 8; |
272 static int GetInlinedNamedStoreInstructionsAfterPatch() { | 79 static int GetInlinedNamedStoreInstructionsAfterPatch() { |
273 ASSERT(Isolate::Current()->inlined_write_barrier_size() != -1); | 80 ASSERT(Isolate::Current()->inlined_write_barrier_size() != -1); |
274 return Isolate::Current()->inlined_write_barrier_size() + 4; | 81 return Isolate::Current()->inlined_write_barrier_size() + 4; |
275 } | 82 } |
276 | 83 |
277 private: | 84 private: |
278 // Type of a member function that generates inline code for a native function. | |
279 typedef void (CodeGenerator::*InlineFunctionGenerator) | |
280 (ZoneList<Expression*>*); | |
281 | |
282 static const InlineFunctionGenerator kInlineFunctionGenerators[]; | |
283 | |
284 // Construction/Destruction | |
285 explicit CodeGenerator(MacroAssembler* masm); | |
286 | |
287 // Accessors | |
288 inline bool is_eval(); | |
289 inline Scope* scope(); | |
290 inline bool is_strict_mode(); | |
291 inline StrictModeFlag strict_mode_flag(); | |
292 | |
293 // Generating deferred code. | |
294 void ProcessDeferred(); | |
295 | |
296 static const int kInvalidSlotNumber = -1; | |
297 | |
298 int NumberOfSlot(Slot* slot); | |
299 | |
300 // State | |
301 bool has_cc() const { return cc_reg_ != al; } | |
302 JumpTarget* true_target() const { return state_->true_target(); } | |
303 JumpTarget* false_target() const { return state_->false_target(); } | |
304 | |
305 // Track loop nesting level. | |
306 int loop_nesting() const { return loop_nesting_; } | |
307 void IncrementLoopNesting() { loop_nesting_++; } | |
308 void DecrementLoopNesting() { loop_nesting_--; } | |
309 | |
310 // Node visitors. | |
311 void VisitStatements(ZoneList<Statement*>* statements); | |
312 | |
313 virtual void VisitSlot(Slot* node); | |
314 #define DEF_VISIT(type) \ | |
315 virtual void Visit##type(type* node); | |
316 AST_NODE_LIST(DEF_VISIT) | |
317 #undef DEF_VISIT | |
318 | |
319 // Main code generation function | |
320 void Generate(CompilationInfo* info); | |
321 | |
322 // Generate the return sequence code. Should be called no more than | |
323 // once per compiled function, immediately after binding the return | |
324 // target (which can not be done more than once). The return value should | |
325 // be in r0. | |
326 void GenerateReturnSequence(); | |
327 | |
328 // Returns the arguments allocation mode. | |
329 ArgumentsAllocationMode ArgumentsMode(); | |
330 | |
331 // Store the arguments object and allocate it if necessary. | |
332 void StoreArgumentsObject(bool initial); | |
333 | |
334 // The following are used by class Reference. | |
335 void LoadReference(Reference* ref); | |
336 void UnloadReference(Reference* ref); | |
337 | |
338 MemOperand SlotOperand(Slot* slot, Register tmp); | |
339 | |
340 MemOperand ContextSlotOperandCheckExtensions(Slot* slot, | |
341 Register tmp, | |
342 Register tmp2, | |
343 JumpTarget* slow); | |
344 | |
345 // Expressions | |
346 void LoadCondition(Expression* x, | |
347 JumpTarget* true_target, | |
348 JumpTarget* false_target, | |
349 bool force_cc); | |
350 void Load(Expression* expr); | |
351 void LoadGlobal(); | |
352 void LoadGlobalReceiver(Register scratch); | |
353 | |
354 // Read a value from a slot and leave it on top of the expression stack. | |
355 void LoadFromSlot(Slot* slot, TypeofState typeof_state); | |
356 void LoadFromSlotCheckForArguments(Slot* slot, TypeofState state); | |
357 | |
358 // Store the value on top of the stack to a slot. | |
359 void StoreToSlot(Slot* slot, InitState init_state); | |
360 | |
361 // Support for compiling assignment expressions. | |
362 void EmitSlotAssignment(Assignment* node); | |
363 void EmitNamedPropertyAssignment(Assignment* node); | |
364 void EmitKeyedPropertyAssignment(Assignment* node); | |
365 | |
366 // Load a named property, returning it in r0. The receiver is passed on the | |
367 // stack, and remains there. | |
368 void EmitNamedLoad(Handle<String> name, bool is_contextual); | |
369 | |
370 // Store to a named property. If the store is contextual, value is passed on | |
371 // the frame and consumed. Otherwise, receiver and value are passed on the | |
372 // frame and consumed. The result is returned in r0. | |
373 void EmitNamedStore(Handle<String> name, bool is_contextual); | |
374 | |
375 // Load a keyed property, leaving it in r0. The receiver and key are | |
376 // passed on the stack, and remain there. | |
377 void EmitKeyedLoad(); | |
378 | |
379 // Store a keyed property. Key and receiver are on the stack and the value is | |
380 // in r0. Result is returned in r0. | |
381 void EmitKeyedStore(StaticType* key_type, WriteBarrierCharacter wb_info); | |
382 | |
383 void LoadFromGlobalSlotCheckExtensions(Slot* slot, | |
384 TypeofState typeof_state, | |
385 JumpTarget* slow); | |
386 | |
387 // Support for loading from local/global variables and arguments | |
388 // whose location is known unless they are shadowed by | |
389 // eval-introduced bindings. Generates no code for unsupported slot | |
390 // types and therefore expects to fall through to the slow jump target. | |
391 void EmitDynamicLoadFromSlotFastCase(Slot* slot, | |
392 TypeofState typeof_state, | |
393 JumpTarget* slow, | |
394 JumpTarget* done); | |
395 | |
396 // Special code for typeof expressions: Unfortunately, we must | |
397 // be careful when loading the expression in 'typeof' | |
398 // expressions. We are not allowed to throw reference errors for | |
399 // non-existing properties of the global object, so we must make it | |
400 // look like an explicit property access, instead of an access | |
401 // through the context chain. | |
402 void LoadTypeofExpression(Expression* x); | |
403 | |
404 void ToBoolean(JumpTarget* true_target, JumpTarget* false_target); | |
405 | |
406 // Generate code that computes a shortcutting logical operation. | |
407 void GenerateLogicalBooleanOperation(BinaryOperation* node); | |
408 | |
409 void GenericBinaryOperation(Token::Value op, | |
410 OverwriteMode overwrite_mode, | |
411 GenerateInlineSmi inline_smi, | |
412 int known_rhs = | |
413 GenericBinaryOpStub::kUnknownIntValue); | |
414 void Comparison(Condition cc, | |
415 Expression* left, | |
416 Expression* right, | |
417 bool strict = false); | |
418 | |
419 void SmiOperation(Token::Value op, | |
420 Handle<Object> value, | |
421 bool reversed, | |
422 OverwriteMode mode); | |
423 | |
424 void CallWithArguments(ZoneList<Expression*>* arguments, | |
425 CallFunctionFlags flags, | |
426 int position); | |
427 | |
428 // An optimized implementation of expressions of the form | |
429 // x.apply(y, arguments). We call x the applicand and y the receiver. | |
430 // The optimization avoids allocating an arguments object if possible. | |
431 void CallApplyLazy(Expression* applicand, | |
432 Expression* receiver, | |
433 VariableProxy* arguments, | |
434 int position); | |
435 | |
436 // Control flow | |
437 void Branch(bool if_true, JumpTarget* target); | |
438 void CheckStack(); | |
439 | |
440 bool CheckForInlineRuntimeCall(CallRuntime* node); | |
441 | |
442 static Handle<Code> ComputeLazyCompile(int argc); | |
443 void ProcessDeclarations(ZoneList<Declaration*>* declarations); | |
444 | |
445 // Declare global variables and functions in the given array of | |
446 // name/value pairs. | |
447 void DeclareGlobals(Handle<FixedArray> pairs); | |
448 | |
449 // Instantiate the function based on the shared function info. | |
450 void InstantiateFunction(Handle<SharedFunctionInfo> function_info, | |
451 bool pretenure); | |
452 | |
453 // Support for type checks. | |
454 void GenerateIsSmi(ZoneList<Expression*>* args); | |
455 void GenerateIsNonNegativeSmi(ZoneList<Expression*>* args); | |
456 void GenerateIsArray(ZoneList<Expression*>* args); | |
457 void GenerateIsRegExp(ZoneList<Expression*>* args); | |
458 void GenerateIsObject(ZoneList<Expression*>* args); | |
459 void GenerateIsSpecObject(ZoneList<Expression*>* args); | |
460 void GenerateIsFunction(ZoneList<Expression*>* args); | |
461 void GenerateIsUndetectableObject(ZoneList<Expression*>* args); | |
462 void GenerateIsStringWrapperSafeForDefaultValueOf( | |
463 ZoneList<Expression*>* args); | |
464 | |
465 // Support for construct call checks. | |
466 void GenerateIsConstructCall(ZoneList<Expression*>* args); | |
467 | |
468 // Support for arguments.length and arguments[?]. | |
469 void GenerateArgumentsLength(ZoneList<Expression*>* args); | |
470 void GenerateArguments(ZoneList<Expression*>* args); | |
471 | |
472 // Support for accessing the class and value fields of an object. | |
473 void GenerateClassOf(ZoneList<Expression*>* args); | |
474 void GenerateValueOf(ZoneList<Expression*>* args); | |
475 void GenerateSetValueOf(ZoneList<Expression*>* args); | |
476 | |
477 // Fast support for charCodeAt(n). | |
478 void GenerateStringCharCodeAt(ZoneList<Expression*>* args); | |
479 | |
480 // Fast support for string.charAt(n) and string[n]. | |
481 void GenerateStringCharFromCode(ZoneList<Expression*>* args); | |
482 | |
483 // Fast support for string.charAt(n) and string[n]. | |
484 void GenerateStringCharAt(ZoneList<Expression*>* args); | |
485 | |
486 // Fast support for object equality testing. | |
487 void GenerateObjectEquals(ZoneList<Expression*>* args); | |
488 | |
489 void GenerateLog(ZoneList<Expression*>* args); | |
490 | |
491 // Fast support for Math.random(). | |
492 void GenerateRandomHeapNumber(ZoneList<Expression*>* args); | |
493 | |
494 // Fast support for StringAdd. | |
495 void GenerateStringAdd(ZoneList<Expression*>* args); | |
496 | |
497 // Fast support for SubString. | |
498 void GenerateSubString(ZoneList<Expression*>* args); | |
499 | |
500 // Fast support for StringCompare. | |
501 void GenerateStringCompare(ZoneList<Expression*>* args); | |
502 | |
503 // Support for direct calls from JavaScript to native RegExp code. | |
504 void GenerateRegExpExec(ZoneList<Expression*>* args); | |
505 | |
506 void GenerateRegExpConstructResult(ZoneList<Expression*>* args); | |
507 | |
508 // Support for fast native caches. | |
509 void GenerateGetFromCache(ZoneList<Expression*>* args); | |
510 | |
511 // Fast support for number to string. | |
512 void GenerateNumberToString(ZoneList<Expression*>* args); | |
513 | |
514 // Fast swapping of elements. | |
515 void GenerateSwapElements(ZoneList<Expression*>* args); | |
516 | |
517 // Fast call for custom callbacks. | |
518 void GenerateCallFunction(ZoneList<Expression*>* args); | |
519 | |
520 // Fast call to math functions. | |
521 void GenerateMathPow(ZoneList<Expression*>* args); | |
522 void GenerateMathSin(ZoneList<Expression*>* args); | |
523 void GenerateMathCos(ZoneList<Expression*>* args); | |
524 void GenerateMathSqrt(ZoneList<Expression*>* args); | |
525 void GenerateMathLog(ZoneList<Expression*>* args); | |
526 | |
527 void GenerateIsRegExpEquivalent(ZoneList<Expression*>* args); | |
528 | |
529 void GenerateHasCachedArrayIndex(ZoneList<Expression*>* args); | |
530 void GenerateGetCachedArrayIndex(ZoneList<Expression*>* args); | |
531 void GenerateFastAsciiArrayJoin(ZoneList<Expression*>* args); | |
532 | |
533 // Simple condition analysis. | |
534 enum ConditionAnalysis { | |
535 ALWAYS_TRUE, | |
536 ALWAYS_FALSE, | |
537 DONT_KNOW | |
538 }; | |
539 ConditionAnalysis AnalyzeCondition(Expression* cond); | |
540 | |
541 // Methods used to indicate which source code is generated for. Source | |
542 // positions are collected by the assembler and emitted with the relocation | |
543 // information. | |
544 void CodeForFunctionPosition(FunctionLiteral* fun); | |
545 void CodeForReturnPosition(FunctionLiteral* fun); | |
546 void CodeForStatementPosition(Statement* node); | |
547 void CodeForDoWhileConditionPosition(DoWhileStatement* stmt); | |
548 void CodeForSourcePosition(int pos); | |
549 | |
550 #ifdef DEBUG | |
551 // True if the registers are valid for entry to a block. | |
552 bool HasValidEntryRegisters(); | |
553 #endif | |
554 | |
555 List<DeferredCode*> deferred_; | |
556 | |
557 // Assembler | |
558 MacroAssembler* masm_; // to generate code | |
559 | |
560 CompilationInfo* info_; | |
561 | |
562 // Code generation state | |
563 VirtualFrame* frame_; | |
564 RegisterAllocator* allocator_; | |
565 Condition cc_reg_; | |
566 CodeGenState* state_; | |
567 int loop_nesting_; | |
568 | |
569 Vector<TypeInfo>* type_info_; | |
570 | |
571 // Jump targets | |
572 BreakTarget function_return_; | |
573 | |
574 // True if the function return is shadowed (ie, jumping to the target | |
575 // function_return_ does not jump to the true function return, but rather | |
576 // to some unlinking code). | |
577 bool function_return_is_shadowed_; | |
578 | |
579 friend class VirtualFrame; | |
580 friend class Isolate; | |
581 friend class JumpTarget; | |
582 friend class Reference; | |
583 friend class FastCodeGenerator; | |
584 friend class FullCodeGenerator; | |
585 friend class FullCodeGenSyntaxChecker; | |
586 friend class InlineRuntimeFunctionsTable; | |
587 friend class LCodeGen; | |
588 | |
589 DISALLOW_COPY_AND_ASSIGN(CodeGenerator); | 85 DISALLOW_COPY_AND_ASSIGN(CodeGenerator); |
590 }; | 86 }; |
591 | 87 |
592 | 88 |
593 } } // namespace v8::internal | 89 } } // namespace v8::internal |
594 | 90 |
595 #endif // V8_ARM_CODEGEN_ARM_H_ | 91 #endif // V8_ARM_CODEGEN_ARM_H_ |
OLD | NEW |