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 2265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2276 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2276 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2277 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 2277 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); |
2278 __ CallStub(&stub); | 2278 __ CallStub(&stub); |
2279 RecordJSReturnSite(expr); | 2279 RecordJSReturnSite(expr); |
2280 // Restore context register. | 2280 // Restore context register. |
2281 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2281 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
2282 context()->DropAndPlug(1, eax); | 2282 context()->DropAndPlug(1, eax); |
2283 } | 2283 } |
2284 | 2284 |
2285 | 2285 |
| 2286 void FullCodeGenerator::EmitResolvePossiblyDirectEval(ResolveEvalFlag flag, |
| 2287 int arg_count) { |
| 2288 // Push copy of the first argument or undefined if it doesn't exist. |
| 2289 if (arg_count > 0) { |
| 2290 __ push(Operand(esp, arg_count * kPointerSize)); |
| 2291 } else { |
| 2292 __ push(Immediate(Factory::undefined_value())); |
| 2293 } |
| 2294 |
| 2295 // Push the receiver of the enclosing function. |
| 2296 __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize)); |
| 2297 |
| 2298 // Push the strict mode flag. |
| 2299 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); |
| 2300 |
| 2301 __ CallRuntime(flag == SKIP_CONTEXT_LOOKUP |
| 2302 ? Runtime::kResolvePossiblyDirectEvalNoLookup |
| 2303 : Runtime::kResolvePossiblyDirectEval, 4); |
| 2304 } |
| 2305 |
| 2306 |
2286 void FullCodeGenerator::VisitCall(Call* expr) { | 2307 void FullCodeGenerator::VisitCall(Call* expr) { |
2287 #ifdef DEBUG | 2308 #ifdef DEBUG |
2288 // We want to verify that RecordJSReturnSite gets called on all paths | 2309 // We want to verify that RecordJSReturnSite gets called on all paths |
2289 // through this function. Avoid early returns. | 2310 // through this function. Avoid early returns. |
2290 expr->return_is_recorded_ = false; | 2311 expr->return_is_recorded_ = false; |
2291 #endif | 2312 #endif |
2292 | 2313 |
2293 Comment cmnt(masm_, "[ Call"); | 2314 Comment cmnt(masm_, "[ Call"); |
2294 Expression* fun = expr->expression(); | 2315 Expression* fun = expr->expression(); |
2295 Variable* var = fun->AsVariableProxy()->AsVariable(); | 2316 Variable* var = fun->AsVariableProxy()->AsVariable(); |
2296 | 2317 |
2297 if (var != NULL && var->is_possibly_eval()) { | 2318 if (var != NULL && var->is_possibly_eval()) { |
2298 // In a call to eval, we first call %ResolvePossiblyDirectEval to | 2319 // In a call to eval, we first call %ResolvePossiblyDirectEval to |
2299 // resolve the function we need to call and the receiver of the | 2320 // resolve the function we need to call and the receiver of the |
2300 // call. Then we call the resolved function using the given | 2321 // call. Then we call the resolved function using the given |
2301 // arguments. | 2322 // arguments. |
2302 ZoneList<Expression*>* args = expr->arguments(); | 2323 ZoneList<Expression*>* args = expr->arguments(); |
2303 int arg_count = args->length(); | 2324 int arg_count = args->length(); |
2304 { PreservePositionScope pos_scope(masm()->positions_recorder()); | 2325 { PreservePositionScope pos_scope(masm()->positions_recorder()); |
2305 VisitForStackValue(fun); | 2326 VisitForStackValue(fun); |
2306 // Reserved receiver slot. | 2327 // Reserved receiver slot. |
2307 __ push(Immediate(Factory::undefined_value())); | 2328 __ push(Immediate(Factory::undefined_value())); |
2308 | 2329 |
2309 // Push the arguments. | 2330 // Push the arguments. |
2310 for (int i = 0; i < arg_count; i++) { | 2331 for (int i = 0; i < arg_count; i++) { |
2311 VisitForStackValue(args->at(i)); | 2332 VisitForStackValue(args->at(i)); |
2312 } | 2333 } |
2313 | 2334 |
2314 // Push copy of the function - found below the arguments. | 2335 // If we know that eval can only be shadowed by eval-introduced |
2315 __ push(Operand(esp, (arg_count + 1) * kPointerSize)); | 2336 // variables we attempt to load the global eval function directly |
2316 | 2337 // in generated code. If we succeed, there is no need to perform a |
2317 // Push copy of the first argument or undefined if it doesn't exist. | 2338 // context lookup in the runtime system. |
2318 if (arg_count > 0) { | 2339 Label done; |
2319 __ push(Operand(esp, arg_count * kPointerSize)); | 2340 if (var->AsSlot() != NULL && var->mode() == Variable::DYNAMIC_GLOBAL) { |
2320 } else { | 2341 Label slow; |
2321 __ push(Immediate(Factory::undefined_value())); | 2342 EmitLoadGlobalSlotCheckExtensions(var->AsSlot(), |
| 2343 NOT_INSIDE_TYPEOF, |
| 2344 &slow); |
| 2345 // Push the function and resolve eval. |
| 2346 __ push(eax); |
| 2347 EmitResolvePossiblyDirectEval(SKIP_CONTEXT_LOOKUP, arg_count); |
| 2348 __ jmp(&done); |
| 2349 __ bind(&slow); |
2322 } | 2350 } |
2323 | 2351 |
2324 // Push the receiver of the enclosing function and do runtime call. | 2352 // Push copy of the function (found below the arguments) and |
2325 __ push(Operand(ebp, (2 + scope()->num_parameters()) * kPointerSize)); | 2353 // resolve eval. |
2326 // Push the strict mode flag. | 2354 __ push(Operand(esp, (arg_count + 1) * kPointerSize)); |
2327 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); | 2355 EmitResolvePossiblyDirectEval(PERFORM_CONTEXT_LOOKUP, arg_count); |
2328 __ CallRuntime(Runtime::kResolvePossiblyDirectEval, 4); | 2356 if (done.is_linked()) { |
| 2357 __ bind(&done); |
| 2358 } |
2329 | 2359 |
2330 // The runtime call returns a pair of values in eax (function) and | 2360 // The runtime call returns a pair of values in eax (function) and |
2331 // edx (receiver). Touch up the stack with the right values. | 2361 // edx (receiver). Touch up the stack with the right values. |
2332 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx); | 2362 __ mov(Operand(esp, (arg_count + 0) * kPointerSize), edx); |
2333 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); | 2363 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); |
2334 } | 2364 } |
2335 // Record source position for debugger. | 2365 // Record source position for debugger. |
2336 SetSourcePosition(expr->position()); | 2366 SetSourcePosition(expr->position()); |
2337 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; | 2367 InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
2338 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); | 2368 CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_VALUE); |
(...skipping 2114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4453 // And return. | 4483 // And return. |
4454 __ ret(0); | 4484 __ ret(0); |
4455 } | 4485 } |
4456 | 4486 |
4457 | 4487 |
4458 #undef __ | 4488 #undef __ |
4459 | 4489 |
4460 } } // namespace v8::internal | 4490 } } // namespace v8::internal |
4461 | 4491 |
4462 #endif // V8_TARGET_ARCH_IA32 | 4492 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |