void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Comment cmnt(masm_, "[ ObjectLiteral");
- Label boilerplate_exists;
__ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
- // r2 = literal array (0).
__ ldr(r2, FieldMemOperand(r2, JSFunction::kLiteralsOffset));
- int literal_offset =
- FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
- __ ldr(r0, FieldMemOperand(r2, literal_offset));
- // Check whether we need to materialize the object literal boilerplate.
- __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
- __ cmp(r0, Operand(ip));
- __ b(ne, &boilerplate_exists);
- // Create boilerplate if it does not exist.
- // r1 = literal index (1).
__ mov(r1, Operand(Smi::FromInt(expr->literal_index())));
- // r0 = constant properties (2).
__ mov(r0, Operand(expr->constant_properties()));
__ stm(db_w, sp, r2.bit() | r1.bit() | r0.bit());
- __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
- __ bind(&boilerplate_exists);
- // r0 contains boilerplate.
- // Clone boilerplate.
- __ push(r0);
if (expr->depth() > 1) {
- __ CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
+ __ CallRuntime(Runtime::kCreateObjectLiteral, 3);
} else {
- __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1);
+ __ CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
}
// If result_saved == true: The result is saved on top of the
void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
Comment cmnt(masm_, "[ ArrayLiteral");
- Label make_clone;
-
- // Fetch the function's literals array.
__ ldr(r3, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
__ ldr(r3, FieldMemOperand(r3, JSFunction::kLiteralsOffset));
- // Check if the literal's boilerplate has been instantiated.
- int offset =
- FixedArray::kHeaderSize + (expr->literal_index() * kPointerSize);
- __ ldr(r0, FieldMemOperand(r3, offset));
- __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
- __ cmp(r0, ip);
- __ b(&make_clone, ne);
-
- // Instantiate the boilerplate.
__ mov(r2, Operand(Smi::FromInt(expr->literal_index())));
__ mov(r1, Operand(expr->literals()));
__ stm(db_w, sp, r3.bit() | r2.bit() | r1.bit());
- __ CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
-
- __ bind(&make_clone);
- // Clone the boilerplate.
- __ push(r0);
if (expr->depth() > 1) {
- __ CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
+ __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
} else {
- __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1);
+ __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
}
bool result_saved = false; // Is the result saved to the stack?
void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Comment cmnt(masm_, "[ ObjectLiteral");
- Label exists;
- // Registers will be used as follows:
- // edi = JS function.
- // ebx = literals array.
- // eax = boilerplate
-
__ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
- __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset));
- int literal_offset =
- FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
- __ mov(eax, FieldOperand(ebx, literal_offset));
- __ cmp(eax, Factory::undefined_value());
- __ j(not_equal, &exists);
- // Create boilerplate if it does not exist.
- // Literal array (0).
- __ push(ebx);
- // Literal index (1).
+ __ push(FieldOperand(edi, JSFunction::kLiteralsOffset));
__ push(Immediate(Smi::FromInt(expr->literal_index())));
- // Constant properties (2).
__ push(Immediate(expr->constant_properties()));
- __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
- __ bind(&exists);
- // eax contains boilerplate.
- // Clone boilerplate.
- __ push(eax);
- if (expr->depth() == 1) {
- __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1);
+ if (expr->depth() > 1) {
+ __ CallRuntime(Runtime::kCreateObjectLiteral, 3);
} else {
- __ CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
+ __ CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
}
// If result_saved == true: The result is saved on top of the
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(FieldOperand(ebx, JSFunction::kLiteralsOffset));
__ 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);
+ __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
} else {
- __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1);
+ __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
}
bool result_saved = false; // Is the result saved to the stack?
}
+static Object* Runtime_CreateObjectLiteral(Arguments args) {
+ HandleScope scope;
+ ASSERT(args.length() == 3);
+ CONVERT_ARG_CHECKED(FixedArray, literals, 0);
+ CONVERT_SMI_CHECKED(literals_index, args[1]);
+ CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
+
+ // Check if boilerplate exists. If not, create it first.
+ Handle<Object> boilerplate(literals->get(literals_index));
+ if (*boilerplate == Heap::undefined_value()) {
+ boilerplate = CreateObjectLiteralBoilerplate(literals, constant_properties);
+ if (boilerplate.is_null()) return Failure::Exception();
+ // Update the functions literal and return the boilerplate.
+ literals->set(literals_index, *boilerplate);
+ }
+ return DeepCopyBoilerplate(JSObject::cast(*boilerplate));
+}
+
+
+static Object* Runtime_CreateObjectLiteralShallow(Arguments args) {
+ HandleScope scope;
+ ASSERT(args.length() == 3);
+ CONVERT_ARG_CHECKED(FixedArray, literals, 0);
+ CONVERT_SMI_CHECKED(literals_index, args[1]);
+ CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2);
+
+ // Check if boilerplate exists. If not, create it first.
+ Handle<Object> boilerplate(literals->get(literals_index));
+ if (*boilerplate == Heap::undefined_value()) {
+ boilerplate = CreateObjectLiteralBoilerplate(literals, constant_properties);
+ if (boilerplate.is_null()) return Failure::Exception();
+ // Update the functions literal and return the boilerplate.
+ literals->set(literals_index, *boilerplate);
+ }
+ return Heap::CopyJSObject(JSObject::cast(*boilerplate));
+}
+
+
+static Object* Runtime_CreateArrayLiteral(Arguments args) {
+ HandleScope scope;
+ ASSERT(args.length() == 3);
+ CONVERT_ARG_CHECKED(FixedArray, literals, 0);
+ CONVERT_SMI_CHECKED(literals_index, args[1]);
+ CONVERT_ARG_CHECKED(FixedArray, elements, 2);
+
+ // Check if boilerplate exists. If not, create it first.
+ Handle<Object> boilerplate(literals->get(literals_index));
+ if (*boilerplate == Heap::undefined_value()) {
+ boilerplate = CreateArrayLiteralBoilerplate(literals, elements);
+ if (boilerplate.is_null()) return Failure::Exception();
+ // Update the functions literal and return the boilerplate.
+ literals->set(literals_index, *boilerplate);
+ }
+ return DeepCopyBoilerplate(JSObject::cast(*boilerplate));
+}
+
+
+static Object* Runtime_CreateArrayLiteralShallow(Arguments args) {
+ HandleScope scope;
+ ASSERT(args.length() == 3);
+ CONVERT_ARG_CHECKED(FixedArray, literals, 0);
+ CONVERT_SMI_CHECKED(literals_index, args[1]);
+ CONVERT_ARG_CHECKED(FixedArray, elements, 2);
+
+ // Check if boilerplate exists. If not, create it first.
+ Handle<Object> boilerplate(literals->get(literals_index));
+ if (*boilerplate == Heap::undefined_value()) {
+ boilerplate = CreateArrayLiteralBoilerplate(literals, elements);
+ if (boilerplate.is_null()) return Failure::Exception();
+ // Update the functions literal and return the boilerplate.
+ literals->set(literals_index, *boilerplate);
+ }
+ return Heap::CopyJSObject(JSObject::cast(*boilerplate));
+}
+
+
static Object* Runtime_CreateCatchExtensionObject(Arguments args) {
ASSERT(args.length() == 2);
CONVERT_CHECKED(String, key, args[0]);
F(CreateObjectLiteralBoilerplate, 3, 1) \
F(CloneLiteralBoilerplate, 1, 1) \
F(CloneShallowLiteralBoilerplate, 1, 1) \
+ F(CreateObjectLiteral, 3, 1) \
+ F(CreateObjectLiteralShallow, 3, 1) \
+ F(CreateArrayLiteral, 3, 1) \
+ F(CreateArrayLiteralShallow, 3, 1) \
\
/* Catch context extension objects */ \
F(CreateCatchExtensionObject, 2, 1) \
void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
Comment cmnt(masm_, "[ ObjectLiteral");
- Label boilerplate_exists;
-
__ movq(rdi, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
- __ movq(rbx, FieldOperand(rdi, JSFunction::kLiteralsOffset));
- int literal_offset =
- FixedArray::kHeaderSize + expr->literal_index() * kPointerSize;
- __ movq(rax, FieldOperand(rbx, literal_offset));
- __ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
- __ j(not_equal, &boilerplate_exists);
- // Create boilerplate if it does not exist.
- // Literal array (0).
- __ push(rbx);
- // Literal index (1).
+ __ push(FieldOperand(rdi, JSFunction::kLiteralsOffset));
__ Push(Smi::FromInt(expr->literal_index()));
- // Constant properties (2).
__ Push(expr->constant_properties());
- __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
- __ bind(&boilerplate_exists);
- // rax contains boilerplate.
- // Clone boilerplate.
- __ push(rax);
- if (expr->depth() == 1) {
- __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1);
+ if (expr->depth() > 1) {
+ __ CallRuntime(Runtime::kCreateObjectLiteral, 3);
} else {
- __ CallRuntime(Runtime::kCloneLiteralBoilerplate, 1);
+ __ CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
}
// If result_saved == true: The result is saved on top of the
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(FieldOperand(rbx, JSFunction::kLiteralsOffset));
__ 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);
+ __ CallRuntime(Runtime::kCreateArrayLiteral, 3);
} else {
- __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1);
+ __ CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
}
bool result_saved = false; // Is the result saved to the stack?