Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(621)

Unified Diff: src/runtime.cc

Issue 12953002: Simplify debug evaluate. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/cctest/test-heap.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index 934c82eb10566973cd6fead748b1144f10b20989..0b5d2095aac4713d4d1828519f2bfc6159e0d729 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -9015,7 +9015,7 @@ static ObjectPair CompileGlobalEval(Isolate* isolate,
// and return the compiled function bound in the local context.
Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
source,
- Handle<Context>(isolate->context()),
+ context,
context->IsNativeContext(),
language_mode,
NO_PARSE_RESTRICTION,
@@ -11919,21 +11919,58 @@ static Handle<Object> GetArgumentsObject(Isolate* isolate,
}
-static const char kSourceStr[] =
- "(function(arguments,__source__){return eval(__source__);})";
+// Compile and evaluate source for the given context.
+static MaybeObject* DebugEvaluate(Isolate* isolate,
+ Handle<Context> context,
+ Handle<Object> context_extension,
+ Handle<Object> receiver,
+ Handle<String> source) {
+ if (context_extension->IsJSObject()) {
+ Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
+ Handle<JSFunction> closure(context->closure(), isolate);
+ context = isolate->factory()->NewWithContext(closure, context, extension);
+ }
+
+ Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
+ source,
+ context,
+ context->IsNativeContext(),
+ CLASSIC_MODE,
+ NO_PARSE_RESTRICTION,
+ RelocInfo::kNoPosition);
+ if (shared.is_null()) return Failure::Exception();
+
+ Handle<JSFunction> eval_fun =
+ isolate->factory()->NewFunctionFromSharedFunctionInfo(
+ shared, context, NOT_TENURED);
+ bool pending_exception;
+ Handle<Object> result = Execution::Call(
+ eval_fun, receiver, 0, NULL, &pending_exception);
+
+ if (pending_exception) return Failure::Exception();
+
+ // Skip the global proxy as it has no properties and always delegates to the
+ // real global object.
+ if (result->IsJSGlobalProxy()) {
+ result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate)));
+ }
+
+ // Clear the oneshot breakpoints so that the debugger does not step further.
+ isolate->debug()->ClearStepping();
+ return *result;
+}
// Evaluate a piece of JavaScript in the context of a stack frame for
-// debugging. This is accomplished by creating a new context which in its
-// extension part has all the parameters and locals of the function on the
-// stack frame. A function which calls eval with the code to evaluate is then
-// compiled in this context and called in this context. As this context
-// replaces the context of the function on the stack frame a new (empty)
-// function is created as well to be used as the closure for the context.
-// This function and the context acts as replacements for the function on the
-// stack frame presenting the same view of the values of parameters and
-// local variables as if the piece of JavaScript was evaluated at the point
-// where the function on the stack frame is currently stopped.
+// debugging. This is done by creating a new context which in its extension
+// part has all the parameters and locals of the function on the stack frame
+// as well as a materialized arguments object. As this context replaces
+// the context of the function on the stack frame a new (empty) function
+// is created as well to be used as the closure for the context.
+// This closure as replacements for the one on the stack frame presenting
+// the same view of the values of parameters and local variables as if the
+// piece of JavaScript was evaluated at the point where the function on the
+// stack frame is currently stopped when we compile and run the (direct) eval.
RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
HandleScope scope(isolate);
@@ -11941,17 +11978,15 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
// evaluated.
ASSERT(args.length() == 6);
Object* check_result;
- { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(
+ { MaybeObject* maybe_result = Runtime_CheckExecutionState(
RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check_result->ToObject(&check_result)) {
- return maybe_check_result;
- }
+ if (!maybe_result->ToObject(&check_result)) return maybe_result;
}
CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
- Handle<Object> additional_context(args[5], isolate);
+ Handle<Object> context_extension(args[5], isolate);
// Handle the processing of break.
DisableBreak disable_break_save(disable_break);
@@ -11962,7 +11997,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
JavaScriptFrame* frame = it.frame();
FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
- Handle<ScopeInfo> scope_info(function->shared()->scope_info());
// Traverse the saved contexts chain to find the active context for the
// selected frame.
@@ -11987,28 +12021,39 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
ASSERT(go_between_scope_info->ContextLocalCount() == 0);
#endif
- // Materialize the content of the local scope into a JSObject.
+ // Materialize the content of the local scope including the arguments object.
Handle<JSObject> local_scope = MaterializeLocalScopeWithFrameInspector(
isolate, frame, &frame_inspector);
RETURN_IF_EMPTY_HANDLE(isolate, local_scope);
+ Handle<Context> frame_context(Context::cast(frame->context()));
+ Handle<Context> function_context;
+ Handle<ScopeInfo> scope_info(function->shared()->scope_info());
+ if (scope_info->HasContext()) {
+ function_context = Handle<Context>(frame_context->declaration_context());
+ }
+ Handle<Object> arguments = GetArgumentsObject(isolate,
+ frame,
+ &frame_inspector,
+ scope_info,
+ function_context);
+ SetProperty(isolate,
+ local_scope,
+ isolate->factory()->arguments_string(),
+ arguments,
+ ::NONE,
+ kNonStrictMode);
+
// Allocate a new context for the debug evaluation and set the extension
// object build.
- Handle<Context> context =
- isolate->factory()->NewFunctionContext(Context::MIN_CONTEXT_SLOTS,
- go_between);
+ Handle<Context> context = isolate->factory()->NewFunctionContext(
+ Context::MIN_CONTEXT_SLOTS, go_between);
// Use the materialized local scope in a with context.
context =
isolate->factory()->NewWithContext(go_between, context, local_scope);
// Copy any with contexts present and chain them in front of this context.
- Handle<Context> frame_context(Context::cast(frame->context()));
- Handle<Context> function_context;
- // Get the function's context if it has one.
- if (scope_info->HasContext()) {
- function_context = Handle<Context>(frame_context->declaration_context());
- }
context = CopyNestedScopeContextChain(isolate,
go_between,
context,
@@ -12021,79 +12066,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
return exception;
}
- if (additional_context->IsJSObject()) {
- Handle<JSObject> extension = Handle<JSObject>::cast(additional_context);
- context =
- isolate->factory()->NewWithContext(go_between, context, extension);
- }
-
- // Wrap the evaluation statement in a new function compiled in the newly
- // created context. The function has one parameter which has to be called
- // 'arguments'. This it to have access to what would have been 'arguments' in
- // the function being debugged.
- // function(arguments,__source__) {return eval(__source__);}
-
- Handle<String> function_source =
- isolate->factory()->NewStringFromAscii(
- Vector<const char>(kSourceStr, sizeof(kSourceStr) - 1));
-
- // Currently, the eval code will be executed in non-strict mode,
- // even in the strict code context.
- Handle<SharedFunctionInfo> shared =
- Compiler::CompileEval(function_source,
- context,
- context->IsNativeContext(),
- CLASSIC_MODE,
- NO_PARSE_RESTRICTION,
- RelocInfo::kNoPosition);
- if (shared.is_null()) return Failure::Exception();
- Handle<JSFunction> compiled_function =
- isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context);
-
- // Invoke the result of the compilation to get the evaluation function.
- bool has_pending_exception;
Handle<Object> receiver(frame->receiver(), isolate);
- Handle<Object> evaluation_function =
- Execution::Call(compiled_function, receiver, 0, NULL,
- &has_pending_exception);
- if (has_pending_exception) return Failure::Exception();
-
- Handle<Object> arguments = GetArgumentsObject(isolate,
- frame,
- &frame_inspector,
- scope_info,
- function_context);
-
- // Check if eval is blocked in the context and temporarily allow it
- // for debugger.
- Handle<Context> native_context = Handle<Context>(context->native_context());
- bool eval_disabled =
- native_context->allow_code_gen_from_strings()->IsFalse();
- if (eval_disabled) {
- native_context->set_allow_code_gen_from_strings(
- isolate->heap()->true_value());
- }
- // Invoke the evaluation function and return the result.
- Handle<Object> argv[] = { arguments, source };
- Handle<Object> result =
- Execution::Call(Handle<JSFunction>::cast(evaluation_function),
- receiver,
- ARRAY_SIZE(argv),
- argv,
- &has_pending_exception);
- if (eval_disabled) {
- native_context->set_allow_code_gen_from_strings(
- isolate->heap()->false_value());
- }
- if (has_pending_exception) return Failure::Exception();
-
- // Skip the global proxy as it has no properties and always delegates to the
- // real global object.
- if (result->IsJSGlobalProxy()) {
- result = Handle<JSObject>(JSObject::cast(result->GetPrototype(isolate)));
- }
-
- return *result;
+ return DebugEvaluate(isolate, context, context_extension, receiver, source);
}
@@ -12104,15 +12078,13 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
// evaluated.
ASSERT(args.length() == 4);
Object* check_result;
- { MaybeObject* maybe_check_result = Runtime_CheckExecutionState(
+ { MaybeObject* maybe_result = Runtime_CheckExecutionState(
RUNTIME_ARGUMENTS(isolate, args));
- if (!maybe_check_result->ToObject(&check_result)) {
- return maybe_check_result;
- }
+ if (!maybe_result->ToObject(&check_result)) return maybe_result;
}
CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
- Handle<Object> additional_context(args[3], isolate);
+ Handle<Object> context_extension(args[3], isolate);
// Handle the processing of break.
DisableBreak disable_break_save(disable_break);
@@ -12130,45 +12102,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
// Get the native context now set to the top context from before the
// debugger was invoked.
Handle<Context> context = isolate->native_context();
-
- bool is_global = true;
-
- if (additional_context->IsJSObject()) {
- // Create a new with context with the additional context information between
- // the context of the debugged function and the eval code to be executed.
- context = isolate->factory()->NewWithContext(
- Handle<JSFunction>(context->closure()),
- context,
- Handle<JSObject>::cast(additional_context));
- is_global = false;
- }
-
- // Compile the source to be evaluated.
- // Currently, the eval code will be executed in non-strict mode,
- // even in the strict code context.
- Handle<SharedFunctionInfo> shared =
- Compiler::CompileEval(source,
- context,
- is_global,
- CLASSIC_MODE,
- NO_PARSE_RESTRICTION,
- RelocInfo::kNoPosition);
- if (shared.is_null()) return Failure::Exception();
- Handle<JSFunction> compiled_function =
- Handle<JSFunction>(
- isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
- context));
-
- // Invoke the result of the compilation to get the evaluation function.
- bool has_pending_exception;
Handle<Object> receiver = isolate->global_object();
- Handle<Object> result =
- Execution::Call(compiled_function, receiver, 0, NULL,
- &has_pending_exception);
- // Clear the oneshot breakpoints so that the debugger does not step further.
- isolate->debug()->ClearStepping();
- if (has_pending_exception) return Failure::Exception();
- return *result;
+ return DebugEvaluate(isolate, context, context_extension, receiver, source);
}
« no previous file with comments | « no previous file | test/cctest/test-heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698