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 |