Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/debug/debug-evaluate.h" | 5 #include "src/debug/debug-evaluate.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/contexts.h" | 8 #include "src/contexts.h" |
| 9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
| 10 #include "src/debug/debug-frames.h" | 10 #include "src/debug/debug-frames.h" |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 264 // FunctionGetArguments can't throw an exception. | 264 // FunctionGetArguments can't throw an exception. |
| 265 Handle<JSObject> arguments = | 265 Handle<JSObject> arguments = |
| 266 Handle<JSObject>::cast(Accessors::FunctionGetArguments(function)); | 266 Handle<JSObject>::cast(Accessors::FunctionGetArguments(function)); |
| 267 Handle<String> arguments_str = isolate_->factory()->arguments_string(); | 267 Handle<String> arguments_str = isolate_->factory()->arguments_string(); |
| 268 JSObject::SetOwnPropertyIgnoreAttributes(target, arguments_str, arguments, | 268 JSObject::SetOwnPropertyIgnoreAttributes(target, arguments_str, arguments, |
| 269 NONE) | 269 NONE) |
| 270 .Check(); | 270 .Check(); |
| 271 } | 271 } |
| 272 | 272 |
| 273 | 273 |
| 274 // Iterate the context chain until a function context of a non-arrow function. | |
| 275 // Return whether that function context-allocates the receiver. | |
| 276 bool HasContextAllocatedReceiver(Context* context) { | |
| 277 DisallowHeapAllocation no_gc; | |
| 278 while (!context->IsNativeContext() && !context->IsScriptContext()) { | |
|
Michael Starzinger
2015/12/07 10:42:57
This iteration seems to walk the context chain unt
| |
| 279 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); | |
| 280 if (scope_info->HasReceiver()) { | |
| 281 // Normal function. If the receiver is not context-allocated, we won't be | |
| 282 // able to find the correct receiver value. | |
| 283 return scope_info->HasContextAllocatedReceiver(); | |
| 284 } | |
| 285 context = context->previous(); | |
| 286 } | |
| 287 return false; | |
| 288 } | |
| 289 | |
| 290 | |
| 274 Handle<Context> DebugEvaluate::ContextBuilder::MaterializeReceiver( | 291 Handle<Context> DebugEvaluate::ContextBuilder::MaterializeReceiver( |
| 275 Handle<Context> target, Handle<JSFunction> function) { | 292 Handle<Context> target, Handle<JSFunction> function) { |
| 276 Handle<SharedFunctionInfo> shared(function->shared()); | 293 Handle<SharedFunctionInfo> shared(function->shared()); |
| 277 Handle<ScopeInfo> scope_info(shared->scope_info()); | 294 Handle<ScopeInfo> scope_info(shared->scope_info()); |
| 278 Handle<Object> receiver; | 295 Handle<Object> receiver; |
| 279 switch (scope_info->scope_type()) { | 296 switch (scope_info->scope_type()) { |
| 280 case FUNCTION_SCOPE: { | 297 case FUNCTION_SCOPE: { |
| 281 VariableMode mode; | 298 // Use existing context if it already includes "this". |
| 282 InitializationFlag init_flag; | 299 if (scope_info->ReceiverContextSlotIndex() >= 0) return target; |
| 283 MaybeAssignedFlag maybe_assigned_flag; | 300 if (!scope_info->HasReceiver()) { |
| 284 | 301 // Arrow functions do not have an own receiver. It is resolved like any |
| 285 // Don't bother creating a fake context node if "this" is in the context | 302 // other variable from outer scopes. If it's not context-allocated in |
| 286 // already. | 303 // outer contexts, we cannot find its value. In that case, prevent |
| 287 if (ScopeInfo::ContextSlotIndex(scope_info, | 304 // resolving to the incorrect "this" by defaulting to undefined. |
| 288 isolate_->factory()->this_string(), &mode, | 305 if (HasContextAllocatedReceiver(*target)) { |
| 289 &init_flag, &maybe_assigned_flag) >= 0) { | 306 return target; |
| 290 return target; | 307 } else { |
| 308 receiver = isolate_->factory()->undefined_value(); | |
| 309 } | |
| 310 } else { | |
| 311 receiver = handle(frame_->receiver(), isolate_); | |
| 291 } | 312 } |
| 292 receiver = handle(frame_->receiver(), isolate_); | |
| 293 break; | 313 break; |
| 294 } | 314 } |
| 295 case MODULE_SCOPE: | 315 case MODULE_SCOPE: |
| 296 receiver = isolate_->factory()->undefined_value(); | 316 receiver = isolate_->factory()->undefined_value(); |
| 297 break; | 317 break; |
| 298 case SCRIPT_SCOPE: | 318 case SCRIPT_SCOPE: |
| 299 receiver = handle(function->global_proxy(), isolate_); | 319 receiver = handle(function->global_proxy(), isolate_); |
| 300 break; | 320 break; |
| 301 default: | 321 default: |
| 302 // For eval code, arrow functions, and the like, there's no "this" binding | 322 // For eval code, there's no "this" binding to materialize. |
| 303 // to materialize. | |
| 304 return target; | 323 return target; |
| 305 } | 324 } |
| 306 | 325 |
| 307 return isolate_->factory()->NewCatchContext( | 326 return isolate_->factory()->NewCatchContext( |
| 308 function, target, isolate_->factory()->this_string(), receiver); | 327 function, target, isolate_->factory()->this_string(), receiver); |
| 309 } | 328 } |
| 310 | 329 |
| 311 } // namespace internal | 330 } // namespace internal |
| 312 } // namespace v8 | 331 } // namespace v8 |
| OLD | NEW |