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

Side by Side Diff: src/ia32/full-codegen-ia32.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, 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/ic-ia32.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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 #ifdef DEBUG 131 #ifdef DEBUG
132 if (strlen(FLAG_stop_at) > 0 && 132 if (strlen(FLAG_stop_at) > 0 &&
133 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { 133 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) {
134 __ int3(); 134 __ int3();
135 } 135 }
136 #endif 136 #endif
137 137
138 // Sloppy mode functions and builtins need to replace the receiver with the 138 // Sloppy mode functions and builtins need to replace the receiver with the
139 // global proxy when called as functions (without an explicit receiver 139 // global proxy when called as functions (without an explicit receiver
140 // object). 140 // object).
141 if (info->is_sloppy_mode() && !info->is_native()) { 141 if (info->strict_mode() == SLOPPY && !info->is_native()) {
142 Label ok; 142 Label ok;
143 // +1 for return address. 143 // +1 for return address.
144 int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize; 144 int receiver_offset = (info->scope()->num_parameters() + 1) * kPointerSize;
145 __ mov(ecx, Operand(esp, receiver_offset)); 145 __ mov(ecx, Operand(esp, receiver_offset));
146 146
147 __ cmp(ecx, isolate()->factory()->undefined_value()); 147 __ cmp(ecx, isolate()->factory()->undefined_value());
148 __ j(not_equal, &ok, Label::kNear); 148 __ j(not_equal, &ok, Label::kNear);
149 149
150 __ mov(ecx, GlobalObjectOperand()); 150 __ mov(ecx, GlobalObjectOperand());
151 __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset)); 151 __ mov(ecx, FieldOperand(ecx, GlobalObject::kGlobalReceiverOffset));
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 int offset = num_parameters * kPointerSize; 238 int offset = num_parameters * kPointerSize;
239 __ lea(edx, 239 __ lea(edx,
240 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset)); 240 Operand(ebp, StandardFrameConstants::kCallerSPOffset + offset));
241 __ push(edx); 241 __ push(edx);
242 __ push(Immediate(Smi::FromInt(num_parameters))); 242 __ push(Immediate(Smi::FromInt(num_parameters)));
243 // Arguments to ArgumentsAccessStub: 243 // Arguments to ArgumentsAccessStub:
244 // function, receiver address, parameter count. 244 // function, receiver address, parameter count.
245 // The stub will rewrite receiver and parameter count if the previous 245 // The stub will rewrite receiver and parameter count if the previous
246 // stack frame was an arguments adapter frame. 246 // stack frame was an arguments adapter frame.
247 ArgumentsAccessStub::Type type; 247 ArgumentsAccessStub::Type type;
248 if (!is_sloppy_mode()) { 248 if (strict_mode() == STRICT) {
249 type = ArgumentsAccessStub::NEW_STRICT; 249 type = ArgumentsAccessStub::NEW_STRICT;
250 } else if (function()->has_duplicate_parameters()) { 250 } else if (function()->has_duplicate_parameters()) {
251 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; 251 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW;
252 } else { 252 } else {
253 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; 253 type = ArgumentsAccessStub::NEW_SLOPPY_FAST;
254 } 254 }
255 ArgumentsAccessStub stub(type); 255 ArgumentsAccessStub stub(type);
256 __ CallStub(&stub); 256 __ CallStub(&stub);
257 257
258 SetVar(arguments, eax, ebx, edx); 258 SetVar(arguments, eax, ebx, edx);
(...skipping 10 matching lines...) Expand all
269 scope()->VisitIllegalRedeclaration(this); 269 scope()->VisitIllegalRedeclaration(this);
270 270
271 } else { 271 } else {
272 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS); 272 PrepareForBailoutForId(BailoutId::FunctionEntry(), NO_REGISTERS);
273 { Comment cmnt(masm_, "[ Declarations"); 273 { Comment cmnt(masm_, "[ Declarations");
274 // For named function expressions, declare the function name as a 274 // For named function expressions, declare the function name as a
275 // constant. 275 // constant.
276 if (scope()->is_function_scope() && scope()->function() != NULL) { 276 if (scope()->is_function_scope() && scope()->function() != NULL) {
277 VariableDeclaration* function = scope()->function(); 277 VariableDeclaration* function = scope()->function();
278 ASSERT(function->proxy()->var()->mode() == CONST || 278 ASSERT(function->proxy()->var()->mode() == CONST ||
279 function->proxy()->var()->mode() == CONST_HARMONY); 279 function->proxy()->var()->mode() == CONST_LEGACY);
280 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED); 280 ASSERT(function->proxy()->var()->location() != Variable::UNALLOCATED);
281 VisitVariableDeclaration(function); 281 VisitVariableDeclaration(function);
282 } 282 }
283 VisitDeclarations(scope()->declarations()); 283 VisitDeclarations(scope()->declarations());
284 } 284 }
285 285
286 { Comment cmnt(masm_, "[ Stack check"); 286 { Comment cmnt(masm_, "[ Stack check");
287 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS); 287 PrepareForBailoutForId(BailoutId::Declarations(), NO_REGISTERS);
288 Label ok; 288 Label ok;
289 ExternalReference stack_limit = 289 ExternalReference stack_limit =
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 739
740 740
741 void FullCodeGenerator::VisitVariableDeclaration( 741 void FullCodeGenerator::VisitVariableDeclaration(
742 VariableDeclaration* declaration) { 742 VariableDeclaration* declaration) {
743 // If it was not possible to allocate the variable at compile time, we 743 // If it was not possible to allocate the variable at compile time, we
744 // need to "declare" it at runtime to make sure it actually exists in the 744 // need to "declare" it at runtime to make sure it actually exists in the
745 // local context. 745 // local context.
746 VariableProxy* proxy = declaration->proxy(); 746 VariableProxy* proxy = declaration->proxy();
747 VariableMode mode = declaration->mode(); 747 VariableMode mode = declaration->mode();
748 Variable* variable = proxy->var(); 748 Variable* variable = proxy->var();
749 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; 749 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
750 switch (variable->location()) { 750 switch (variable->location()) {
751 case Variable::UNALLOCATED: 751 case Variable::UNALLOCATED:
752 globals_->Add(variable->name(), zone()); 752 globals_->Add(variable->name(), zone());
753 globals_->Add(variable->binding_needs_init() 753 globals_->Add(variable->binding_needs_init()
754 ? isolate()->factory()->the_hole_value() 754 ? isolate()->factory()->the_hole_value()
755 : isolate()->factory()->undefined_value(), zone()); 755 : isolate()->factory()->undefined_value(), zone());
756 break; 756 break;
757 757
758 case Variable::PARAMETER: 758 case Variable::PARAMETER:
759 case Variable::LOCAL: 759 case Variable::LOCAL:
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 // space for nested functions that don't need literals cloning. If 1260 // space for nested functions that don't need literals cloning. If
1261 // we're running with the --always-opt or the --prepare-always-opt 1261 // we're running with the --always-opt or the --prepare-always-opt
1262 // flag, we need to use the runtime function so that the new function 1262 // flag, we need to use the runtime function so that the new function
1263 // we are creating here gets a chance to have its code optimized and 1263 // we are creating here gets a chance to have its code optimized and
1264 // doesn't just get a copy of the existing unoptimized code. 1264 // doesn't just get a copy of the existing unoptimized code.
1265 if (!FLAG_always_opt && 1265 if (!FLAG_always_opt &&
1266 !FLAG_prepare_always_opt && 1266 !FLAG_prepare_always_opt &&
1267 !pretenure && 1267 !pretenure &&
1268 scope()->is_function_scope() && 1268 scope()->is_function_scope() &&
1269 info->num_literals() == 0) { 1269 info->num_literals() == 0) {
1270 FastNewClosureStub stub(info->language_mode(), info->is_generator()); 1270 FastNewClosureStub stub(info->strict_mode(), info->is_generator());
1271 __ mov(ebx, Immediate(info)); 1271 __ mov(ebx, Immediate(info));
1272 __ CallStub(&stub); 1272 __ CallStub(&stub);
1273 } else { 1273 } else {
1274 __ push(esi); 1274 __ push(esi);
1275 __ push(Immediate(info)); 1275 __ push(Immediate(info));
1276 __ push(Immediate(pretenure 1276 __ push(Immediate(pretenure
1277 ? isolate()->factory()->true_value() 1277 ? isolate()->factory()->true_value()
1278 : isolate()->factory()->false_value())); 1278 : isolate()->factory()->false_value()));
1279 __ CallRuntime(Runtime::kNewClosure, 3); 1279 __ CallRuntime(Runtime::kNewClosure, 3);
1280 } 1280 }
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 // eval-introduced variables. Eval is used a lot without 1386 // eval-introduced variables. Eval is used a lot without
1387 // introducing variables. In those cases, we do not want to 1387 // introducing variables. In those cases, we do not want to
1388 // perform a runtime call for all variables in the scope 1388 // perform a runtime call for all variables in the scope
1389 // containing the eval. 1389 // containing the eval.
1390 if (var->mode() == DYNAMIC_GLOBAL) { 1390 if (var->mode() == DYNAMIC_GLOBAL) {
1391 EmitLoadGlobalCheckExtensions(var, typeof_state, slow); 1391 EmitLoadGlobalCheckExtensions(var, typeof_state, slow);
1392 __ jmp(done); 1392 __ jmp(done);
1393 } else if (var->mode() == DYNAMIC_LOCAL) { 1393 } else if (var->mode() == DYNAMIC_LOCAL) {
1394 Variable* local = var->local_if_not_shadowed(); 1394 Variable* local = var->local_if_not_shadowed();
1395 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow)); 1395 __ mov(eax, ContextSlotOperandCheckExtensions(local, slow));
1396 if (local->mode() == LET || 1396 if (local->mode() == LET || local->mode() == CONST ||
1397 local->mode() == CONST || 1397 local->mode() == CONST_LEGACY) {
1398 local->mode() == CONST_HARMONY) {
1399 __ cmp(eax, isolate()->factory()->the_hole_value()); 1398 __ cmp(eax, isolate()->factory()->the_hole_value());
1400 __ j(not_equal, done); 1399 __ j(not_equal, done);
1401 if (local->mode() == CONST) { 1400 if (local->mode() == CONST_LEGACY) {
1402 __ mov(eax, isolate()->factory()->undefined_value()); 1401 __ mov(eax, isolate()->factory()->undefined_value());
1403 } else { // LET || CONST_HARMONY 1402 } else { // LET || CONST
1404 __ push(Immediate(var->name())); 1403 __ push(Immediate(var->name()));
1405 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1404 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1406 } 1405 }
1407 } 1406 }
1408 __ jmp(done); 1407 __ jmp(done);
1409 } 1408 }
1410 } 1409 }
1411 1410
1412 1411
1413 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { 1412 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 // binding is initialized: 1457 // binding is initialized:
1459 // function() { f(); let x = 1; function f() { x = 2; } } 1458 // function() { f(); let x = 1; function f() { x = 2; } }
1460 // 1459 //
1461 bool skip_init_check; 1460 bool skip_init_check;
1462 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) { 1461 if (var->scope()->DeclarationScope() != scope()->DeclarationScope()) {
1463 skip_init_check = false; 1462 skip_init_check = false;
1464 } else { 1463 } else {
1465 // Check that we always have valid source position. 1464 // Check that we always have valid source position.
1466 ASSERT(var->initializer_position() != RelocInfo::kNoPosition); 1465 ASSERT(var->initializer_position() != RelocInfo::kNoPosition);
1467 ASSERT(proxy->position() != RelocInfo::kNoPosition); 1466 ASSERT(proxy->position() != RelocInfo::kNoPosition);
1468 skip_init_check = var->mode() != CONST && 1467 skip_init_check = var->mode() != CONST_LEGACY &&
1469 var->initializer_position() < proxy->position(); 1468 var->initializer_position() < proxy->position();
1470 } 1469 }
1471 1470
1472 if (!skip_init_check) { 1471 if (!skip_init_check) {
1473 // Let and const need a read barrier. 1472 // Let and const need a read barrier.
1474 Label done; 1473 Label done;
1475 GetVar(eax, var); 1474 GetVar(eax, var);
1476 __ cmp(eax, isolate()->factory()->the_hole_value()); 1475 __ cmp(eax, isolate()->factory()->the_hole_value());
1477 __ j(not_equal, &done, Label::kNear); 1476 __ j(not_equal, &done, Label::kNear);
1478 if (var->mode() == LET || var->mode() == CONST_HARMONY) { 1477 if (var->mode() == LET || var->mode() == CONST) {
1479 // Throw a reference error when using an uninitialized let/const 1478 // Throw a reference error when using an uninitialized let/const
1480 // binding in harmony mode. 1479 // binding in harmony mode.
1481 __ push(Immediate(var->name())); 1480 __ push(Immediate(var->name()));
1482 __ CallRuntime(Runtime::kThrowReferenceError, 1); 1481 __ CallRuntime(Runtime::kThrowReferenceError, 1);
1483 } else { 1482 } else {
1484 // Uninitalized const bindings outside of harmony mode are unholed. 1483 // Uninitalized const bindings outside of harmony mode are unholed.
1485 ASSERT(var->mode() == CONST); 1484 ASSERT(var->mode() == CONST_LEGACY);
1486 __ mov(eax, isolate()->factory()->undefined_value()); 1485 __ mov(eax, isolate()->factory()->undefined_value());
1487 } 1486 }
1488 __ bind(&done); 1487 __ bind(&done);
1489 context()->Plug(eax); 1488 context()->Plug(eax);
1490 break; 1489 break;
1491 } 1490 }
1492 } 1491 }
1493 context()->Plug(var); 1492 context()->Plug(var);
1494 break; 1493 break;
1495 } 1494 }
(...skipping 894 matching lines...) Expand 10 before | Expand all | Expand 10 after
2390 CallStoreIC(); 2389 CallStoreIC();
2391 break; 2390 break;
2392 } 2391 }
2393 case KEYED_PROPERTY: { 2392 case KEYED_PROPERTY: {
2394 __ push(eax); // Preserve value. 2393 __ push(eax); // Preserve value.
2395 VisitForStackValue(prop->obj()); 2394 VisitForStackValue(prop->obj());
2396 VisitForAccumulatorValue(prop->key()); 2395 VisitForAccumulatorValue(prop->key());
2397 __ mov(ecx, eax); 2396 __ mov(ecx, eax);
2398 __ pop(edx); // Receiver. 2397 __ pop(edx); // Receiver.
2399 __ pop(eax); // Restore value. 2398 __ pop(eax); // Restore value.
2400 Handle<Code> ic = is_sloppy_mode() 2399 Handle<Code> ic = strict_mode() == SLOPPY
2401 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2400 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2402 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2401 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2403 CallIC(ic); 2402 CallIC(ic);
2404 break; 2403 break;
2405 } 2404 }
2406 } 2405 }
2407 context()->Plug(eax); 2406 context()->Plug(eax);
2408 } 2407 }
2409 2408
2410 2409
2411 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( 2410 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot(
2412 Variable* var, MemOperand location) { 2411 Variable* var, MemOperand location) {
2413 __ mov(location, eax); 2412 __ mov(location, eax);
2414 if (var->IsContextSlot()) { 2413 if (var->IsContextSlot()) {
2415 __ mov(edx, eax); 2414 __ mov(edx, eax);
2416 int offset = Context::SlotOffset(var->index()); 2415 int offset = Context::SlotOffset(var->index());
2417 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs); 2416 __ RecordWriteContextSlot(ecx, offset, edx, ebx, kDontSaveFPRegs);
2418 } 2417 }
2419 } 2418 }
2420 2419
2421 2420
2422 void FullCodeGenerator::EmitCallStoreContextSlot( 2421 void FullCodeGenerator::EmitCallStoreContextSlot(
2423 Handle<String> name, LanguageMode mode) { 2422 Handle<String> name, StrictMode strict_mode) {
2424 __ push(eax); // Value. 2423 __ push(eax); // Value.
2425 __ push(esi); // Context. 2424 __ push(esi); // Context.
2426 __ push(Immediate(name)); 2425 __ push(Immediate(name));
2427 __ push(Immediate(Smi::FromInt(mode))); 2426 __ push(Immediate(Smi::FromInt(strict_mode)));
2428 __ CallRuntime(Runtime::kStoreContextSlot, 4); 2427 __ CallRuntime(Runtime::kStoreContextSlot, 4);
2429 } 2428 }
2430 2429
2431 2430
2432 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 2431 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
2433 Token::Value op) { 2432 Token::Value op) {
2434 if (var->IsUnallocated()) { 2433 if (var->IsUnallocated()) {
2435 // Global var, const, or let. 2434 // Global var, const, or let.
2436 __ mov(ecx, var->name()); 2435 __ mov(ecx, var->name());
2437 __ mov(edx, GlobalObjectOperand()); 2436 __ mov(edx, GlobalObjectOperand());
2438 CallStoreIC(); 2437 CallStoreIC();
2439 2438
2440 } else if (op == Token::INIT_CONST) { 2439 } else if (op == Token::INIT_CONST_LEGACY) {
2441 // Const initializers need a write barrier. 2440 // Const initializers need a write barrier.
2442 ASSERT(!var->IsParameter()); // No const parameters. 2441 ASSERT(!var->IsParameter()); // No const parameters.
2443 if (var->IsLookupSlot()) { 2442 if (var->IsLookupSlot()) {
2444 __ push(eax); 2443 __ push(eax);
2445 __ push(esi); 2444 __ push(esi);
2446 __ push(Immediate(var->name())); 2445 __ push(Immediate(var->name()));
2447 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3); 2446 __ CallRuntime(Runtime::kInitializeConstContextSlot, 3);
2448 } else { 2447 } else {
2449 ASSERT(var->IsStackLocal() || var->IsContextSlot()); 2448 ASSERT(var->IsStackLocal() || var->IsContextSlot());
2450 Label skip; 2449 Label skip;
2451 MemOperand location = VarOperand(var, ecx); 2450 MemOperand location = VarOperand(var, ecx);
2452 __ mov(edx, location); 2451 __ mov(edx, location);
2453 __ cmp(edx, isolate()->factory()->the_hole_value()); 2452 __ cmp(edx, isolate()->factory()->the_hole_value());
2454 __ j(not_equal, &skip, Label::kNear); 2453 __ j(not_equal, &skip, Label::kNear);
2455 EmitStoreToStackLocalOrContextSlot(var, location); 2454 EmitStoreToStackLocalOrContextSlot(var, location);
2456 __ bind(&skip); 2455 __ bind(&skip);
2457 } 2456 }
2458 2457
2459 } else if (var->mode() == LET && op != Token::INIT_LET) { 2458 } else if (var->mode() == LET && op != Token::INIT_LET) {
2460 // Non-initializing assignment to let variable needs a write barrier. 2459 // Non-initializing assignment to let variable needs a write barrier.
2461 if (var->IsLookupSlot()) { 2460 if (var->IsLookupSlot()) {
2462 EmitCallStoreContextSlot(var->name(), language_mode()); 2461 EmitCallStoreContextSlot(var->name(), strict_mode());
2463 } else { 2462 } else {
2464 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2463 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2465 Label assign; 2464 Label assign;
2466 MemOperand location = VarOperand(var, ecx); 2465 MemOperand location = VarOperand(var, ecx);
2467 __ mov(edx, location); 2466 __ mov(edx, location);
2468 __ cmp(edx, isolate()->factory()->the_hole_value()); 2467 __ cmp(edx, isolate()->factory()->the_hole_value());
2469 __ j(not_equal, &assign, Label::kNear); 2468 __ j(not_equal, &assign, Label::kNear);
2470 __ push(Immediate(var->name())); 2469 __ push(Immediate(var->name()));
2471 __ CallRuntime(Runtime::kThrowReferenceError, 1); 2470 __ CallRuntime(Runtime::kThrowReferenceError, 1);
2472 __ bind(&assign); 2471 __ bind(&assign);
2473 EmitStoreToStackLocalOrContextSlot(var, location); 2472 EmitStoreToStackLocalOrContextSlot(var, location);
2474 } 2473 }
2475 2474
2476 } else if (!var->is_const_mode() || op == Token::INIT_CONST_HARMONY) { 2475 } else if (!var->is_const_mode() || op == Token::INIT_CONST) {
2477 // Assignment to var or initializing assignment to let/const 2476 // Assignment to var or initializing assignment to let/const
2478 // in harmony mode. 2477 // in harmony mode.
2479 if (var->IsLookupSlot()) { 2478 if (var->IsLookupSlot()) {
2480 EmitCallStoreContextSlot(var->name(), language_mode()); 2479 EmitCallStoreContextSlot(var->name(), strict_mode());
2481 } else { 2480 } else {
2482 ASSERT(var->IsStackAllocated() || var->IsContextSlot()); 2481 ASSERT(var->IsStackAllocated() || var->IsContextSlot());
2483 MemOperand location = VarOperand(var, ecx); 2482 MemOperand location = VarOperand(var, ecx);
2484 if (generate_debug_code_ && op == Token::INIT_LET) { 2483 if (generate_debug_code_ && op == Token::INIT_LET) {
2485 // Check for an uninitialized let binding. 2484 // Check for an uninitialized let binding.
2486 __ mov(edx, location); 2485 __ mov(edx, location);
2487 __ cmp(edx, isolate()->factory()->the_hole_value()); 2486 __ cmp(edx, isolate()->factory()->the_hole_value());
2488 __ Check(equal, kLetBindingReInitialization); 2487 __ Check(equal, kLetBindingReInitialization);
2489 } 2488 }
2490 EmitStoreToStackLocalOrContextSlot(var, location); 2489 EmitStoreToStackLocalOrContextSlot(var, location);
(...skipping 25 matching lines...) Expand all
2516 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { 2515 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) {
2517 // Assignment to a property, using a keyed store IC. 2516 // Assignment to a property, using a keyed store IC.
2518 // eax : value 2517 // eax : value
2519 // esp[0] : key 2518 // esp[0] : key
2520 // esp[kPointerSize] : receiver 2519 // esp[kPointerSize] : receiver
2521 2520
2522 __ pop(ecx); // Key. 2521 __ pop(ecx); // Key.
2523 __ pop(edx); 2522 __ pop(edx);
2524 // Record source code position before IC call. 2523 // Record source code position before IC call.
2525 SetSourcePosition(expr->position()); 2524 SetSourcePosition(expr->position());
2526 Handle<Code> ic = is_sloppy_mode() 2525 Handle<Code> ic = strict_mode() == SLOPPY
2527 ? isolate()->builtins()->KeyedStoreIC_Initialize() 2526 ? isolate()->builtins()->KeyedStoreIC_Initialize()
2528 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 2527 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
2529 CallIC(ic, expr->AssignmentFeedbackId()); 2528 CallIC(ic, expr->AssignmentFeedbackId());
2530 2529
2531 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 2530 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
2532 context()->Plug(eax); 2531 context()->Plug(eax);
2533 } 2532 }
2534 2533
2535 2534
2536 void FullCodeGenerator::VisitProperty(Property* expr) { 2535 void FullCodeGenerator::VisitProperty(Property* expr) {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
2690 // Push copy of the first argument or undefined if it doesn't exist. 2689 // Push copy of the first argument or undefined if it doesn't exist.
2691 if (arg_count > 0) { 2690 if (arg_count > 0) {
2692 __ push(Operand(esp, arg_count * kPointerSize)); 2691 __ push(Operand(esp, arg_count * kPointerSize));
2693 } else { 2692 } else {
2694 __ push(Immediate(isolate()->factory()->undefined_value())); 2693 __ push(Immediate(isolate()->factory()->undefined_value()));
2695 } 2694 }
2696 2695
2697 // Push the receiver of the enclosing function. 2696 // Push the receiver of the enclosing function.
2698 __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize)); 2697 __ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize));
2699 // Push the language mode. 2698 // Push the language mode.
2700 __ push(Immediate(Smi::FromInt(language_mode()))); 2699 __ push(Immediate(Smi::FromInt(strict_mode())));
2701 2700
2702 // Push the start position of the scope the calls resides in. 2701 // Push the start position of the scope the calls resides in.
2703 __ push(Immediate(Smi::FromInt(scope()->start_position()))); 2702 __ push(Immediate(Smi::FromInt(scope()->start_position())));
2704 2703
2705 // Do the runtime call. 2704 // Do the runtime call.
2706 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); 2705 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
2707 } 2706 }
2708 2707
2709 2708
2710 void FullCodeGenerator::VisitCall(Call* expr) { 2709 void FullCodeGenerator::VisitCall(Call* expr) {
(...skipping 1464 matching lines...) Expand 10 before | Expand all | Expand 10 after
4175 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { 4174 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
4176 switch (expr->op()) { 4175 switch (expr->op()) {
4177 case Token::DELETE: { 4176 case Token::DELETE: {
4178 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); 4177 Comment cmnt(masm_, "[ UnaryOperation (DELETE)");
4179 Property* property = expr->expression()->AsProperty(); 4178 Property* property = expr->expression()->AsProperty();
4180 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 4179 VariableProxy* proxy = expr->expression()->AsVariableProxy();
4181 4180
4182 if (property != NULL) { 4181 if (property != NULL) {
4183 VisitForStackValue(property->obj()); 4182 VisitForStackValue(property->obj());
4184 VisitForStackValue(property->key()); 4183 VisitForStackValue(property->key());
4185 StrictModeFlag strict_mode_flag = (language_mode() == SLOPPY_MODE) 4184 __ push(Immediate(Smi::FromInt(strict_mode())));
4186 ? kSloppyMode : kStrictMode;
4187 __ push(Immediate(Smi::FromInt(strict_mode_flag)));
4188 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4185 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4189 context()->Plug(eax); 4186 context()->Plug(eax);
4190 } else if (proxy != NULL) { 4187 } else if (proxy != NULL) {
4191 Variable* var = proxy->var(); 4188 Variable* var = proxy->var();
4192 // Delete of an unqualified identifier is disallowed in strict mode 4189 // Delete of an unqualified identifier is disallowed in strict mode
4193 // but "delete this" is allowed. 4190 // but "delete this" is allowed.
4194 ASSERT(language_mode() == SLOPPY_MODE || var->is_this()); 4191 ASSERT(strict_mode() == SLOPPY || var->is_this());
4195 if (var->IsUnallocated()) { 4192 if (var->IsUnallocated()) {
4196 __ push(GlobalObjectOperand()); 4193 __ push(GlobalObjectOperand());
4197 __ push(Immediate(var->name())); 4194 __ push(Immediate(var->name()));
4198 __ push(Immediate(Smi::FromInt(kSloppyMode))); 4195 __ push(Immediate(Smi::FromInt(SLOPPY)));
4199 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); 4196 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION);
4200 context()->Plug(eax); 4197 context()->Plug(eax);
4201 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 4198 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
4202 // Result of deleting non-global variables is false. 'this' is 4199 // Result of deleting non-global variables is false. 'this' is
4203 // not really a variable, though we implement it as one. The 4200 // not really a variable, though we implement it as one. The
4204 // subexpression does not have side effects. 4201 // subexpression does not have side effects.
4205 context()->Plug(var->is_this()); 4202 context()->Plug(var->is_this());
4206 } else { 4203 } else {
4207 // Non-global variable. Call the runtime to try to delete from the 4204 // Non-global variable. Call the runtime to try to delete from the
4208 // context where the variable was introduced. 4205 // context where the variable was introduced.
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
4455 context()->PlugTOS(); 4452 context()->PlugTOS();
4456 } 4453 }
4457 } else { 4454 } else {
4458 context()->Plug(eax); 4455 context()->Plug(eax);
4459 } 4456 }
4460 break; 4457 break;
4461 } 4458 }
4462 case KEYED_PROPERTY: { 4459 case KEYED_PROPERTY: {
4463 __ pop(ecx); 4460 __ pop(ecx);
4464 __ pop(edx); 4461 __ pop(edx);
4465 Handle<Code> ic = is_sloppy_mode() 4462 Handle<Code> ic = strict_mode() == SLOPPY
4466 ? isolate()->builtins()->KeyedStoreIC_Initialize() 4463 ? isolate()->builtins()->KeyedStoreIC_Initialize()
4467 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); 4464 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict();
4468 CallIC(ic, expr->CountStoreFeedbackId()); 4465 CallIC(ic, expr->CountStoreFeedbackId());
4469 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); 4466 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG);
4470 if (expr->is_postfix()) { 4467 if (expr->is_postfix()) {
4471 // Result is on the stack 4468 // Result is on the stack
4472 if (!context()->IsEffect()) { 4469 if (!context()->IsEffect()) {
4473 context()->PlugTOS(); 4470 context()->PlugTOS();
4474 } 4471 }
4475 } else { 4472 } else {
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
4912 4909
4913 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(), 4910 ASSERT_EQ(isolate->builtins()->OsrAfterStackCheck()->entry(),
4914 Assembler::target_address_at(call_target_address)); 4911 Assembler::target_address_at(call_target_address));
4915 return OSR_AFTER_STACK_CHECK; 4912 return OSR_AFTER_STACK_CHECK;
4916 } 4913 }
4917 4914
4918 4915
4919 } } // namespace v8::internal 4916 } } // namespace v8::internal
4920 4917
4921 #endif // V8_TARGET_ARCH_IA32 4918 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/ic-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698