| 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-scopes.h" | 5 #include "src/debug/debug-scopes.h" |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/compiler.h" |
| 8 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
| 9 #include "src/frames-inl.h" | 10 #include "src/frames-inl.h" |
| 10 #include "src/globals.h" | 11 #include "src/globals.h" |
| 11 #include "src/isolate-inl.h" | 12 #include "src/isolate-inl.h" |
| 12 #include "src/parsing/parser.h" | 13 #include "src/parsing/parser.h" |
| 13 | 14 |
| 14 namespace v8 { | 15 namespace v8 { |
| 15 namespace internal { | 16 namespace internal { |
| 16 | 17 |
| 17 ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector, | 18 ScopeIterator::ScopeIterator(Isolate* isolate, FrameInspector* frame_inspector, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 } | 74 } |
| 74 if (scope_info->scope_type() == FUNCTION_SCOPE) { | 75 if (scope_info->scope_type() == FUNCTION_SCOPE) { |
| 75 nested_scope_chain_.Add(ExtendedScopeInfo(scope_info, | 76 nested_scope_chain_.Add(ExtendedScopeInfo(scope_info, |
| 76 shared_info->start_position(), | 77 shared_info->start_position(), |
| 77 shared_info->end_position())); | 78 shared_info->end_position())); |
| 78 } | 79 } |
| 79 if (!collect_non_locals) return; | 80 if (!collect_non_locals) return; |
| 80 } | 81 } |
| 81 | 82 |
| 82 // Reparse the code and analyze the scopes. | 83 // Reparse the code and analyze the scopes. |
| 83 Scope* scope = NULL; | |
| 84 // Check whether we are in global, eval or function code. | 84 // Check whether we are in global, eval or function code. |
| 85 Zone zone(isolate->allocator()); | 85 Zone zone(isolate->allocator()); |
| 86 base::SmartPointer<ParseInfo> info; |
| 86 if (scope_info->scope_type() != FUNCTION_SCOPE) { | 87 if (scope_info->scope_type() != FUNCTION_SCOPE) { |
| 87 // Global or eval code. | 88 // Global or eval code. |
| 88 Handle<Script> script(Script::cast(shared_info->script())); | 89 Handle<Script> script(Script::cast(shared_info->script())); |
| 89 ParseInfo info(&zone, script); | 90 info.Reset(new ParseInfo(&zone, script)); |
| 91 info->set_toplevel(); |
| 90 if (scope_info->scope_type() == SCRIPT_SCOPE) { | 92 if (scope_info->scope_type() == SCRIPT_SCOPE) { |
| 91 info.set_global(); | 93 info->set_global(); |
| 92 } else { | 94 } else { |
| 93 DCHECK(scope_info->scope_type() == EVAL_SCOPE); | 95 DCHECK(scope_info->scope_type() == EVAL_SCOPE); |
| 94 info.set_eval(); | 96 info->set_eval(); |
| 95 info.set_context(Handle<Context>(function->context())); | 97 info->set_context(Handle<Context>(function->context())); |
| 96 } | 98 } |
| 97 if (Parser::ParseStatic(&info) && Scope::Analyze(&info)) { | |
| 98 scope = info.literal()->scope(); | |
| 99 } | |
| 100 if (!ignore_nested_scopes) RetrieveScopeChain(scope); | |
| 101 if (collect_non_locals) CollectNonLocals(scope); | |
| 102 } else { | 99 } else { |
| 103 // Function code | 100 // Inner function. |
| 104 ParseInfo info(&zone, function); | 101 info.Reset(new ParseInfo(&zone, function)); |
| 105 if (Parser::ParseStatic(&info) && Scope::Analyze(&info)) { | |
| 106 scope = info.literal()->scope(); | |
| 107 } | |
| 108 if (!ignore_nested_scopes) RetrieveScopeChain(scope); | |
| 109 if (collect_non_locals) CollectNonLocals(scope); | |
| 110 } | 102 } |
| 103 Scope* scope = NULL; |
| 104 if (Compiler::ParseAndAnalyze(info.get())) scope = info->literal()->scope(); |
| 105 if (!ignore_nested_scopes) RetrieveScopeChain(scope); |
| 106 if (collect_non_locals) CollectNonLocals(scope); |
| 111 UnwrapEvaluationContext(); | 107 UnwrapEvaluationContext(); |
| 112 } | 108 } |
| 113 | 109 |
| 114 | 110 |
| 115 ScopeIterator::ScopeIterator(Isolate* isolate, Handle<JSFunction> function) | 111 ScopeIterator::ScopeIterator(Isolate* isolate, Handle<JSFunction> function) |
| 116 : isolate_(isolate), | 112 : isolate_(isolate), |
| 117 frame_inspector_(NULL), | 113 frame_inspector_(NULL), |
| 118 context_(function->context()), | 114 context_(function->context()), |
| 119 seen_script_scope_(false), | 115 seen_script_scope_(false), |
| 120 failed_(false) { | 116 failed_(false) { |
| 121 if (!function->shared()->IsSubjectToDebugging()) context_ = Handle<Context>(); | 117 if (!function->shared()->IsSubjectToDebugging()) context_ = Handle<Context>(); |
| 122 UnwrapEvaluationContext(); | 118 UnwrapEvaluationContext(); |
| 123 } | 119 } |
| 124 | 120 |
| 125 void ScopeIterator::UnwrapEvaluationContext() { | 121 void ScopeIterator::UnwrapEvaluationContext() { |
| 126 while (true) { | 122 while (true) { |
| 127 if (context_.is_null()) return; | 123 if (context_.is_null()) return; |
| 128 if (!context_->IsDebugEvaluateContext()) return; | 124 if (!context_->IsDebugEvaluateContext()) return; |
| 129 // An existing debug-evaluate context can only be outside the local scope. | |
| 130 DCHECK(nested_scope_chain_.is_empty()); | |
| 131 Handle<Object> wrapped(context_->get(Context::WRAPPED_CONTEXT_INDEX), | 125 Handle<Object> wrapped(context_->get(Context::WRAPPED_CONTEXT_INDEX), |
| 132 isolate_); | 126 isolate_); |
| 133 if (wrapped->IsContext()) { | 127 if (wrapped->IsContext()) { |
| 134 context_ = Handle<Context>::cast(wrapped); | 128 context_ = Handle<Context>::cast(wrapped); |
| 135 } else { | 129 } else { |
| 136 context_ = Handle<Context>(context_->previous(), isolate_); | 130 context_ = Handle<Context>(context_->previous(), isolate_); |
| 137 } | 131 } |
| 138 } | 132 } |
| 139 } | 133 } |
| 140 | 134 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 case WITH_SCOPE: | 227 case WITH_SCOPE: |
| 234 DCHECK(context_->IsWithContext() || context_->IsDebugEvaluateContext()); | 228 DCHECK(context_->IsWithContext() || context_->IsDebugEvaluateContext()); |
| 235 return ScopeTypeWith; | 229 return ScopeTypeWith; |
| 236 case CATCH_SCOPE: | 230 case CATCH_SCOPE: |
| 237 DCHECK(context_->IsCatchContext()); | 231 DCHECK(context_->IsCatchContext()); |
| 238 return ScopeTypeCatch; | 232 return ScopeTypeCatch; |
| 239 case BLOCK_SCOPE: | 233 case BLOCK_SCOPE: |
| 240 DCHECK(!scope_info->HasContext() || context_->IsBlockContext()); | 234 DCHECK(!scope_info->HasContext() || context_->IsBlockContext()); |
| 241 return ScopeTypeBlock; | 235 return ScopeTypeBlock; |
| 242 case EVAL_SCOPE: | 236 case EVAL_SCOPE: |
| 243 UNREACHABLE(); | 237 DCHECK(!scope_info->HasContext() || context_->IsFunctionContext()); |
| 238 return ScopeTypeEval; |
| 244 } | 239 } |
| 240 UNREACHABLE(); |
| 245 } | 241 } |
| 246 if (context_->IsNativeContext()) { | 242 if (context_->IsNativeContext()) { |
| 247 DCHECK(context_->global_object()->IsJSGlobalObject()); | 243 DCHECK(context_->global_object()->IsJSGlobalObject()); |
| 248 // If we are at the native context and have not yet seen script scope, | 244 // If we are at the native context and have not yet seen script scope, |
| 249 // fake it. | 245 // fake it. |
| 250 return seen_script_scope_ ? ScopeTypeGlobal : ScopeTypeScript; | 246 return seen_script_scope_ ? ScopeTypeGlobal : ScopeTypeScript; |
| 251 } | 247 } |
| 252 if (context_->IsFunctionContext()) { | 248 if (context_->IsFunctionContext()) { |
| 253 return ScopeTypeClosure; | 249 return ScopeTypeClosure; |
| 254 } | 250 } |
| (...skipping 26 matching lines...) Expand all Loading... |
| 281 DCHECK(nested_scope_chain_.length() == 1); | 277 DCHECK(nested_scope_chain_.length() == 1); |
| 282 return MaterializeLocalScope(); | 278 return MaterializeLocalScope(); |
| 283 case ScopeIterator::ScopeTypeWith: | 279 case ScopeIterator::ScopeTypeWith: |
| 284 return WithContextExtension(); | 280 return WithContextExtension(); |
| 285 case ScopeIterator::ScopeTypeCatch: | 281 case ScopeIterator::ScopeTypeCatch: |
| 286 return MaterializeCatchScope(); | 282 return MaterializeCatchScope(); |
| 287 case ScopeIterator::ScopeTypeClosure: | 283 case ScopeIterator::ScopeTypeClosure: |
| 288 // Materialize the content of the closure scope into a JSObject. | 284 // Materialize the content of the closure scope into a JSObject. |
| 289 return MaterializeClosure(); | 285 return MaterializeClosure(); |
| 290 case ScopeIterator::ScopeTypeBlock: | 286 case ScopeIterator::ScopeTypeBlock: |
| 291 return MaterializeBlockScope(); | 287 case ScopeIterator::ScopeTypeEval: |
| 288 return MaterializeInnerScope(); |
| 292 case ScopeIterator::ScopeTypeModule: | 289 case ScopeIterator::ScopeTypeModule: |
| 293 return MaterializeModuleScope(); | 290 return MaterializeModuleScope(); |
| 294 } | 291 } |
| 295 UNREACHABLE(); | 292 UNREACHABLE(); |
| 296 return Handle<JSObject>(); | 293 return Handle<JSObject>(); |
| 297 } | 294 } |
| 298 | 295 |
| 299 | 296 |
| 300 bool ScopeIterator::HasContext() { | 297 bool ScopeIterator::HasContext() { |
| 301 ScopeType type = Type(); | 298 ScopeType type = Type(); |
| 302 if (type == ScopeTypeBlock || type == ScopeTypeLocal) { | 299 if (type == ScopeTypeBlock || type == ScopeTypeLocal || |
| 300 type == ScopeTypeEval) { |
| 303 if (!nested_scope_chain_.is_empty()) { | 301 if (!nested_scope_chain_.is_empty()) { |
| 304 return nested_scope_chain_.last().scope_info->HasContext(); | 302 return nested_scope_chain_.last().scope_info->HasContext(); |
| 305 } | 303 } |
| 306 } | 304 } |
| 307 return true; | 305 return true; |
| 308 } | 306 } |
| 309 | 307 |
| 310 | 308 |
| 311 bool ScopeIterator::SetVariableValue(Handle<String> variable_name, | 309 bool ScopeIterator::SetVariableValue(Handle<String> variable_name, |
| 312 Handle<Object> new_value) { | 310 Handle<Object> new_value) { |
| 313 DCHECK(!failed_); | 311 DCHECK(!failed_); |
| 314 switch (Type()) { | 312 switch (Type()) { |
| 315 case ScopeIterator::ScopeTypeGlobal: | 313 case ScopeIterator::ScopeTypeGlobal: |
| 316 break; | 314 break; |
| 317 case ScopeIterator::ScopeTypeLocal: | 315 case ScopeIterator::ScopeTypeLocal: |
| 318 return SetLocalVariableValue(variable_name, new_value); | 316 return SetLocalVariableValue(variable_name, new_value); |
| 319 case ScopeIterator::ScopeTypeWith: | 317 case ScopeIterator::ScopeTypeWith: |
| 320 break; | 318 break; |
| 321 case ScopeIterator::ScopeTypeCatch: | 319 case ScopeIterator::ScopeTypeCatch: |
| 322 return SetCatchVariableValue(variable_name, new_value); | 320 return SetCatchVariableValue(variable_name, new_value); |
| 323 case ScopeIterator::ScopeTypeClosure: | 321 case ScopeIterator::ScopeTypeClosure: |
| 324 return SetClosureVariableValue(variable_name, new_value); | 322 return SetClosureVariableValue(variable_name, new_value); |
| 325 case ScopeIterator::ScopeTypeScript: | 323 case ScopeIterator::ScopeTypeScript: |
| 326 return SetScriptVariableValue(variable_name, new_value); | 324 return SetScriptVariableValue(variable_name, new_value); |
| 327 case ScopeIterator::ScopeTypeBlock: | 325 case ScopeIterator::ScopeTypeBlock: |
| 328 return SetBlockVariableValue(variable_name, new_value); | 326 case ScopeIterator::ScopeTypeEval: |
| 327 return SetInnerScopeVariableValue(variable_name, new_value); |
| 329 case ScopeIterator::ScopeTypeModule: | 328 case ScopeIterator::ScopeTypeModule: |
| 330 // TODO(2399): should we implement it? | 329 // TODO(2399): should we implement it? |
| 331 break; | 330 break; |
| 332 } | 331 } |
| 333 return false; | 332 return false; |
| 334 } | 333 } |
| 335 | 334 |
| 336 | 335 |
| 337 Handle<ScopeInfo> ScopeIterator::CurrentScopeInfo() { | 336 Handle<ScopeInfo> ScopeIterator::CurrentScopeInfo() { |
| 338 DCHECK(!failed_); | 337 DCHECK(!failed_); |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 479 | 478 |
| 480 Handle<Context> frame_context = | 479 Handle<Context> frame_context = |
| 481 Handle<Context>::cast(frame_inspector_->GetContext()); | 480 Handle<Context>::cast(frame_inspector_->GetContext()); |
| 482 | 481 |
| 483 HandleScope scope(isolate_); | 482 HandleScope scope(isolate_); |
| 484 Handle<SharedFunctionInfo> shared(function->shared()); | 483 Handle<SharedFunctionInfo> shared(function->shared()); |
| 485 Handle<ScopeInfo> scope_info(shared->scope_info()); | 484 Handle<ScopeInfo> scope_info(shared->scope_info()); |
| 486 | 485 |
| 487 if (!scope_info->HasContext()) return local_scope; | 486 if (!scope_info->HasContext()) return local_scope; |
| 488 | 487 |
| 489 // Third fill all context locals. | 488 // Fill all context locals. |
| 490 Handle<Context> function_context(frame_context->closure_context()); | 489 Handle<Context> function_context(frame_context->closure_context()); |
| 491 CopyContextLocalsToScopeObject(scope_info, function_context, local_scope); | 490 CopyContextLocalsToScopeObject(scope_info, function_context, local_scope); |
| 492 | 491 |
| 493 // Finally copy any properties from the function context extension. | 492 // Finally copy any properties from the function context extension. |
| 494 // These will be variables introduced by eval. | 493 // These will be variables introduced by eval. |
| 495 if (function_context->closure() == *function && | 494 if (function_context->closure() == *function && |
| 496 function_context->has_extension() && | |
| 497 !function_context->IsNativeContext()) { | 495 !function_context->IsNativeContext()) { |
| 498 bool success = CopyContextExtensionToScopeObject( | 496 CopyContextExtensionToScopeObject(function_context, local_scope, |
| 499 handle(function_context->extension_object(), isolate_), local_scope, | 497 INCLUDE_PROTOS); |
| 500 INCLUDE_PROTOS); | |
| 501 if (!success) return MaybeHandle<JSObject>(); | |
| 502 } | 498 } |
| 503 | 499 |
| 504 return local_scope; | 500 return local_scope; |
| 505 } | 501 } |
| 506 | 502 |
| 507 | 503 |
| 508 // Create a plain JSObject which materializes the closure content for the | 504 // Create a plain JSObject which materializes the closure content for the |
| 509 // context. | 505 // context. |
| 510 Handle<JSObject> ScopeIterator::MaterializeClosure() { | 506 Handle<JSObject> ScopeIterator::MaterializeClosure() { |
| 511 Handle<Context> context = CurrentContext(); | 507 Handle<Context> context = CurrentContext(); |
| 512 DCHECK(context->IsFunctionContext()); | 508 DCHECK(context->IsFunctionContext()); |
| 513 | 509 |
| 514 Handle<SharedFunctionInfo> shared(context->closure()->shared()); | 510 Handle<SharedFunctionInfo> shared(context->closure()->shared()); |
| 515 Handle<ScopeInfo> scope_info(shared->scope_info()); | 511 Handle<ScopeInfo> scope_info(shared->scope_info()); |
| 516 | 512 |
| 517 // Allocate and initialize a JSObject with all the content of this function | 513 // Allocate and initialize a JSObject with all the content of this function |
| 518 // closure. | 514 // closure. |
| 519 Handle<JSObject> closure_scope = | 515 Handle<JSObject> closure_scope = |
| 520 isolate_->factory()->NewJSObjectWithNullProto(); | 516 isolate_->factory()->NewJSObjectWithNullProto(); |
| 521 | 517 |
| 522 // Fill all context locals to the context extension. | 518 // Fill all context locals to the context extension. |
| 523 CopyContextLocalsToScopeObject(scope_info, context, closure_scope); | 519 CopyContextLocalsToScopeObject(scope_info, context, closure_scope); |
| 524 | 520 |
| 525 // Finally copy any properties from the function context extension. This will | 521 // Finally copy any properties from the function context extension. This will |
| 526 // be variables introduced by eval. | 522 // be variables introduced by eval. |
| 527 if (context->has_extension()) { | 523 CopyContextExtensionToScopeObject(context, closure_scope, OWN_ONLY); |
| 528 bool success = CopyContextExtensionToScopeObject( | |
| 529 handle(context->extension_object(), isolate_), closure_scope, OWN_ONLY); | |
| 530 DCHECK(success); | |
| 531 USE(success); | |
| 532 } | |
| 533 | 524 |
| 534 return closure_scope; | 525 return closure_scope; |
| 535 } | 526 } |
| 536 | 527 |
| 537 | 528 |
| 538 // Create a plain JSObject which materializes the scope for the specified | 529 // Create a plain JSObject which materializes the scope for the specified |
| 539 // catch context. | 530 // catch context. |
| 540 Handle<JSObject> ScopeIterator::MaterializeCatchScope() { | 531 Handle<JSObject> ScopeIterator::MaterializeCatchScope() { |
| 541 Handle<Context> context = CurrentContext(); | 532 Handle<Context> context = CurrentContext(); |
| 542 DCHECK(context->IsCatchContext()); | 533 DCHECK(context->IsCatchContext()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 557 Handle<Context> context = CurrentContext(); | 548 Handle<Context> context = CurrentContext(); |
| 558 DCHECK(context->IsWithContext()); | 549 DCHECK(context->IsWithContext()); |
| 559 if (context->extension_receiver()->IsJSProxy()) { | 550 if (context->extension_receiver()->IsJSProxy()) { |
| 560 return isolate_->factory()->NewJSObjectWithNullProto(); | 551 return isolate_->factory()->NewJSObjectWithNullProto(); |
| 561 } | 552 } |
| 562 return handle(JSObject::cast(context->extension_receiver())); | 553 return handle(JSObject::cast(context->extension_receiver())); |
| 563 } | 554 } |
| 564 | 555 |
| 565 // Create a plain JSObject which materializes the block scope for the specified | 556 // Create a plain JSObject which materializes the block scope for the specified |
| 566 // block context. | 557 // block context. |
| 567 Handle<JSObject> ScopeIterator::MaterializeBlockScope() { | 558 Handle<JSObject> ScopeIterator::MaterializeInnerScope() { |
| 568 Handle<JSObject> block_scope = | 559 Handle<JSObject> inner_scope = |
| 569 isolate_->factory()->NewJSObjectWithNullProto(); | 560 isolate_->factory()->NewJSObjectWithNullProto(); |
| 570 | 561 |
| 571 Handle<Context> context = Handle<Context>::null(); | 562 Handle<Context> context = Handle<Context>::null(); |
| 572 if (!nested_scope_chain_.is_empty()) { | 563 if (!nested_scope_chain_.is_empty()) { |
| 573 Handle<ScopeInfo> scope_info = nested_scope_chain_.last().scope_info; | 564 Handle<ScopeInfo> scope_info = nested_scope_chain_.last().scope_info; |
| 574 frame_inspector_->MaterializeStackLocals(block_scope, scope_info); | 565 frame_inspector_->MaterializeStackLocals(inner_scope, scope_info); |
| 575 if (scope_info->HasContext()) context = CurrentContext(); | 566 if (scope_info->HasContext()) context = CurrentContext(); |
| 576 } else { | 567 } else { |
| 577 context = CurrentContext(); | 568 context = CurrentContext(); |
| 578 } | 569 } |
| 579 | 570 |
| 580 if (!context.is_null()) { | 571 if (!context.is_null()) { |
| 581 // Fill all context locals. | 572 // Fill all context locals. |
| 582 CopyContextLocalsToScopeObject(handle(context->scope_info()), | 573 CopyContextLocalsToScopeObject(CurrentScopeInfo(), context, inner_scope); |
| 583 context, block_scope); | 574 CopyContextExtensionToScopeObject(context, inner_scope, OWN_ONLY); |
| 584 // Fill all extension variables. | |
| 585 if (context->extension_object() != nullptr) { | |
| 586 bool success = CopyContextExtensionToScopeObject( | |
| 587 handle(context->extension_object()), block_scope, OWN_ONLY); | |
| 588 DCHECK(success); | |
| 589 USE(success); | |
| 590 } | |
| 591 } | 575 } |
| 592 return block_scope; | 576 return inner_scope; |
| 593 } | 577 } |
| 594 | 578 |
| 595 | 579 |
| 596 // Create a plain JSObject which materializes the module scope for the specified | 580 // Create a plain JSObject which materializes the module scope for the specified |
| 597 // module context. | 581 // module context. |
| 598 MaybeHandle<JSObject> ScopeIterator::MaterializeModuleScope() { | 582 MaybeHandle<JSObject> ScopeIterator::MaterializeModuleScope() { |
| 599 Handle<Context> context = CurrentContext(); | 583 Handle<Context> context = CurrentContext(); |
| 600 DCHECK(context->IsModuleContext()); | 584 DCHECK(context->IsModuleContext()); |
| 601 Handle<ScopeInfo> scope_info(context->scope_info()); | 585 Handle<ScopeInfo> scope_info(context->scope_info()); |
| 602 | 586 |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 | 676 |
| 693 if (scope_info->HasContext() && | 677 if (scope_info->HasContext() && |
| 694 SetContextVariableValue(scope_info, CurrentContext(), variable_name, | 678 SetContextVariableValue(scope_info, CurrentContext(), variable_name, |
| 695 new_value)) { | 679 new_value)) { |
| 696 return true; | 680 return true; |
| 697 } | 681 } |
| 698 | 682 |
| 699 return result; | 683 return result; |
| 700 } | 684 } |
| 701 | 685 |
| 702 bool ScopeIterator::SetBlockVariableValue(Handle<String> variable_name, | 686 bool ScopeIterator::SetInnerScopeVariableValue(Handle<String> variable_name, |
| 703 Handle<Object> new_value) { | 687 Handle<Object> new_value) { |
| 704 Handle<ScopeInfo> scope_info = CurrentScopeInfo(); | 688 Handle<ScopeInfo> scope_info = CurrentScopeInfo(); |
| 689 DCHECK(scope_info->scope_type() == BLOCK_SCOPE || |
| 690 scope_info->scope_type() == EVAL_SCOPE); |
| 705 JavaScriptFrame* frame = GetFrame(); | 691 JavaScriptFrame* frame = GetFrame(); |
| 706 | 692 |
| 707 // Setting stack locals of optimized frames is not supported. | 693 // Setting stack locals of optimized frames is not supported. |
| 708 if (SetStackVariableValue(scope_info, frame, variable_name, new_value)) { | 694 if (SetStackVariableValue(scope_info, frame, variable_name, new_value)) { |
| 709 return true; | 695 return true; |
| 710 } | 696 } |
| 711 | 697 |
| 712 if (HasContext() && SetContextVariableValue(scope_info, CurrentContext(), | 698 if (HasContext() && SetContextVariableValue(scope_info, CurrentContext(), |
| 713 variable_name, new_value)) { | 699 variable_name, new_value)) { |
| 714 return true; | 700 return true; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 Handle<Object> value = Handle<Object>(context->get(context_index), isolate); | 755 Handle<Object> value = Handle<Object>(context->get(context_index), isolate); |
| 770 // Reflect variables under TDZ as undefined in scope object. | 756 // Reflect variables under TDZ as undefined in scope object. |
| 771 if (value->IsTheHole()) continue; | 757 if (value->IsTheHole()) continue; |
| 772 // This should always succeed. | 758 // This should always succeed. |
| 773 // TODO(verwaest): Use AddDataProperty instead. | 759 // TODO(verwaest): Use AddDataProperty instead. |
| 774 JSObject::SetOwnPropertyIgnoreAttributes(scope_object, name, value, NONE) | 760 JSObject::SetOwnPropertyIgnoreAttributes(scope_object, name, value, NONE) |
| 775 .Check(); | 761 .Check(); |
| 776 } | 762 } |
| 777 } | 763 } |
| 778 | 764 |
| 779 bool ScopeIterator::CopyContextExtensionToScopeObject( | 765 void ScopeIterator::CopyContextExtensionToScopeObject( |
| 780 Handle<JSObject> extension, Handle<JSObject> scope_object, | 766 Handle<Context> context, Handle<JSObject> scope_object, |
| 781 KeyCollectionType type) { | 767 KeyCollectionType type) { |
| 782 Handle<FixedArray> keys; | 768 if (context->extension_object() == nullptr) return; |
| 783 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 769 Handle<JSObject> extension(context->extension_object()); |
| 784 isolate_, keys, JSReceiver::GetKeys(extension, type, ENUMERABLE_STRINGS), | 770 Handle<FixedArray> keys = |
| 785 false); | 771 JSReceiver::GetKeys(extension, type, ENUMERABLE_STRINGS) |
| 772 .ToHandleChecked(); |
| 786 | 773 |
| 787 for (int i = 0; i < keys->length(); i++) { | 774 for (int i = 0; i < keys->length(); i++) { |
| 788 // Names of variables introduced by eval are strings. | 775 // Names of variables introduced by eval are strings. |
| 789 DCHECK(keys->get(i)->IsString()); | 776 DCHECK(keys->get(i)->IsString()); |
| 790 Handle<String> key(String::cast(keys->get(i))); | 777 Handle<String> key(String::cast(keys->get(i))); |
| 791 Handle<Object> value; | 778 Handle<Object> value = |
| 792 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 779 Object::GetPropertyOrElement(extension, key).ToHandleChecked(); |
| 793 isolate_, value, Object::GetPropertyOrElement(extension, key), false); | 780 JSObject::SetOwnPropertyIgnoreAttributes(scope_object, key, value, NONE) |
| 794 RETURN_ON_EXCEPTION_VALUE( | 781 .Check(); |
| 795 isolate_, JSObject::SetOwnPropertyIgnoreAttributes( | |
| 796 scope_object, key, value, NONE), false); | |
| 797 } | 782 } |
| 798 return true; | |
| 799 } | 783 } |
| 800 | 784 |
| 801 void ScopeIterator::GetNestedScopeChain(Isolate* isolate, Scope* scope, | 785 void ScopeIterator::GetNestedScopeChain(Isolate* isolate, Scope* scope, |
| 802 int position) { | 786 int position) { |
| 803 if (!scope->is_eval_scope()) { | 787 if (scope->is_hidden()) { |
| 804 if (scope->is_hidden()) { | 788 // We need to add this chain element in case the scope has a context |
| 805 // We need to add this chain element in case the scope has a context | 789 // associated. We need to keep the scope chain and context chain in sync. |
| 806 // associated. We need to keep the scope chain and context chain in sync. | 790 nested_scope_chain_.Add(ExtendedScopeInfo(scope->GetScopeInfo(isolate))); |
| 807 nested_scope_chain_.Add(ExtendedScopeInfo(scope->GetScopeInfo(isolate))); | 791 } else { |
| 808 } else { | 792 nested_scope_chain_.Add(ExtendedScopeInfo(scope->GetScopeInfo(isolate), |
| 809 nested_scope_chain_.Add(ExtendedScopeInfo(scope->GetScopeInfo(isolate), | 793 scope->start_position(), |
| 810 scope->start_position(), | 794 scope->end_position())); |
| 811 scope->end_position())); | |
| 812 } | |
| 813 } | 795 } |
| 814 for (int i = 0; i < scope->inner_scopes()->length(); i++) { | 796 for (int i = 0; i < scope->inner_scopes()->length(); i++) { |
| 815 Scope* inner_scope = scope->inner_scopes()->at(i); | 797 Scope* inner_scope = scope->inner_scopes()->at(i); |
| 816 int beg_pos = inner_scope->start_position(); | 798 int beg_pos = inner_scope->start_position(); |
| 817 int end_pos = inner_scope->end_position(); | 799 int end_pos = inner_scope->end_position(); |
| 818 DCHECK((beg_pos >= 0 && end_pos >= 0) || inner_scope->is_hidden()); | 800 DCHECK((beg_pos >= 0 && end_pos >= 0) || inner_scope->is_hidden()); |
| 819 if (beg_pos <= position && position < end_pos) { | 801 if (beg_pos <= position && position < end_pos) { |
| 820 GetNestedScopeChain(isolate, inner_scope, position); | 802 GetNestedScopeChain(isolate, inner_scope, position); |
| 821 return; | 803 return; |
| 822 } | 804 } |
| 823 } | 805 } |
| 824 } | 806 } |
| 825 | 807 |
| 826 } // namespace internal | 808 } // namespace internal |
| 827 } // namespace v8 | 809 } // namespace v8 |
| OLD | NEW |