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

Unified Diff: src/runtime.cc

Issue 11563: Fixing the detection of aliased eval so that it is exact.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 12 years, 1 month 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 | « src/runtime.h ('k') | src/top.h » ('j') | test/cctest/test-api.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
===================================================================
--- src/runtime.cc (revision 805)
+++ src/runtime.cc (working copy)
@@ -3930,95 +3930,107 @@
}
-static Object* EvalContext() {
- // The topmost JS frame belongs to the eval function which called
- // the CompileString runtime function. We need to unwind one level
- // to get to the caller of eval.
- StackFrameLocator locator;
- JavaScriptFrame* frame = locator.FindJavaScriptFrame(1);
+static Object* Runtime_GlobalReceiver(Arguments args) {
+ ASSERT(args.length() == 1);
+ Object* global = args[0];
+ if (!global->IsJSGlobalObject()) return Heap::null_value();
+ return JSGlobalObject::cast(global)->global_receiver();
+}
- // TODO(900055): Right now we check if the caller of eval() supports
- // eval to determine if it's an aliased eval or not. This may not be
- // entirely correct in the unlikely case where a function uses both
- // aliased and direct eval calls.
+
+static Object* Runtime_CompileString(Arguments args) {
HandleScope scope;
- if (!ScopeInfo<>::SupportsEval(frame->FindCode())) {
- // Aliased eval: Evaluate in the global context of the eval
- // function to support aliased, cross environment evals.
- return *Top::global_context();
- }
+ ASSERT(args.length() == 2);
+ CONVERT_ARG_CHECKED(String, source, 0);
+ CONVERT_ARG_CHECKED(Smi, line_offset, 1);
- // Fetch the caller context from the frame.
- Handle<Context> caller(Context::cast(frame->context()));
+ // Compile source string.
+ Handle<JSFunction> boilerplate =
+ Compiler::CompileEval(source, line_offset->value(), true);
+ if (boilerplate.is_null()) return Failure::Exception();
+ Handle<Context> context(Top::context()->global_context());
+ Handle<JSFunction> fun =
+ Factory::NewFunctionFromBoilerplate(boilerplate, context);
+ return *fun;
+}
- // Check for eval() invocations that cross environments. Use the
- // context from the stack if evaluating in current environment.
- Handle<Context> target = Top::global_context();
- if (caller->global_context() == *target) return *caller;
- // Otherwise, use the global context from the other environment.
- return *target;
-}
+static Object* Runtime_ExecDirectEval(Arguments args) {
+ ASSERT(args.length() == 1);
+ if (!args[0]->IsString()) return args[0];
-static Object* Runtime_EvalReceiver(Arguments args) {
- ASSERT(args.length() == 1);
+ Handle<String> source = args.at<String>(0);
+
+ // Compute the eval context.
+ HandleScope scope;
StackFrameLocator locator;
JavaScriptFrame* frame = locator.FindJavaScriptFrame(1);
- // Fetch the caller context from the frame.
- Context* caller = Context::cast(frame->context());
+ Handle<Context> context(Context::cast(frame->context()));
+ bool is_global = context->IsGlobalContext();
- // Check for eval() invocations that cross environments. Use the
- // top frames receiver if evaluating in current environment.
- Context* global_context = Top::context()->global()->global_context();
- if (caller->global_context() == global_context) {
- return frame->receiver();
+ // Compile source string.
+ Handle<JSFunction> boilerplate =
+ Compiler::CompileEval(source, 0, is_global);
+ if (boilerplate.is_null()) return Failure::Exception();
+ Handle<JSFunction> fun =
+ Factory::NewFunctionFromBoilerplate(boilerplate, context);
+
+ // Call generated function
+ Handle<Object> receiver(frame->receiver());
+ bool has_pending_exception = false;
+ Handle<Object> result =
+ Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
+ if (has_pending_exception) {
+ ASSERT(Top::has_pending_exception());
+ return Failure::Exception();
}
+ return *result;
+}
- // Otherwise use the given argument (the global object of the
- // receiving context).
- return args[0];
+
+static Object* Runtime_SetInPotentiallyDirectEval(Arguments args) {
+ ASSERT(args.length() == 0);
+ Top::set_in_potentially_direct_eval(true);
+ return Heap::undefined_value();
}
-static Object* Runtime_GlobalReceiver(Arguments args) {
- ASSERT(args.length() == 1);
- Object* global = args[0];
- if (!global->IsJSGlobalObject()) return Heap::null_value();
- return JSGlobalObject::cast(global)->global_receiver();
+static Object* Runtime_ClearInPotentiallyDirectEval(Arguments args) {
+ ASSERT(args.length() == 0);
+ Top::set_in_potentially_direct_eval(false);
+ return Heap::undefined_value();
}
-static Object* Runtime_CompileString(Arguments args) {
- HandleScope scope;
- ASSERT(args.length() == 3);
- CONVERT_ARG_CHECKED(String, source, 0);
- CONVERT_ARG_CHECKED(Smi, line_offset, 1);
- bool contextual = args[2]->IsTrue();
- RUNTIME_ASSERT(contextual || args[2]->IsFalse());
+static Object* Runtime_InDirectEval(Arguments args) {
+ ASSERT(args.length() == 0);
- // Compute the eval context.
- Handle<Context> context;
- if (contextual) {
- // Get eval context. May not be available if we are calling eval
- // through an alias, and the corresponding frame doesn't have a
- // proper eval context set up.
- Object* eval_context = EvalContext();
- if (eval_context->IsFailure()) return eval_context;
- context = Handle<Context>(Context::cast(eval_context));
- } else {
- context = Handle<Context>(Top::context()->global_context());
+ // No need to look further if the static analysis showed that this
+ // is aliased.
+ if (!Top::is_in_potentially_direct_eval()) {
+ return Heap::false_value();
}
-
- // Compile source string.
- bool is_global = context->IsGlobalContext();
- Handle<JSFunction> boilerplate =
- Compiler::CompileEval(source, line_offset->value(), is_global);
- if (boilerplate.is_null()) return Failure::Exception();
- Handle<JSFunction> fun =
- Factory::NewFunctionFromBoilerplate(boilerplate, context);
- return *fun;
+ // Find where the 'eval' symbol is bound. It is unaliased only if
+ // it is bound in the global object.
+ HandleScope scope;
+ StackFrameLocator locator;
+ JavaScriptFrame* frame = locator.FindJavaScriptFrame(1);
+ Context* context = Context::cast(frame->context());
+ int index;
+ PropertyAttributes attributes;
+ while (context && !context->IsGlobalContext()) {
+ context->Lookup(Factory::eval_symbol(), FOLLOW_PROTOTYPE_CHAIN,
+ &index, &attributes);
+ if (attributes != ABSENT) return Heap::false_value();
+ if (context->is_function_context()) {
+ context = Context::cast(context->closure()->context());
+ } else {
+ context = context->previous();
+ }
+ }
+ return Heap::true_value();
}
« no previous file with comments | « src/runtime.h ('k') | src/top.h » ('j') | test/cctest/test-api.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698