Chromium Code Reviews| 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 |