| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_ARM64 | 7 #if V8_TARGET_ARCH_ARM64 |
| 8 | 8 |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 #ifdef DEBUG | 117 #ifdef DEBUG |
| 118 if (strlen(FLAG_stop_at) > 0 && | 118 if (strlen(FLAG_stop_at) > 0 && |
| 119 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { | 119 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { |
| 120 __ Debug("stop-at", __LINE__, BREAK); | 120 __ Debug("stop-at", __LINE__, BREAK); |
| 121 } | 121 } |
| 122 #endif | 122 #endif |
| 123 | 123 |
| 124 // Sloppy mode functions and builtins need to replace the receiver with the | 124 // Sloppy mode functions and builtins need to replace the receiver with the |
| 125 // global proxy when called as functions (without an explicit receiver | 125 // global proxy when called as functions (without an explicit receiver |
| 126 // object). | 126 // object). |
| 127 if (info->strict_mode() == SLOPPY && !info->is_native()) { | 127 if (is_sloppy(info->language_mode()) && !info->is_native()) { |
| 128 Label ok; | 128 Label ok; |
| 129 int receiver_offset = info->scope()->num_parameters() * kXRegSize; | 129 int receiver_offset = info->scope()->num_parameters() * kXRegSize; |
| 130 __ Peek(x10, receiver_offset); | 130 __ Peek(x10, receiver_offset); |
| 131 __ JumpIfNotRoot(x10, Heap::kUndefinedValueRootIndex, &ok); | 131 __ JumpIfNotRoot(x10, Heap::kUndefinedValueRootIndex, &ok); |
| 132 | 132 |
| 133 __ Ldr(x10, GlobalObjectMemOperand()); | 133 __ Ldr(x10, GlobalObjectMemOperand()); |
| 134 __ Ldr(x10, FieldMemOperand(x10, GlobalObject::kGlobalProxyOffset)); | 134 __ Ldr(x10, FieldMemOperand(x10, GlobalObject::kGlobalProxyOffset)); |
| 135 __ Poke(x10, receiver_offset); | 135 __ Poke(x10, receiver_offset); |
| 136 | 136 |
| 137 __ Bind(&ok); | 137 __ Bind(&ok); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 int offset = num_parameters * kPointerSize; | 256 int offset = num_parameters * kPointerSize; |
| 257 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset + offset); | 257 __ Add(x2, fp, StandardFrameConstants::kCallerSPOffset + offset); |
| 258 __ Mov(x1, Smi::FromInt(num_parameters)); | 258 __ Mov(x1, Smi::FromInt(num_parameters)); |
| 259 __ Push(x3, x2, x1); | 259 __ Push(x3, x2, x1); |
| 260 | 260 |
| 261 // Arguments to ArgumentsAccessStub: | 261 // Arguments to ArgumentsAccessStub: |
| 262 // function, receiver address, parameter count. | 262 // function, receiver address, parameter count. |
| 263 // The stub will rewrite receiver and parameter count if the previous | 263 // The stub will rewrite receiver and parameter count if the previous |
| 264 // stack frame was an arguments adapter frame. | 264 // stack frame was an arguments adapter frame. |
| 265 ArgumentsAccessStub::Type type; | 265 ArgumentsAccessStub::Type type; |
| 266 if (strict_mode() == STRICT) { | 266 if (is_strict(language_mode())) { |
| 267 type = ArgumentsAccessStub::NEW_STRICT; | 267 type = ArgumentsAccessStub::NEW_STRICT; |
| 268 } else if (function()->has_duplicate_parameters()) { | 268 } else if (function()->has_duplicate_parameters()) { |
| 269 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; | 269 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; |
| 270 } else { | 270 } else { |
| 271 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; | 271 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; |
| 272 } | 272 } |
| 273 ArgumentsAccessStub stub(isolate(), type); | 273 ArgumentsAccessStub stub(isolate(), type); |
| 274 __ CallStub(&stub); | 274 __ CallStub(&stub); |
| 275 | 275 |
| 276 SetVar(arguments, x0, x1, x2); | 276 SetVar(arguments, x0, x1, x2); |
| (...skipping 1004 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1281 // nested functions that don't need literals cloning. If we're running with | 1281 // nested functions that don't need literals cloning. If we're running with |
| 1282 // the --always-opt or the --prepare-always-opt flag, we need to use the | 1282 // the --always-opt or the --prepare-always-opt flag, we need to use the |
| 1283 // runtime function so that the new function we are creating here gets a | 1283 // runtime function so that the new function we are creating here gets a |
| 1284 // chance to have its code optimized and doesn't just get a copy of the | 1284 // chance to have its code optimized and doesn't just get a copy of the |
| 1285 // existing unoptimized code. | 1285 // existing unoptimized code. |
| 1286 if (!FLAG_always_opt && | 1286 if (!FLAG_always_opt && |
| 1287 !FLAG_prepare_always_opt && | 1287 !FLAG_prepare_always_opt && |
| 1288 !pretenure && | 1288 !pretenure && |
| 1289 scope()->is_function_scope() && | 1289 scope()->is_function_scope() && |
| 1290 info->num_literals() == 0) { | 1290 info->num_literals() == 0) { |
| 1291 FastNewClosureStub stub(isolate(), info->strict_mode(), info->kind()); | 1291 FastNewClosureStub stub(isolate(), info->language_mode(), info->kind()); |
| 1292 __ Mov(x2, Operand(info)); | 1292 __ Mov(x2, Operand(info)); |
| 1293 __ CallStub(&stub); | 1293 __ CallStub(&stub); |
| 1294 } else { | 1294 } else { |
| 1295 __ Mov(x11, Operand(info)); | 1295 __ Mov(x11, Operand(info)); |
| 1296 __ LoadRoot(x10, pretenure ? Heap::kTrueValueRootIndex | 1296 __ LoadRoot(x10, pretenure ? Heap::kTrueValueRootIndex |
| 1297 : Heap::kFalseValueRootIndex); | 1297 : Heap::kFalseValueRootIndex); |
| 1298 __ Push(cp, x11, x10); | 1298 __ Push(cp, x11, x10); |
| 1299 __ CallRuntime(Runtime::kNewClosure, 3); | 1299 __ CallRuntime(Runtime::kNewClosure, 3); |
| 1300 } | 1300 } |
| 1301 context()->Plug(x0); | 1301 context()->Plug(x0); |
| (...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1714 } | 1714 } |
| 1715 break; | 1715 break; |
| 1716 } | 1716 } |
| 1717 if (property->emit_store()) { | 1717 if (property->emit_store()) { |
| 1718 // Duplicate receiver on stack. | 1718 // Duplicate receiver on stack. |
| 1719 __ Peek(x0, 0); | 1719 __ Peek(x0, 0); |
| 1720 __ Push(x0); | 1720 __ Push(x0); |
| 1721 VisitForStackValue(key); | 1721 VisitForStackValue(key); |
| 1722 VisitForStackValue(value); | 1722 VisitForStackValue(value); |
| 1723 EmitSetHomeObjectIfNeeded(value, 2); | 1723 EmitSetHomeObjectIfNeeded(value, 2); |
| 1724 __ Mov(x0, Smi::FromInt(SLOPPY)); // Strict mode | 1724 __ Mov(x0, Smi::FromInt(SLOPPY)); // Language mode |
| 1725 __ Push(x0); | 1725 __ Push(x0); |
| 1726 __ CallRuntime(Runtime::kSetProperty, 4); | 1726 __ CallRuntime(Runtime::kSetProperty, 4); |
| 1727 } else { | 1727 } else { |
| 1728 VisitForEffect(key); | 1728 VisitForEffect(key); |
| 1729 VisitForEffect(value); | 1729 VisitForEffect(value); |
| 1730 } | 1730 } |
| 1731 break; | 1731 break; |
| 1732 case ObjectLiteral::Property::PROTOTYPE: | 1732 case ObjectLiteral::Property::PROTOTYPE: |
| 1733 DCHECK(property->emit_store()); | 1733 DCHECK(property->emit_store()); |
| 1734 // Duplicate receiver on stack. | 1734 // Duplicate receiver on stack. |
| (...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2342 break; | 2342 break; |
| 2343 } | 2343 } |
| 2344 case KEYED_PROPERTY: { | 2344 case KEYED_PROPERTY: { |
| 2345 __ Push(x0); // Preserve value. | 2345 __ Push(x0); // Preserve value. |
| 2346 VisitForStackValue(prop->obj()); | 2346 VisitForStackValue(prop->obj()); |
| 2347 VisitForAccumulatorValue(prop->key()); | 2347 VisitForAccumulatorValue(prop->key()); |
| 2348 __ Mov(StoreDescriptor::NameRegister(), x0); | 2348 __ Mov(StoreDescriptor::NameRegister(), x0); |
| 2349 __ Pop(StoreDescriptor::ReceiverRegister(), | 2349 __ Pop(StoreDescriptor::ReceiverRegister(), |
| 2350 StoreDescriptor::ValueRegister()); | 2350 StoreDescriptor::ValueRegister()); |
| 2351 Handle<Code> ic = | 2351 Handle<Code> ic = |
| 2352 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); | 2352 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2353 CallIC(ic); | 2353 CallIC(ic); |
| 2354 break; | 2354 break; |
| 2355 } | 2355 } |
| 2356 } | 2356 } |
| 2357 context()->Plug(x0); | 2357 context()->Plug(x0); |
| 2358 } | 2358 } |
| 2359 | 2359 |
| 2360 | 2360 |
| 2361 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 2361 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
| 2362 Variable* var, MemOperand location) { | 2362 Variable* var, MemOperand location) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2409 __ Push(x10); | 2409 __ Push(x10); |
| 2410 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 2410 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 2411 // Perform the assignment. | 2411 // Perform the assignment. |
| 2412 __ Bind(&assign); | 2412 __ Bind(&assign); |
| 2413 EmitStoreToStackLocalOrContextSlot(var, location); | 2413 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2414 | 2414 |
| 2415 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { | 2415 } else if (!var->is_const_mode() || op == Token::INIT_CONST) { |
| 2416 if (var->IsLookupSlot()) { | 2416 if (var->IsLookupSlot()) { |
| 2417 // Assignment to var. | 2417 // Assignment to var. |
| 2418 __ Mov(x11, Operand(var->name())); | 2418 __ Mov(x11, Operand(var->name())); |
| 2419 __ Mov(x10, Smi::FromInt(strict_mode())); | 2419 __ Mov(x10, Smi::FromInt(language_mode())); |
| 2420 // jssp[0] : mode. | 2420 // jssp[0] : mode. |
| 2421 // jssp[8] : name. | 2421 // jssp[8] : name. |
| 2422 // jssp[16] : context. | 2422 // jssp[16] : context. |
| 2423 // jssp[24] : value. | 2423 // jssp[24] : value. |
| 2424 __ Push(x0, cp, x11, x10); | 2424 __ Push(x0, cp, x11, x10); |
| 2425 __ CallRuntime(Runtime::kStoreLookupSlot, 4); | 2425 __ CallRuntime(Runtime::kStoreLookupSlot, 4); |
| 2426 } else { | 2426 } else { |
| 2427 // Assignment to var or initializing assignment to let/const in harmony | 2427 // Assignment to var or initializing assignment to let/const in harmony |
| 2428 // mode. | 2428 // mode. |
| 2429 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); | 2429 DCHECK(var->IsStackAllocated() || var->IsContextSlot()); |
| 2430 MemOperand location = VarOperand(var, x1); | 2430 MemOperand location = VarOperand(var, x1); |
| 2431 if (FLAG_debug_code && op == Token::INIT_LET) { | 2431 if (FLAG_debug_code && op == Token::INIT_LET) { |
| 2432 __ Ldr(x10, location); | 2432 __ Ldr(x10, location); |
| 2433 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex); | 2433 __ CompareRoot(x10, Heap::kTheHoleValueRootIndex); |
| 2434 __ Check(eq, kLetBindingReInitialization); | 2434 __ Check(eq, kLetBindingReInitialization); |
| 2435 } | 2435 } |
| 2436 EmitStoreToStackLocalOrContextSlot(var, location); | 2436 EmitStoreToStackLocalOrContextSlot(var, location); |
| 2437 } | 2437 } |
| 2438 } else if (IsSignallingAssignmentToConst(var, op, strict_mode())) { | 2438 } else if (IsSignallingAssignmentToConst(var, op, language_mode())) { |
| 2439 __ CallRuntime(Runtime::kThrowConstAssignError, 0); | 2439 __ CallRuntime(Runtime::kThrowConstAssignError, 0); |
| 2440 } | 2440 } |
| 2441 } | 2441 } |
| 2442 | 2442 |
| 2443 | 2443 |
| 2444 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2444 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
| 2445 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); | 2445 ASM_LOCATION("FullCodeGenerator::EmitNamedPropertyAssignment"); |
| 2446 // Assignment to a property, using a named store IC. | 2446 // Assignment to a property, using a named store IC. |
| 2447 Property* prop = expr->target()->AsProperty(); | 2447 Property* prop = expr->target()->AsProperty(); |
| 2448 DCHECK(prop != NULL); | 2448 DCHECK(prop != NULL); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2463 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | 2463 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { |
| 2464 // Assignment to named property of super. | 2464 // Assignment to named property of super. |
| 2465 // x0 : value | 2465 // x0 : value |
| 2466 // stack : receiver ('this'), home_object | 2466 // stack : receiver ('this'), home_object |
| 2467 DCHECK(prop != NULL); | 2467 DCHECK(prop != NULL); |
| 2468 Literal* key = prop->key()->AsLiteral(); | 2468 Literal* key = prop->key()->AsLiteral(); |
| 2469 DCHECK(key != NULL); | 2469 DCHECK(key != NULL); |
| 2470 | 2470 |
| 2471 __ Push(key->value()); | 2471 __ Push(key->value()); |
| 2472 __ Push(x0); | 2472 __ Push(x0); |
| 2473 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreToSuper_Strict | 2473 __ CallRuntime((is_strict(language_mode()) ? Runtime::kStoreToSuper_Strict |
| 2474 : Runtime::kStoreToSuper_Sloppy), | 2474 : Runtime::kStoreToSuper_Sloppy), |
| 2475 4); | 2475 4); |
| 2476 } | 2476 } |
| 2477 | 2477 |
| 2478 | 2478 |
| 2479 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { | 2479 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { |
| 2480 // Assignment to named property of super. | 2480 // Assignment to named property of super. |
| 2481 // x0 : value | 2481 // x0 : value |
| 2482 // stack : receiver ('this'), home_object, key | 2482 // stack : receiver ('this'), home_object, key |
| 2483 DCHECK(prop != NULL); | 2483 DCHECK(prop != NULL); |
| 2484 | 2484 |
| 2485 __ Push(x0); | 2485 __ Push(x0); |
| 2486 __ CallRuntime((strict_mode() == STRICT ? Runtime::kStoreKeyedToSuper_Strict | 2486 __ CallRuntime( |
| 2487 : Runtime::kStoreKeyedToSuper_Sloppy), | 2487 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
| 2488 4); | 2488 : Runtime::kStoreKeyedToSuper_Sloppy), |
| 2489 4); |
| 2489 } | 2490 } |
| 2490 | 2491 |
| 2491 | 2492 |
| 2492 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2493 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2493 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); | 2494 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); |
| 2494 // Assignment to a property, using a keyed store IC. | 2495 // Assignment to a property, using a keyed store IC. |
| 2495 | 2496 |
| 2496 // Record source code position before IC call. | 2497 // Record source code position before IC call. |
| 2497 SetSourcePosition(expr->position()); | 2498 SetSourcePosition(expr->position()); |
| 2498 // TODO(all): Could we pass this in registers rather than on the stack? | 2499 // TODO(all): Could we pass this in registers rather than on the stack? |
| 2499 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); | 2500 __ Pop(StoreDescriptor::NameRegister(), StoreDescriptor::ReceiverRegister()); |
| 2500 DCHECK(StoreDescriptor::ValueRegister().is(x0)); | 2501 DCHECK(StoreDescriptor::ValueRegister().is(x0)); |
| 2501 | 2502 |
| 2502 Handle<Code> ic = CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); | 2503 Handle<Code> ic = |
| 2504 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2503 CallIC(ic, expr->AssignmentFeedbackId()); | 2505 CallIC(ic, expr->AssignmentFeedbackId()); |
| 2504 | 2506 |
| 2505 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2507 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2506 context()->Plug(x0); | 2508 context()->Plug(x0); |
| 2507 } | 2509 } |
| 2508 | 2510 |
| 2509 | 2511 |
| 2510 void FullCodeGenerator::VisitProperty(Property* expr) { | 2512 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2511 Comment cmnt(masm_, "[ Property"); | 2513 Comment cmnt(masm_, "[ Property"); |
| 2512 Expression* key = expr->key(); | 2514 Expression* key = expr->key(); |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2717 } else { | 2719 } else { |
| 2718 __ LoadRoot(x9, Heap::kUndefinedValueRootIndex); | 2720 __ LoadRoot(x9, Heap::kUndefinedValueRootIndex); |
| 2719 } | 2721 } |
| 2720 | 2722 |
| 2721 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 2723 __ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
| 2722 // Prepare to push the receiver of the enclosing function. | 2724 // Prepare to push the receiver of the enclosing function. |
| 2723 int receiver_offset = 2 + info_->scope()->num_parameters(); | 2725 int receiver_offset = 2 + info_->scope()->num_parameters(); |
| 2724 __ Ldr(x11, MemOperand(fp, receiver_offset * kPointerSize)); | 2726 __ Ldr(x11, MemOperand(fp, receiver_offset * kPointerSize)); |
| 2725 | 2727 |
| 2726 // Prepare to push the language mode. | 2728 // Prepare to push the language mode. |
| 2727 __ Mov(x12, Smi::FromInt(strict_mode())); | 2729 __ Mov(x12, Smi::FromInt(language_mode())); |
| 2728 // Prepare to push the start position of the scope the calls resides in. | 2730 // Prepare to push the start position of the scope the calls resides in. |
| 2729 __ Mov(x13, Smi::FromInt(scope()->start_position())); | 2731 __ Mov(x13, Smi::FromInt(scope()->start_position())); |
| 2730 | 2732 |
| 2731 // Push. | 2733 // Push. |
| 2732 __ Push(x9, x10, x11, x12, x13); | 2734 __ Push(x9, x10, x11, x12, x13); |
| 2733 | 2735 |
| 2734 // Do the runtime call. | 2736 // Do the runtime call. |
| 2735 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); | 2737 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
| 2736 } | 2738 } |
| 2737 | 2739 |
| (...skipping 1513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4251 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 4253 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
| 4252 switch (expr->op()) { | 4254 switch (expr->op()) { |
| 4253 case Token::DELETE: { | 4255 case Token::DELETE: { |
| 4254 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 4256 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
| 4255 Property* property = expr->expression()->AsProperty(); | 4257 Property* property = expr->expression()->AsProperty(); |
| 4256 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 4258 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 4257 | 4259 |
| 4258 if (property != NULL) { | 4260 if (property != NULL) { |
| 4259 VisitForStackValue(property->obj()); | 4261 VisitForStackValue(property->obj()); |
| 4260 VisitForStackValue(property->key()); | 4262 VisitForStackValue(property->key()); |
| 4261 __ Mov(x10, Smi::FromInt(strict_mode())); | 4263 __ Mov(x10, Smi::FromInt(language_mode())); |
| 4262 __ Push(x10); | 4264 __ Push(x10); |
| 4263 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4265 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
| 4264 context()->Plug(x0); | 4266 context()->Plug(x0); |
| 4265 } else if (proxy != NULL) { | 4267 } else if (proxy != NULL) { |
| 4266 Variable* var = proxy->var(); | 4268 Variable* var = proxy->var(); |
| 4267 // Delete of an unqualified identifier is disallowed in strict mode | 4269 // Delete of an unqualified identifier is disallowed in strict mode |
| 4268 // but "delete this" is allowed. | 4270 // but "delete this" is allowed. |
| 4269 DCHECK(strict_mode() == SLOPPY || var->is_this()); | 4271 DCHECK(is_sloppy(language_mode()) || var->is_this()); |
| 4270 if (var->IsUnallocated()) { | 4272 if (var->IsUnallocated()) { |
| 4271 __ Ldr(x12, GlobalObjectMemOperand()); | 4273 __ Ldr(x12, GlobalObjectMemOperand()); |
| 4272 __ Mov(x11, Operand(var->name())); | 4274 __ Mov(x11, Operand(var->name())); |
| 4273 __ Mov(x10, Smi::FromInt(SLOPPY)); | 4275 __ Mov(x10, Smi::FromInt(SLOPPY)); |
| 4274 __ Push(x12, x11, x10); | 4276 __ Push(x12, x11, x10); |
| 4275 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4277 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
| 4276 context()->Plug(x0); | 4278 context()->Plug(x0); |
| 4277 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4279 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
| 4278 // Result of deleting non-global, non-dynamic variables is false. | 4280 // Result of deleting non-global, non-dynamic variables is false. |
| 4279 // The subexpression does not have side effects. | 4281 // The subexpression does not have side effects. |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4578 } | 4580 } |
| 4579 } else { | 4581 } else { |
| 4580 context()->Plug(x0); | 4582 context()->Plug(x0); |
| 4581 } | 4583 } |
| 4582 break; | 4584 break; |
| 4583 } | 4585 } |
| 4584 case KEYED_PROPERTY: { | 4586 case KEYED_PROPERTY: { |
| 4585 __ Pop(StoreDescriptor::NameRegister()); | 4587 __ Pop(StoreDescriptor::NameRegister()); |
| 4586 __ Pop(StoreDescriptor::ReceiverRegister()); | 4588 __ Pop(StoreDescriptor::ReceiverRegister()); |
| 4587 Handle<Code> ic = | 4589 Handle<Code> ic = |
| 4588 CodeFactory::KeyedStoreIC(isolate(), strict_mode()).code(); | 4590 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 4589 CallIC(ic, expr->CountStoreFeedbackId()); | 4591 CallIC(ic, expr->CountStoreFeedbackId()); |
| 4590 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4592 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 4591 if (expr->is_postfix()) { | 4593 if (expr->is_postfix()) { |
| 4592 if (!context()->IsEffect()) { | 4594 if (!context()->IsEffect()) { |
| 4593 context()->PlugTOS(); | 4595 context()->PlugTOS(); |
| 4594 } | 4596 } |
| 4595 } else { | 4597 } else { |
| 4596 context()->Plug(x0); | 4598 context()->Plug(x0); |
| 4597 } | 4599 } |
| 4598 break; | 4600 break; |
| (...skipping 799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5398 return previous_; | 5400 return previous_; |
| 5399 } | 5401 } |
| 5400 | 5402 |
| 5401 | 5403 |
| 5402 #undef __ | 5404 #undef __ |
| 5403 | 5405 |
| 5404 | 5406 |
| 5405 } } // namespace v8::internal | 5407 } } // namespace v8::internal |
| 5406 | 5408 |
| 5407 #endif // V8_TARGET_ARCH_ARM64 | 5409 #endif // V8_TARGET_ARCH_ARM64 |
| OLD | NEW |