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

Side by Side Diff: src/runtime.cc

Issue 11000: Periodic merge of bleeding_edge to experimental code generator branch.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: Created 12 years 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/scopes.h » ('j') | no next file with comments »
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 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698