OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |