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 910 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
921 int number_of_literals = fun->NumberOfLiterals(); | 921 int number_of_literals = fun->NumberOfLiterals(); |
922 Handle<FixedArray> literals = | 922 Handle<FixedArray> literals = |
923 Factory::NewFixedArray(number_of_literals, TENURED); | 923 Factory::NewFixedArray(number_of_literals, TENURED); |
924 if (number_of_literals > 0) { | 924 if (number_of_literals > 0) { |
925 // Insert the object, regexp and array functions in the literals | 925 // Insert the object, regexp and array functions in the literals |
926 // array prefix. These are the functions that will be used when | 926 // array prefix. These are the functions that will be used when |
927 // creating object, regexp and array literals. | 927 // creating object, regexp and array literals. |
928 literals->set(JSFunction::kLiteralGlobalContextIndex, | 928 literals->set(JSFunction::kLiteralGlobalContextIndex, |
929 context->global_context()); | 929 context->global_context()); |
930 } | 930 } |
931 target->set_literals(*literals); | 931 target->set_literals(*literals, SKIP_WRITE_BARRIER); |
932 } | 932 } |
933 | 933 |
934 target->set_context(*context); | 934 target->set_context(*context); |
935 return *target; | 935 return *target; |
936 } | 936 } |
937 | 937 |
938 | 938 |
939 static Object* CharCodeAt(String* subject, Object* index) { | 939 static Object* CharCodeAt(String* subject, Object* index) { |
940 uint32_t i = 0; | 940 uint32_t i = 0; |
941 if (!Array::IndexFromObject(index, &i)) return Heap::nan_value(); | 941 if (!Array::IndexFromObject(index, &i)) return Heap::nan_value(); |
(...skipping 2185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3127 CONVERT_CHECKED(JSFunction, callee, args[0]); | 3127 CONVERT_CHECKED(JSFunction, callee, args[0]); |
3128 | 3128 |
3129 // Compute the frame holding the arguments. | 3129 // Compute the frame holding the arguments. |
3130 JavaScriptFrameIterator it; | 3130 JavaScriptFrameIterator it; |
3131 it.AdvanceToArgumentsFrame(); | 3131 it.AdvanceToArgumentsFrame(); |
3132 JavaScriptFrame* frame = it.frame(); | 3132 JavaScriptFrame* frame = it.frame(); |
3133 | 3133 |
3134 const int length = frame->GetProvidedParametersCount(); | 3134 const int length = frame->GetProvidedParametersCount(); |
3135 Object* result = Heap::AllocateArgumentsObject(callee, length); | 3135 Object* result = Heap::AllocateArgumentsObject(callee, length); |
3136 if (result->IsFailure()) return result; | 3136 if (result->IsFailure()) return result; |
3137 FixedArray* array = FixedArray::cast(JSObject::cast(result)->elements()); | 3137 if (length > 0) { |
3138 ASSERT(array->length() == length); | 3138 Object* obj = Heap::AllocateFixedArray(length); |
3139 WriteBarrierMode mode = array->GetWriteBarrierMode(); | 3139 if (obj->IsFailure()) return obj; |
3140 for (int i = 0; i < length; i++) { | 3140 FixedArray* array = FixedArray::cast(obj); |
3141 array->set(i, frame->GetParameter(i), mode); | 3141 ASSERT(array->length() == length); |
3142 WriteBarrierMode mode = array->GetWriteBarrierMode(); | |
3143 for (int i = 0; i < length; i++) { | |
3144 array->set(i, frame->GetParameter(i), mode); | |
3145 } | |
3146 JSObject::cast(result)->set_elements(array); | |
3142 } | 3147 } |
3143 return result; | 3148 return result; |
3144 } | 3149 } |
3145 | 3150 |
3146 | 3151 |
3147 static Object* Runtime_NewArgumentsFast(Arguments args) { | 3152 static Object* Runtime_NewArgumentsFast(Arguments args) { |
3148 NoHandleAllocation ha; | 3153 NoHandleAllocation ha; |
3149 ASSERT(args.length() == 3); | 3154 ASSERT(args.length() == 3); |
3150 | 3155 |
3151 JSFunction* callee = JSFunction::cast(args[0]); | 3156 JSFunction* callee = JSFunction::cast(args[0]); |
3152 Object** parameters = reinterpret_cast<Object**>(args[1]); | 3157 Object** parameters = reinterpret_cast<Object**>(args[1]); |
3153 const int length = Smi::cast(args[2])->value(); | 3158 const int length = Smi::cast(args[2])->value(); |
3154 | 3159 |
3155 Object* result = Heap::AllocateArgumentsObject(callee, length); | 3160 Object* result = Heap::AllocateArgumentsObject(callee, length); |
3156 if (result->IsFailure()) return result; | 3161 if (result->IsFailure()) return result; |
3157 FixedArray* array = FixedArray::cast(JSObject::cast(result)->elements()); | 3162 ASSERT(Heap::InNewSpace(result)); |
3158 ASSERT(array->length() == length); | 3163 |
3159 WriteBarrierMode mode = array->GetWriteBarrierMode(); | 3164 // Allocate the elements if needed. |
3160 for (int i = 0; i < length; i++) { | 3165 if (length > 0) { |
3161 array->set(i, *--parameters, mode); | 3166 // Allocate the fixed array. |
3167 Object* obj = Heap::AllocateRawFixedArray(length); | |
3168 if (obj->IsFailure()) return obj; | |
3169 reinterpret_cast<Array*>(obj)->set_map(Heap::fixed_array_map()); | |
3170 FixedArray* array = FixedArray::cast(obj); | |
3171 array->set_length(length); | |
3172 WriteBarrierMode mode = array->GetWriteBarrierMode(); | |
3173 for (int i = 0; i < length; i++) { | |
3174 array->set(i, *--parameters, mode); | |
3175 } | |
3176 JSObject::cast(result)->set_elements(FixedArray::cast(obj), | |
3177 SKIP_WRITE_BARRIER); | |
3162 } | 3178 } |
3163 return result; | 3179 return result; |
3164 } | 3180 } |
3165 | 3181 |
3166 | 3182 |
3167 static Object* Runtime_NewClosure(Arguments args) { | 3183 static Object* Runtime_NewClosure(Arguments args) { |
3168 HandleScope scope; | 3184 HandleScope scope; |
3169 ASSERT(args.length() == 2); | 3185 ASSERT(args.length() == 2); |
3170 CONVERT_ARG_CHECKED(JSFunction, boilerplate, 0); | 3186 CONVERT_ARG_CHECKED(JSFunction, boilerplate, 0); |
3171 CONVERT_ARG_CHECKED(Context, context, 1); | 3187 CONVERT_ARG_CHECKED(Context, context, 1); |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3359 ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0); | 3375 ASSERT(!x->IsTheHole() || (attributes & READ_ONLY) != 0); |
3360 USE(attributes); | 3376 USE(attributes); |
3361 return x->IsTheHole() ? Heap::undefined_value() : x; | 3377 return x->IsTheHole() ? Heap::undefined_value() : x; |
3362 } | 3378 } |
3363 | 3379 |
3364 | 3380 |
3365 static Object* ComputeContextSlotReceiver(Object* holder) { | 3381 static Object* ComputeContextSlotReceiver(Object* holder) { |
3366 // If the "property" we were looking for is a local variable or an | 3382 // If the "property" we were looking for is a local variable or an |
3367 // argument in a context, the receiver is the global object; see | 3383 // argument in a context, the receiver is the global object; see |
3368 // ECMA-262, 3rd., 10.1.6 and 10.2.3. | 3384 // ECMA-262, 3rd., 10.1.6 and 10.2.3. |
3385 // Contexts and Globals are most common. | |
Kasper Lund
2008/10/23 14:51:33
I would change Globals to 'global objects', but th
| |
3369 HeapObject* object = HeapObject::cast(holder); | 3386 HeapObject* object = HeapObject::cast(holder); |
Kasper Lund
2008/10/23 14:51:33
You should be able to get rid of the 'object' vari
| |
3387 if (holder->IsContext()) { | |
3388 return Context::cast(holder)->global()->global_receiver(); | |
3389 } | |
3390 if (object->IsGlobalObject()) { | |
3391 // If the holder is a global object, we have to be careful to wrap | |
3392 // it in its proxy if necessary. | |
3393 return GlobalObject::cast(object)->global_receiver(); | |
3394 } | |
3395 | |
3370 Context* top = Top::context(); | 3396 Context* top = Top::context(); |
3371 if (holder->IsContext()) return top->global()->global_receiver(); | |
3372 | |
3373 // TODO(125): Find a better - and faster way - of checking for | 3397 // TODO(125): Find a better - and faster way - of checking for |
3374 // arguments and context extension objects. This kinda sucks. | 3398 // arguments and context extension objects. This kinda sucks. |
3375 JSFunction* context_extension_function = | 3399 JSFunction* context_extension_function = |
3376 top->global_context()->context_extension_function(); | 3400 top->global_context()->context_extension_function(); |
3377 JSObject* arguments_boilerplate = | 3401 JSObject* arguments_boilerplate = |
3378 top->global_context()->arguments_boilerplate(); | 3402 top->global_context()->arguments_boilerplate(); |
3379 JSFunction* arguments_function = | 3403 JSFunction* arguments_function = |
3380 JSFunction::cast(arguments_boilerplate->map()->constructor()); | 3404 JSFunction::cast(arguments_boilerplate->map()->constructor()); |
3381 // If the holder is an arguments object or a context extension then the | 3405 // If the holder is an arguments object or a context extension then the |
3382 // receiver is also the global object; | 3406 // receiver is also the global object; |
3383 Object* constructor = HeapObject::cast(holder)->map()->constructor(); | 3407 Object* constructor = HeapObject::cast(holder)->map()->constructor(); |
3384 if (constructor == context_extension_function || | 3408 if (constructor == context_extension_function || |
3385 constructor == arguments_function) { | 3409 constructor == arguments_function) { |
3386 return Top::context()->global()->global_receiver(); | 3410 return Top::context()->global()->global_receiver(); |
3387 } | 3411 } |
3388 | 3412 |
3389 // If the holder is a global object, we have to be careful to wrap | 3413 return object; |
3390 // it in its proxy if necessary. | |
3391 if (object->IsGlobalObject()) { | |
3392 return GlobalObject::cast(object)->global_receiver(); | |
3393 } else { | |
3394 return object; | |
3395 } | |
3396 } | 3414 } |
3397 | 3415 |
3398 | 3416 |
3399 static ObjPair LoadContextSlotHelper(Arguments args, bool throw_error) { | 3417 static ObjPair LoadContextSlotHelper(Arguments args, bool throw_error) { |
3400 HandleScope scope; | 3418 HandleScope scope; |
3401 ASSERT(args.length() == 2); | 3419 ASSERT(args.length() == 2); |
3402 | 3420 |
3403 if (!args[0]->IsContext()) return MakePair(IllegalOperation(), NULL); | 3421 if (!args[0]->IsContext()) return MakePair(IllegalOperation(), NULL); |
3404 Handle<Context> context = args.at<Context>(0); | 3422 Handle<Context> context = args.at<Context>(0); |
3405 Handle<String> name(String::cast(args[1])); | 3423 Handle<String> name(String::cast(args[1])); |
(...skipping 1487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4893 | 4911 |
4894 if (sinfo->number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) { | 4912 if (sinfo->number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) { |
4895 index = ScopeInfo<>::ContextSlotIndex(*code, Heap::arguments_symbol(), | 4913 index = ScopeInfo<>::ContextSlotIndex(*code, Heap::arguments_symbol(), |
4896 NULL); | 4914 NULL); |
4897 if (index != -1) { | 4915 if (index != -1) { |
4898 return Handle<Object>(function_context->get(index)); | 4916 return Handle<Object>(function_context->get(index)); |
4899 } | 4917 } |
4900 } | 4918 } |
4901 | 4919 |
4902 const int length = frame->GetProvidedParametersCount(); | 4920 const int length = frame->GetProvidedParametersCount(); |
4903 Handle<Object> arguments = Factory::NewArgumentsObject(function, length); | 4921 Handle<JSObject> arguments = Factory::NewArgumentsObject(function, length); |
4904 FixedArray* array = FixedArray::cast(JSObject::cast(*arguments)->elements()); | 4922 Handle<FixedArray> array = Factory::NewFixedArray(length); |
4905 ASSERT(array->length() == length); | |
4906 WriteBarrierMode mode = array->GetWriteBarrierMode(); | 4923 WriteBarrierMode mode = array->GetWriteBarrierMode(); |
4907 for (int i = 0; i < length; i++) { | 4924 for (int i = 0; i < length; i++) { |
4908 array->set(i, frame->GetParameter(i), mode); | 4925 array->set(i, frame->GetParameter(i), mode); |
4909 } | 4926 } |
4927 arguments->set_elements(*array); | |
4910 return arguments; | 4928 return arguments; |
4911 } | 4929 } |
4912 | 4930 |
4913 | 4931 |
4914 // Evaluate a piece of JavaScript in the context of a stack frame for | 4932 // Evaluate a piece of JavaScript in the context of a stack frame for |
4915 // debugging. This is acomplished by creating a new context which in its | 4933 // debugging. This is acomplished by creating a new context which in its |
4916 // extension part has all the parameters and locals of the function on the | 4934 // extension part has all the parameters and locals of the function on the |
4917 // stack frame. A function which calls eval with the code to evaluate is then | 4935 // stack frame. A function which calls eval with the code to evaluate is then |
4918 // compiled in this context and called in this context. As this context | 4936 // compiled in this context and called in this context. As this context |
4919 // replaces the context of the function on the stack frame a new (empty) | 4937 // replaces the context of the function on the stack frame a new (empty) |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5511 | 5529 |
5512 void Runtime::PerformGC(Object* result) { | 5530 void Runtime::PerformGC(Object* result) { |
5513 Failure* failure = Failure::cast(result); | 5531 Failure* failure = Failure::cast(result); |
5514 // Try to do a garbage collection; ignore it if it fails. The C | 5532 // Try to do a garbage collection; ignore it if it fails. The C |
5515 // entry stub will throw an out-of-memory exception in that case. | 5533 // entry stub will throw an out-of-memory exception in that case. |
5516 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); | 5534 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); |
5517 } | 5535 } |
5518 | 5536 |
5519 | 5537 |
5520 } } // namespace v8::internal | 5538 } } // namespace v8::internal |
OLD | NEW |