| 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 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 | 281 |
| 282 static Object* Runtime_IsConstructCall(Arguments args) { | 282 static Object* Runtime_IsConstructCall(Arguments args) { |
| 283 NoHandleAllocation ha; | 283 NoHandleAllocation ha; |
| 284 ASSERT(args.length() == 0); | 284 ASSERT(args.length() == 0); |
| 285 JavaScriptFrameIterator it; | 285 JavaScriptFrameIterator it; |
| 286 return Heap::ToBoolean(it.frame()->IsConstructor()); | 286 return Heap::ToBoolean(it.frame()->IsConstructor()); |
| 287 } | 287 } |
| 288 | 288 |
| 289 | 289 |
| 290 static Object* Runtime_RegExpCompile(Arguments args) { | 290 static Object* Runtime_RegExpCompile(Arguments args) { |
| 291 HandleScope scope; // create a new handle scope | 291 HandleScope scope; |
| 292 ASSERT(args.length() == 3); | 292 ASSERT(args.length() == 3); |
| 293 CONVERT_CHECKED(JSRegExp, raw_re, args[0]); | 293 CONVERT_CHECKED(JSRegExp, raw_re, args[0]); |
| 294 Handle<JSRegExp> re(raw_re); | 294 Handle<JSRegExp> re(raw_re); |
| 295 CONVERT_CHECKED(String, raw_pattern, args[1]); | 295 CONVERT_CHECKED(String, raw_pattern, args[1]); |
| 296 Handle<String> pattern(raw_pattern); | 296 Handle<String> pattern(raw_pattern); |
| 297 CONVERT_CHECKED(String, raw_flags, args[2]); | 297 CONVERT_CHECKED(String, raw_flags, args[2]); |
| 298 Handle<String> flags(raw_flags); | 298 Handle<String> flags(raw_flags); |
| 299 Handle<Object> result = RegExpImpl::Compile(re, pattern, flags); | 299 Handle<Object> result = RegExpImpl::Compile(re, pattern, flags); |
| 300 if (result.is_null()) return Failure::Exception(); | 300 if (result.is_null()) return Failure::Exception(); |
| 301 return *result; | 301 return *result; |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 | 779 |
| 780 static Object* Runtime_RegExpExec(Arguments args) { | 780 static Object* Runtime_RegExpExec(Arguments args) { |
| 781 HandleScope scope; | 781 HandleScope scope; |
| 782 ASSERT(args.length() == 3); | 782 ASSERT(args.length() == 3); |
| 783 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); | 783 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); |
| 784 Handle<JSRegExp> regexp(raw_regexp); | 784 Handle<JSRegExp> regexp(raw_regexp); |
| 785 CONVERT_CHECKED(String, raw_subject, args[1]); | 785 CONVERT_CHECKED(String, raw_subject, args[1]); |
| 786 Handle<String> subject(raw_subject); | 786 Handle<String> subject(raw_subject); |
| 787 Handle<Object> index(args[2]); | 787 Handle<Object> index(args[2]); |
| 788 ASSERT(index->IsNumber()); | 788 ASSERT(index->IsNumber()); |
| 789 return *RegExpImpl::Exec(regexp, subject, index); | 789 Handle<Object> result = RegExpImpl::Exec(regexp, subject, index); |
| 790 if (result.is_null()) return Failure::Exception(); |
| 791 return *result; |
| 790 } | 792 } |
| 791 | 793 |
| 792 | 794 |
| 793 static Object* Runtime_RegExpExecGlobal(Arguments args) { | 795 static Object* Runtime_RegExpExecGlobal(Arguments args) { |
| 794 HandleScope scope; | 796 HandleScope scope; |
| 795 ASSERT(args.length() == 2); | 797 ASSERT(args.length() == 2); |
| 796 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); | 798 CONVERT_CHECKED(JSRegExp, raw_regexp, args[0]); |
| 797 Handle<JSRegExp> regexp(raw_regexp); | 799 Handle<JSRegExp> regexp(raw_regexp); |
| 798 CONVERT_CHECKED(String, raw_subject, args[1]); | 800 CONVERT_CHECKED(String, raw_subject, args[1]); |
| 799 Handle<String> subject(raw_subject); | 801 Handle<String> subject(raw_subject); |
| 800 return *RegExpImpl::ExecGlobal(regexp, subject); | 802 Handle<Object> result = RegExpImpl::ExecGlobal(regexp, subject); |
| 803 if (result.is_null()) return Failure::Exception(); |
| 804 return *result; |
| 801 } | 805 } |
| 802 | 806 |
| 803 | 807 |
| 804 static Object* Runtime_MaterializeRegExpLiteral(Arguments args) { | 808 static Object* Runtime_MaterializeRegExpLiteral(Arguments args) { |
| 805 HandleScope scope; | 809 HandleScope scope; |
| 806 ASSERT(args.length() == 4); | 810 ASSERT(args.length() == 4); |
| 807 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 811 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
| 808 int index = Smi::cast(args[1])->value(); | 812 int index = Smi::cast(args[1])->value(); |
| 809 Handle<String> pattern = args.at<String>(2); | 813 Handle<String> pattern = args.at<String>(2); |
| 810 Handle<String> flags = args.at<String>(3); | 814 Handle<String> flags = args.at<String>(3); |
| (...skipping 1626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2437 : Heap::AllocateRawTwoByteString(length); | 2441 : Heap::AllocateRawTwoByteString(length); |
| 2438 if (o->IsFailure()) return o; | 2442 if (o->IsFailure()) return o; |
| 2439 String* result = String::cast(o); | 2443 String* result = String::cast(o); |
| 2440 StringShape result_shape(result); | 2444 StringShape result_shape(result); |
| 2441 bool has_changed_character = false; | 2445 bool has_changed_character = false; |
| 2442 | 2446 |
| 2443 // Convert all characters to upper case, assuming that they will fit | 2447 // Convert all characters to upper case, assuming that they will fit |
| 2444 // in the buffer | 2448 // in the buffer |
| 2445 Access<StringInputBuffer> buffer(&string_input_buffer); | 2449 Access<StringInputBuffer> buffer(&string_input_buffer); |
| 2446 buffer->Reset(s); | 2450 buffer->Reset(s); |
| 2447 unibrow::uchar chars[unibrow::kMaxCaseConvertedSize]; | 2451 unibrow::uchar chars[Converter::kMaxWidth]; |
| 2448 int i = 0; | 2452 int i = 0; |
| 2449 // We can assume that the string is not empty | 2453 // We can assume that the string is not empty |
| 2450 uc32 current = buffer->GetNext(); | 2454 uc32 current = buffer->GetNext(); |
| 2451 while (i < length) { | 2455 while (i < length) { |
| 2452 bool has_next = buffer->has_more(); | 2456 bool has_next = buffer->has_more(); |
| 2453 uc32 next = has_next ? buffer->GetNext() : 0; | 2457 uc32 next = has_next ? buffer->GetNext() : 0; |
| 2454 int char_length = mapping->get(current, next, chars); | 2458 int char_length = mapping->get(current, next, chars); |
| 2455 if (char_length == 0) { | 2459 if (char_length == 0) { |
| 2456 // The case conversion of this character is the character itself. | 2460 // The case conversion of this character is the character itself. |
| 2457 result->Set(result_shape, i, current); | 2461 result->Set(result_shape, i, current); |
| (...skipping 1465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3923 Object* result; | 3927 Object* result; |
| 3924 if (isnan(value) || (fpclassify(value) == FP_INFINITE)) { | 3928 if (isnan(value) || (fpclassify(value) == FP_INFINITE)) { |
| 3925 result = Heap::false_value(); | 3929 result = Heap::false_value(); |
| 3926 } else { | 3930 } else { |
| 3927 result = Heap::true_value(); | 3931 result = Heap::true_value(); |
| 3928 } | 3932 } |
| 3929 return result; | 3933 return result; |
| 3930 } | 3934 } |
| 3931 | 3935 |
| 3932 | 3936 |
| 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) { | 3937 static Object* Runtime_GlobalReceiver(Arguments args) { |
| 3985 ASSERT(args.length() == 1); | 3938 ASSERT(args.length() == 1); |
| 3986 Object* global = args[0]; | 3939 Object* global = args[0]; |
| 3987 if (!global->IsJSGlobalObject()) return Heap::null_value(); | 3940 if (!global->IsJSGlobalObject()) return Heap::null_value(); |
| 3988 return JSGlobalObject::cast(global)->global_receiver(); | 3941 return JSGlobalObject::cast(global)->global_receiver(); |
| 3989 } | 3942 } |
| 3990 | 3943 |
| 3991 | 3944 |
| 3992 static Object* Runtime_CompileString(Arguments args) { | 3945 static Object* Runtime_CompileString(Arguments args) { |
| 3993 HandleScope scope; | 3946 HandleScope scope; |
| 3994 ASSERT(args.length() == 3); | 3947 ASSERT(args.length() == 2); |
| 3995 CONVERT_ARG_CHECKED(String, source, 0); | 3948 CONVERT_ARG_CHECKED(String, source, 0); |
| 3996 CONVERT_ARG_CHECKED(Smi, line_offset, 1); | 3949 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 | 3950 |
| 4014 // Compile source string. | 3951 // Compile source string. |
| 4015 bool is_global = context->IsGlobalContext(); | |
| 4016 Handle<JSFunction> boilerplate = | 3952 Handle<JSFunction> boilerplate = |
| 4017 Compiler::CompileEval(source, line_offset->value(), is_global); | 3953 Compiler::CompileEval(source, line_offset->value(), true); |
| 4018 if (boilerplate.is_null()) return Failure::Exception(); | 3954 if (boilerplate.is_null()) return Failure::Exception(); |
| 3955 Handle<Context> context(Top::context()->global_context()); |
| 4019 Handle<JSFunction> fun = | 3956 Handle<JSFunction> fun = |
| 4020 Factory::NewFunctionFromBoilerplate(boilerplate, context); | 3957 Factory::NewFunctionFromBoilerplate(boilerplate, context); |
| 4021 return *fun; | 3958 return *fun; |
| 4022 } | 3959 } |
| 4023 | 3960 |
| 4024 | 3961 |
| 3962 static Handle<JSFunction> GetBuiltinFunction(String* name) { |
| 3963 LookupResult result; |
| 3964 Top::global_context()->builtins()->LocalLookup(name, &result); |
| 3965 return Handle<JSFunction>(JSFunction::cast(result.GetValue())); |
| 3966 } |
| 3967 |
| 3968 |
| 3969 static Object* CompileDirectEval(Handle<String> source) { |
| 3970 // Compute the eval context. |
| 3971 HandleScope scope; |
| 3972 StackFrameLocator locator; |
| 3973 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
| 3974 Handle<Context> context(Context::cast(frame->context())); |
| 3975 bool is_global = context->IsGlobalContext(); |
| 3976 |
| 3977 // Compile source string. |
| 3978 Handle<JSFunction> boilerplate = Compiler::CompileEval(source, 0, is_global); |
| 3979 if (boilerplate.is_null()) return Failure::Exception(); |
| 3980 Handle<JSFunction> fun = |
| 3981 Factory::NewFunctionFromBoilerplate(boilerplate, context); |
| 3982 return *fun; |
| 3983 } |
| 3984 |
| 3985 |
| 3986 static Object* Runtime_ResolvePossiblyDirectEval(Arguments args) { |
| 3987 ASSERT(args.length() == 2); |
| 3988 |
| 3989 HandleScope scope; |
| 3990 |
| 3991 CONVERT_ARG_CHECKED(JSFunction, callee, 0); |
| 3992 |
| 3993 Handle<Object> receiver; |
| 3994 |
| 3995 // Find where the 'eval' symbol is bound. It is unaliased only if |
| 3996 // it is bound in the global context. |
| 3997 StackFrameLocator locator; |
| 3998 JavaScriptFrame* frame = locator.FindJavaScriptFrame(0); |
| 3999 Handle<Context> context(Context::cast(frame->context())); |
| 4000 int index; |
| 4001 PropertyAttributes attributes; |
| 4002 while (!context.is_null()) { |
| 4003 receiver = context->Lookup(Factory::eval_symbol(), FOLLOW_PROTOTYPE_CHAIN, |
| 4004 &index, &attributes); |
| 4005 if (attributes != ABSENT) break; |
| 4006 if (context->is_function_context()) { |
| 4007 context = Handle<Context>(Context::cast(context->closure()->context())); |
| 4008 } else { |
| 4009 context = Handle<Context>(context->previous()); |
| 4010 } |
| 4011 } |
| 4012 |
| 4013 if (context->IsGlobalContext()) { |
| 4014 // 'eval' is bound in the global context, but it may have been overwritten. |
| 4015 // Compare it to the builtin 'GlobalEval' function to make sure. |
| 4016 Handle<JSFunction> global_eval = |
| 4017 GetBuiltinFunction(Heap::global_eval_symbol()); |
| 4018 if (global_eval.is_identical_to(callee)) { |
| 4019 // A direct eval call. |
| 4020 if (args[1]->IsString()) { |
| 4021 CONVERT_ARG_CHECKED(String, source, 1); |
| 4022 // A normal eval call on a string. Compile it and return the |
| 4023 // compiled function bound in the local context. |
| 4024 Object* compiled_source = CompileDirectEval(source); |
| 4025 if (compiled_source->IsFailure()) return compiled_source; |
| 4026 receiver = Handle<Object>(frame->receiver()); |
| 4027 callee = Handle<JSFunction>(JSFunction::cast(compiled_source)); |
| 4028 } else { |
| 4029 // An eval call that is not called on a string. Global eval |
| 4030 // deals better with this. |
| 4031 receiver = Handle<Object>(Top::global_context()->global()); |
| 4032 } |
| 4033 } else { |
| 4034 // 'eval' is overwritten. Just call the function with the given arguments. |
| 4035 receiver = Handle<Object>(Top::global_context()->global()); |
| 4036 } |
| 4037 } else { |
| 4038 // 'eval' is not bound in the global context. Just call the function |
| 4039 // with the given arguments. This is not necessarily the global eval. |
| 4040 if (receiver->IsContext()) { |
| 4041 context = Handle<Context>::cast(receiver); |
| 4042 receiver = Handle<Object>(context->get(index)); |
| 4043 } |
| 4044 } |
| 4045 |
| 4046 Handle<FixedArray> call = Factory::NewFixedArray(2); |
| 4047 call->set(0, *callee); |
| 4048 call->set(1, *receiver); |
| 4049 return *call; |
| 4050 } |
| 4051 |
| 4052 |
| 4025 static Object* Runtime_CompileScript(Arguments args) { | 4053 static Object* Runtime_CompileScript(Arguments args) { |
| 4026 HandleScope scope; | 4054 HandleScope scope; |
| 4027 ASSERT(args.length() == 4); | 4055 ASSERT(args.length() == 4); |
| 4028 | 4056 |
| 4029 CONVERT_ARG_CHECKED(String, source, 0); | 4057 CONVERT_ARG_CHECKED(String, source, 0); |
| 4030 CONVERT_ARG_CHECKED(String, script, 1); | 4058 CONVERT_ARG_CHECKED(String, script, 1); |
| 4031 CONVERT_CHECKED(Smi, line_attrs, args[2]); | 4059 CONVERT_CHECKED(Smi, line_attrs, args[2]); |
| 4032 int line = line_attrs->value(); | 4060 int line = line_attrs->value(); |
| 4033 CONVERT_CHECKED(Smi, col_attrs, args[3]); | 4061 CONVERT_CHECKED(Smi, col_attrs, args[3]); |
| 4034 int col = col_attrs->value(); | 4062 int col = col_attrs->value(); |
| (...skipping 1837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5872 } else { | 5900 } else { |
| 5873 // Handle last resort GC and make sure to allow future allocations | 5901 // Handle last resort GC and make sure to allow future allocations |
| 5874 // to grow the heap without causing GCs (if possible). | 5902 // to grow the heap without causing GCs (if possible). |
| 5875 Counters::gc_last_resort_from_js.Increment(); | 5903 Counters::gc_last_resort_from_js.Increment(); |
| 5876 Heap::CollectAllGarbage(); | 5904 Heap::CollectAllGarbage(); |
| 5877 } | 5905 } |
| 5878 } | 5906 } |
| 5879 | 5907 |
| 5880 | 5908 |
| 5881 } } // namespace v8::internal | 5909 } } // namespace v8::internal |
| OLD | NEW |