OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 5215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5226 context, | 5226 context, |
5227 true, | 5227 true, |
5228 validate); | 5228 validate); |
5229 if (boilerplate.is_null()) return Failure::Exception(); | 5229 if (boilerplate.is_null()) return Failure::Exception(); |
5230 Handle<JSFunction> fun = | 5230 Handle<JSFunction> fun = |
5231 Factory::NewFunctionFromBoilerplate(boilerplate, context, NOT_TENURED); | 5231 Factory::NewFunctionFromBoilerplate(boilerplate, context, NOT_TENURED); |
5232 return *fun; | 5232 return *fun; |
5233 } | 5233 } |
5234 | 5234 |
5235 | 5235 |
5236 static Handle<JSFunction> GetBuiltinFunction(String* name) { | 5236 static ObjectPair Runtime_ResolvePossiblyDirectEval(Arguments args) { |
5237 LookupResult result; | 5237 ASSERT(args.length() == 3); |
5238 Top::global_context()->builtins()->LocalLookup(name, &result); | 5238 if (!args[0]->IsJSFunction()) { |
5239 return Handle<JSFunction>(JSFunction::cast(result.GetValue())); | 5239 return MakePair(Top::ThrowIllegalOperation(), NULL); |
5240 } | 5240 } |
5241 | 5241 |
| 5242 HandleScope scope; |
| 5243 Handle<JSFunction> callee = args.at<JSFunction>(0); |
| 5244 Handle<Object> receiver; // Will be overwritten. |
5242 | 5245 |
5243 static Object* CompileDirectEval(Handle<String> source) { | 5246 // Compute the calling context. |
5244 // Compute the eval context. | 5247 Handle<Context> context = Handle<Context>(Top::context()); |
5245 HandleScope scope; | 5248 #ifdef DEBUG |
| 5249 // Make sure Top::context() agrees with the old code that traversed |
| 5250 // the stack frames to compute the context. |
5246 StackFrameLocator locator; | 5251 StackFrameLocator locator; |
5247 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | 5252 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
5248 Handle<Context> context(Context::cast(frame->context())); | 5253 ASSERT(Context::cast(frame->context()) == *context); |
5249 bool is_global = context->IsGlobalContext(); | 5254 #endif |
5250 | |
5251 // Compile source string in the current context. | |
5252 Handle<JSFunction> boilerplate = Compiler::CompileEval( | |
5253 source, | |
5254 context, | |
5255 is_global, | |
5256 Compiler::DONT_VALIDATE_JSON); | |
5257 if (boilerplate.is_null()) return Failure::Exception(); | |
5258 Handle<JSFunction> fun = | |
5259 Factory::NewFunctionFromBoilerplate(boilerplate, context, NOT_TENURED); | |
5260 return *fun; | |
5261 } | |
5262 | |
5263 | |
5264 static Object* Runtime_ResolvePossiblyDirectEval(Arguments args) { | |
5265 ASSERT(args.length() == 2); | |
5266 | |
5267 HandleScope scope; | |
5268 | |
5269 CONVERT_ARG_CHECKED(JSFunction, callee, 0); | |
5270 | |
5271 Handle<Object> receiver; | |
5272 | 5255 |
5273 // Find where the 'eval' symbol is bound. It is unaliased only if | 5256 // Find where the 'eval' symbol is bound. It is unaliased only if |
5274 // it is bound in the global context. | 5257 // it is bound in the global context. |
5275 StackFrameLocator locator; | 5258 int index = -1; |
5276 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); | 5259 PropertyAttributes attributes = ABSENT; |
5277 Handle<Context> context(Context::cast(frame->context())); | 5260 while (true) { |
5278 int index; | |
5279 PropertyAttributes attributes; | |
5280 while (!context.is_null()) { | |
5281 receiver = context->Lookup(Factory::eval_symbol(), FOLLOW_PROTOTYPE_CHAIN, | 5261 receiver = context->Lookup(Factory::eval_symbol(), FOLLOW_PROTOTYPE_CHAIN, |
5282 &index, &attributes); | 5262 &index, &attributes); |
5283 // Stop search when eval is found or when the global context is | 5263 // Stop search when eval is found or when the global context is |
5284 // reached. | 5264 // reached. |
5285 if (attributes != ABSENT || context->IsGlobalContext()) break; | 5265 if (attributes != ABSENT || context->IsGlobalContext()) break; |
5286 if (context->is_function_context()) { | 5266 if (context->is_function_context()) { |
5287 context = Handle<Context>(Context::cast(context->closure()->context())); | 5267 context = Handle<Context>(Context::cast(context->closure()->context())); |
5288 } else { | 5268 } else { |
5289 context = Handle<Context>(context->previous()); | 5269 context = Handle<Context>(context->previous()); |
5290 } | 5270 } |
5291 } | 5271 } |
5292 | 5272 |
5293 // If eval could not be resolved, it has been deleted and we need to | 5273 // If eval could not be resolved, it has been deleted and we need to |
5294 // throw a reference error. | 5274 // throw a reference error. |
5295 if (attributes == ABSENT) { | 5275 if (attributes == ABSENT) { |
5296 Handle<Object> name = Factory::eval_symbol(); | 5276 Handle<Object> name = Factory::eval_symbol(); |
5297 Handle<Object> reference_error = | 5277 Handle<Object> reference_error = |
5298 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); | 5278 Factory::NewReferenceError("not_defined", HandleVector(&name, 1)); |
5299 return Top::Throw(*reference_error); | 5279 return MakePair(Top::Throw(*reference_error), NULL); |
5300 } | 5280 } |
5301 | 5281 |
5302 if (context->IsGlobalContext()) { | 5282 if (!context->IsGlobalContext()) { |
5303 // 'eval' is bound in the global context, but it may have been overwritten. | |
5304 // Compare it to the builtin 'GlobalEval' function to make sure. | |
5305 Handle<JSFunction> global_eval = | |
5306 GetBuiltinFunction(Heap::global_eval_symbol()); | |
5307 if (global_eval.is_identical_to(callee)) { | |
5308 // A direct eval call. | |
5309 if (args[1]->IsString()) { | |
5310 CONVERT_ARG_CHECKED(String, source, 1); | |
5311 // A normal eval call on a string. Compile it and return the | |
5312 // compiled function bound in the local context. | |
5313 Object* compiled_source = CompileDirectEval(source); | |
5314 if (compiled_source->IsFailure()) return compiled_source; | |
5315 receiver = Handle<Object>(frame->receiver()); | |
5316 callee = Handle<JSFunction>(JSFunction::cast(compiled_source)); | |
5317 } else { | |
5318 // An eval call that is not called on a string. Global eval | |
5319 // deals better with this. | |
5320 receiver = Handle<Object>(Top::global_context()->global()); | |
5321 } | |
5322 } else { | |
5323 // 'eval' is overwritten. Just call the function with the given arguments. | |
5324 receiver = Handle<Object>(Top::global_context()->global()); | |
5325 } | |
5326 } else { | |
5327 // 'eval' is not bound in the global context. Just call the function | 5283 // 'eval' is not bound in the global context. Just call the function |
5328 // with the given arguments. This is not necessarily the global eval. | 5284 // with the given arguments. This is not necessarily the global eval. |
5329 if (receiver->IsContext()) { | 5285 if (receiver->IsContext()) { |
5330 context = Handle<Context>::cast(receiver); | 5286 context = Handle<Context>::cast(receiver); |
5331 receiver = Handle<Object>(context->get(index)); | 5287 receiver = Handle<Object>(context->get(index)); |
| 5288 } else if (receiver->IsJSContextExtensionObject()) { |
| 5289 receiver = Handle<JSObject>(Top::context()->global()->global_receiver()); |
5332 } | 5290 } |
| 5291 return MakePair(*callee, *receiver); |
5333 } | 5292 } |
5334 | 5293 |
5335 Handle<FixedArray> call = Factory::NewFixedArray(2); | 5294 // 'eval' is bound in the global context, but it may have been overwritten. |
5336 call->set(0, *callee); | 5295 // Compare it to the builtin 'GlobalEval' function to make sure. |
5337 call->set(1, *receiver); | 5296 if (*callee != Top::global_context()->global_eval_fun() || |
5338 return *call; | 5297 !args[1]->IsString()) { |
| 5298 return MakePair(*callee, Top::context()->global()->global_receiver()); |
| 5299 } |
| 5300 |
| 5301 // Deal with a normal eval call with a string argument. Compile it |
| 5302 // and return the compiled function bound in the local context. |
| 5303 Handle<String> source = args.at<String>(1); |
| 5304 Handle<JSFunction> boilerplate = Compiler::CompileEval( |
| 5305 source, |
| 5306 Handle<Context>(Top::context()), |
| 5307 Top::context()->IsGlobalContext(), |
| 5308 Compiler::DONT_VALIDATE_JSON); |
| 5309 if (boilerplate.is_null()) return MakePair(Failure::Exception(), NULL); |
| 5310 callee = Factory::NewFunctionFromBoilerplate( |
| 5311 boilerplate, |
| 5312 Handle<Context>(Top::context()), |
| 5313 NOT_TENURED); |
| 5314 return MakePair(*callee, args[2]); |
5339 } | 5315 } |
5340 | 5316 |
5341 | 5317 |
5342 static Object* Runtime_SetNewFunctionAttributes(Arguments args) { | 5318 static Object* Runtime_SetNewFunctionAttributes(Arguments args) { |
5343 // This utility adjusts the property attributes for newly created Function | 5319 // This utility adjusts the property attributes for newly created Function |
5344 // object ("new Function(...)") by changing the map. | 5320 // object ("new Function(...)") by changing the map. |
5345 // All it does is changing the prototype property to enumerable | 5321 // All it does is changing the prototype property to enumerable |
5346 // as specified in ECMA262, 15.3.5.2. | 5322 // as specified in ECMA262, 15.3.5.2. |
5347 HandleScope scope; | 5323 HandleScope scope; |
5348 ASSERT(args.length() == 1); | 5324 ASSERT(args.length() == 1); |
(...skipping 2699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8048 } else { | 8024 } else { |
8049 // Handle last resort GC and make sure to allow future allocations | 8025 // Handle last resort GC and make sure to allow future allocations |
8050 // to grow the heap without causing GCs (if possible). | 8026 // to grow the heap without causing GCs (if possible). |
8051 Counters::gc_last_resort_from_js.Increment(); | 8027 Counters::gc_last_resort_from_js.Increment(); |
8052 Heap::CollectAllGarbage(false); | 8028 Heap::CollectAllGarbage(false); |
8053 } | 8029 } |
8054 } | 8030 } |
8055 | 8031 |
8056 | 8032 |
8057 } } // namespace v8::internal | 8033 } } // namespace v8::internal |
OLD | NEW |