OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 11162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11173 } | 11173 } |
11174 details->set(kFrameDetailsReceiverIndex, *receiver); | 11174 details->set(kFrameDetailsReceiverIndex, *receiver); |
11175 | 11175 |
11176 ASSERT_EQ(details_size, details_index); | 11176 ASSERT_EQ(details_size, details_index); |
11177 return *isolate->factory()->NewJSArrayWithElements(details); | 11177 return *isolate->factory()->NewJSArrayWithElements(details); |
11178 } | 11178 } |
11179 | 11179 |
11180 | 11180 |
11181 // Create a plain JSObject which materializes the local scope for the specified | 11181 // Create a plain JSObject which materializes the local scope for the specified |
11182 // frame. | 11182 // frame. |
11183 static Handle<JSObject> MaterializeLocalScopeWithFrameInspector( | 11183 static Handle<JSObject> MaterializeStackLocalsWithFrameInspector( |
11184 Isolate* isolate, | 11184 Isolate* isolate, |
Toon Verwaest
2013/07/17 14:55:04
This still isn't strictly correct, because we can
| |
11185 JavaScriptFrame* frame, | 11185 Handle<JSObject> target, |
11186 Handle<JSFunction> function, | |
11186 FrameInspector* frame_inspector) { | 11187 FrameInspector* frame_inspector) { |
11187 Handle<JSFunction> function(JSFunction::cast(frame_inspector->GetFunction())); | |
11188 Handle<SharedFunctionInfo> shared(function->shared()); | 11188 Handle<SharedFunctionInfo> shared(function->shared()); |
11189 Handle<ScopeInfo> scope_info(shared->scope_info()); | 11189 Handle<ScopeInfo> scope_info(shared->scope_info()); |
11190 | 11190 |
11191 // Allocate and initialize a JSObject with all the arguments, stack locals | |
11192 // heap locals and extension properties of the debugged function. | |
11193 Handle<JSObject> local_scope = | |
11194 isolate->factory()->NewJSObject(isolate->object_function()); | |
11195 | |
11196 // First fill all parameters. | 11191 // First fill all parameters. |
11197 for (int i = 0; i < scope_info->ParameterCount(); ++i) { | 11192 for (int i = 0; i < scope_info->ParameterCount(); ++i) { |
11198 Handle<Object> value(i < frame_inspector->GetParametersCount() | 11193 Handle<Object> value(i < frame_inspector->GetParametersCount() |
11199 ? frame_inspector->GetParameter(i) | 11194 ? frame_inspector->GetParameter(i) |
11200 : isolate->heap()->undefined_value(), | 11195 : isolate->heap()->undefined_value(), |
11201 isolate); | 11196 isolate); |
11202 | 11197 |
11203 RETURN_IF_EMPTY_HANDLE_VALUE( | 11198 RETURN_IF_EMPTY_HANDLE_VALUE( |
11204 isolate, | 11199 isolate, |
11205 SetProperty(isolate, | 11200 SetProperty(isolate, |
11206 local_scope, | 11201 target, |
11207 Handle<String>(scope_info->ParameterName(i)), | 11202 Handle<String>(scope_info->ParameterName(i)), |
11208 value, | 11203 value, |
11209 NONE, | 11204 NONE, |
11210 kNonStrictMode), | 11205 kNonStrictMode), |
11211 Handle<JSObject>()); | 11206 Handle<JSObject>()); |
11212 } | 11207 } |
11213 | 11208 |
11214 // Second fill all stack locals. | 11209 // Second fill all stack locals. |
11215 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { | 11210 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { |
11216 RETURN_IF_EMPTY_HANDLE_VALUE( | 11211 RETURN_IF_EMPTY_HANDLE_VALUE( |
11217 isolate, | 11212 isolate, |
11218 SetProperty(isolate, | 11213 SetProperty(isolate, |
11219 local_scope, | 11214 target, |
11220 Handle<String>(scope_info->StackLocalName(i)), | 11215 Handle<String>(scope_info->StackLocalName(i)), |
11221 Handle<Object>(frame_inspector->GetExpression(i), isolate), | 11216 Handle<Object>(frame_inspector->GetExpression(i), isolate), |
11222 NONE, | 11217 NONE, |
11223 kNonStrictMode), | 11218 kNonStrictMode), |
11224 Handle<JSObject>()); | 11219 Handle<JSObject>()); |
11225 } | 11220 } |
11226 | 11221 |
11227 if (scope_info->HasContext()) { | 11222 return target; |
11228 // Third fill all context locals. | 11223 } |
11229 Handle<Context> frame_context(Context::cast(frame->context())); | |
11230 Handle<Context> function_context(frame_context->declaration_context()); | |
11231 if (!scope_info->CopyContextLocalsToScopeObject( | |
11232 isolate, function_context, local_scope)) { | |
11233 return Handle<JSObject>(); | |
11234 } | |
11235 | 11224 |
11236 // Finally copy any properties from the function context extension. | |
11237 // These will be variables introduced by eval. | |
11238 if (function_context->closure() == *function) { | |
11239 if (function_context->has_extension() && | |
11240 !function_context->IsNativeContext()) { | |
11241 Handle<JSObject> ext(JSObject::cast(function_context->extension())); | |
11242 bool threw = false; | |
11243 Handle<FixedArray> keys = | |
11244 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); | |
11245 if (threw) return Handle<JSObject>(); | |
11246 | 11225 |
11247 for (int i = 0; i < keys->length(); i++) { | 11226 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate, |
11248 // Names of variables introduced by eval are strings. | 11227 Handle<JSObject> target, |
11249 ASSERT(keys->get(i)->IsString()); | 11228 Handle<JSFunction> function, |
11250 Handle<String> key(String::cast(keys->get(i))); | 11229 JavaScriptFrame* frame, |
11251 RETURN_IF_EMPTY_HANDLE_VALUE( | 11230 int inlined_jsframe_index) { |
11252 isolate, | 11231 if (inlined_jsframe_index != 0 || frame->is_optimized()) { |
11253 SetProperty(isolate, | 11232 // Optimized frames are not supported. |
Toon Verwaest
2013/07/17 14:55:04
I'd prefer if this were an ASSERT. If we can't do
| |
11254 local_scope, | 11233 return; |
11255 key, | 11234 } |
11256 GetProperty(isolate, ext, key), | 11235 |
11257 NONE, | 11236 Handle<SharedFunctionInfo> shared(function->shared()); |
11258 kNonStrictMode), | 11237 Handle<ScopeInfo> scope_info(shared->scope_info()); |
11259 Handle<JSObject>()); | 11238 |
11260 } | 11239 // Parameters. |
11240 for (int i = 0; i < scope_info->ParameterCount(); ++i) { | |
11241 HandleScope scope(isolate); | |
11242 Handle<Object> value = GetProperty( | |
11243 isolate, target, Handle<String>(scope_info->ParameterName(i))); | |
11244 frame->SetParameterValue(i, *value); | |
11245 } | |
11246 | |
11247 // Stack locals. | |
11248 for (int i = 0; i < scope_info->StackLocalCount(); ++i) { | |
11249 HandleScope scope(isolate); | |
11250 Handle<Object> value = GetProperty( | |
11251 isolate, target, Handle<String>(scope_info->StackLocalName(i))); | |
11252 frame->SetExpression(i, *value); | |
11253 } | |
11254 } | |
11255 | |
11256 | |
11257 static Handle<JSObject> MaterializeLocalContext(Isolate* isolate, | |
11258 Handle<JSObject> target, | |
11259 Handle<JSFunction> function, | |
11260 JavaScriptFrame* frame) { | |
11261 HandleScope scope(isolate); | |
11262 Handle<SharedFunctionInfo> shared(function->shared()); | |
11263 Handle<ScopeInfo> scope_info(shared->scope_info()); | |
11264 | |
11265 if (!scope_info->HasContext()) return target; | |
11266 | |
11267 // Third fill all context locals. | |
11268 Handle<Context> frame_context(Context::cast(frame->context())); | |
11269 Handle<Context> function_context(frame_context->declaration_context()); | |
11270 if (!scope_info->CopyContextLocalsToScopeObject( | |
11271 isolate, function_context, target)) { | |
11272 return Handle<JSObject>(); | |
11273 } | |
11274 | |
11275 // Finally copy any properties from the function context extension. | |
11276 // These will be variables introduced by eval. | |
11277 if (function_context->closure() == *function) { | |
11278 if (function_context->has_extension() && | |
11279 !function_context->IsNativeContext()) { | |
11280 Handle<JSObject> ext(JSObject::cast(function_context->extension())); | |
11281 bool threw = false; | |
11282 Handle<FixedArray> keys = | |
11283 GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS, &threw); | |
11284 if (threw) return Handle<JSObject>(); | |
11285 | |
11286 for (int i = 0; i < keys->length(); i++) { | |
11287 // Names of variables introduced by eval are strings. | |
11288 ASSERT(keys->get(i)->IsString()); | |
11289 Handle<String> key(String::cast(keys->get(i))); | |
11290 RETURN_IF_EMPTY_HANDLE_VALUE( | |
11291 isolate, | |
11292 SetProperty(isolate, | |
11293 target, | |
11294 key, | |
11295 GetProperty(isolate, ext, key), | |
11296 NONE, | |
11297 kNonStrictMode), | |
11298 Handle<JSObject>()); | |
11261 } | 11299 } |
11262 } | 11300 } |
11263 } | 11301 } |
11264 | 11302 |
11265 return local_scope; | 11303 return target; |
11266 } | 11304 } |
11267 | 11305 |
11268 | 11306 |
11269 static Handle<JSObject> MaterializeLocalScope( | 11307 static Handle<JSObject> MaterializeLocalScope( |
11270 Isolate* isolate, | 11308 Isolate* isolate, |
11271 JavaScriptFrame* frame, | 11309 JavaScriptFrame* frame, |
11272 int inlined_jsframe_index) { | 11310 int inlined_jsframe_index) { |
11273 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); | 11311 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); |
11274 return MaterializeLocalScopeWithFrameInspector(isolate, | 11312 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); |
11275 frame, | 11313 |
11276 &frame_inspector); | 11314 Handle<JSObject> local_scope = |
11315 isolate->factory()->NewJSObject(isolate->object_function()); | |
11316 local_scope = MaterializeStackLocalsWithFrameInspector( | |
11317 isolate, local_scope, function, &frame_inspector); | |
11318 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, local_scope, Handle<JSObject>()); | |
11319 | |
11320 return MaterializeLocalContext(isolate, local_scope, function, frame); | |
11277 } | 11321 } |
11278 | 11322 |
11279 | 11323 |
11280 // Set the context local variable value. | 11324 // Set the context local variable value. |
11281 static bool SetContextLocalValue(Isolate* isolate, | 11325 static bool SetContextLocalValue(Isolate* isolate, |
11282 Handle<ScopeInfo> scope_info, | 11326 Handle<ScopeInfo> scope_info, |
11283 Handle<Context> context, | 11327 Handle<Context> context, |
11284 Handle<String> variable_name, | 11328 Handle<String> variable_name, |
11285 Handle<Object> new_value) { | 11329 Handle<Object> new_value) { |
11286 for (int i = 0; i < scope_info->ContextLocalCount(); i++) { | 11330 for (int i = 0; i < scope_info->ContextLocalCount(); i++) { |
(...skipping 1132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
12419 | 12463 |
12420 // Clear all stepping set by PrepareStep. | 12464 // Clear all stepping set by PrepareStep. |
12421 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) { | 12465 RUNTIME_FUNCTION(MaybeObject*, Runtime_ClearStepping) { |
12422 HandleScope scope(isolate); | 12466 HandleScope scope(isolate); |
12423 ASSERT(args.length() == 0); | 12467 ASSERT(args.length() == 0); |
12424 isolate->debug()->ClearStepping(); | 12468 isolate->debug()->ClearStepping(); |
12425 return isolate->heap()->undefined_value(); | 12469 return isolate->heap()->undefined_value(); |
12426 } | 12470 } |
12427 | 12471 |
12428 | 12472 |
12429 static bool IsBlockOrCatchOrWithScope(ScopeIterator::ScopeType type) { | |
12430 return type == ScopeIterator::ScopeTypeBlock || | |
12431 type == ScopeIterator::ScopeTypeCatch || | |
12432 type == ScopeIterator::ScopeTypeWith; | |
12433 } | |
12434 | |
12435 | |
12436 // Creates a copy of the with context chain. The copy of the context chain is | |
12437 // is linked to the function context supplied. | |
12438 static Handle<Context> CopyNestedScopeContextChain(Isolate* isolate, | |
12439 Handle<JSFunction> function, | |
12440 Handle<Context> base, | |
12441 JavaScriptFrame* frame, | |
12442 int inlined_jsframe_index) { | |
12443 HandleScope scope(isolate); | |
12444 List<Handle<ScopeInfo> > scope_chain; | |
12445 List<Handle<Context> > context_chain; | |
12446 | |
12447 ScopeIterator it(isolate, frame, inlined_jsframe_index); | |
12448 if (it.Failed()) return Handle<Context>::null(); | |
12449 | |
12450 for ( ; IsBlockOrCatchOrWithScope(it.Type()); it.Next()) { | |
12451 ASSERT(!it.Done()); | |
12452 scope_chain.Add(it.CurrentScopeInfo()); | |
12453 context_chain.Add(it.CurrentContext()); | |
12454 } | |
12455 | |
12456 // At the end of the chain. Return the base context to link to. | |
12457 Handle<Context> context = base; | |
12458 | |
12459 // Iteratively copy and or materialize the nested contexts. | |
12460 while (!scope_chain.is_empty()) { | |
12461 Handle<ScopeInfo> scope_info = scope_chain.RemoveLast(); | |
12462 Handle<Context> current = context_chain.RemoveLast(); | |
12463 ASSERT(!(scope_info->HasContext() & current.is_null())); | |
12464 | |
12465 if (scope_info->scope_type() == CATCH_SCOPE) { | |
12466 ASSERT(current->IsCatchContext()); | |
12467 Handle<String> name(String::cast(current->extension())); | |
12468 Handle<Object> thrown_object(current->get(Context::THROWN_OBJECT_INDEX), | |
12469 isolate); | |
12470 context = | |
12471 isolate->factory()->NewCatchContext(function, | |
12472 context, | |
12473 name, | |
12474 thrown_object); | |
12475 } else if (scope_info->scope_type() == BLOCK_SCOPE) { | |
12476 // Materialize the contents of the block scope into a JSObject. | |
12477 ASSERT(current->IsBlockContext()); | |
12478 Handle<JSObject> block_scope_object = | |
12479 MaterializeBlockScope(isolate, current); | |
12480 CHECK(!block_scope_object.is_null()); | |
12481 // Allocate a new function context for the debug evaluation and set the | |
12482 // extension object. | |
12483 Handle<Context> new_context = | |
12484 isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS, | |
12485 function); | |
12486 new_context->set_extension(*block_scope_object); | |
12487 new_context->set_previous(*context); | |
12488 context = new_context; | |
12489 } else { | |
12490 ASSERT(scope_info->scope_type() == WITH_SCOPE); | |
12491 ASSERT(current->IsWithContext()); | |
12492 Handle<JSObject> extension(JSObject::cast(current->extension())); | |
12493 context = | |
12494 isolate->factory()->NewWithContext(function, context, extension); | |
12495 } | |
12496 } | |
12497 | |
12498 return scope.CloseAndEscape(context); | |
12499 } | |
12500 | |
12501 | |
12502 // Helper function to find or create the arguments object for | 12473 // Helper function to find or create the arguments object for |
12503 // Runtime_DebugEvaluate. | 12474 // Runtime_DebugEvaluate. |
12504 static Handle<Object> GetArgumentsObject(Isolate* isolate, | 12475 static Handle<JSObject> MaterializeArgumentsObject( |
12505 JavaScriptFrame* frame, | 12476 Isolate* isolate, |
12506 FrameInspector* frame_inspector, | 12477 Handle<JSObject> target, |
12507 Handle<ScopeInfo> scope_info, | 12478 Handle<JSFunction> function, |
12508 Handle<Context> function_context) { | 12479 FrameInspector* frame_inspector) { |
12509 // Try to find the value of 'arguments' to pass as parameter. If it is not | 12480 // Do not materialize the arguments object for eval or top-level code. |
12510 // found (that is the debugged function does not reference 'arguments' and | 12481 // Skip if "arguments" is already taken. |
12511 // does not support eval) then create an 'arguments' object. | 12482 if (!function->shared()->is_function() || |
12512 int index; | 12483 target->HasLocalProperty(isolate->heap()->arguments_string())) { |
12513 if (scope_info->StackLocalCount() > 0) { | 12484 return target; |
Toon Verwaest
2013/07/17 14:55:04
This does not work in general for aliasing non-str
| |
12514 index = scope_info->StackSlotIndex(isolate->heap()->arguments_string()); | |
12515 if (index != -1) { | |
12516 return Handle<Object>(frame->GetExpression(index), isolate); | |
12517 } | |
12518 } | |
12519 | |
12520 if (scope_info->HasHeapAllocatedLocals()) { | |
12521 VariableMode mode; | |
12522 InitializationFlag init_flag; | |
12523 index = scope_info->ContextSlotIndex( | |
12524 isolate->heap()->arguments_string(), &mode, &init_flag); | |
12525 if (index != -1) { | |
12526 return Handle<Object>(function_context->get(index), isolate); | |
12527 } | |
12528 } | 12485 } |
12529 | 12486 |
12530 // FunctionGetArguments can't return a non-Object. | 12487 // FunctionGetArguments can't return a non-Object. |
12531 return Handle<JSObject>(JSObject::cast( | 12488 Handle<JSObject> arguments(JSObject::cast( |
12532 Accessors::FunctionGetArguments(frame_inspector->GetFunction(), | 12489 Accessors::FunctionGetArguments(frame_inspector->GetFunction(), |
12533 NULL)->ToObjectUnchecked()), isolate); | 12490 NULL)->ToObjectUnchecked()), isolate); |
12491 SetProperty(isolate, | |
12492 target, | |
12493 isolate->factory()->arguments_string(), | |
12494 arguments, | |
12495 ::NONE, | |
12496 kNonStrictMode); | |
12497 return target; | |
12534 } | 12498 } |
12535 | 12499 |
12536 | 12500 |
12537 // Compile and evaluate source for the given context. | 12501 // Compile and evaluate source for the given context. |
12538 static MaybeObject* DebugEvaluate(Isolate* isolate, | 12502 static MaybeObject* DebugEvaluate(Isolate* isolate, |
12539 Handle<Context> context, | 12503 Handle<Context> context, |
12540 Handle<Object> context_extension, | 12504 Handle<Object> context_extension, |
12541 Handle<Object> receiver, | 12505 Handle<Object> receiver, |
12542 Handle<String> source) { | 12506 Handle<String> source) { |
12543 if (context_extension->IsJSObject()) { | 12507 if (context_extension->IsJSObject()) { |
(...skipping 26 matching lines...) Expand all Loading... | |
12570 result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate))); | 12534 result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate))); |
12571 } | 12535 } |
12572 | 12536 |
12573 // Clear the oneshot breakpoints so that the debugger does not step further. | 12537 // Clear the oneshot breakpoints so that the debugger does not step further. |
12574 isolate->debug()->ClearStepping(); | 12538 isolate->debug()->ClearStepping(); |
12575 return *result; | 12539 return *result; |
12576 } | 12540 } |
12577 | 12541 |
12578 | 12542 |
12579 // Evaluate a piece of JavaScript in the context of a stack frame for | 12543 // Evaluate a piece of JavaScript in the context of a stack frame for |
12580 // debugging. This is done by creating a new context which in its extension | 12544 // debugging. Things that need special attention are: |
12581 // part has all the parameters and locals of the function on the stack frame | 12545 // - Parameters and stack-allocated locals need to be materialized. Altered |
12582 // as well as a materialized arguments object. As this context replaces | 12546 // values need to be written back to the stack afterwards. |
12583 // the context of the function on the stack frame a new (empty) function | 12547 // - The arguments object needs to materialized. |
12584 // is created as well to be used as the closure for the context. | |
12585 // This closure as replacements for the one on the stack frame presenting | |
12586 // the same view of the values of parameters and local variables as if the | |
12587 // piece of JavaScript was evaluated at the point where the function on the | |
12588 // stack frame is currently stopped when we compile and run the (direct) eval. | |
12589 // Returns array of | |
12590 // #0: evaluate result | |
12591 // #1: local variables materizalized again as object after evaluation, contain | |
12592 // original variable values as they remained on stack | |
12593 // #2: local variables materizalized as object before evaluation (and possibly | |
12594 // modified by expression having been executed) | |
12595 // Since user expression only reaches (and modifies) copies of local variables, | |
12596 // those copies are returned to the caller to allow tracking the changes and | |
12597 // manually updating the actual variables. | |
12598 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { | 12548 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) { |
12599 HandleScope scope(isolate); | 12549 HandleScope scope(isolate); |
12600 | 12550 |
12601 // Check the execution state and decode arguments frame and source to be | 12551 // Check the execution state and decode arguments frame and source to be |
12602 // evaluated. | 12552 // evaluated. |
12603 ASSERT(args.length() == 6); | 12553 ASSERT(args.length() == 6); |
12604 Object* check_result; | 12554 Object* check_result; |
12605 { MaybeObject* maybe_result = Runtime_CheckExecutionState( | 12555 { MaybeObject* maybe_result = Runtime_CheckExecutionState( |
12606 RUNTIME_ARGUMENTS(isolate, args)); | 12556 RUNTIME_ARGUMENTS(isolate, args)); |
12607 if (!maybe_result->ToObject(&check_result)) return maybe_result; | 12557 if (!maybe_result->ToObject(&check_result)) return maybe_result; |
(...skipping 14 matching lines...) Expand all Loading... | |
12622 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); | 12572 FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate); |
12623 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); | 12573 Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction())); |
12624 | 12574 |
12625 // Traverse the saved contexts chain to find the active context for the | 12575 // Traverse the saved contexts chain to find the active context for the |
12626 // selected frame. | 12576 // selected frame. |
12627 SaveContext* save = FindSavedContextForFrame(isolate, frame); | 12577 SaveContext* save = FindSavedContextForFrame(isolate, frame); |
12628 | 12578 |
12629 SaveContext savex(isolate); | 12579 SaveContext savex(isolate); |
12630 isolate->set_context(*(save->context())); | 12580 isolate->set_context(*(save->context())); |
12631 | 12581 |
12632 // Create the (empty) function replacing the function on the stack frame for | 12582 // Evaluate on the context of the frame. |
12633 // the purpose of evaluating in the context created below. It is important | 12583 Handle<Context> context(Context::cast(frame->context())); |
12634 // that this function does not describe any parameters and local variables | 12584 ASSERT(!context.is_null()); |
12635 // in the context. If it does then this will cause problems with the lookup | |
12636 // in Context::Lookup, where context slots for parameters and local variables | |
12637 // are looked at before the extension object. | |
12638 Handle<JSFunction> go_between = | |
12639 isolate->factory()->NewFunction(isolate->factory()->empty_string(), | |
12640 isolate->factory()->undefined_value()); | |
12641 go_between->set_context(function->context()); | |
12642 #ifdef DEBUG | |
12643 Handle<ScopeInfo> go_between_scope_info(go_between->shared()->scope_info()); | |
12644 ASSERT(go_between_scope_info->ParameterCount() == 0); | |
12645 ASSERT(go_between_scope_info->ContextLocalCount() == 0); | |
12646 #endif | |
12647 | 12585 |
12648 // Materialize the content of the local scope including the arguments object. | 12586 // Materialize stack locals and the arguments object. |
12649 Handle<JSObject> local_scope = MaterializeLocalScopeWithFrameInspector( | 12587 Handle<JSObject> materialized = |
12650 isolate, frame, &frame_inspector); | 12588 isolate->factory()->NewJSObject(isolate->object_function()); |
12651 RETURN_IF_EMPTY_HANDLE(isolate, local_scope); | |
12652 | 12589 |
12653 // Do not materialize the arguments object for eval or top-level code. | 12590 materialized = MaterializeStackLocalsWithFrameInspector( |
12654 if (function->shared()->is_function()) { | 12591 isolate, materialized, function, &frame_inspector); |
12655 Handle<Context> frame_context(Context::cast(frame->context())); | 12592 RETURN_IF_EMPTY_HANDLE(isolate, materialized); |
12656 Handle<Context> function_context; | |
12657 Handle<ScopeInfo> scope_info(function->shared()->scope_info()); | |
12658 if (scope_info->HasContext()) { | |
12659 function_context = Handle<Context>(frame_context->declaration_context()); | |
12660 } | |
12661 Handle<Object> arguments = GetArgumentsObject(isolate, | |
12662 frame, | |
12663 &frame_inspector, | |
12664 scope_info, | |
12665 function_context); | |
12666 SetProperty(isolate, | |
12667 local_scope, | |
12668 isolate->factory()->arguments_string(), | |
12669 arguments, | |
12670 ::NONE, | |
12671 kNonStrictMode); | |
12672 } | |
12673 | 12593 |
12674 // Allocate a new context for the debug evaluation and set the extension | 12594 materialized = MaterializeArgumentsObject( |
12675 // object build. | 12595 isolate, materialized, function, &frame_inspector); |
12676 Handle<Context> context = isolate->factory()->NewFunctionContext( | 12596 RETURN_IF_EMPTY_HANDLE(isolate, materialized); |
12677 Context::MIN_CONTEXT_SLOTS, go_between); | |
12678 | 12597 |
12679 // Use the materialized local scope in a with context. | 12598 // Add the materialized object in a with-scope to shadow the stack locals. |
12680 context = | 12599 context = isolate->factory()->NewWithContext(function, context, materialized); |
12681 isolate->factory()->NewWithContext(go_between, context, local_scope); | |
12682 | |
12683 // Copy any with contexts present and chain them in front of this context. | |
12684 context = CopyNestedScopeContextChain(isolate, | |
12685 go_between, | |
12686 context, | |
12687 frame, | |
12688 inlined_jsframe_index); | |
12689 if (context.is_null()) { | |
12690 ASSERT(isolate->has_pending_exception()); | |
12691 MaybeObject* exception = isolate->pending_exception(); | |
12692 isolate->clear_pending_exception(); | |
12693 return exception; | |
12694 } | |
12695 | 12600 |
12696 Handle<Object> receiver(frame->receiver(), isolate); | 12601 Handle<Object> receiver(frame->receiver(), isolate); |
12697 Object* evaluate_result_object; | 12602 Object* evaluate_result_object; |
12698 { MaybeObject* maybe_result = | 12603 { MaybeObject* maybe_result = |
12699 DebugEvaluate(isolate, context, context_extension, receiver, source); | 12604 DebugEvaluate(isolate, context, context_extension, receiver, source); |
12700 if (!maybe_result->ToObject(&evaluate_result_object)) return maybe_result; | 12605 if (!maybe_result->ToObject(&evaluate_result_object)) return maybe_result; |
12701 } | 12606 } |
12702 Handle<Object> evaluate_result(evaluate_result_object, isolate); | |
12703 | 12607 |
12704 Handle<JSObject> local_scope_control_copy = | 12608 // Write back potential changes to materialized stack locals to the stack. |
12705 MaterializeLocalScopeWithFrameInspector(isolate, frame, | 12609 UpdateStackLocalsFromMaterializedObject( |
12706 &frame_inspector); | 12610 isolate, materialized, function, frame, inlined_jsframe_index); |
12707 | 12611 |
12708 Handle<FixedArray> resultArray = isolate->factory()->NewFixedArray(3); | 12612 return evaluate_result_object; |
12709 resultArray->set(0, *evaluate_result); | |
12710 resultArray->set(1, *local_scope_control_copy); | |
12711 resultArray->set(2, *local_scope); | |
12712 | |
12713 return *(isolate->factory()->NewJSArrayWithElements(resultArray)); | |
12714 } | 12613 } |
12715 | 12614 |
12716 | 12615 |
12717 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) { | 12616 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) { |
12718 HandleScope scope(isolate); | 12617 HandleScope scope(isolate); |
12719 | 12618 |
12720 // Check the execution state and decode arguments frame and source to be | 12619 // Check the execution state and decode arguments frame and source to be |
12721 // evaluated. | 12620 // evaluated. |
12722 ASSERT(args.length() == 4); | 12621 ASSERT(args.length() == 4); |
12723 Object* check_result; | 12622 Object* check_result; |
(...skipping 1354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
14078 // Handle last resort GC and make sure to allow future allocations | 13977 // Handle last resort GC and make sure to allow future allocations |
14079 // to grow the heap without causing GCs (if possible). | 13978 // to grow the heap without causing GCs (if possible). |
14080 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13979 isolate->counters()->gc_last_resort_from_js()->Increment(); |
14081 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13980 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
14082 "Runtime::PerformGC"); | 13981 "Runtime::PerformGC"); |
14083 } | 13982 } |
14084 } | 13983 } |
14085 | 13984 |
14086 | 13985 |
14087 } } // namespace v8::internal | 13986 } } // namespace v8::internal |
OLD | NEW |