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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime.h ('k') | src/top.h » ('j') | test/cctest/test-api.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 3912 matching lines...) Expand 10 before | Expand all | Expand 10 after
3923 Object* result; 3923 Object* result;
3924 if (isnan(value) || (fpclassify(value) == FP_INFINITE)) { 3924 if (isnan(value) || (fpclassify(value) == FP_INFINITE)) {
3925 result = Heap::false_value(); 3925 result = Heap::false_value();
3926 } else { 3926 } else {
3927 result = Heap::true_value(); 3927 result = Heap::true_value();
3928 } 3928 }
3929 return result; 3929 return result;
3930 } 3930 }
3931 3931
3932 3932
3933 static Object* EvalContext() {
3934 // The topmost JS frame belongs to the eval function which called
3935 // the CompileString runtime function. We need to unwind one level
3936 // to get to the caller of eval.
3937 StackFrameLocator locator;
3938 JavaScriptFrame* frame = locator.FindJavaScriptFrame(1);
3939
3940 // TODO(900055): Right now we check if the caller of eval() supports
3941 // eval to determine if it's an aliased eval or not. This may not be
3942 // entirely correct in the unlikely case where a function uses both
3943 // aliased and direct eval calls.
3944 HandleScope scope;
3945 if (!ScopeInfo<>::SupportsEval(frame->FindCode())) {
3946 // Aliased eval: Evaluate in the global context of the eval
3947 // function to support aliased, cross environment evals.
3948 return *Top::global_context();
3949 }
3950
3951 // Fetch the caller context from the frame.
3952 Handle<Context> caller(Context::cast(frame->context()));
3953
3954 // Check for eval() invocations that cross environments. Use the
3955 // context from the stack if evaluating in current environment.
3956 Handle<Context> target = Top::global_context();
3957 if (caller->global_context() == *target) return *caller;
3958
3959 // Otherwise, use the global context from the other environment.
3960 return *target;
3961 }
3962
3963
3964 static Object* Runtime_EvalReceiver(Arguments args) {
3965 ASSERT(args.length() == 1);
3966 StackFrameLocator locator;
3967 JavaScriptFrame* frame = locator.FindJavaScriptFrame(1);
3968 // Fetch the caller context from the frame.
3969 Context* caller = Context::cast(frame->context());
3970
3971 // Check for eval() invocations that cross environments. Use the
3972 // top frames receiver if evaluating in current environment.
3973 Context* global_context = Top::context()->global()->global_context();
3974 if (caller->global_context() == global_context) {
3975 return frame->receiver();
3976 }
3977
3978 // Otherwise use the given argument (the global object of the
3979 // receiving context).
3980 return args[0];
3981 }
3982
3983
3984 static Object* Runtime_GlobalReceiver(Arguments args) { 3933 static Object* Runtime_GlobalReceiver(Arguments args) {
3985 ASSERT(args.length() == 1); 3934 ASSERT(args.length() == 1);
3986 Object* global = args[0]; 3935 Object* global = args[0];
3987 if (!global->IsJSGlobalObject()) return Heap::null_value(); 3936 if (!global->IsJSGlobalObject()) return Heap::null_value();
3988 return JSGlobalObject::cast(global)->global_receiver(); 3937 return JSGlobalObject::cast(global)->global_receiver();
3989 } 3938 }
3990 3939
3991 3940
3992 static Object* Runtime_CompileString(Arguments args) { 3941 static Object* Runtime_CompileString(Arguments args) {
3993 HandleScope scope; 3942 HandleScope scope;
3994 ASSERT(args.length() == 3); 3943 ASSERT(args.length() == 2);
3995 CONVERT_ARG_CHECKED(String, source, 0); 3944 CONVERT_ARG_CHECKED(String, source, 0);
3996 CONVERT_ARG_CHECKED(Smi, line_offset, 1); 3945 CONVERT_ARG_CHECKED(Smi, line_offset, 1);
3997 bool contextual = args[2]->IsTrue();
3998 RUNTIME_ASSERT(contextual || args[2]->IsFalse());
3999
4000 // Compute the eval context.
4001 Handle<Context> context;
4002 if (contextual) {
4003 // Get eval context. May not be available if we are calling eval
4004 // through an alias, and the corresponding frame doesn't have a
4005 // proper eval context set up.
4006 Object* eval_context = EvalContext();
4007 if (eval_context->IsFailure()) return eval_context;
4008 context = Handle<Context>(Context::cast(eval_context));
4009 } else {
4010 context = Handle<Context>(Top::context()->global_context());
4011 }
4012
4013 3946
4014 // Compile source string. 3947 // Compile source string.
4015 bool is_global = context->IsGlobalContext();
4016 Handle<JSFunction> boilerplate = 3948 Handle<JSFunction> boilerplate =
4017 Compiler::CompileEval(source, line_offset->value(), is_global); 3949 Compiler::CompileEval(source, line_offset->value(), true);
4018 if (boilerplate.is_null()) return Failure::Exception(); 3950 if (boilerplate.is_null()) return Failure::Exception();
3951 Handle<Context> context(Top::context()->global_context());
4019 Handle<JSFunction> fun = 3952 Handle<JSFunction> fun =
4020 Factory::NewFunctionFromBoilerplate(boilerplate, context); 3953 Factory::NewFunctionFromBoilerplate(boilerplate, context);
4021 return *fun; 3954 return *fun;
4022 } 3955 }
4023 3956
4024 3957
3958 static Object* Runtime_ExecDirectEval(Arguments args) {
3959 ASSERT(args.length() == 1);
3960
3961 if (!args[0]->IsString()) return args[0];
3962
3963 Handle<String> source = args.at<String>(0);
3964
3965 // Compute the eval context.
3966 HandleScope scope;
3967 StackFrameLocator locator;
3968 JavaScriptFrame* frame = locator.FindJavaScriptFrame(1);
3969 Handle<Context> context(Context::cast(frame->context()));
3970 bool is_global = context->IsGlobalContext();
3971
3972 // Compile source string.
3973 Handle<JSFunction> boilerplate =
3974 Compiler::CompileEval(source, 0, is_global);
3975 if (boilerplate.is_null()) return Failure::Exception();
3976 Handle<JSFunction> fun =
3977 Factory::NewFunctionFromBoilerplate(boilerplate, context);
3978
3979 // Call generated function
3980 Handle<Object> receiver(frame->receiver());
3981 bool has_pending_exception = false;
3982 Handle<Object> result =
3983 Execution::Call(fun, receiver, 0, NULL, &has_pending_exception);
3984 if (has_pending_exception) {
3985 ASSERT(Top::has_pending_exception());
3986 return Failure::Exception();
3987 }
3988 return *result;
3989 }
3990
3991
3992 static Object* Runtime_SetInPotentiallyDirectEval(Arguments args) {
3993 ASSERT(args.length() == 0);
3994 Top::set_in_potentially_direct_eval(true);
3995 return Heap::undefined_value();
3996 }
3997
3998
3999 static Object* Runtime_ClearInPotentiallyDirectEval(Arguments args) {
4000 ASSERT(args.length() == 0);
4001 Top::set_in_potentially_direct_eval(false);
4002 return Heap::undefined_value();
4003 }
4004
4005
4006 static Object* Runtime_InDirectEval(Arguments args) {
4007 ASSERT(args.length() == 0);
4008
4009 // No need to look further if the static analysis showed that this
4010 // is aliased.
4011 if (!Top::is_in_potentially_direct_eval()) {
4012 return Heap::false_value();
4013 }
4014
4015 // Find where the 'eval' symbol is bound. It is unaliased only if
4016 // it is bound in the global object.
4017 HandleScope scope;
4018 StackFrameLocator locator;
4019 JavaScriptFrame* frame = locator.FindJavaScriptFrame(1);
4020 Context* context = Context::cast(frame->context());
4021 int index;
4022 PropertyAttributes attributes;
4023 while (context && !context->IsGlobalContext()) {
4024 context->Lookup(Factory::eval_symbol(), FOLLOW_PROTOTYPE_CHAIN,
4025 &index, &attributes);
4026 if (attributes != ABSENT) return Heap::false_value();
4027 if (context->is_function_context()) {
4028 context = Context::cast(context->closure()->context());
4029 } else {
4030 context = context->previous();
4031 }
4032 }
4033 return Heap::true_value();
4034 }
4035
4036
4025 static Object* Runtime_CompileScript(Arguments args) { 4037 static Object* Runtime_CompileScript(Arguments args) {
4026 HandleScope scope; 4038 HandleScope scope;
4027 ASSERT(args.length() == 4); 4039 ASSERT(args.length() == 4);
4028 4040
4029 CONVERT_ARG_CHECKED(String, source, 0); 4041 CONVERT_ARG_CHECKED(String, source, 0);
4030 CONVERT_ARG_CHECKED(String, script, 1); 4042 CONVERT_ARG_CHECKED(String, script, 1);
4031 CONVERT_CHECKED(Smi, line_attrs, args[2]); 4043 CONVERT_CHECKED(Smi, line_attrs, args[2]);
4032 int line = line_attrs->value(); 4044 int line = line_attrs->value();
4033 CONVERT_CHECKED(Smi, col_attrs, args[3]); 4045 CONVERT_CHECKED(Smi, col_attrs, args[3]);
4034 int col = col_attrs->value(); 4046 int col = col_attrs->value();
(...skipping 1837 matching lines...) Expand 10 before | Expand all | Expand 10 after
5872 } else { 5884 } else {
5873 // Handle last resort GC and make sure to allow future allocations 5885 // Handle last resort GC and make sure to allow future allocations
5874 // to grow the heap without causing GCs (if possible). 5886 // to grow the heap without causing GCs (if possible).
5875 Counters::gc_last_resort_from_js.Increment(); 5887 Counters::gc_last_resort_from_js.Increment();
5876 Heap::CollectAllGarbage(); 5888 Heap::CollectAllGarbage();
5877 } 5889 }
5878 } 5890 }
5879 5891
5880 5892
5881 } } // namespace v8::internal 5893 } } // namespace v8::internal
OLDNEW
« 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