| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 // selected frame. | 61 // selected frame. |
| 62 SaveContext* save = | 62 SaveContext* save = |
| 63 DebugFrameHelper::FindSavedContextForFrame(isolate, frame); | 63 DebugFrameHelper::FindSavedContextForFrame(isolate, frame); |
| 64 SaveContext savex(isolate); | 64 SaveContext savex(isolate); |
| 65 isolate->set_context(*(save->context())); | 65 isolate->set_context(*(save->context())); |
| 66 | 66 |
| 67 // This is not a lot different than DebugEvaluate::Global, except that | 67 // This is not a lot different than DebugEvaluate::Global, except that |
| 68 // variables accessible by the function we are evaluating from are | 68 // variables accessible by the function we are evaluating from are |
| 69 // materialized and included on top of the native context. Changes to | 69 // materialized and included on top of the native context. Changes to |
| 70 // the materialized object are written back afterwards. | 70 // the materialized object are written back afterwards. |
| 71 // Note that the native context is taken from the original context chain, | |
| 72 // which may not be the current native context of the isolate. | |
| 73 ContextBuilder context_builder(isolate, frame, inlined_jsframe_index); | 71 ContextBuilder context_builder(isolate, frame, inlined_jsframe_index); |
| 74 if (isolate->has_pending_exception()) return MaybeHandle<Object>(); | 72 if (isolate->has_pending_exception()) return MaybeHandle<Object>(); |
| 75 | 73 |
| 76 Handle<Context> context = context_builder.native_context(); | 74 Handle<Context> context = isolate->native_context(); |
| 77 Handle<JSObject> receiver(context->global_proxy()); | 75 Handle<JSObject> receiver(context->global_proxy()); |
| 76 Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate); |
| 78 MaybeHandle<Object> maybe_result = Evaluate( | 77 MaybeHandle<Object> maybe_result = Evaluate( |
| 79 isolate, context_builder.outer_info(), | 78 isolate, context_builder.outer_info(), |
| 80 context_builder.innermost_context(), context_extension, receiver, source); | 79 context_builder.innermost_context(), context_extension, receiver, source); |
| 81 if (!maybe_result.is_null() && !FLAG_debug_eval_readonly_locals) { | 80 if (!maybe_result.is_null()) context_builder.UpdateValues(); |
| 82 context_builder.UpdateValues(); | |
| 83 } | |
| 84 return maybe_result; | 81 return maybe_result; |
| 85 } | 82 } |
| 86 | 83 |
| 87 | 84 |
| 88 // Compile and evaluate source for the given context. | 85 // Compile and evaluate source for the given context. |
| 89 MaybeHandle<Object> DebugEvaluate::Evaluate( | 86 MaybeHandle<Object> DebugEvaluate::Evaluate( |
| 90 Isolate* isolate, Handle<SharedFunctionInfo> outer_info, | 87 Isolate* isolate, Handle<SharedFunctionInfo> outer_info, |
| 91 Handle<Context> context, Handle<HeapObject> context_extension, | 88 Handle<Context> context, Handle<HeapObject> context_extension, |
| 92 Handle<Object> receiver, Handle<String> source) { | 89 Handle<Object> receiver, Handle<String> source) { |
| 93 if (context_extension->IsJSObject()) { | 90 if (context_extension->IsJSObject()) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 123 DebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate, | 120 DebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate, |
| 124 JavaScriptFrame* frame, | 121 JavaScriptFrame* frame, |
| 125 int inlined_jsframe_index) | 122 int inlined_jsframe_index) |
| 126 : isolate_(isolate), | 123 : isolate_(isolate), |
| 127 frame_(frame), | 124 frame_(frame), |
| 128 inlined_jsframe_index_(inlined_jsframe_index) { | 125 inlined_jsframe_index_(inlined_jsframe_index) { |
| 129 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); | 126 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); |
| 130 Handle<JSFunction> local_function = | 127 Handle<JSFunction> local_function = |
| 131 handle(JSFunction::cast(frame_inspector.GetFunction())); | 128 handle(JSFunction::cast(frame_inspector.GetFunction())); |
| 132 Handle<Context> outer_context(local_function->context()); | 129 Handle<Context> outer_context(local_function->context()); |
| 133 native_context_ = Handle<Context>(outer_context->native_context()); | 130 Handle<Context> native_context = isolate->native_context(); |
| 134 Handle<JSFunction> global_function(native_context_->closure()); | 131 Handle<JSFunction> global_function(native_context->closure()); |
| 135 outer_info_ = handle(global_function->shared()); | 132 outer_info_ = handle(global_function->shared()); |
| 136 Handle<Context> inner_context; | 133 Handle<Context> inner_context; |
| 137 | 134 |
| 138 bool stop = false; | 135 bool stop = false; |
| 139 | 136 |
| 140 // Iterate the original context chain to create a context chain that reflects | 137 // Iterate the original context chain to create a context chain that reflects |
| 141 // our needs. The original context chain may look like this: | 138 // our needs. The original context chain may look like this: |
| 142 // <native context> <outer contexts> <function context> <inner contexts> | 139 // <native context> <outer contexts> <function context> <inner contexts> |
| 143 // In the resulting context chain, we want to materialize the receiver, | 140 // In the resulting context chain, we want to materialize the receiver, |
| 144 // the parameters of the current function, the stack locals. We only | 141 // the parameters of the current function, the stack locals. We only |
| (...skipping 17 matching lines...) Expand all Loading... |
| 162 ScopeIterator::ScopeType scope_type = it.Type(); | 159 ScopeIterator::ScopeType scope_type = it.Type(); |
| 163 if (scope_type == ScopeIterator::ScopeTypeLocal) { | 160 if (scope_type == ScopeIterator::ScopeTypeLocal) { |
| 164 DCHECK_EQ(FUNCTION_SCOPE, it.CurrentScopeInfo()->scope_type()); | 161 DCHECK_EQ(FUNCTION_SCOPE, it.CurrentScopeInfo()->scope_type()); |
| 165 it.GetNonLocals(&non_locals_); | 162 it.GetNonLocals(&non_locals_); |
| 166 Handle<Context> local_context = | 163 Handle<Context> local_context = |
| 167 it.HasContext() ? it.CurrentContext() : outer_context; | 164 it.HasContext() ? it.CurrentContext() : outer_context; |
| 168 | 165 |
| 169 // The "this" binding, if any, can't be bound via "with". If we need | 166 // The "this" binding, if any, can't be bound via "with". If we need |
| 170 // to, add another node onto the outer context to bind "this". | 167 // to, add another node onto the outer context to bind "this". |
| 171 Handle<Context> receiver_context = | 168 Handle<Context> receiver_context = |
| 172 MaterializeReceiver(native_context_, local_context, local_function, | 169 MaterializeReceiver(native_context, local_context, local_function, |
| 173 global_function, it.ThisIsNonLocal()); | 170 global_function, it.ThisIsNonLocal()); |
| 174 | 171 |
| 175 Handle<JSObject> materialized_function = NewJSObjectWithNullProto(); | 172 Handle<JSObject> materialized_function = NewJSObjectWithNullProto(); |
| 176 frame_inspector.MaterializeStackLocals(materialized_function, | 173 frame_inspector.MaterializeStackLocals(materialized_function, |
| 177 local_function); | 174 local_function); |
| 178 MaterializeArgumentsObject(materialized_function, local_function); | 175 MaterializeArgumentsObject(materialized_function, local_function); |
| 179 MaterializeContextChain(materialized_function, local_context); | 176 MaterializeContextChain(materialized_function, local_context); |
| 180 | 177 |
| 181 Handle<Context> with_context = isolate->factory()->NewWithContext( | 178 Handle<Context> with_context = isolate->factory()->NewWithContext( |
| 182 global_function, receiver_context, materialized_function); | 179 global_function, receiver_context, materialized_function); |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 Handle<JSObject> arguments = | 302 Handle<JSObject> arguments = |
| 306 Handle<JSObject>::cast(Accessors::FunctionGetArguments(function)); | 303 Handle<JSObject>::cast(Accessors::FunctionGetArguments(function)); |
| 307 Handle<String> arguments_str = isolate_->factory()->arguments_string(); | 304 Handle<String> arguments_str = isolate_->factory()->arguments_string(); |
| 308 JSObject::SetOwnPropertyIgnoreAttributes(target, arguments_str, arguments, | 305 JSObject::SetOwnPropertyIgnoreAttributes(target, arguments_str, arguments, |
| 309 NONE) | 306 NONE) |
| 310 .Check(); | 307 .Check(); |
| 311 } | 308 } |
| 312 | 309 |
| 313 | 310 |
| 314 MaybeHandle<Object> DebugEvaluate::ContextBuilder::LoadFromContext( | 311 MaybeHandle<Object> DebugEvaluate::ContextBuilder::LoadFromContext( |
| 315 Handle<Context> context, Handle<String> name, bool* global) { | 312 Handle<Context> context, Handle<String> name) { |
| 316 static const ContextLookupFlags flags = FOLLOW_CONTEXT_CHAIN; | 313 static const ContextLookupFlags flags = FOLLOW_CONTEXT_CHAIN; |
| 317 int index; | 314 int index; |
| 318 PropertyAttributes attributes; | 315 PropertyAttributes attributes; |
| 319 BindingFlags binding; | 316 BindingFlags binding; |
| 320 Handle<Object> holder = | 317 Handle<Object> holder = |
| 321 context->Lookup(name, flags, &index, &attributes, &binding); | 318 context->Lookup(name, flags, &index, &attributes, &binding); |
| 322 if (holder.is_null()) return MaybeHandle<Object>(); | 319 if (holder.is_null()) return MaybeHandle<Object>(); |
| 323 Handle<Object> value; | 320 Handle<Object> value; |
| 324 if (index != Context::kNotFound) { // Found on context. | 321 if (index != Context::kNotFound) { // Found on context. |
| 325 Handle<Context> context = Handle<Context>::cast(holder); | 322 Handle<Context> context = Handle<Context>::cast(holder); |
| 326 // Do not shadow variables on the script context. | |
| 327 *global = context->IsScriptContext(); | |
| 328 return Handle<Object>(context->get(index), isolate_); | 323 return Handle<Object>(context->get(index), isolate_); |
| 329 } else { // Found on object. | 324 } else { // Found on object. |
| 330 Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder); | 325 Handle<JSReceiver> object = Handle<JSReceiver>::cast(holder); |
| 331 // Do not shadow properties on the global object. | |
| 332 *global = object->IsJSGlobalObject(); | |
| 333 return JSReceiver::GetDataProperty(object, name); | 326 return JSReceiver::GetDataProperty(object, name); |
| 334 } | 327 } |
| 335 } | 328 } |
| 336 | 329 |
| 337 | 330 |
| 338 void DebugEvaluate::ContextBuilder::MaterializeContextChain( | 331 void DebugEvaluate::ContextBuilder::MaterializeContextChain( |
| 339 Handle<JSObject> target, Handle<Context> context) { | 332 Handle<JSObject> target, Handle<Context> context) { |
| 340 for (const Handle<String>& name : non_locals_) { | 333 for (const Handle<String>& name : non_locals_) { |
| 341 HandleScope scope(isolate_); | 334 HandleScope scope(isolate_); |
| 342 Handle<Object> value; | 335 Handle<Object> value; |
| 343 bool global; | 336 if (!LoadFromContext(context, name).ToHandle(&value)) continue; |
| 344 if (!LoadFromContext(context, name, &global).ToHandle(&value) || global) { | |
| 345 // If resolving the variable fails, skip it. If it resolves to a global | |
| 346 // variable, skip it as well since it's not read-only and can be resolved | |
| 347 // within debug-evaluate. | |
| 348 continue; | |
| 349 } | |
| 350 JSObject::SetOwnPropertyIgnoreAttributes(target, name, value, NONE).Check(); | 337 JSObject::SetOwnPropertyIgnoreAttributes(target, name, value, NONE).Check(); |
| 351 } | 338 } |
| 352 } | 339 } |
| 353 | 340 |
| 354 | 341 |
| 355 void DebugEvaluate::ContextBuilder::StoreToContext(Handle<Context> context, | 342 void DebugEvaluate::ContextBuilder::StoreToContext(Handle<Context> context, |
| 356 Handle<String> name, | 343 Handle<String> name, |
| 357 Handle<Object> value) { | 344 Handle<Object> value) { |
| 358 static const ContextLookupFlags flags = FOLLOW_CONTEXT_CHAIN; | 345 static const ContextLookupFlags flags = FOLLOW_CONTEXT_CHAIN; |
| 359 int index; | 346 int index; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 387 } | 374 } |
| 388 | 375 |
| 389 | 376 |
| 390 Handle<Context> DebugEvaluate::ContextBuilder::MaterializeReceiver( | 377 Handle<Context> DebugEvaluate::ContextBuilder::MaterializeReceiver( |
| 391 Handle<Context> parent_context, Handle<Context> lookup_context, | 378 Handle<Context> parent_context, Handle<Context> lookup_context, |
| 392 Handle<JSFunction> local_function, Handle<JSFunction> global_function, | 379 Handle<JSFunction> local_function, Handle<JSFunction> global_function, |
| 393 bool this_is_non_local) { | 380 bool this_is_non_local) { |
| 394 Handle<Object> receiver = isolate_->factory()->undefined_value(); | 381 Handle<Object> receiver = isolate_->factory()->undefined_value(); |
| 395 Handle<String> this_string = isolate_->factory()->this_string(); | 382 Handle<String> this_string = isolate_->factory()->this_string(); |
| 396 if (this_is_non_local) { | 383 if (this_is_non_local) { |
| 397 bool global; | 384 LoadFromContext(lookup_context, this_string).ToHandle(&receiver); |
| 398 LoadFromContext(lookup_context, this_string, &global).ToHandle(&receiver); | |
| 399 } else if (local_function->shared()->scope_info()->HasReceiver()) { | 385 } else if (local_function->shared()->scope_info()->HasReceiver()) { |
| 400 receiver = handle(frame_->receiver(), isolate_); | 386 receiver = handle(frame_->receiver(), isolate_); |
| 401 } | 387 } |
| 402 return isolate_->factory()->NewCatchContext(global_function, parent_context, | 388 return isolate_->factory()->NewCatchContext(global_function, parent_context, |
| 403 this_string, receiver); | 389 this_string, receiver); |
| 404 } | 390 } |
| 405 | 391 |
| 406 } // namespace internal | 392 } // namespace internal |
| 407 } // namespace v8 | 393 } // namespace v8 |
| OLD | NEW |