OLD | NEW |
---|---|
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2355 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2355 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2356 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 2356 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); |
2357 __ CallStub(&stub); | 2357 __ CallStub(&stub); |
2358 RecordJSReturnSite(expr); | 2358 RecordJSReturnSite(expr); |
2359 // Restore context register. | 2359 // Restore context register. |
2360 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 2360 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
2361 context()->DropAndPlug(1, r0); | 2361 context()->DropAndPlug(1, r0); |
2362 } | 2362 } |
2363 | 2363 |
2364 | 2364 |
2365 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, | |
2366 int arg_count) { | |
2367 // Push copy of the first argument or undefined if it doesn't exist. | |
2368 if (arg_count > 0) { | |
2369 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); | |
2370 } else { | |
2371 __ LoadRoot(r1, Heap::kUndefinedValueRootIndex); | |
2372 } | |
2373 __ push(r1); | |
2374 | |
2375 // Push the receiver of the enclosing function and do runtime call. | |
2376 __ ldr(r1, | |
Mads Ager (chromium)
2011/03/01 15:13:22
Looks like this would fit on one line?
| |
2377 MemOperand(fp, (2 + scope()->num_parameters()) * kPointerSize)); | |
2378 __ push(r1); | |
2379 // Push the strict mode flag. | |
2380 __ mov(r1, Operand(Smi::FromInt(strict_mode_flag()))); | |
2381 __ push(r1); | |
2382 | |
2383 __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP | |
2384 ? Runtime::kResolvePossiblyDirectEvalNoLookup | |
2385 : Runtime::kResolvePossiblyDirectEval, 4); | |
2386 } | |
2387 | |
2388 | |
2365 void FullCodeGenerator::VisitCall(Call* expr) { | 2389 void FullCodeGenerator::VisitCall(Call* expr) { |
2366 #ifdef DEBUG | 2390 #ifdef DEBUG |
2367 // We want to verify that RecordJSReturnSite gets called on all paths | 2391 // We want to verify that RecordJSReturnSite gets called on all paths |
2368 // through this function. Avoid early returns. | 2392 // through this function. Avoid early returns. |
2369 expr->return_is_recorded_ = false; | 2393 expr->return_is_recorded_ = false; |
2370 #endif | 2394 #endif |
2371 | 2395 |
2372 Comment cmnt(masm_, "[ Call"); | 2396 Comment cmnt(masm_, "[ Call"); |
2373 Expression* fun = expr->expression(); | 2397 Expression* fun = expr->expression(); |
2374 Variable* var = fun->AsVariableProxy()->AsVariable(); | 2398 Variable* var = fun->AsVariableProxy()->AsVariable(); |
2375 | 2399 |
2376 if (var != NULL && var->is_possibly_eval()) { | 2400 if (var != NULL && var->is_possibly_eval()) { |
2377 // In a call to eval, we first call %ResolvePossiblyDirectEval to | 2401 // In a call to eval, we first call %ResolvePossiblyDirectEval to |
2378 // resolve the function we need to call and the receiver of the | 2402 // resolve the function we need to call and the receiver of the |
2379 // call. Then we call the resolved function using the given | 2403 // call. Then we call the resolved function using the given |
2380 // arguments. | 2404 // arguments. |
2381 ZoneList<Expression*>* args = expr->arguments(); | 2405 ZoneList<Expression*>* args = expr->arguments(); |
2382 int arg_count = args->length(); | 2406 int arg_count = args->length(); |
2383 | 2407 |
2384 { PreservePositionScope pos_scope(masm()->positions_recorder()); | 2408 { PreservePositionScope pos_scope(masm()->positions_recorder()); |
2385 VisitForStackValue(fun); | 2409 VisitForStackValue(fun); |
2386 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); | 2410 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); |
2387 __ push(r2); // Reserved receiver slot. | 2411 __ push(r2); // Reserved receiver slot. |
2388 | 2412 |
2389 // Push the arguments. | 2413 // Push the arguments. |
2390 for (int i = 0; i < arg_count; i++) { | 2414 for (int i = 0; i < arg_count; i++) { |
2391 VisitForStackValue(args->at(i)); | 2415 VisitForStackValue(args->at(i)); |
2392 } | 2416 } |
2393 | 2417 |
2394 // Push copy of the function - found below the arguments. | 2418 // If we know that eval can only be shadowed by eval-introduced |
2419 // variables we attempt to load the global eval function directly | |
2420 // in generated code. If we succeed, there is no need to perform a | |
2421 // context lookup in the runtime system. | |
2422 Label done; | |
2423 if (var->AsSlot() != NULL && var->mode() == Variable::DYNAMIC_GLOBAL) { | |
2424 Label slow; | |
2425 EmitLoadGlobalSlotCheckExtensions(var->AsSlot(), | |
2426 NOT_INSIDE_TYPEOF, | |
2427 &slow); | |
2428 // Push the function and resolve eval. | |
2429 __ push(r0); | |
2430 EmitResolvePossiblyDirectEval(SKIP_CONTEXT_LOOKUP, arg_count); | |
2431 __ jmp(&done); | |
2432 __ bind(&slow); | |
2433 } | |
2434 | |
2435 // Push copy of the function (found below the arguments) and | |
2436 // resolve eval. | |
2395 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2437 __ ldr(r1, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2396 __ push(r1); | 2438 __ push(r1); |
2397 | 2439 EmitResolvePossiblyDirectEval(PERFORM_CONTEXT_LOOKUP, arg_count); |
2398 // Push copy of the first argument or undefined if it doesn't exist. | 2440 if (done.is_linked()) { |
2399 if (arg_count > 0) { | 2441 __ bind(&done); |
2400 __ ldr(r1, MemOperand(sp, arg_count * kPointerSize)); | |
2401 __ push(r1); | |
2402 } else { | |
2403 __ push(r2); | |
2404 } | 2442 } |
2405 | 2443 |
2406 // Push the receiver of the enclosing function and do runtime call. | |
2407 __ ldr(r1, | |
2408 MemOperand(fp, (2 + scope()->num_parameters()) * kPointerSize)); | |
2409 __ push(r1); | |
2410 // Push the strict mode flag. | |
2411 __ mov(r1, Operand(Smi::FromInt(strict_mode_flag()))); | |
2412 __ push(r1); | |
2413 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 4); | |
2414 | |
2415 // The runtime call returns a pair of values in r0 (function) and | 2444 // The runtime call returns a pair of values in r0 (function) and |
2416 // r1 (receiver). Touch up the stack with the right values. | 2445 // r1 (receiver). Touch up the stack with the right values. |
2417 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); | 2446 __ str(r0, MemOperand(sp, (arg_count + 1) * kPointerSize)); |
2418 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); | 2447 __ str(r1, MemOperand(sp, arg_count * kPointerSize)); |
2419 } | 2448 } |
2420 | 2449 |
2421 // Record source position for debugger. | 2450 // Record source position for debugger. |
2422 SetSourcePosition(expr->position()); | 2451 SetSourcePosition(expr->position()); |
2423 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2452 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2424 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 2453 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); |
(...skipping 1754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4179 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. | 4208 __ mov(r1, Operand(r1, ASR, 1)); // Un-smi-tag value. |
4180 __ add(pc, r1, Operand(masm_->CodeObject())); | 4209 __ add(pc, r1, Operand(masm_->CodeObject())); |
4181 } | 4210 } |
4182 | 4211 |
4183 | 4212 |
4184 #undef __ | 4213 #undef __ |
4185 | 4214 |
4186 } } // namespace v8::internal | 4215 } } // namespace v8::internal |
4187 | 4216 |
4188 #endif // V8_TARGET_ARCH_ARM | 4217 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |