| Index: src/full-codegen.h
|
| ===================================================================
|
| --- src/full-codegen.h (revision 8618)
|
| +++ src/full-codegen.h (working copy)
|
| @@ -80,6 +80,7 @@
|
| explicit FullCodeGenerator(MacroAssembler* masm)
|
| : masm_(masm),
|
| info_(NULL),
|
| + scope_(NULL),
|
| nesting_stack_(NULL),
|
| loop_depth_(0),
|
| context_(NULL),
|
| @@ -113,6 +114,7 @@
|
| class TryFinally;
|
| class Finally;
|
| class ForIn;
|
| + class TestContext;
|
|
|
| class NestedStatement BASE_EMBEDDED {
|
| public:
|
| @@ -151,9 +153,11 @@
|
| return stack_depth;
|
| }
|
| NestedStatement* outer() { return previous_; }
|
| - protected:
|
| +
|
| + protected:
|
| MacroAssembler* masm() { return codegen_->masm(); }
|
| - private:
|
| +
|
| + private:
|
| FullCodeGenerator* codegen_;
|
| NestedStatement* previous_;
|
| DISALLOW_COPY_AND_ASSIGN(NestedStatement);
|
| @@ -296,7 +300,11 @@
|
| // Helper function to convert a pure value into a test context. The value
|
| // is expected on the stack or the accumulator, depending on the platform.
|
| // See the platform-specific implementation for details.
|
| - void DoTest(Label* if_true, Label* if_false, Label* fall_through);
|
| + void DoTest(Expression* condition,
|
| + Label* if_true,
|
| + Label* if_false,
|
| + Label* fall_through);
|
| + void DoTest(const TestContext* context);
|
|
|
| // Helper function to split control flow and avoid a branch to the
|
| // fall-through label if it is set up.
|
| @@ -328,48 +336,55 @@
|
|
|
| void VisitForEffect(Expression* expr) {
|
| EffectContext context(this);
|
| - HandleInNonTestContext(expr, NO_REGISTERS);
|
| + VisitInCurrentContext(expr);
|
| }
|
|
|
| void VisitForAccumulatorValue(Expression* expr) {
|
| AccumulatorValueContext context(this);
|
| - HandleInNonTestContext(expr, TOS_REG);
|
| + VisitInCurrentContext(expr);
|
| }
|
|
|
| void VisitForStackValue(Expression* expr) {
|
| StackValueContext context(this);
|
| - HandleInNonTestContext(expr, NO_REGISTERS);
|
| + VisitInCurrentContext(expr);
|
| }
|
|
|
| void VisitForControl(Expression* expr,
|
| Label* if_true,
|
| Label* if_false,
|
| Label* fall_through) {
|
| - TestContext context(this, if_true, if_false, fall_through);
|
| - VisitInTestContext(expr);
|
| - // Forwarding bailouts to children is a one shot operation. It
|
| - // should have been processed at this point.
|
| - ASSERT(forward_bailout_pending_ == NULL);
|
| + TestContext context(this, expr, if_true, if_false, fall_through);
|
| + VisitInCurrentContext(expr);
|
| }
|
|
|
| - void HandleInNonTestContext(Expression* expr, State state);
|
| - void VisitInTestContext(Expression* expr);
|
| -
|
| void VisitDeclarations(ZoneList<Declaration*>* declarations);
|
| void DeclareGlobals(Handle<FixedArray> pairs);
|
|
|
| // Try to perform a comparison as a fast inlined literal compare if
|
| // the operands allow it. Returns true if the compare operations
|
| // has been matched and all code generated; false otherwise.
|
| - bool TryLiteralCompare(Token::Value op,
|
| - Expression* left,
|
| - Expression* right,
|
| + bool TryLiteralCompare(CompareOperation* compare,
|
| Label* if_true,
|
| Label* if_false,
|
| Label* fall_through);
|
|
|
| + // Platform-specific code for comparing the type of a value with
|
| + // a given literal string.
|
| + void EmitLiteralCompareTypeof(Expression* expr,
|
| + Handle<String> check,
|
| + Label* if_true,
|
| + Label* if_false,
|
| + Label* fall_through);
|
| +
|
| + // Platform-specific code for strict equality comparison with
|
| + // the undefined value.
|
| + void EmitLiteralCompareUndefined(Expression* expr,
|
| + Label* if_true,
|
| + Label* if_false,
|
| + Label* fall_through);
|
| +
|
| // Bailout support.
|
| - void PrepareForBailout(AstNode* node, State state);
|
| + void PrepareForBailout(Expression* node, State state);
|
| void PrepareForBailoutForId(int id, State state);
|
|
|
| // Record a call's return site offset, used to rebuild the frame if the
|
| @@ -517,23 +532,11 @@
|
| return is_strict_mode() ? kStrictMode : kNonStrictMode;
|
| }
|
| FunctionLiteral* function() { return info_->function(); }
|
| - Scope* scope() { return info_->scope(); }
|
| + Scope* scope() { return scope_; }
|
|
|
| static Register result_register();
|
| static Register context_register();
|
|
|
| - // Helper for calling an IC stub.
|
| - void EmitCallIC(Handle<Code> ic,
|
| - RelocInfo::Mode mode,
|
| - unsigned ast_id);
|
| -
|
| - // Calling an IC stub with a patch site. Passing NULL for patch_site
|
| - // or non NULL patch_site which is not activated indicates no inlined smi code
|
| - // and emits a nop after the IC call.
|
| - void EmitCallIC(Handle<Code> ic,
|
| - JumpPatchSite* patch_site,
|
| - unsigned ast_id);
|
| -
|
| // Set fields in the stack frame. Offsets are the frame pointer relative
|
| // offsets defined in, e.g., StandardFrameConstants.
|
| void StoreToFrameField(int frame_offset, Register value);
|
| @@ -542,6 +545,10 @@
|
| // in v8::internal::Context.
|
| void LoadContextField(Register dst, int context_index);
|
|
|
| + // Push the function argument for the runtime functions PushWithContext
|
| + // and PushCatchContext.
|
| + void PushFunctionArgumentForContextAllocation();
|
| +
|
| // AST node visit functions.
|
| #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
|
| AST_NODE_LIST(DECLARE_VISIT)
|
| @@ -549,8 +556,10 @@
|
|
|
| void EmitUnaryOperation(UnaryOperation* expr, const char* comment);
|
|
|
| - // Handles the shortcutted logical binary operations in VisitBinaryOperation.
|
| - void EmitLogicalOperation(BinaryOperation* expr);
|
| + void VisitComma(BinaryOperation* expr);
|
| + void VisitLogicalExpression(BinaryOperation* expr);
|
| + void VisitArithmeticExpression(BinaryOperation* expr);
|
| + void VisitInCurrentContext(Expression* expr);
|
|
|
| void VisitForTypeofValue(Expression* expr);
|
|
|
| @@ -598,11 +607,6 @@
|
| // context.
|
| virtual void DropAndPlug(int count, Register reg) const = 0;
|
|
|
| - // For shortcutting operations || and &&.
|
| - virtual void EmitLogicalLeft(BinaryOperation* expr,
|
| - Label* eval_right,
|
| - Label* done) const = 0;
|
| -
|
| // Set up branch labels for a test expression. The three Label** parameters
|
| // are output parameters.
|
| virtual void PrepareTest(Label* materialize_true,
|
| @@ -611,12 +615,14 @@
|
| Label** if_false,
|
| Label** fall_through) const = 0;
|
|
|
| - virtual void HandleExpression(Expression* expr) const = 0;
|
| -
|
| // Returns true if we are evaluating only for side effects (ie if the result
|
| // will be discarded).
|
| virtual bool IsEffect() const { return false; }
|
|
|
| + // Returns true if we are evaluating for the value (in accu/on stack).
|
| + virtual bool IsAccumulatorValue() const { return false; }
|
| + virtual bool IsStackValue() const { return false; }
|
| +
|
| // Returns true if we are branching on the value rather than materializing
|
| // it. Only used for asserts.
|
| virtual bool IsTest() const { return false; }
|
| @@ -644,15 +650,12 @@
|
| virtual void Plug(Heap::RootListIndex) const;
|
| virtual void PlugTOS() const;
|
| virtual void DropAndPlug(int count, Register reg) const;
|
| - virtual void EmitLogicalLeft(BinaryOperation* expr,
|
| - Label* eval_right,
|
| - Label* done) const;
|
| virtual void PrepareTest(Label* materialize_true,
|
| Label* materialize_false,
|
| Label** if_true,
|
| Label** if_false,
|
| Label** fall_through) const;
|
| - virtual void HandleExpression(Expression* expr) const;
|
| + virtual bool IsAccumulatorValue() const { return true; }
|
| };
|
|
|
| class StackValueContext : public ExpressionContext {
|
| @@ -668,24 +671,23 @@
|
| virtual void Plug(Heap::RootListIndex) const;
|
| virtual void PlugTOS() const;
|
| virtual void DropAndPlug(int count, Register reg) const;
|
| - virtual void EmitLogicalLeft(BinaryOperation* expr,
|
| - Label* eval_right,
|
| - Label* done) const;
|
| virtual void PrepareTest(Label* materialize_true,
|
| Label* materialize_false,
|
| Label** if_true,
|
| Label** if_false,
|
| Label** fall_through) const;
|
| - virtual void HandleExpression(Expression* expr) const;
|
| + virtual bool IsStackValue() const { return true; }
|
| };
|
|
|
| class TestContext : public ExpressionContext {
|
| public:
|
| - explicit TestContext(FullCodeGenerator* codegen,
|
| - Label* true_label,
|
| - Label* false_label,
|
| - Label* fall_through)
|
| + TestContext(FullCodeGenerator* codegen,
|
| + Expression* condition,
|
| + Label* true_label,
|
| + Label* false_label,
|
| + Label* fall_through)
|
| : ExpressionContext(codegen),
|
| + condition_(condition),
|
| true_label_(true_label),
|
| false_label_(false_label),
|
| fall_through_(fall_through) { }
|
| @@ -695,6 +697,7 @@
|
| return reinterpret_cast<const TestContext*>(context);
|
| }
|
|
|
| + Expression* condition() const { return condition_; }
|
| Label* true_label() const { return true_label_; }
|
| Label* false_label() const { return false_label_; }
|
| Label* fall_through() const { return fall_through_; }
|
| @@ -707,18 +710,15 @@
|
| virtual void Plug(Heap::RootListIndex) const;
|
| virtual void PlugTOS() const;
|
| virtual void DropAndPlug(int count, Register reg) const;
|
| - virtual void EmitLogicalLeft(BinaryOperation* expr,
|
| - Label* eval_right,
|
| - Label* done) const;
|
| virtual void PrepareTest(Label* materialize_true,
|
| Label* materialize_false,
|
| Label** if_true,
|
| Label** if_false,
|
| Label** fall_through) const;
|
| - virtual void HandleExpression(Expression* expr) const;
|
| virtual bool IsTest() const { return true; }
|
|
|
| private:
|
| + Expression* condition_;
|
| Label* true_label_;
|
| Label* false_label_;
|
| Label* fall_through_;
|
| @@ -737,20 +737,17 @@
|
| virtual void Plug(Heap::RootListIndex) const;
|
| virtual void PlugTOS() const;
|
| virtual void DropAndPlug(int count, Register reg) const;
|
| - virtual void EmitLogicalLeft(BinaryOperation* expr,
|
| - Label* eval_right,
|
| - Label* done) const;
|
| virtual void PrepareTest(Label* materialize_true,
|
| Label* materialize_false,
|
| Label** if_true,
|
| Label** if_false,
|
| Label** fall_through) const;
|
| - virtual void HandleExpression(Expression* expr) const;
|
| virtual bool IsEffect() const { return true; }
|
| };
|
|
|
| MacroAssembler* masm_;
|
| CompilationInfo* info_;
|
| + Scope* scope_;
|
| Label return_label_;
|
| NestedStatement* nesting_stack_;
|
| int loop_depth_;
|
|
|