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

Side by Side Diff: src/arm/full-codegen-arm.cc

Issue 181543002: Eliminate extended mode, and other modes clean-up (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 #ifdef DEBUG 143 #ifdef DEBUG
144 if (strlen(FLAG_stop_at) > 0 && 144 if (strlen(FLAG_stop_at) > 0 &&
145 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 145 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
146 __ stop("stop-at"); 146 __ stop("stop-at");
147 } 147 }
148 #endif 148 #endif
149 149
150 // Sloppy mode functions and builtins need to replace the receiver with the 150 // Sloppy mode functions and builtins need to replace the receiver with the
151 // global proxy when called as functions (without an explicit receiver 151 // global proxy when called as functions (without an explicit receiver
152 // object). 152 // object).
153 if (info->is_sloppy_mode() && !info->is_native()) { 153 if (info->strict_mode() == SLOPPY && !info->is_native()) {
154 Label ok; 154 Label ok;
155 int receiver_offset = info->scope()->num_parameters() * kPointerSize; 155 int receiver_offset = info->scope()->num_parameters() * kPointerSize;
156 __ ldr(r2, MemOperand(sp, receiver_offset)); 156 __ ldr(r2, MemOperand(sp, receiver_offset));
157 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex); 157 __ CompareRoot(r2, Heap::kUndefinedValueRootIndex);
158 __ b(ne, &ok); 158 __ b(ne, &ok);
159 159
160 __ ldr(r2, GlobalObjectOperand()); 160 __ ldr(r2, GlobalObjectOperand());
161 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); 161 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset));
162 162
163 __ str(r2, MemOperand(sp, receiver_offset)); 163 __ str(r2, MemOperand(sp, receiver_offset));
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 __ add(r2, fp, 257 __ add(r2, fp,
258 Operand(StandardFrameConstants::kCallerSPOffset + offset)); 258 Operand(StandardFrameConstants::kCallerSPOffset + offset));
259 __ mov(r1, Operand(Smi::FromInt(num_parameters))); 259 __ mov(r1, Operand(Smi::FromInt(num_parameters)));
260 __ Push(r3, r2, r1); 260 __ Push(r3, r2, r1);
261 261
262 // Arguments to ArgumentsAccessStub: 262 // Arguments to ArgumentsAccessStub:
263 // function, receiver address, parameter count. 263 // function, receiver address, parameter count.
264 // The stub will rewrite receiever and parameter count if the previous 264 // The stub will rewrite receiever and parameter count if the previous
265 // stack frame was an arguments adapter frame. 265 // stack frame was an arguments adapter frame.
266 ArgumentsAccessStub::Type type; 266 ArgumentsAccessStub::Type type;
267 if (!is_sloppy_mode()) { 267 if (strict_mode() == STRICT) {
268 type = ArgumentsAccessStub::NEW_STRICT; 268 type = ArgumentsAccessStub::NEW_STRICT;
269 } else if (function()->has_duplicate_parameters()) { 269 } else if (function()->has_duplicate_parameters()) {
270 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; 270 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
271 } else { 271 } else {
272 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; 272 type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
273 } 273 }
274 ArgumentsAccessStub stub(type); 274 ArgumentsAccessStub stub(type);
275 __ CallStub(&stub); 275 __ CallStub(&stub);
276 276
277 SetVar(arguments, r0, r1, r2); 277 SetVar(arguments, r0, r1, r2);
(...skipping 10 matching lines...) Expand all
288 scope()->VisitIllegalRedeclaration(this); 288 scope()->VisitIllegalRedeclaration(this);
289 289
290 } else { 290 } else {
291 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 291 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
292 { Comment cmnt(masm_, "[ Declarations"); 292 { Comment cmnt(masm_, "[ Declarations");
293 // For named function expressions, declare the function name as a 293 // For named function expressions, declare the function name as a
294 // constant. 294 // constant.
295 if (scope()->is_function_scope() && scope()->function() != NULL) { 295 if (scope()->is_function_scope() && scope()->function() != NULL) {
296 VariableDeclaration* function = scope()->function(); 296 VariableDeclaration* function = scope()->function();
297 ASSERT(function->proxy()->var()->mode() == CONST || 297 ASSERT(function->proxy()->var()->mode() == CONST ||
298 function->proxy()->var()->mode() == CONST_HARMONY); 298 function->proxy()->var()->mode() == CONST_LEGACY);
299 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); 299 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED);
300 VisitVariableDeclaration(function); 300 VisitVariableDeclaration(function);
301 } 301 }
302 VisitDeclarations(scope()->declarations()); 302 VisitDeclarations(scope()->declarations());
303 } 303 }
304 304
305 { Comment cmnt(masm_, "[ Stack check"); 305 { Comment cmnt(masm_, "[ Stack check");
306 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); 306 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
307 Label ok; 307 Label ok;
308 __ LoadRoot(ip, Heap::kStackLimitRootIndex); 308 __ LoadRoot(ip, Heap::kStackLimitRootIndex);
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 785
786 786
787 void FullCodeGenerator::VisitVariableDeclaration( 787 void FullCodeGenerator::VisitVariableDeclaration(
788 VariableDeclaration* declaration) { 788 VariableDeclaration* declaration) {
789 // If it was not possible to allocate the variable at compile time, we 789 // If it was not possible to allocate the variable at compile time, we
790 // need to "declare" it at runtime to make sure it actually exists in the 790 // need to "declare" it at runtime to make sure it actually exists in the
791 // local context. 791 // local context.
792 VariableProxy* proxy = declaration->proxy(); 792 VariableProxy* proxy = declaration->proxy();
793 VariableMode mode = declaration->mode(); 793 VariableMode mode = declaration->mode();
794 Variable* variable = proxy->var(); 794 Variable* variable = proxy->var();
795 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; 795 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
796 switch (variable->location()) { 796 switch (variable->location()) {
797 case Variable::UNALLOCATED: 797 case Variable::UNALLOCATED:
798 globals_->Add(variable->name(), zone()); 798 globals_->Add(variable->name(), zone());
799 globals_->Add(variable->binding_needs_init() 799 globals_->Add(variable->binding_needs_init()
800 ? isolate()->factory()->the_hole_value() 800 ? isolate()->factory()->the_hole_value()
801 : isolate()->factory()->undefined_value(), 801 : isolate()->factory()->undefined_value(),
802 zone()); 802 zone());
803 break; 803 break;
804 804
805 case Variable::PARAMETER: 805 case Variable::PARAMETER:
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 // space for nested functions that don't need literals cloning. If 1324 // space for nested functions that don't need literals cloning. If
1325 // we're running with the --always-opt or the --prepare-always-opt 1325 // we're running with the --always-opt or the --prepare-always-opt
1326 // flag, we need to use the runtime function so that the new function 1326 // flag, we need to use the runtime function so that the new function
1327 // we are creating here gets a chance to have its code optimized and 1327 // we are creating here gets a chance to have its code optimized and
1328 // doesn't just get a copy of the existing unoptimized code. 1328 // doesn't just get a copy of the existing unoptimized code.
1329 if (!FLAG_always_opt && 1329 if (!FLAG_always_opt &&
1330 !FLAG_prepare_always_opt && 1330 !FLAG_prepare_always_opt &&
1331 !pretenure && 1331 !pretenure &&
1332 scope()->is_function_scope() && 1332 scope()->is_function_scope() &&
1333 info->num_literals() == 0) { 1333 info->num_literals() == 0) {
1334 FastNewClosureStub stub(info->language_mode(), info->is_generator()); 1334 FastNewClosureStub stub(info->strict_mode(), info->is_generator());
1335 __ mov(r2, Operand(info)); 1335 __ mov(r2, Operand(info));
1336 __ CallStub(&stub); 1336 __ CallStub(&stub);
1337 } else { 1337 } else {
1338 __ mov(r0, Operand(info)); 1338 __ mov(r0, Operand(info));
1339 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex 1339 __ LoadRoot(r1, pretenure ? Heap::kTrueValueRootIndex
1340 : Heap::kFalseValueRootIndex); 1340 : Heap::kFalseValueRootIndex);
1341 __ Push(cp, r0, r1); 1341 __ Push(cp, r0, r1);
1342 __ CallRuntime(Runtime::kNewClosure, 3); 1342 __ CallRuntime(Runtime::kNewClosure, 3);
1343 } 1343 }
1344 context()->Plug(r0); 1344 context()->Plug(r0);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1448 // eval-introduced variables. Eval is used a lot without 1448 // eval-introduced variables. Eval is used a lot without
1449 // introducing variables. In those cases, we do not want to 1449 // introducing variables. In those cases, we do not want to
1450 // perform a runtime call for all variables in the scope 1450 // perform a runtime call for all variables in the scope
1451 // containing the eval. 1451 // containing the eval.
1452 if (var->mode() == DYNAMIC_GLOBAL) { 1452 if (var->mode() == DYNAMIC_GLOBAL) {
1453 EmitLoadGlobalCheckExtensions(var, typeof_state, slow); 1453 EmitLoadGlobalCheckExtensions(var, typeof_state, slow);
1454 __ jmp(done); 1454 __ jmp(done);
1455 } else if (var->mode() == DYNAMIC_LOCAL) { 1455 } else if (var->mode() == DYNAMIC_LOCAL) {
1456 Variable* local = var->local_if_not_shadowed(); 1456 Variable* local = var->local_if_not_shadowed();
1457 __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow)); 1457 __ ldr(r0, ContextSlotOperandCheckExtensions(local, slow));
1458 if (local->mode() == LET || 1458 if (local->mode() == LET || local->mode() == CONST ||
1459 local->mode() == CONST || 1459 local->mode() == CONST_LEGACY) {
1460 local->mode() == CONST_HARMONY) {
1461 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); 1460 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex);
1462 if (local->mode() == CONST) { 1461 if (local->mode() == CONST_LEGACY) {
1463 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); 1462 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
1464 } else { // LET || CONST_HARMONY 1463 } else { // LET || CONST
1465 __ b(ne, done); 1464 __ b(ne, done);
1466 __ mov(r0, Operand(var->name())); 1465 __ mov(r0, Operand(var->name()));
1467 __ push(r0); 1466 __ push(r0);
1468 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1467 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1469 } 1468 }
1470 } 1469 }
1471 __ jmp(done); 1470 __ jmp(done);
1472 } 1471 }
1473 } 1472 }
1474 1473
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1521 // binding is initialized: 1520 // binding is initialized:
1522 // function() { f(); let x = 1; function f() { x = 2; } } 1521 // function() { f(); let x = 1; function f() { x = 2; } }
1523 // 1522 //
1524 bool skip_init_check; 1523 bool skip_init_check;
1525 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) { 1524 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) {
1526 skip_init_check = false; 1525 skip_init_check = false;
1527 } else { 1526 } else {
1528 // Check that we always have valid source position. 1527 // Check that we always have valid source position.
1529 ASSERT(var->initializer_position() != RelocInfo::kNoPosition); 1528 ASSERT(var->initializer_position() != RelocInfo::kNoPosition);
1530 ASSERT(proxy->position() != RelocInfo::kNoPosition); 1529 ASSERT(proxy->position() != RelocInfo::kNoPosition);
1531 skip_init_check = var->mode() != CONST && 1530 skip_init_check = var->mode() != CONST_LEGACY &&
1532 var->initializer_position() < proxy->position(); 1531 var->initializer_position() < proxy->position();
1533 } 1532 }
1534 1533
1535 if (!skip_init_check) { 1534 if (!skip_init_check) {
1536 // Let and const need a read barrier. 1535 // Let and const need a read barrier.
1537 GetVar(r0, var); 1536 GetVar(r0, var);
1538 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex); 1537 __ CompareRoot(r0, Heap::kTheHoleValueRootIndex);
1539 if (var->mode() == LET || var->mode() == CONST_HARMONY) { 1538 if (var->mode() == LET || var->mode() == CONST) {
1540 // Throw a reference error when using an uninitialized let/const 1539 // Throw a reference error when using an uninitialized let/const
1541 // binding in harmony mode. 1540 // binding in harmony mode.
1542 Label done; 1541 Label done;
1543 __ b(ne, &done); 1542 __ b(ne, &done);
1544 __ mov(r0, Operand(var->name())); 1543 __ mov(r0, Operand(var->name()));
1545 __ push(r0); 1544 __ push(r0);
1546 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1545 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1547 __ bind(&done); 1546 __ bind(&done);
1548 } else { 1547 } else {
1549 // Uninitalized const bindings outside of harmony mode are unholed. 1548 // Uninitalized const bindings outside of harmony mode are unholed.
1550 ASSERT(var->mode() == CONST); 1549 ASSERT(var->mode() == CONST_LEGACY);
1551 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq); 1550 __ LoadRoot(r0, Heap::kUndefinedValueRootIndex, eq);
1552 } 1551 }
1553 context()->Plug(r0); 1552 context()->Plug(r0);
1554 break; 1553 break;
1555 } 1554 }
1556 } 1555 }
1557 context()->Plug(var); 1556 context()->Plug(var);
1558 break; 1557 break;
1559 } 1558 }
1560 1559
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after
2438 __ mov(r2, Operand(prop->key()->AsLiteral()->value())); 2437 __ mov(r2, Operand(prop->key()->AsLiteral()->value()));
2439 CallStoreIC(); 2438 CallStoreIC();
2440 break; 2439 break;
2441 } 2440 }
2442 case KEYED_PROPERTY: { 2441 case KEYED_PROPERTY: {
2443 __ push(r0); // Preserve value. 2442 __ push(r0); // Preserve value.
2444 VisitForStackValue(prop->obj()); 2443 VisitForStackValue(prop->obj());
2445 VisitForAccumulatorValue(prop->key()); 2444 VisitForAccumulatorValue(prop->key());
2446 __ mov(r1, r0); 2445 __ mov(r1, r0);
2447 __ Pop(r0, r2); // r0 = restored value. 2446 __ Pop(r0, r2); // r0 = restored value.
2448 Handle<Code> ic = is_sloppy_mode() 2447 Handle<Code> ic = strict_mode() == SLOPPY
2449 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2448 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2450 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2449 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2451 CallIC(ic); 2450 CallIC(ic);
2452 break; 2451 break;
2453 } 2452 }
2454 } 2453 }
2455 context()->Plug(r0); 2454 context()->Plug(r0);
2456 } 2455 }
2457 2456
2458 2457
2459 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2458 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2460 Variable* var, MemOperand location) { 2459 Variable* var, MemOperand location) {
2461 __ str(result_register(), location); 2460 __ str(result_register(), location);
2462 if (var->IsContextSlot()) { 2461 if (var->IsContextSlot()) {
2463 // RecordWrite may destroy all its register arguments. 2462 // RecordWrite may destroy all its register arguments.
2464 __ mov(r3, result_register()); 2463 __ mov(r3, result_register());
2465 int offset = Context::SlotOffset(var->index()); 2464 int offset = Context::SlotOffset(var->index());
2466 __ RecordWriteContextSlot( 2465 __ RecordWriteContextSlot(
2467 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs); 2466 r1, offset, r3, r2, kLRHasBeenSaved, kDontSaveFPRegs);
2468 } 2467 }
2469 } 2468 }
2470 2469
2471 2470
2472 void FullCodeGenerator::EmitCallStoreContextSlot( 2471 void FullCodeGenerator::EmitCallStoreContextSlot(
2473 Handle<String> name, LanguageMode mode) { 2472 Handle<String> name, StrictMode strict_mode) {
2474 __ push(r0); // Value. 2473 __ push(r0); // Value.
2475 __ mov(r1, Operand(name)); 2474 __ mov(r1, Operand(name));
2476 __ mov(r0, Operand(Smi::FromInt(mode))); 2475 __ mov(r0, Operand(Smi::FromInt(strict_mode)));
2477 __ Push(cp, r1, r0); // Context, name, strict mode. 2476 __ Push(cp, r1, r0); // Context, name, strict mode.
2478 __ CallRuntime(Runtime::kStoreContextSlot, 4); 2477 __ CallRuntime(Runtime::kStoreContextSlot, 4);
2479 } 2478 }
2480 2479
2481 2480
2482 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2481 void FullCodeGenerator::EmitVariableAssignment(Variable* var, Token::Value op) {
2483 Token::Value op) {
2484 if (var->IsUnallocated()) { 2482 if (var->IsUnallocated()) {
2485 // Global var, const, or let. 2483 // Global var, const, or let.
2486 __ mov(r2, Operand(var->name())); 2484 __ mov(r2, Operand(var->name()));
2487 __ ldr(r1, GlobalObjectOperand()); 2485 __ ldr(r1, GlobalObjectOperand());
2488 CallStoreIC(); 2486 CallStoreIC();
2489 2487
2490 } else if (op == Token::INIT_CONST) { 2488 } else if (op == Token::INIT_CONST_LEGACY) {
2491 // Const initializers need a write barrier. 2489 // Const initializers need a write barrier.
2492 ASSERT(!var->IsParameter()); // No const parameters. 2490 ASSERT(!var->IsParameter()); // No const parameters.
2493 if (var->IsLookupSlot()) { 2491 if (var->IsLookupSlot()) {
2494 __ push(r0); 2492 __ push(r0);
2495 __ mov(r0, Operand(var->name())); 2493 __ mov(r0, Operand(var->name()));
2496 __ Push(cp, r0); // Context and name. 2494 __ Push(cp, r0); // Context and name.
2497 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 2495 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
2498 } else { 2496 } else {
2499 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2497 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2500 Label skip; 2498 Label skip;
2501 MemOperand location = VarOperand(var, r1); 2499 MemOperand location = VarOperand(var, r1);
2502 __ ldr(r2, location); 2500 __ ldr(r2, location);
2503 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); 2501 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex);
2504 __ b(ne, &skip); 2502 __ b(ne, &skip);
2505 EmitStoreToStackLocalOrContextSlot(var, location); 2503 EmitStoreToStackLocalOrContextSlot(var, location);
2506 __ bind(&skip); 2504 __ bind(&skip);
2507 } 2505 }
2508 2506
2509 } else if (var->mode() == LET && op != Token::INIT_LET) { 2507 } else if (var->mode() == LET && op != Token::INIT_LET) {
2510 // Non-initializing assignment to let variable needs a write barrier. 2508 // Non-initializing assignment to let variable needs a write barrier.
2511 if (var->IsLookupSlot()) { 2509 if (var->IsLookupSlot()) {
2512 EmitCallStoreContextSlot(var->name(), language_mode()); 2510 EmitCallStoreContextSlot(var->name(), strict_mode());
2513 } else { 2511 } else {
2514 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2512 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2515 Label assign; 2513 Label assign;
2516 MemOperand location = VarOperand(var, r1); 2514 MemOperand location = VarOperand(var, r1);
2517 __ ldr(r3, location); 2515 __ ldr(r3, location);
2518 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex); 2516 __ CompareRoot(r3, Heap::kTheHoleValueRootIndex);
2519 __ b(ne, &assign); 2517 __ b(ne, &assign);
2520 __ mov(r3, Operand(var->name())); 2518 __ mov(r3, Operand(var->name()));
2521 __ push(r3); 2519 __ push(r3);
2522 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2520 __ CallRuntime(Runtime::kThrowReferenceError, 1);
2523 // Perform the assignment. 2521 // Perform the assignment.
2524 __ bind(&assign); 2522 __ bind(&assign);
2525 EmitStoreToStackLocalOrContextSlot(var, location); 2523 EmitStoreToStackLocalOrContextSlot(var, location);
2526 } 2524 }
2527 2525
2528 } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) { 2526 } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
2529 // Assignment to var or initializing assignment to let/const 2527 // Assignment to var or initializing assignment to let/const
2530 // in harmony mode. 2528 // in harmony mode.
2531 if (var->IsLookupSlot()) { 2529 if (var->IsLookupSlot()) {
2532 EmitCallStoreContextSlot(var->name(), language_mode()); 2530 EmitCallStoreContextSlot(var->name(), strict_mode());
2533 } else { 2531 } else {
2534 ASSERT((var->IsStackAllocated() || var->IsContextSlot())); 2532 ASSERT((var->IsStackAllocated() || var->IsContextSlot()));
2535 MemOperand location = VarOperand(var, r1); 2533 MemOperand location = VarOperand(var, r1);
2536 if (generate_debug_code_ && op == Token::INIT_LET) { 2534 if (generate_debug_code_ && op == Token::INIT_LET) {
2537 // Check for an uninitialized let binding. 2535 // Check for an uninitialized let binding.
2538 __ ldr(r2, location); 2536 __ ldr(r2, location);
2539 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex); 2537 __ CompareRoot(r2, Heap::kTheHoleValueRootIndex);
2540 __ Check(eq, kLetBindingReInitialization); 2538 __ Check(eq, kLetBindingReInitialization);
2541 } 2539 }
2542 EmitStoreToStackLocalOrContextSlot(var, location); 2540 EmitStoreToStackLocalOrContextSlot(var, location);
(...skipping 21 matching lines...) Expand all
2564 } 2562 }
2565 2563
2566 2564
2567 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2565 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2568 // Assignment to a property, using a keyed store IC. 2566 // Assignment to a property, using a keyed store IC.
2569 2567
2570 // Record source code position before IC call. 2568 // Record source code position before IC call.
2571 SetSourcePosition(expr->position()); 2569 SetSourcePosition(expr->position());
2572 __ Pop(r2, r1); // r1 = key. 2570 __ Pop(r2, r1); // r1 = key.
2573 2571
2574 Handle<Code> ic = is_sloppy_mode() 2572 Handle<Code> ic = strict_mode() == SLOPPY
2575 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2573 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2576 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2574 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2577 CallIC(ic, expr->AssignmentFeedbackId()); 2575 CallIC(ic, expr->AssignmentFeedbackId());
2578 2576
2579 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2577 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2580 context()->Plug(r0); 2578 context()->Plug(r0);
2581 } 2579 }
2582 2580
2583 2581
2584 void FullCodeGenerator::VisitProperty(Property* expr) { 2582 void FullCodeGenerator::VisitProperty(Property* expr) {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
2737 if (arg_count > 0) { 2735 if (arg_count > 0) {
2738 __ ldr(r4, MemOperand(sp, arg_count * kPointerSize)); 2736 __ ldr(r4, MemOperand(sp, arg_count * kPointerSize));
2739 } else { 2737 } else {
2740 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex); 2738 __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
2741 } 2739 }
2742 2740
2743 // r3: the receiver of the enclosing function. 2741 // r3: the receiver of the enclosing function.
2744 int receiver_offset = 2 + info_->scope()->num_parameters(); 2742 int receiver_offset = 2 + info_->scope()->num_parameters();
2745 __ ldr(r3, MemOperand(fp, receiver_offset * kPointerSize)); 2743 __ ldr(r3, MemOperand(fp, receiver_offset * kPointerSize));
2746 2744
2747 // r2: the language mode. 2745 // r2: strict mode.
2748 __ mov(r2, Operand(Smi::FromInt(language_mode()))); 2746 __ mov(r2, Operand(Smi::FromInt(strict_mode())));
2749 2747
2750 // r1: the start position of the scope the calls resides in. 2748 // r1: the start position of the scope the calls resides in.
2751 __ mov(r1, Operand(Smi::FromInt(scope()->start_position()))); 2749 __ mov(r1, Operand(Smi::FromInt(scope()->start_position())));
2752 2750
2753 // Do the runtime call. 2751 // Do the runtime call.
2754 __ Push(r4, r3, r2, r1); 2752 __ Push(r4, r3, r2, r1);
2755 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2753 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2756 } 2754 }
2757 2755
2758 2756
(...skipping 1419 matching lines...) Expand 10 before | Expand all | Expand 10 after
4178 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 4176 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
4179 switch (expr->op()) { 4177 switch (expr->op()) {
4180 case Token::DELETE: { 4178 case Token::DELETE: {
4181 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 4179 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
4182 Property* property = expr->expression()->AsProperty(); 4180 Property* property = expr->expression()->AsProperty();
4183 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 4181 VariableProxy* proxy = expr->expression()->AsVariableProxy();
4184 4182
4185 if (property != NULL) { 4183 if (property != NULL) {
4186 VisitForStackValue(property->obj()); 4184 VisitForStackValue(property->obj());
4187 VisitForStackValue(property->key()); 4185 VisitForStackValue(property->key());
4188 StrictModeFlag strict_mode_flag = (language_mode() == SLOPPY_MODE) 4186 __ mov(r1, Operand(Smi::FromInt(strict_mode())));
4189 ? kSloppyMode : kStrictMode;
4190 __ mov(r1, Operand(Smi::FromInt(strict_mode_flag)));
4191 __ push(r1); 4187 __ push(r1);
4192 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4188 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4193 context()->Plug(r0); 4189 context()->Plug(r0);
4194 } else if (proxy != NULL) { 4190 } else if (proxy != NULL) {
4195 Variable* var = proxy->var(); 4191 Variable* var = proxy->var();
4196 // Delete of an unqualified identifier is disallowed in strict mode 4192 // Delete of an unqualified identifier is disallowed in strict mode
4197 // but "delete this" is allowed. 4193 // but "delete this" is allowed.
4198 ASSERT(language_mode() == SLOPPY_MODE || var->is_this()); 4194 ASSERT(strict_mode() == SLOPPY || var->is_this());
4199 if (var->IsUnallocated()) { 4195 if (var->IsUnallocated()) {
4200 __ ldr(r2, GlobalObjectOperand()); 4196 __ ldr(r2, GlobalObjectOperand());
4201 __ mov(r1, Operand(var->name())); 4197 __ mov(r1, Operand(var->name()));
4202 __ mov(r0, Operand(Smi::FromInt(kSloppyMode))); 4198 __ mov(r0, Operand(Smi::FromInt(SLOPPY)));
4203 __ Push(r2, r1, r0); 4199 __ Push(r2, r1, r0);
4204 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4200 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4205 context()->Plug(r0); 4201 context()->Plug(r0);
4206 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4202 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4207 // Result of deleting non-global, non-dynamic variables is false. 4203 // Result of deleting non-global, non-dynamic variables is false.
4208 // The subexpression does not have side effects. 4204 // The subexpression does not have side effects.
4209 context()->Plug(var->is_this()); 4205 context()->Plug(var->is_this());
4210 } else { 4206 } else {
4211 // Non-global variable. Call the runtime to try to delete from the 4207 // Non-global variable. Call the runtime to try to delete from the
4212 // context where the variable was introduced. 4208 // context where the variable was introduced.
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
4446 if (!context()->IsEffect()) { 4442 if (!context()->IsEffect()) {
4447 context()->PlugTOS(); 4443 context()->PlugTOS();
4448 } 4444 }
4449 } else { 4445 } else {
4450 context()->Plug(r0); 4446 context()->Plug(r0);
4451 } 4447 }
4452 break; 4448 break;
4453 } 4449 }
4454 case KEYED_PROPERTY: { 4450 case KEYED_PROPERTY: {
4455 __ Pop(r2, r1); // r1 = key. r2 = receiver. 4451 __ Pop(r2, r1); // r1 = key. r2 = receiver.
4456 Handle<Code> ic = is_sloppy_mode() 4452 Handle<Code> ic = strict_mode() == SLOPPY
4457 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4453 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4458 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4454 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4459 CallIC(ic, expr->CountStoreFeedbackId()); 4455 CallIC(ic, expr->CountStoreFeedbackId());
4460 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4456 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4461 if (expr->is_postfix()) { 4457 if (expr->is_postfix()) {
4462 if (!context()->IsEffect()) { 4458 if (!context()->IsEffect()) {
4463 context()->PlugTOS(); 4459 context()->PlugTOS();
4464 } 4460 }
4465 } else { 4461 } else {
4466 context()->Plug(r0); 4462 context()->Plug(r0);
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
4918 ASSERT(Memory::uint32_at(interrupt_address_pointer) == 4914 ASSERT(Memory::uint32_at(interrupt_address_pointer) ==
4919 reinterpret_cast<uint32_t>( 4915 reinterpret_cast<uint32_t>(
4920 isolate->builtins()->OsrAfterStackCheck()->entry())); 4916 isolate->builtins()->OsrAfterStackCheck()->entry()));
4921 return OSR_AFTER_STACK_CHECK; 4917 return OSR_AFTER_STACK_CHECK;
4922 } 4918 }
4923 4919
4924 4920
4925 } } // namespace v8::internal 4921 } } // namespace v8::internal
4926 4922
4927 #endif // V8_TARGET_ARCH_ARM 4923 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/arm/ic-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698