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

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 2487483004: Only treat possible eval calls going through 'with' as special. (Closed)
Patch Set: Rebase Created 4 years, 1 month 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
« no previous file with comments | « src/ast/ast.cc ('k') | src/full-codegen/full-codegen.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/ast-graph-builder.h" 5 #include "src/compiler/ast-graph-builder.h"
6 6
7 #include "src/ast/compile-time-value.h" 7 #include "src/ast/compile-time-value.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/compilation-info.h" 9 #include "src/compilation-info.h"
10 #include "src/compiler.h" 10 #include "src/compiler.h"
(...skipping 2267 matching lines...) Expand 10 before | Expand all | Expand 10 after
2278 2278
2279 void AstGraphBuilder::VisitCall(Call* expr) { 2279 void AstGraphBuilder::VisitCall(Call* expr) {
2280 Expression* callee = expr->expression(); 2280 Expression* callee = expr->expression();
2281 Call::CallType call_type = expr->GetCallType(); 2281 Call::CallType call_type = expr->GetCallType();
2282 2282
2283 // Prepare the callee and the receiver to the function call. This depends on 2283 // Prepare the callee and the receiver to the function call. This depends on
2284 // the semantics of the underlying call type. 2284 // the semantics of the underlying call type.
2285 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny; 2285 ConvertReceiverMode receiver_hint = ConvertReceiverMode::kAny;
2286 Node* receiver_value = nullptr; 2286 Node* receiver_value = nullptr;
2287 Node* callee_value = nullptr; 2287 Node* callee_value = nullptr;
2288 bool possibly_eval = false; 2288 if (expr->is_possibly_eval()) {
2289 switch (call_type) { 2289 if (callee->AsVariableProxy()->var()->IsLookupSlot()) {
2290 case Call::GLOBAL_CALL: {
2291 VariableProxy* proxy = callee->AsVariableProxy();
2292 VectorSlotPair pair = CreateVectorSlotPair(proxy->VariableFeedbackSlot());
2293 PrepareEagerCheckpoint(BeforeId(proxy));
2294 callee_value = BuildVariableLoad(proxy->var(), expr->expression()->id(),
2295 pair, OutputFrameStateCombine::Push());
2296 receiver_hint = ConvertReceiverMode::kNullOrUndefined;
2297 receiver_value = jsgraph()->UndefinedConstant();
2298 break;
2299 }
2300 case Call::WITH_CALL: {
2301 Variable* variable = callee->AsVariableProxy()->var(); 2290 Variable* variable = callee->AsVariableProxy()->var();
2302 DCHECK(variable->location() == VariableLocation::LOOKUP);
2303 Node* name = jsgraph()->Constant(variable->name()); 2291 Node* name = jsgraph()->Constant(variable->name());
2304 const Operator* op = 2292 const Operator* op =
2305 javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall); 2293 javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall);
2306 Node* pair = NewNode(op, name); 2294 Node* pair = NewNode(op, name);
2307 callee_value = NewNode(common()->Projection(0), pair); 2295 callee_value = NewNode(common()->Projection(0), pair);
2308 receiver_value = NewNode(common()->Projection(1), pair); 2296 receiver_value = NewNode(common()->Projection(1), pair);
2309 PrepareFrameState(pair, expr->LookupId(), 2297 PrepareFrameState(pair, expr->LookupId(),
2310 OutputFrameStateCombine::Push(2)); 2298 OutputFrameStateCombine::Push(2));
2311 break; 2299 } else {
2300 VisitForValue(callee);
2301 callee_value = environment()->Pop();
2302 receiver_hint = ConvertReceiverMode::kNullOrUndefined;
2303 receiver_value = jsgraph()->UndefinedConstant();
2312 } 2304 }
2313 case Call::NAMED_PROPERTY_CALL: { 2305 } else {
2314 Property* property = callee->AsProperty(); 2306 switch (call_type) {
2315 VectorSlotPair feedback = 2307 case Call::GLOBAL_CALL: {
2316 CreateVectorSlotPair(property->PropertyFeedbackSlot()); 2308 VariableProxy* proxy = callee->AsVariableProxy();
2317 VisitForValue(property->obj()); 2309 VectorSlotPair pair =
2318 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); 2310 CreateVectorSlotPair(proxy->VariableFeedbackSlot());
2319 Node* object = environment()->Top(); 2311 PrepareEagerCheckpoint(BeforeId(proxy));
2320 callee_value = BuildNamedLoad(object, name, feedback); 2312 callee_value = BuildVariableLoad(proxy->var(), expr->expression()->id(),
2321 PrepareFrameState(callee_value, property->LoadId(), 2313 pair, OutputFrameStateCombine::Push());
2322 OutputFrameStateCombine::Push()); 2314 receiver_hint = ConvertReceiverMode::kNullOrUndefined;
2323 // Note that a property call requires the receiver to be wrapped into 2315 receiver_value = jsgraph()->UndefinedConstant();
2324 // an object for sloppy callees. However the receiver is guaranteed 2316 break;
2325 // not to be null or undefined at this point. 2317 }
2326 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined; 2318 case Call::WITH_CALL: {
2327 receiver_value = environment()->Pop();
2328 break;
2329 }
2330 case Call::KEYED_PROPERTY_CALL: {
2331 Property* property = callee->AsProperty();
2332 VectorSlotPair feedback =
2333 CreateVectorSlotPair(property->PropertyFeedbackSlot());
2334 VisitForValue(property->obj());
2335 VisitForValue(property->key());
2336 Node* key = environment()->Pop();
2337 Node* object = environment()->Top();
2338 callee_value = BuildKeyedLoad(object, key, feedback);
2339 PrepareFrameState(callee_value, property->LoadId(),
2340 OutputFrameStateCombine::Push());
2341 // Note that a property call requires the receiver to be wrapped into
2342 // an object for sloppy callees. However the receiver is guaranteed
2343 // not to be null or undefined at this point.
2344 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
2345 receiver_value = environment()->Pop();
2346 break;
2347 }
2348 case Call::NAMED_SUPER_PROPERTY_CALL: {
2349 Property* property = callee->AsProperty();
2350 SuperPropertyReference* super_ref =
2351 property->obj()->AsSuperPropertyReference();
2352 VisitForValue(super_ref->home_object());
2353 VisitForValue(super_ref->this_var());
2354 Node* home = environment()->Peek(1);
2355 Node* object = environment()->Top();
2356 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2357 callee_value = BuildNamedSuperLoad(object, home, name, VectorSlotPair());
2358 PrepareFrameState(callee_value, property->LoadId(),
2359 OutputFrameStateCombine::Push());
2360 // Note that a property call requires the receiver to be wrapped into
2361 // an object for sloppy callees. Since the receiver is not the target of
2362 // the load, it could very well be null or undefined at this point.
2363 receiver_value = environment()->Pop();
2364 environment()->Drop(1);
2365 break;
2366 }
2367 case Call::KEYED_SUPER_PROPERTY_CALL: {
2368 Property* property = callee->AsProperty();
2369 SuperPropertyReference* super_ref =
2370 property->obj()->AsSuperPropertyReference();
2371 VisitForValue(super_ref->home_object());
2372 VisitForValue(super_ref->this_var());
2373 environment()->Push(environment()->Top()); // Duplicate this_var.
2374 environment()->Push(environment()->Peek(2)); // Duplicate home_obj.
2375 VisitForValue(property->key());
2376 Node* key = environment()->Pop();
2377 Node* home = environment()->Pop();
2378 Node* object = environment()->Pop();
2379 callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair());
2380 PrepareFrameState(callee_value, property->LoadId(),
2381 OutputFrameStateCombine::Push());
2382 // Note that a property call requires the receiver to be wrapped into
2383 // an object for sloppy callees. Since the receiver is not the target of
2384 // the load, it could very well be null or undefined at this point.
2385 receiver_value = environment()->Pop();
2386 environment()->Drop(1);
2387 break;
2388 }
2389 case Call::SUPER_CALL:
2390 return VisitCallSuper(expr);
2391 case Call::POSSIBLY_EVAL_CALL:
2392 possibly_eval = true;
2393 if (callee->AsVariableProxy()->var()->IsLookupSlot()) {
2394 Variable* variable = callee->AsVariableProxy()->var(); 2319 Variable* variable = callee->AsVariableProxy()->var();
2395 Node* name = jsgraph()->Constant(variable->name()); 2320 Node* name = jsgraph()->Constant(variable->name());
2396 const Operator* op = 2321 const Operator* op =
2397 javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall); 2322 javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall);
2398 Node* pair = NewNode(op, name); 2323 Node* pair = NewNode(op, name);
2399 callee_value = NewNode(common()->Projection(0), pair); 2324 callee_value = NewNode(common()->Projection(0), pair);
2400 receiver_value = NewNode(common()->Projection(1), pair); 2325 receiver_value = NewNode(common()->Projection(1), pair);
2401 PrepareFrameState(pair, expr->LookupId(), 2326 PrepareFrameState(pair, expr->LookupId(),
2402 OutputFrameStateCombine::Push(2)); 2327 OutputFrameStateCombine::Push(2));
2328 }
2329 case Call::NAMED_PROPERTY_CALL: {
2330 Property* property = callee->AsProperty();
2331 VectorSlotPair feedback =
2332 CreateVectorSlotPair(property->PropertyFeedbackSlot());
2333 VisitForValue(property->obj());
2334 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2335 Node* object = environment()->Top();
2336 callee_value = BuildNamedLoad(object, name, feedback);
2337 PrepareFrameState(callee_value, property->LoadId(),
2338 OutputFrameStateCombine::Push());
2339 // Note that a property call requires the receiver to be wrapped into
2340 // an object for sloppy callees. However the receiver is guaranteed
2341 // not to be null or undefined at this point.
2342 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
2343 receiver_value = environment()->Pop();
2403 break; 2344 break;
2404 } 2345 }
2405 // Fall through. 2346 case Call::KEYED_PROPERTY_CALL: {
2406 case Call::OTHER_CALL: 2347 Property* property = callee->AsProperty();
2407 VisitForValue(callee); 2348 VectorSlotPair feedback =
2408 callee_value = environment()->Pop(); 2349 CreateVectorSlotPair(property->PropertyFeedbackSlot());
2409 receiver_hint = ConvertReceiverMode::kNullOrUndefined; 2350 VisitForValue(property->obj());
2410 receiver_value = jsgraph()->UndefinedConstant(); 2351 VisitForValue(property->key());
2411 break; 2352 Node* key = environment()->Pop();
2353 Node* object = environment()->Top();
2354 callee_value = BuildKeyedLoad(object, key, feedback);
2355 PrepareFrameState(callee_value, property->LoadId(),
2356 OutputFrameStateCombine::Push());
2357 // Note that a property call requires the receiver to be wrapped into
2358 // an object for sloppy callees. However the receiver is guaranteed
2359 // not to be null or undefined at this point.
2360 receiver_hint = ConvertReceiverMode::kNotNullOrUndefined;
2361 receiver_value = environment()->Pop();
2362 break;
2363 }
2364 case Call::NAMED_SUPER_PROPERTY_CALL: {
2365 Property* property = callee->AsProperty();
2366 SuperPropertyReference* super_ref =
2367 property->obj()->AsSuperPropertyReference();
2368 VisitForValue(super_ref->home_object());
2369 VisitForValue(super_ref->this_var());
2370 Node* home = environment()->Peek(1);
2371 Node* object = environment()->Top();
2372 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName();
2373 callee_value =
2374 BuildNamedSuperLoad(object, home, name, VectorSlotPair());
2375 PrepareFrameState(callee_value, property->LoadId(),
2376 OutputFrameStateCombine::Push());
2377 // Note that a property call requires the receiver to be wrapped into
2378 // an object for sloppy callees. Since the receiver is not the target of
2379 // the load, it could very well be null or undefined at this point.
2380 receiver_value = environment()->Pop();
2381 environment()->Drop(1);
2382 break;
2383 }
2384 case Call::KEYED_SUPER_PROPERTY_CALL: {
2385 Property* property = callee->AsProperty();
2386 SuperPropertyReference* super_ref =
2387 property->obj()->AsSuperPropertyReference();
2388 VisitForValue(super_ref->home_object());
2389 VisitForValue(super_ref->this_var());
2390 environment()->Push(environment()->Top()); // Duplicate this_var.
2391 environment()->Push(environment()->Peek(2)); // Duplicate home_obj.
2392 VisitForValue(property->key());
2393 Node* key = environment()->Pop();
2394 Node* home = environment()->Pop();
2395 Node* object = environment()->Pop();
2396 callee_value = BuildKeyedSuperLoad(object, home, key, VectorSlotPair());
2397 PrepareFrameState(callee_value, property->LoadId(),
2398 OutputFrameStateCombine::Push());
2399 // Note that a property call requires the receiver to be wrapped into
2400 // an object for sloppy callees. Since the receiver is not the target of
2401 // the load, it could very well be null or undefined at this point.
2402 receiver_value = environment()->Pop();
2403 environment()->Drop(1);
2404 break;
2405 }
2406 case Call::SUPER_CALL:
2407 return VisitCallSuper(expr);
2408 case Call::OTHER_CALL:
2409 VisitForValue(callee);
2410 callee_value = environment()->Pop();
2411 receiver_hint = ConvertReceiverMode::kNullOrUndefined;
2412 receiver_value = jsgraph()->UndefinedConstant();
2413 break;
2414 }
2412 } 2415 }
2413 2416
2414 // The callee and the receiver both have to be pushed onto the operand stack 2417 // The callee and the receiver both have to be pushed onto the operand stack
2415 // before arguments are being evaluated. 2418 // before arguments are being evaluated.
2416 environment()->Push(callee_value); 2419 environment()->Push(callee_value);
2417 environment()->Push(receiver_value); 2420 environment()->Push(receiver_value);
2418 2421
2419 // Evaluate all arguments to the function call, 2422 // Evaluate all arguments to the function call,
2420 ZoneList<Expression*>* args = expr->arguments(); 2423 ZoneList<Expression*>* args = expr->arguments();
2421 VisitForValues(args); 2424 VisitForValues(args);
2422 2425
2423 // Resolve callee for a potential direct eval call. This block will mutate the 2426 // Resolve callee for a potential direct eval call. This block will mutate the
2424 // callee value pushed onto the environment. 2427 // callee value pushed onto the environment.
2425 if (possibly_eval && args->length() > 0) { 2428 if (expr->is_possibly_eval() && args->length() > 0) {
2426 int arg_count = args->length(); 2429 int arg_count = args->length();
2427 2430
2428 // Extract callee and source string from the environment. 2431 // Extract callee and source string from the environment.
2429 Node* callee = environment()->Peek(arg_count + 1); 2432 Node* callee = environment()->Peek(arg_count + 1);
2430 Node* source = environment()->Peek(arg_count - 1); 2433 Node* source = environment()->Peek(arg_count - 1);
2431 2434
2432 // Create node to ask for help resolving potential eval call. This will 2435 // Create node to ask for help resolving potential eval call. This will
2433 // provide a fully resolved callee to patch into the environment. 2436 // provide a fully resolved callee to patch into the environment.
2434 Node* function = GetFunctionClosure(); 2437 Node* function = GetFunctionClosure();
2435 Node* language = jsgraph()->Constant(language_mode()); 2438 Node* language = jsgraph()->Constant(language_mode());
(...skipping 10 matching lines...) Expand all
2446 // Patch callee on the environment. 2449 // Patch callee on the environment.
2447 environment()->Poke(arg_count + 1, new_callee); 2450 environment()->Poke(arg_count + 1, new_callee);
2448 } 2451 }
2449 2452
2450 // Create node to perform the function call. 2453 // Create node to perform the function call.
2451 float const frequency = ComputeCallFrequency(expr->CallFeedbackICSlot()); 2454 float const frequency = ComputeCallFrequency(expr->CallFeedbackICSlot());
2452 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); 2455 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot());
2453 const Operator* call = 2456 const Operator* call =
2454 javascript()->CallFunction(args->length() + 2, frequency, feedback, 2457 javascript()->CallFunction(args->length() + 2, frequency, feedback,
2455 receiver_hint, expr->tail_call_mode()); 2458 receiver_hint, expr->tail_call_mode());
2456 PrepareEagerCheckpoint(possibly_eval ? expr->EvalId() : expr->CallId()); 2459 PrepareEagerCheckpoint(expr->is_possibly_eval() ? expr->EvalId()
2460 : expr->CallId());
2457 Node* value = ProcessArguments(call, args->length() + 2); 2461 Node* value = ProcessArguments(call, args->length() + 2);
2458 // The callee passed to the call, we just need to push something here to 2462 // The callee passed to the call, we just need to push something here to
2459 // satisfy the bailout location contract. The fullcodegen code will not 2463 // satisfy the bailout location contract. The fullcodegen code will not
2460 // ever look at this value, so we just push optimized_out here. 2464 // ever look at this value, so we just push optimized_out here.
2461 environment()->Push(jsgraph()->OptimizedOutConstant()); 2465 environment()->Push(jsgraph()->OptimizedOutConstant());
2462 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); 2466 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push());
2463 environment()->Drop(1); 2467 environment()->Drop(1);
2464 ast_context()->ProduceValue(expr, value); 2468 ast_context()->ProduceValue(expr, value);
2465 } 2469 }
2466 2470
(...skipping 1892 matching lines...) Expand 10 before | Expand all | Expand 10 after
4359 // Phi does not exist yet, introduce one. 4363 // Phi does not exist yet, introduce one.
4360 value = NewPhi(inputs, value, control); 4364 value = NewPhi(inputs, value, control);
4361 value->ReplaceInput(inputs - 1, other); 4365 value->ReplaceInput(inputs - 1, other);
4362 } 4366 }
4363 return value; 4367 return value;
4364 } 4368 }
4365 4369
4366 } // namespace compiler 4370 } // namespace compiler
4367 } // namespace internal 4371 } // namespace internal
4368 } // namespace v8 4372 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/ast.cc ('k') | src/full-codegen/full-codegen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698