| 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 |