OLD | NEW |
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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 | 146 |
147 ProfileEntryHookStub::MaybeCallEntryHook(masm_); | 147 ProfileEntryHookStub::MaybeCallEntryHook(masm_); |
148 | 148 |
149 #ifdef DEBUG | 149 #ifdef DEBUG |
150 if (strlen(FLAG_stop_at) > 0 && | 150 if (strlen(FLAG_stop_at) > 0 && |
151 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { | 151 info->function()->name()->IsUtf8EqualTo(CStrVector(FLAG_stop_at))) { |
152 __ stop("stop-at"); | 152 __ stop("stop-at"); |
153 } | 153 } |
154 #endif | 154 #endif |
155 | 155 |
156 // Classic mode functions and builtins need to replace the receiver with the | 156 // Sloppy mode functions and builtins need to replace the receiver with the |
157 // global proxy when called as functions (without an explicit receiver | 157 // global proxy when called as functions (without an explicit receiver |
158 // object). | 158 // object). |
159 if (info->is_classic_mode() && !info->is_native()) { | 159 if (info->is_sloppy_mode() && !info->is_native()) { |
160 Label ok; | 160 Label ok; |
161 int receiver_offset = info->scope()->num_parameters() * kPointerSize; | 161 int receiver_offset = info->scope()->num_parameters() * kPointerSize; |
162 __ lw(at, MemOperand(sp, receiver_offset)); | 162 __ lw(at, MemOperand(sp, receiver_offset)); |
163 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); | 163 __ LoadRoot(a2, Heap::kUndefinedValueRootIndex); |
164 __ Branch(&ok, ne, a2, Operand(at)); | 164 __ Branch(&ok, ne, a2, Operand(at)); |
165 | 165 |
166 __ lw(a2, GlobalObjectOperand()); | 166 __ lw(a2, GlobalObjectOperand()); |
167 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); | 167 __ lw(a2, FieldMemOperand(a2, GlobalObject::kGlobalReceiverOffset)); |
168 | 168 |
169 __ sw(a2, MemOperand(sp, receiver_offset)); | 169 __ sw(a2, MemOperand(sp, receiver_offset)); |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 __ Addu(a2, fp, | 264 __ Addu(a2, fp, |
265 Operand(StandardFrameConstants::kCallerSPOffset + offset)); | 265 Operand(StandardFrameConstants::kCallerSPOffset + offset)); |
266 __ li(a1, Operand(Smi::FromInt(num_parameters))); | 266 __ li(a1, Operand(Smi::FromInt(num_parameters))); |
267 __ Push(a3, a2, a1); | 267 __ Push(a3, a2, a1); |
268 | 268 |
269 // Arguments to ArgumentsAccessStub: | 269 // Arguments to ArgumentsAccessStub: |
270 // function, receiver address, parameter count. | 270 // function, receiver address, parameter count. |
271 // The stub will rewrite receiever and parameter count if the previous | 271 // The stub will rewrite receiever and parameter count if the previous |
272 // stack frame was an arguments adapter frame. | 272 // stack frame was an arguments adapter frame. |
273 ArgumentsAccessStub::Type type; | 273 ArgumentsAccessStub::Type type; |
274 if (!is_classic_mode()) { | 274 if (!is_sloppy_mode()) { |
275 type = ArgumentsAccessStub::NEW_STRICT; | 275 type = ArgumentsAccessStub::NEW_STRICT; |
276 } else if (function()->has_duplicate_parameters()) { | 276 } else if (function()->has_duplicate_parameters()) { |
277 type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW; | 277 type = ArgumentsAccessStub::NEW_SLOPPY_SLOW; |
278 } else { | 278 } else { |
279 type = ArgumentsAccessStub::NEW_NON_STRICT_FAST; | 279 type = ArgumentsAccessStub::NEW_SLOPPY_FAST; |
280 } | 280 } |
281 ArgumentsAccessStub stub(type); | 281 ArgumentsAccessStub stub(type); |
282 __ CallStub(&stub); | 282 __ CallStub(&stub); |
283 | 283 |
284 SetVar(arguments, v0, a1, a2); | 284 SetVar(arguments, v0, a1, a2); |
285 } | 285 } |
286 | 286 |
287 if (FLAG_trace) { | 287 if (FLAG_trace) { |
288 __ CallRuntime(Runtime::kTraceEnter, 0); | 288 __ CallRuntime(Runtime::kTraceEnter, 0); |
289 } | 289 } |
(...skipping 1069 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1359 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, | 1359 void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var, |
1360 TypeofState typeof_state, | 1360 TypeofState typeof_state, |
1361 Label* slow) { | 1361 Label* slow) { |
1362 Register current = cp; | 1362 Register current = cp; |
1363 Register next = a1; | 1363 Register next = a1; |
1364 Register temp = a2; | 1364 Register temp = a2; |
1365 | 1365 |
1366 Scope* s = scope(); | 1366 Scope* s = scope(); |
1367 while (s != NULL) { | 1367 while (s != NULL) { |
1368 if (s->num_heap_slots() > 0) { | 1368 if (s->num_heap_slots() > 0) { |
1369 if (s->calls_non_strict_eval()) { | 1369 if (s->calls_sloppy_eval()) { |
1370 // Check that extension is NULL. | 1370 // Check that extension is NULL. |
1371 __ lw(temp, ContextOperand(current, Context::EXTENSION_INDEX)); | 1371 __ lw(temp, ContextOperand(current, Context::EXTENSION_INDEX)); |
1372 __ Branch(slow, ne, temp, Operand(zero_reg)); | 1372 __ Branch(slow, ne, temp, Operand(zero_reg)); |
1373 } | 1373 } |
1374 // Load next context in chain. | 1374 // Load next context in chain. |
1375 __ lw(next, ContextOperand(current, Context::PREVIOUS_INDEX)); | 1375 __ lw(next, ContextOperand(current, Context::PREVIOUS_INDEX)); |
1376 // Walk the rest of the chain without clobbering cp. | 1376 // Walk the rest of the chain without clobbering cp. |
1377 current = next; | 1377 current = next; |
1378 } | 1378 } |
1379 // If no outer scope calls eval, we do not need to check more | 1379 // If no outer scope calls eval, we do not need to check more |
1380 // context extensions. | 1380 // context extensions. |
1381 if (!s->outer_scope_calls_non_strict_eval() || s->is_eval_scope()) break; | 1381 if (!s->outer_scope_calls_sloppy_eval() || s->is_eval_scope()) break; |
1382 s = s->outer_scope(); | 1382 s = s->outer_scope(); |
1383 } | 1383 } |
1384 | 1384 |
1385 if (s->is_eval_scope()) { | 1385 if (s->is_eval_scope()) { |
1386 Label loop, fast; | 1386 Label loop, fast; |
1387 if (!current.is(next)) { | 1387 if (!current.is(next)) { |
1388 __ Move(next, current); | 1388 __ Move(next, current); |
1389 } | 1389 } |
1390 __ bind(&loop); | 1390 __ bind(&loop); |
1391 // Terminate at native context. | 1391 // Terminate at native context. |
(...skipping 20 matching lines...) Expand all Loading... |
1412 | 1412 |
1413 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, | 1413 MemOperand FullCodeGenerator::ContextSlotOperandCheckExtensions(Variable* var, |
1414 Label* slow) { | 1414 Label* slow) { |
1415 ASSERT(var->IsContextSlot()); | 1415 ASSERT(var->IsContextSlot()); |
1416 Register context = cp; | 1416 Register context = cp; |
1417 Register next = a3; | 1417 Register next = a3; |
1418 Register temp = t0; | 1418 Register temp = t0; |
1419 | 1419 |
1420 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { | 1420 for (Scope* s = scope(); s != var->scope(); s = s->outer_scope()) { |
1421 if (s->num_heap_slots() > 0) { | 1421 if (s->num_heap_slots() > 0) { |
1422 if (s->calls_non_strict_eval()) { | 1422 if (s->calls_sloppy_eval()) { |
1423 // Check that extension is NULL. | 1423 // Check that extension is NULL. |
1424 __ lw(temp, ContextOperand(context, Context::EXTENSION_INDEX)); | 1424 __ lw(temp, ContextOperand(context, Context::EXTENSION_INDEX)); |
1425 __ Branch(slow, ne, temp, Operand(zero_reg)); | 1425 __ Branch(slow, ne, temp, Operand(zero_reg)); |
1426 } | 1426 } |
1427 __ lw(next, ContextOperand(context, Context::PREVIOUS_INDEX)); | 1427 __ lw(next, ContextOperand(context, Context::PREVIOUS_INDEX)); |
1428 // Walk the rest of the chain without clobbering cp. | 1428 // Walk the rest of the chain without clobbering cp. |
1429 context = next; | 1429 context = next; |
1430 } | 1430 } |
1431 } | 1431 } |
1432 // Check that last extension is NULL. | 1432 // Check that last extension is NULL. |
(...skipping 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2452 __ li(a2, Operand(prop->key()->AsLiteral()->value())); | 2452 __ li(a2, Operand(prop->key()->AsLiteral()->value())); |
2453 CallStoreIC(); | 2453 CallStoreIC(); |
2454 break; | 2454 break; |
2455 } | 2455 } |
2456 case KEYED_PROPERTY: { | 2456 case KEYED_PROPERTY: { |
2457 __ push(result_register()); // Preserve value. | 2457 __ push(result_register()); // Preserve value. |
2458 VisitForStackValue(prop->obj()); | 2458 VisitForStackValue(prop->obj()); |
2459 VisitForAccumulatorValue(prop->key()); | 2459 VisitForAccumulatorValue(prop->key()); |
2460 __ mov(a1, result_register()); | 2460 __ mov(a1, result_register()); |
2461 __ Pop(a0, a2); // a0 = restored value. | 2461 __ Pop(a0, a2); // a0 = restored value. |
2462 Handle<Code> ic = is_classic_mode() | 2462 Handle<Code> ic = is_sloppy_mode() |
2463 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2463 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2464 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2464 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2465 CallIC(ic); | 2465 CallIC(ic); |
2466 break; | 2466 break; |
2467 } | 2467 } |
2468 } | 2468 } |
2469 context()->Plug(v0); | 2469 context()->Plug(v0); |
2470 } | 2470 } |
2471 | 2471 |
2472 | 2472 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2584 // Record source code position before IC call. | 2584 // Record source code position before IC call. |
2585 SetSourcePosition(expr->position()); | 2585 SetSourcePosition(expr->position()); |
2586 // Call keyed store IC. | 2586 // Call keyed store IC. |
2587 // The arguments are: | 2587 // The arguments are: |
2588 // - a0 is the value, | 2588 // - a0 is the value, |
2589 // - a1 is the key, | 2589 // - a1 is the key, |
2590 // - a2 is the receiver. | 2590 // - a2 is the receiver. |
2591 __ mov(a0, result_register()); | 2591 __ mov(a0, result_register()); |
2592 __ Pop(a2, a1); // a1 = key. | 2592 __ Pop(a2, a1); // a1 = key. |
2593 | 2593 |
2594 Handle<Code> ic = is_classic_mode() | 2594 Handle<Code> ic = is_sloppy_mode() |
2595 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 2595 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
2596 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 2596 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
2597 CallIC(ic, expr->AssignmentFeedbackId()); | 2597 CallIC(ic, expr->AssignmentFeedbackId()); |
2598 | 2598 |
2599 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2599 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
2600 context()->Plug(v0); | 2600 context()->Plug(v0); |
2601 } | 2601 } |
2602 | 2602 |
2603 | 2603 |
2604 void FullCodeGenerator::VisitProperty(Property* expr) { | 2604 void FullCodeGenerator::VisitProperty(Property* expr) { |
(...skipping 29 matching lines...) Expand all Loading... |
2634 int arg_count = args->length(); | 2634 int arg_count = args->length(); |
2635 | 2635 |
2636 CallFunctionFlags flags; | 2636 CallFunctionFlags flags; |
2637 // Get the target function. | 2637 // Get the target function. |
2638 if (callee->IsVariableProxy()) { | 2638 if (callee->IsVariableProxy()) { |
2639 { StackValueContext context(this); | 2639 { StackValueContext context(this); |
2640 EmitVariableLoad(callee->AsVariableProxy()); | 2640 EmitVariableLoad(callee->AsVariableProxy()); |
2641 PrepareForBailout(callee, NO_REGISTERS); | 2641 PrepareForBailout(callee, NO_REGISTERS); |
2642 } | 2642 } |
2643 // Push undefined as receiver. This is patched in the method prologue if it | 2643 // Push undefined as receiver. This is patched in the method prologue if it |
2644 // is a classic mode method. | 2644 // is a sloppy mode method. |
2645 __ Push(isolate()->factory()->undefined_value()); | 2645 __ Push(isolate()->factory()->undefined_value()); |
2646 flags = NO_CALL_FUNCTION_FLAGS; | 2646 flags = NO_CALL_FUNCTION_FLAGS; |
2647 } else { | 2647 } else { |
2648 // Load the function from the receiver. | 2648 // Load the function from the receiver. |
2649 ASSERT(callee->IsProperty()); | 2649 ASSERT(callee->IsProperty()); |
2650 __ lw(v0, MemOperand(sp, 0)); | 2650 __ lw(v0, MemOperand(sp, 0)); |
2651 EmitNamedPropertyLoad(callee->AsProperty()); | 2651 EmitNamedPropertyLoad(callee->AsProperty()); |
2652 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); | 2652 PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); |
2653 // Push the target function under the receiver. | 2653 // Push the target function under the receiver. |
2654 __ lw(at, MemOperand(sp, 0)); | 2654 __ lw(at, MemOperand(sp, 0)); |
(...skipping 1565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4220 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 4220 void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
4221 switch (expr->op()) { | 4221 switch (expr->op()) { |
4222 case Token::DELETE: { | 4222 case Token::DELETE: { |
4223 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); | 4223 Comment cmnt(masm_, "[ UnaryOperation (DELETE)"); |
4224 Property* property = expr->expression()->AsProperty(); | 4224 Property* property = expr->expression()->AsProperty(); |
4225 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 4225 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
4226 | 4226 |
4227 if (property != NULL) { | 4227 if (property != NULL) { |
4228 VisitForStackValue(property->obj()); | 4228 VisitForStackValue(property->obj()); |
4229 VisitForStackValue(property->key()); | 4229 VisitForStackValue(property->key()); |
4230 StrictModeFlag strict_mode_flag = (language_mode() == CLASSIC_MODE) | 4230 StrictModeFlag strict_mode_flag = (language_mode() == SLOPPY_MODE) |
4231 ? kNonStrictMode : kStrictMode; | 4231 ? kSloppyMode : kStrictMode; |
4232 __ li(a1, Operand(Smi::FromInt(strict_mode_flag))); | 4232 __ li(a1, Operand(Smi::FromInt(strict_mode_flag))); |
4233 __ push(a1); | 4233 __ push(a1); |
4234 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4234 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
4235 context()->Plug(v0); | 4235 context()->Plug(v0); |
4236 } else if (proxy != NULL) { | 4236 } else if (proxy != NULL) { |
4237 Variable* var = proxy->var(); | 4237 Variable* var = proxy->var(); |
4238 // Delete of an unqualified identifier is disallowed in strict mode | 4238 // Delete of an unqualified identifier is disallowed in strict mode |
4239 // but "delete this" is allowed. | 4239 // but "delete this" is allowed. |
4240 ASSERT(language_mode() == CLASSIC_MODE || var->is_this()); | 4240 ASSERT(language_mode() == SLOPPY_MODE || var->is_this()); |
4241 if (var->IsUnallocated()) { | 4241 if (var->IsUnallocated()) { |
4242 __ lw(a2, GlobalObjectOperand()); | 4242 __ lw(a2, GlobalObjectOperand()); |
4243 __ li(a1, Operand(var->name())); | 4243 __ li(a1, Operand(var->name())); |
4244 __ li(a0, Operand(Smi::FromInt(kNonStrictMode))); | 4244 __ li(a0, Operand(Smi::FromInt(kSloppyMode))); |
4245 __ Push(a2, a1, a0); | 4245 __ Push(a2, a1, a0); |
4246 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); | 4246 __ InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION); |
4247 context()->Plug(v0); | 4247 context()->Plug(v0); |
4248 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 4248 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
4249 // Result of deleting non-global, non-dynamic variables is false. | 4249 // Result of deleting non-global, non-dynamic variables is false. |
4250 // The subexpression does not have side effects. | 4250 // The subexpression does not have side effects. |
4251 context()->Plug(var->is_this()); | 4251 context()->Plug(var->is_this()); |
4252 } else { | 4252 } else { |
4253 // Non-global variable. Call the runtime to try to delete from the | 4253 // Non-global variable. Call the runtime to try to delete from the |
4254 // context where the variable was introduced. | 4254 // context where the variable was introduced. |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4493 context()->PlugTOS(); | 4493 context()->PlugTOS(); |
4494 } | 4494 } |
4495 } else { | 4495 } else { |
4496 context()->Plug(v0); | 4496 context()->Plug(v0); |
4497 } | 4497 } |
4498 break; | 4498 break; |
4499 } | 4499 } |
4500 case KEYED_PROPERTY: { | 4500 case KEYED_PROPERTY: { |
4501 __ mov(a0, result_register()); // Value. | 4501 __ mov(a0, result_register()); // Value. |
4502 __ Pop(a2, a1); // a1 = key, a2 = receiver. | 4502 __ Pop(a2, a1); // a1 = key, a2 = receiver. |
4503 Handle<Code> ic = is_classic_mode() | 4503 Handle<Code> ic = is_sloppy_mode() |
4504 ? isolate()->builtins()->KeyedStoreIC_Initialize() | 4504 ? isolate()->builtins()->KeyedStoreIC_Initialize() |
4505 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); | 4505 : isolate()->builtins()->KeyedStoreIC_Initialize_Strict(); |
4506 CallIC(ic, expr->CountStoreFeedbackId()); | 4506 CallIC(ic, expr->CountStoreFeedbackId()); |
4507 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4507 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4508 if (expr->is_postfix()) { | 4508 if (expr->is_postfix()) { |
4509 if (!context()->IsEffect()) { | 4509 if (!context()->IsEffect()) { |
4510 context()->PlugTOS(); | 4510 context()->PlugTOS(); |
4511 } | 4511 } |
4512 } else { | 4512 } else { |
4513 context()->Plug(v0); | 4513 context()->Plug(v0); |
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4954 Assembler::target_address_at(pc_immediate_load_address)) == | 4954 Assembler::target_address_at(pc_immediate_load_address)) == |
4955 reinterpret_cast<uint32_t>( | 4955 reinterpret_cast<uint32_t>( |
4956 isolate->builtins()->OsrAfterStackCheck()->entry())); | 4956 isolate->builtins()->OsrAfterStackCheck()->entry())); |
4957 return OSR_AFTER_STACK_CHECK; | 4957 return OSR_AFTER_STACK_CHECK; |
4958 } | 4958 } |
4959 | 4959 |
4960 | 4960 |
4961 } } // namespace v8::internal | 4961 } } // namespace v8::internal |
4962 | 4962 |
4963 #endif // V8_TARGET_ARCH_MIPS | 4963 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |