| Index: src/ia32/fast-codegen-ia32.cc
|
| ===================================================================
|
| --- src/ia32/fast-codegen-ia32.cc (revision 3106)
|
| +++ src/ia32/fast-codegen-ia32.cc (working copy)
|
| @@ -29,6 +29,7 @@
|
|
|
| #include "codegen-inl.h"
|
| #include "fast-codegen.h"
|
| +#include "parser.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| @@ -100,8 +101,8 @@
|
|
|
| void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
|
| // Call the runtime to declare the globals.
|
| + __ push(esi); // The context is the first argument.
|
| __ push(Immediate(pairs));
|
| - __ push(esi); // The context is the second argument.
|
| __ push(Immediate(Smi::FromInt(is_eval_ ? 1 : 0)));
|
| __ CallRuntime(Runtime::kDeclareGlobals, 3);
|
| // Return value is ignored.
|
| @@ -157,8 +158,8 @@
|
| ASSERT(boilerplate->IsBoilerplate());
|
|
|
| // Create a new closure.
|
| + __ push(esi);
|
| __ push(Immediate(boilerplate));
|
| - __ push(esi);
|
| __ CallRuntime(Runtime::kNewClosure, 2);
|
|
|
| if (expr->location().is_temporary()) {
|
| @@ -190,7 +191,7 @@
|
| __ mov(Operand(esp, 0), eax);
|
| } else {
|
| ASSERT(expr->location().is_nowhere());
|
| - __ pop(eax);
|
| + __ add(Operand(esp), Immediate(kPointerSize));
|
| }
|
|
|
| } else {
|
| @@ -206,6 +207,76 @@
|
| }
|
|
|
|
|
| +void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
|
| + Comment cmnt(masm_, "[ ArrayLiteral");
|
| + Label make_clone;
|
| +
|
| + // Fetch the function's literals array.
|
| + __ mov(ebx, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
|
| + __ mov(ebx, FieldOperand(ebx, JSFunction::kLiteralsOffset));
|
| + // Check if the literal's boilerplate has been instantiated.
|
| + int offset =
|
| + FixedArray::kHeaderSize + (expr->literal_index() * kPointerSize);
|
| + __ mov(eax, FieldOperand(ebx, offset));
|
| + __ cmp(eax, Factory::undefined_value());
|
| + __ j(not_equal, &make_clone);
|
| +
|
| + // Instantiate the boilerplate.
|
| + __ push(ebx);
|
| + __ push(Immediate(Smi::FromInt(expr->literal_index())));
|
| + __ push(Immediate(expr->literals()));
|
| + __ CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
|
| +
|
| + __ bind(&make_clone);
|
| + // Clone the boilerplate.
|
| + __ push(eax);
|
| + 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(eax);
|
| + result_saved = true;
|
| + }
|
| + Visit(subexpr);
|
| + ASSERT(subexpr->location().is_temporary());
|
| +
|
| + // Store the subexpression value in the array's elements.
|
| + __ pop(eax); // Subexpression value.
|
| + __ mov(ebx, Operand(esp, 0)); // Copy of array literal.
|
| + __ mov(ebx, FieldOperand(ebx, JSObject::kElementsOffset));
|
| + int offset = FixedArray::kHeaderSize + (i * kPointerSize);
|
| + __ mov(FieldOperand(ebx, offset), eax);
|
| +
|
| + // Update the write barrier for the array store.
|
| + __ RecordWrite(ebx, offset, eax, ecx);
|
| + }
|
| +
|
| + Location destination = expr->location();
|
| + if (destination.is_nowhere() && result_saved) {
|
| + __ add(Operand(esp), Immediate(kPointerSize));
|
| + } else if (destination.is_temporary() && !result_saved) {
|
| + __ push(eax);
|
| + }
|
| +}
|
| +
|
| +
|
| void FastCodeGenerator::VisitAssignment(Assignment* expr) {
|
| Comment cmnt(masm_, "[ Assignment");
|
| ASSERT(expr->op() == Token::ASSIGN || expr->op() == Token::INIT_VAR);
|
| @@ -244,7 +315,7 @@
|
| __ mov(Operand(esp, 0), eax);
|
| } else {
|
| ASSERT(destination.is_nowhere());
|
| - __ pop(eax);
|
| + __ add(Operand(esp), Immediate(kPointerSize));
|
| }
|
|
|
| } else {
|
| @@ -308,7 +379,7 @@
|
| __ mov(Operand(esp, 0), eax);
|
| } else {
|
| ASSERT(expr->location().is_nowhere());
|
| - __ pop(eax);
|
| + __ add(Operand(esp), Immediate(kPointerSize));
|
| }
|
| }
|
|
|
|
|