Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1076)

Unified Diff: src/ppc/full-codegen-ppc.cc

Issue 901083004: Contribution of PowerPC port (continuation of 422063005) - PPC dir update (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Contribution of PowerPC port (continuation of 422063005) - PPC dir update -comments and rebase Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ppc/disasm-ppc.cc ('k') | src/ppc/interface-descriptors-ppc.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ppc/full-codegen-ppc.cc
diff --git a/src/ppc/full-codegen-ppc.cc b/src/ppc/full-codegen-ppc.cc
index 6f43313026952d4da836a8b210b373f5c1fcd429..b7a5d3e33c5c023365816e742b1e8cbd7f714e4c 100644
--- a/src/ppc/full-codegen-ppc.cc
+++ b/src/ppc/full-codegen-ppc.cc
@@ -123,7 +123,7 @@ void FullCodeGenerator::Generate() {
// Sloppy mode functions and builtins need to replace the receiver with the
// global proxy when called as functions (without an explicit receiver
// object).
- if (info->strict_mode() == SLOPPY && !info->is_native()) {
+ if (is_sloppy(info->language_mode()) && !info->is_native()) {
Label ok;
int receiver_offset = info->scope()->num_parameters() * kPointerSize;
__ LoadP(r5, MemOperand(sp, receiver_offset), r0);
@@ -267,7 +267,7 @@ void FullCodeGenerator::Generate() {
// The stub will rewrite receiever and parameter count if the previous
// stack frame was an arguments adapter frame.
ArgumentsAccessStub::Type type;
- if (strict_mode() == STRICT) {
+ if (is_strict(language_mode())) {
type = ArgumentsAccessStub::NEW_STRICT;
} else if (function()->has_duplicate_parameters()) {
type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
@@ -1066,6 +1066,7 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Get the object to enumerate over. If the object is null or undefined, skip
// over the loop. See ECMA-262 version 5, section 12.6.4.
+ SetExpressionPosition(stmt->enumerable());
VisitForAccumulatorValue(stmt->enumerable());
__ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
__ cmp(r3, ip);
@@ -1171,6 +1172,8 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
// Generate code for doing the condition check.
PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS);
__ bind(&loop);
+ SetExpressionPosition(stmt->each());
+
// Load the current count to r3, load the length to r4.
__ LoadP(r3, MemOperand(sp, 0 * kPointerSize));
__ LoadP(r4, MemOperand(sp, 1 * kPointerSize));
@@ -1244,46 +1247,6 @@ void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) {
}
-void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
- Comment cmnt(masm_, "[ ForOfStatement");
- SetStatementPosition(stmt);
-
- Iteration loop_statement(this, stmt);
- increment_loop_depth();
-
- // var iterator = iterable[Symbol.iterator]();
- VisitForEffect(stmt->assign_iterator());
-
- // Loop entry.
- __ bind(loop_statement.continue_label());
-
- // result = iterator.next()
- VisitForEffect(stmt->next_result());
-
- // if (result.done) break;
- Label result_not_done;
- VisitForControl(stmt->result_done(), loop_statement.break_label(),
- &result_not_done, &result_not_done);
- __ bind(&result_not_done);
-
- // each = result.value
- VisitForEffect(stmt->assign_each());
-
- // Generate code for the body of the loop.
- Visit(stmt->body());
-
- // Check stack before looping.
- PrepareForBailoutForId(stmt->BackEdgeId(), NO_REGISTERS);
- EmitBackEdgeBookkeeping(stmt, loop_statement.continue_label());
- __ b(loop_statement.continue_label());
-
- // Exit and decrement the loop depth.
- PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS);
- __ bind(loop_statement.break_label());
- decrement_loop_depth();
-}
-
-
void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
bool pretenure) {
// Use the fast case closure allocation code that allocates in new
@@ -1294,7 +1257,7 @@ void FullCodeGenerator::EmitNewClosure(Handle<SharedFunctionInfo> info,
// doesn't just get a copy of the existing unoptimized code.
if (!FLAG_always_opt && !FLAG_prepare_always_opt && !pretenure &&
scope()->is_function_scope() && info->num_literals() == 0) {
- FastNewClosureStub stub(isolate(), info->strict_mode(), info->kind());
+ FastNewClosureStub stub(isolate(), info->language_mode(), info->kind());
__ mov(r5, Operand(info));
__ CallStub(&stub);
} else {
@@ -1339,6 +1302,19 @@ void FullCodeGenerator::EmitLoadHomeObject(SuperReference* expr) {
}
+void FullCodeGenerator::EmitSetHomeObjectIfNeeded(Expression* initializer,
+ int offset) {
+ if (NeedsHomeObject(initializer)) {
+ __ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
+ __ mov(StoreDescriptor::NameRegister(),
+ Operand(isolate()->factory()->home_object_symbol()));
+ __ LoadP(StoreDescriptor::ValueRegister(),
+ MemOperand(sp, offset * kPointerSize));
+ CallStoreIC();
+ }
+}
+
+
void FullCodeGenerator::EmitLoadGlobalCheckExtensions(VariableProxy* proxy,
TypeofState typeof_state,
Label* slow) {
@@ -1517,6 +1493,11 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
bool skip_init_check;
if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) {
skip_init_check = false;
+ } else if (var->is_this()) {
+ CHECK(info_->function() != nullptr &&
+ (info_->function()->kind() & kSubclassConstructor) != 0);
+ // TODO(dslomov): implement 'this' hole check elimination.
+ skip_init_check = false;
} else {
// Check that we always have valid source position.
DCHECK(var->initializer_position() != RelocInfo::kNoPosition);
@@ -1664,11 +1645,13 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
expr->CalculateEmitStore(zone());
AccessorTable accessor_table(zone());
- for (int i = 0; i < expr->properties()->length(); i++) {
- ObjectLiteral::Property* property = expr->properties()->at(i);
+ int property_index = 0;
+ for (; property_index < expr->properties()->length(); property_index++) {
+ ObjectLiteral::Property* property = expr->properties()->at(property_index);
+ if (property->is_computed_name()) break;
if (property->IsCompileTimeValue()) continue;
- Literal* key = property->key();
+ Literal* key = property->key()->AsLiteral();
Expression* value = property->value();
if (!result_saved) {
__ push(r3); // Save result on stack
@@ -1691,6 +1674,14 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
__ LoadP(StoreDescriptor::ReceiverRegister(), MemOperand(sp));
CallStoreIC(key->LiteralFeedbackId());
PrepareForBailoutForId(key->id(), NO_REGISTERS);
+
+ if (NeedsHomeObject(value)) {
+ __ Move(StoreDescriptor::ReceiverRegister(), r3);
+ __ mov(StoreDescriptor::NameRegister(),
+ Operand(isolate()->factory()->home_object_symbol()));
+ __ LoadP(StoreDescriptor::ValueRegister(), MemOperand(sp));
+ CallStoreIC();
+ }
} else {
VisitForEffect(value);
}
@@ -1702,6 +1693,7 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
VisitForStackValue(key);
VisitForStackValue(value);
if (property->emit_store()) {
+ EmitSetHomeObjectIfNeeded(value, 2);
__ LoadSmiLiteral(r3, Smi::FromInt(SLOPPY)); // PropertyAttributes
__ push(r3);
__ CallRuntime(Runtime::kSetProperty, 4);
@@ -1738,12 +1730,76 @@ void FullCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
__ push(r3);
VisitForStackValue(it->first);
EmitAccessor(it->second->getter);
+ EmitSetHomeObjectIfNeeded(it->second->getter, 2);
EmitAccessor(it->second->setter);
+ EmitSetHomeObjectIfNeeded(it->second->setter, 3);
__ LoadSmiLiteral(r3, Smi::FromInt(NONE));
__ push(r3);
__ CallRuntime(Runtime::kDefineAccessorPropertyUnchecked, 5);
}
+ // Object literals have two parts. The "static" part on the left contains no
+ // computed property names, and so we can compute its map ahead of time; see
+ // runtime.cc::CreateObjectLiteralBoilerplate. The second "dynamic" part
+ // starts with the first computed property name, and continues with all
+ // properties to its right. All the code from above initializes the static
+ // component of the object literal, and arranges for the map of the result to
+ // reflect the static order in which the keys appear. For the dynamic
+ // properties, we compile them into a series of "SetOwnProperty" runtime
+ // calls. This will preserve insertion order.
+ for (; property_index < expr->properties()->length(); property_index++) {
+ ObjectLiteral::Property* property = expr->properties()->at(property_index);
+
+ Expression* value = property->value();
+ if (!result_saved) {
+ __ push(r3); // Save result on the stack
+ result_saved = true;
+ }
+
+ __ LoadP(r3, MemOperand(sp)); // Duplicate receiver.
+ __ push(r3);
+
+ if (property->kind() == ObjectLiteral::Property::PROTOTYPE) {
+ DCHECK(!property->is_computed_name());
+ VisitForStackValue(value);
+ DCHECK(property->emit_store());
+ __ CallRuntime(Runtime::kInternalSetPrototype, 2);
+ } else {
+ EmitPropertyKey(property, expr->GetIdForProperty(property_index));
+ VisitForStackValue(value);
+
+ switch (property->kind()) {
+ case ObjectLiteral::Property::CONSTANT:
+ case ObjectLiteral::Property::MATERIALIZED_LITERAL:
+ case ObjectLiteral::Property::COMPUTED:
+ if (property->emit_store()) {
+ __ LoadSmiLiteral(r3, Smi::FromInt(NONE));
+ __ push(r3);
+ __ CallRuntime(Runtime::kDefineDataPropertyUnchecked, 4);
+ } else {
+ __ Drop(3);
+ }
+ break;
+
+ case ObjectLiteral::Property::PROTOTYPE:
+ UNREACHABLE();
+ break;
+
+ case ObjectLiteral::Property::GETTER:
+ __ mov(r3, Operand(Smi::FromInt(NONE)));
+ __ push(r3);
+ __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4);
+ break;
+
+ case ObjectLiteral::Property::SETTER:
+ __ mov(r3, Operand(Smi::FromInt(NONE)));
+ __ push(r3);
+ __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4);
+ break;
+ }
+ }
+ }
+
if (expr->has_function()) {
DCHECK(result_saved);
__ LoadP(r3, MemOperand(sp));
@@ -1934,16 +1990,13 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
__ push(r3); // Left operand goes on the stack.
VisitForAccumulatorValue(expr->value());
- OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
- ? OVERWRITE_RIGHT
- : NO_OVERWRITE;
SetSourcePosition(expr->position() + 1);
AccumulatorValueContext context(this);
if (ShouldInlineSmiCase(op)) {
- EmitInlineSmiBinaryOp(expr->binary_operation(), op, mode, expr->target(),
+ EmitInlineSmiBinaryOp(expr->binary_operation(), op, expr->target(),
expr->value());
} else {
- EmitBinaryOp(expr->binary_operation(), op, mode);
+ EmitBinaryOp(expr->binary_operation(), op);
}
// Deoptimization point in case the binary operation may have side effects.
@@ -2159,15 +2212,6 @@ void FullCodeGenerator::EmitGeneratorResume(
VisitForAccumulatorValue(value);
__ pop(r4);
- // Check generator state.
- Label wrong_state, closed_state, done;
- __ LoadP(r6, FieldMemOperand(r4, JSGeneratorObject::kContinuationOffset));
- STATIC_ASSERT(JSGeneratorObject::kGeneratorExecuting < 0);
- STATIC_ASSERT(JSGeneratorObject::kGeneratorClosed == 0);
- __ CmpSmiLiteral(r6, Smi::FromInt(0), r0);
- __ beq(&closed_state);
- __ blt(&wrong_state);
-
// Load suspended function and context.
__ LoadP(cp, FieldMemOperand(r4, JSGeneratorObject::kContextOffset));
__ LoadP(r7, FieldMemOperand(r4, JSGeneratorObject::kFunctionOffset));
@@ -2196,7 +2240,7 @@ void FullCodeGenerator::EmitGeneratorResume(
// Enter a new JavaScript frame, and initialize its slots as they were when
// the generator was suspended.
- Label resume_frame;
+ Label resume_frame, done;
__ bind(&push_frame);
__ b(&resume_frame, SetLK);
__ b(&done);
@@ -2260,26 +2304,6 @@ void FullCodeGenerator::EmitGeneratorResume(
// Not reached: the runtime call returns elsewhere.
__ stop("not-reached");
- // Reach here when generator is closed.
- __ bind(&closed_state);
- if (resume_mode == JSGeneratorObject::NEXT) {
- // Return completed iterator result when generator is closed.
- __ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
- __ push(r5);
- // Pop value from top-of-stack slot; box result into result register.
- EmitCreateIteratorResult(true);
- } else {
- // Throw the provided value.
- __ push(r3);
- __ CallRuntime(Runtime::kThrow, 1);
- }
- __ b(&done);
-
- // Throw error if we attempt to operate on a running generator.
- __ bind(&wrong_state);
- __ push(r4);
- __ CallRuntime(Runtime::kThrowGeneratorStateError, 1);
-
__ bind(&done);
context()->Plug(result_register());
}
@@ -2377,7 +2401,6 @@ void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
Token::Value op,
- OverwriteMode mode,
Expression* left_expr,
Expression* right_expr) {
Label done, smi_case, stub_call;
@@ -2397,7 +2420,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
__ bind(&stub_call);
- Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
+ Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
__ b(&done);
@@ -2435,13 +2458,13 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
}
case Token::ADD: {
__ AddAndCheckForOverflow(scratch1, left, right, scratch2, r0);
- __ bne(&stub_call, cr0);
+ __ BranchOnOverflow(&stub_call);
__ mr(right, scratch1);
break;
}
case Token::SUB: {
__ SubAndCheckForOverflow(scratch1, left, right, scratch2, r0);
- __ bne(&stub_call, cr0);
+ __ BranchOnOverflow(&stub_call);
__ mr(right, scratch1);
break;
}
@@ -2454,7 +2477,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
__ Mul(scratch1, r0, ip);
// Check for overflowing the smi range - no overflow if higher 33 bits of
// the result are identical.
- __ TestIfInt32(scratch1, scratch2, ip);
+ __ TestIfInt32(scratch1, r0);
__ bne(&stub_call);
#else
__ SmiUntag(ip, right);
@@ -2515,9 +2538,7 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
for (int i = 0; i < lit->properties()->length(); i++) {
ObjectLiteral::Property* property = lit->properties()->at(i);
- Literal* key = property->key()->AsLiteral();
Expression* value = property->value();
- DCHECK(key != NULL);
if (property->is_static()) {
__ LoadP(scratch, MemOperand(sp, kPointerSize)); // constructor
@@ -2525,8 +2546,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
__ LoadP(scratch, MemOperand(sp, 0)); // prototype
}
__ push(scratch);
- VisitForStackValue(key);
+ EmitPropertyKey(property, lit->GetIdForProperty(i));
VisitForStackValue(value);
+ EmitSetHomeObjectIfNeeded(value, 2);
switch (property->kind()) {
case ObjectLiteral::Property::CONSTANT:
@@ -2538,11 +2560,15 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
break;
case ObjectLiteral::Property::GETTER:
- __ CallRuntime(Runtime::kDefineClassGetter, 3);
+ __ mov(r3, Operand(Smi::FromInt(DONT_ENUM)));
+ __ push(r3);
+ __ CallRuntime(Runtime::kDefineGetterPropertyUnchecked, 4);
break;
case ObjectLiteral::Property::SETTER:
- __ CallRuntime(Runtime::kDefineClassSetter, 3);
+ __ mov(r3, Operand(Smi::FromInt(DONT_ENUM)));
+ __ push(r3);
+ __ CallRuntime(Runtime::kDefineSetterPropertyUnchecked, 4);
break;
default:
@@ -2558,10 +2584,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
}
-void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op,
- OverwriteMode mode) {
+void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ pop(r4);
- Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
+ Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
CallIC(code, expr->BinaryOperationFeedbackId());
patch_site.EmitPatchInfo();
@@ -2636,7 +2661,7 @@ void FullCodeGenerator::EmitAssignment(Expression* expr) {
__ Pop(StoreDescriptor::ValueRegister(),
StoreDescriptor::ReceiverRegister());
Handle<Code> ic =
- CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code();
+ CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
CallIC(ic);
break;
}
@@ -2705,8 +2730,8 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
// Assignment to var.
__ push(r3); // Value.
__ mov(r4, Operand(var->name()));
- __ mov(r3, Operand(Smi::FromInt(strict_mode())));
- __ Push(cp, r4, r3); // Context, name, strict mode.
+ __ mov(r3, Operand(Smi::FromInt(language_mode())));
+ __ Push(cp, r4, r3); // Context, name, language mode.
__ CallRuntime(Runtime::kStoreLookupSlot, 4);
} else {
// Assignment to var or initializing assignment to let/const in harmony
@@ -2721,8 +2746,9 @@ void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
}
EmitStoreToStackLocalOrContextSlot(var, location);
}
+ } else if (IsSignallingAssignmentToConst(var, op, language_mode())) {
+ __ CallRuntime(Runtime::kThrowConstAssignError, 0);
}
- // Non-initializing assignments to consts are ignored.
}
@@ -2754,8 +2780,8 @@ void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) {
__ Push(key->value());
__ Push(r3);
- __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict
- : Runtime::kStoreToSuper_Sloppy),
+ __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict
+ : Runtime::kStoreToSuper_Sloppy),
4);
}
@@ -2767,9 +2793,10 @@ void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) {
DCHECK(prop != NULL);
__ Push(r3);
- __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict
- : Runtime::kStoreKeyedToSuper_Sloppy),
- 4);
+ __ CallRuntime(
+ (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict
+ : Runtime::kStoreKeyedToSuper_Sloppy),
+ 4);
}
@@ -2781,7 +2808,8 @@ void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
__ Pop(StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister());
DCHECK(StoreDescriptor::ValueRegister().is(r3));
- Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code();
+ Handle<Code> ic =
+ CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
CallIC(ic, expr->AssignmentFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
@@ -2973,8 +3001,8 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
// Record source position of the IC call.
SetSourcePosition(expr->position());
- Handle<Code> ic = CallIC::initialize_stub(isolate(), arg_count, call_type);
- __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackSlot()));
+ Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code();
+ __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackICSlot()));
__ LoadP(r4, MemOperand(sp, (arg_count + 1) * kPointerSize), r0);
// Don't assign a type feedback id to the IC, since type feedback is provided
// by the vector above.
@@ -3002,8 +3030,8 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
int receiver_offset = 2 + info_->scope()->num_parameters();
__ LoadP(r6, MemOperand(fp, receiver_offset * kPointerSize), r0);
- // r5: strict mode.
- __ LoadSmiLiteral(r5, Smi::FromInt(strict_mode()));
+ // r5: language mode.
+ __ LoadSmiLiteral(r5, Smi::FromInt(language_mode()));
// r4: the start position of the scope the calls resides in.
__ LoadSmiLiteral(r4, Smi::FromInt(scope()->start_position()));
@@ -3140,11 +3168,15 @@ void FullCodeGenerator::VisitCall(Call* expr) {
}
}
} else if (call_type == Call::SUPER_CALL) {
- SuperReference* super_ref = callee->AsSuperReference();
- EmitLoadSuperConstructor(super_ref);
- __ Push(result_register());
- VisitForStackValue(super_ref->this_var());
- EmitCall(expr, CallICState::METHOD);
+ if (FLAG_experimental_classes) {
+ EmitSuperConstructorCall(expr);
+ } else {
+ SuperReference* super_ref = callee->AsSuperReference();
+ EmitLoadSuperConstructor(super_ref);
+ __ Push(result_register());
+ VisitForStackValue(super_ref->this_var());
+ EmitCall(expr, CallICState::METHOD);
+ }
} else {
DCHECK(call_type == Call::OTHER_CALL);
// Call to an arbitrary expression not handled specially above.
@@ -3213,6 +3245,61 @@ void FullCodeGenerator::VisitCallNew(CallNew* expr) {
}
+void FullCodeGenerator::EmitSuperConstructorCall(Call* expr) {
+ SuperReference* super_ref = expr->expression()->AsSuperReference();
+ EmitLoadSuperConstructor(super_ref);
+ __ push(result_register());
+
+ Variable* this_var = super_ref->this_var()->var();
+
+ GetVar(r3, this_var);
+ __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
+ Label uninitialized_this;
+ __ beq(&uninitialized_this);
+ __ mov(r3, Operand(this_var->name()));
+ __ push(r3);
+ __ CallRuntime(Runtime::kThrowReferenceError, 1);
+ __ bind(&uninitialized_this);
+
+ // Push the arguments ("left-to-right") on the stack.
+ ZoneList<Expression*>* args = expr->arguments();
+ int arg_count = args->length();
+ for (int i = 0; i < arg_count; i++) {
+ VisitForStackValue(args->at(i));
+ }
+
+ // Call the construct call builtin that handles allocation and
+ // constructor invocation.
+ SetSourcePosition(expr->position());
+
+ // Load function and argument count into r1 and r0.
+ __ mov(r3, Operand(arg_count));
+ __ LoadP(r4, MemOperand(sp, arg_count * kPointerSize));
+
+ // Record call targets in unoptimized code.
+ if (FLAG_pretenuring_call_new) {
+ UNREACHABLE();
+ /* TODO(dslomov): support pretenuring.
+ EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot());
+ DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() ==
+ expr->CallNewFeedbackSlot().ToInt() + 1);
+ */
+ }
+
+ __ Move(r5, FeedbackVector());
+ __ LoadSmiLiteral(r6, SmiFromSlot(expr->CallFeedbackSlot()));
+
+ // TODO(dslomov): use a different stub and propagate new.target.
+ CallConstructStub stub(isolate(), RECORD_CONSTRUCTOR_TARGET);
+ __ Call(stub.GetCode(), RelocInfo::CONSTRUCT_CALL);
+
+ RecordJSReturnSite(expr);
+
+ EmitVariableAssignment(this_var, Token::INIT_CONST);
+ context()->Plug(r3);
+}
+
+
void FullCodeGenerator::EmitIsSmi(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
DCHECK(args->length() == 1);
@@ -4512,7 +4599,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
if (property != NULL) {
VisitForStackValue(property->obj());
VisitForStackValue(property->key());
- __ LoadSmiLiteral(r4, Smi::FromInt(strict_mode()));
+ __ LoadSmiLiteral(r4, Smi::FromInt(language_mode()));
__ push(r4);
__ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
context()->Plug(r3);
@@ -4520,7 +4607,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
Variable* var = proxy->var();
// Delete of an unqualified identifier is disallowed in strict mode
// but "delete this" is allowed.
- DCHECK(strict_mode() == SLOPPY || var->is_this());
+ DCHECK(is_sloppy(language_mode()) || var->is_this());
if (var->IsUnallocated()) {
__ LoadP(r5, GlobalObjectOperand());
__ mov(r4, Operand(var->name()));
@@ -4768,8 +4855,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
// Record position before stub call.
SetSourcePosition(expr->position());
- Handle<Code> code =
- CodeFactory::BinaryOpIC(isolate(), Token::ADD, NO_OVERWRITE).code();
+ Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD).code();
CallIC(code, expr->CountBinOpFeedbackId());
patch_site.EmitPatchInfo();
__ bind(&done);
@@ -4838,7 +4924,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
__ Pop(StoreDescriptor::ReceiverRegister(),
StoreDescriptor::NameRegister());
Handle<Code> ic =
- CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code();
+ CodeFactory::KeyedStoreIC(isolate(), language_mode()).code();
CallIC(ic, expr->CountStoreFeedbackId());
PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
if (expr->is_postfix()) {
« no previous file with comments | « src/ppc/disasm-ppc.cc ('k') | src/ppc/interface-descriptors-ppc.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698