Index: src/x64/fast-codegen-x64.cc |
=================================================================== |
--- src/x64/fast-codegen-x64.cc (revision 3106) |
+++ src/x64/fast-codegen-x64.cc (working copy) |
@@ -30,6 +30,7 @@ |
#include "codegen-inl.h" |
#include "debug.h" |
#include "fast-codegen.h" |
+#include "parser.h" |
namespace v8 { |
namespace internal { |
@@ -108,8 +109,8 @@ |
void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
// Call the runtime to declare the globals. |
+ __ push(rsi); // The context is the first argument. |
__ Push(pairs); |
- __ push(rsi); // The context is the second argument. |
__ Push(Smi::FromInt(is_eval_ ? 1 : 0)); |
__ CallRuntime(Runtime::kDeclareGlobals, 3); |
// Return value is ignored. |
@@ -174,8 +175,8 @@ |
ASSERT(boilerplate->IsBoilerplate()); |
// Create a new closure. |
+ __ push(rsi); |
__ Push(boilerplate); |
- __ push(rsi); |
__ CallRuntime(Runtime::kNewClosure, 2); |
if (expr->location().is_temporary()) { |
@@ -206,7 +207,7 @@ |
__ movq(Operand(rsp, 0), rax); |
} else { |
ASSERT(expr->location().is_nowhere()); |
- __ pop(rax); |
+ __ addq(rsp, Immediate(kPointerSize)); |
} |
} else { |
@@ -222,6 +223,76 @@ |
} |
+void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { |
+ Comment cmnt(masm_, "[ ArrayLiteral"); |
+ Label make_clone; |
+ |
+ // Fetch the function's literals array. |
+ __ movq(rbx, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset)); |
+ __ movq(rbx, FieldOperand(rbx, JSFunction::kLiteralsOffset)); |
+ // Check if the literal's boilerplate has been instantiated. |
+ int offset = |
+ FixedArray::kHeaderSize + (expr->literal_index() * kPointerSize); |
+ __ movq(rax, FieldOperand(rbx, offset)); |
+ __ CompareRoot(rax, Heap::kUndefinedValueRootIndex); |
+ __ j(not_equal, &make_clone); |
+ |
+ // Instantiate the boilerplate. |
+ __ push(rbx); |
+ __ Push(Smi::FromInt(expr->literal_index())); |
+ __ Push(expr->literals()); |
+ __ CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3); |
+ |
+ __ bind(&make_clone); |
+ // Clone the boilerplate. |
+ __ push(rax); |
+ if (expr->depth() > 1) { |
+ __ CallRuntime(Runtime::kCloneLiteralBoilerplate, 1); |
+ } else { |
+ __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1); |
+ } |
+ |
+ bool result_saved = false; // Is the result saved to the stack? |
+ |
+ // Emit code to evaluate all the non-constant subexpressions and to store |
+ // them into the newly cloned array. |
+ ZoneList<Expression*>* subexprs = expr->values(); |
+ for (int i = 0, len = subexprs->length(); i < len; i++) { |
+ Expression* subexpr = subexprs->at(i); |
+ // If the subexpression is a literal or a simple materialized literal it |
+ // is already set in the cloned array. |
+ if (subexpr->AsLiteral() != NULL || |
+ CompileTimeValue::IsCompileTimeValue(subexpr)) { |
+ continue; |
+ } |
+ |
+ if (!result_saved) { |
+ __ push(rax); |
+ result_saved = true; |
+ } |
+ Visit(subexpr); |
+ ASSERT(subexpr->location().is_temporary()); |
+ |
+ // Store the subexpression value in the array's elements. |
+ __ pop(rax); // Subexpression value. |
+ __ movq(rbx, Operand(rsp, 0)); // Copy of array literal. |
+ __ movq(rbx, FieldOperand(rbx, JSObject::kElementsOffset)); |
+ int offset = FixedArray::kHeaderSize + (i * kPointerSize); |
+ __ movq(FieldOperand(rbx, offset), rax); |
+ |
+ // Update the write barrier for the array store. |
+ __ RecordWrite(rbx, offset, rax, rcx); |
+ } |
+ |
+ Location destination = expr->location(); |
+ if (destination.is_nowhere() && result_saved) { |
+ __ addq(rsp, Immediate(kPointerSize)); |
+ } else if (destination.is_temporary() && !result_saved) { |
+ __ push(rax); |
+ } |
+} |
+ |
+ |
void FastCodeGenerator::VisitAssignment(Assignment* expr) { |
Comment cmnt(masm_, "[ Assignment"); |
ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR); |
@@ -259,7 +330,7 @@ |
if (destination.is_temporary()) { |
__ movq(Operand(rsp, 0), rax); |
} else { |
- __ pop(rax); |
+ __ addq(rsp, Immediate(kPointerSize)); |
} |
} else { |
if (source.is_temporary()) { |
@@ -321,7 +392,7 @@ |
__ movq(Operand(rsp, 0), rax); |
} else { |
ASSERT(expr->location().is_nowhere()); |
- __ pop(rax); |
+ __ addq(rsp, Immediate(kPointerSize)); |
} |
} |