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 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 NoHandleAllocation ha; | 1201 NoHandleAllocation ha; |
1202 ASSERT(args.length() == 1); | 1202 ASSERT(args.length() == 1); |
1203 | 1203 |
1204 CONVERT_CHECKED(JSFunction, f, args[0]); | 1204 CONVERT_CHECKED(JSFunction, f, args[0]); |
1205 // The function_data field of the shared function info is used exclusively by | 1205 // The function_data field of the shared function info is used exclusively by |
1206 // the API. | 1206 // the API. |
1207 return !f->shared()->function_data()->IsUndefined() ? Heap::true_value() | 1207 return !f->shared()->function_data()->IsUndefined() ? Heap::true_value() |
1208 : Heap::false_value(); | 1208 : Heap::false_value(); |
1209 } | 1209 } |
1210 | 1210 |
| 1211 static Object* Runtime_FunctionIsBuiltin(Arguments args) { |
| 1212 NoHandleAllocation ha; |
| 1213 ASSERT(args.length() == 1); |
| 1214 |
| 1215 CONVERT_CHECKED(JSFunction, f, args[0]); |
| 1216 return f->IsBuiltin() ? Heap::true_value() : Heap::false_value(); |
| 1217 } |
| 1218 |
1211 | 1219 |
1212 static Object* Runtime_SetCode(Arguments args) { | 1220 static Object* Runtime_SetCode(Arguments args) { |
1213 HandleScope scope; | 1221 HandleScope scope; |
1214 ASSERT(args.length() == 2); | 1222 ASSERT(args.length() == 2); |
1215 | 1223 |
1216 CONVERT_ARG_CHECKED(JSFunction, target, 0); | 1224 CONVERT_ARG_CHECKED(JSFunction, target, 0); |
1217 Handle<Object> code = args.at<Object>(1); | 1225 Handle<Object> code = args.at<Object>(1); |
1218 | 1226 |
1219 Handle<Context> context(target->context()); | 1227 Handle<Context> context(target->context()); |
1220 | 1228 |
(...skipping 1764 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2985 // the check for deletions during a for-in. | 2993 // the check for deletions during a for-in. |
2986 static Object* Runtime_GetPropertyNamesFast(Arguments args) { | 2994 static Object* Runtime_GetPropertyNamesFast(Arguments args) { |
2987 ASSERT(args.length() == 1); | 2995 ASSERT(args.length() == 1); |
2988 | 2996 |
2989 CONVERT_CHECKED(JSObject, raw_object, args[0]); | 2997 CONVERT_CHECKED(JSObject, raw_object, args[0]); |
2990 | 2998 |
2991 if (raw_object->IsSimpleEnum()) return raw_object->map(); | 2999 if (raw_object->IsSimpleEnum()) return raw_object->map(); |
2992 | 3000 |
2993 HandleScope scope; | 3001 HandleScope scope; |
2994 Handle<JSObject> object(raw_object); | 3002 Handle<JSObject> object(raw_object); |
2995 Handle<FixedArray> content = GetKeysInFixedArrayFor(object); | 3003 Handle<FixedArray> content = GetKeysInFixedArrayFor(object, |
| 3004 INCLUDE_PROTOS); |
2996 | 3005 |
2997 // Test again, since cache may have been built by preceding call. | 3006 // Test again, since cache may have been built by preceding call. |
2998 if (object->IsSimpleEnum()) return object->map(); | 3007 if (object->IsSimpleEnum()) return object->map(); |
2999 | 3008 |
3000 return *content; | 3009 return *content; |
3001 } | 3010 } |
3002 | 3011 |
3003 | 3012 |
| 3013 static Object* Runtime_LocalKeys(Arguments args) { |
| 3014 ASSERT_EQ(args.length(), 1); |
| 3015 CONVERT_CHECKED(JSObject, raw_object, args[0]); |
| 3016 HandleScope scope; |
| 3017 Handle<JSObject> object(raw_object); |
| 3018 Handle<FixedArray> contents = GetKeysInFixedArrayFor(object, |
| 3019 LOCAL_ONLY); |
| 3020 // Some fast paths through GetKeysInFixedArrayFor reuse a cached |
| 3021 // property array and since the result is mutable we have to create |
| 3022 // a fresh clone on each invocation. |
| 3023 Handle<FixedArray> copy = Factory::NewFixedArray(contents->length()); |
| 3024 contents->CopyTo(0, *copy, 0, contents->length()); |
| 3025 return *Factory::NewJSArrayWithElements(copy); |
| 3026 } |
| 3027 |
| 3028 |
3004 static Object* Runtime_GetArgumentsProperty(Arguments args) { | 3029 static Object* Runtime_GetArgumentsProperty(Arguments args) { |
3005 NoHandleAllocation ha; | 3030 NoHandleAllocation ha; |
3006 ASSERT(args.length() == 1); | 3031 ASSERT(args.length() == 1); |
3007 | 3032 |
3008 // Compute the frame holding the arguments. | 3033 // Compute the frame holding the arguments. |
3009 JavaScriptFrameIterator it; | 3034 JavaScriptFrameIterator it; |
3010 it.AdvanceToArgumentsFrame(); | 3035 it.AdvanceToArgumentsFrame(); |
3011 JavaScriptFrame* frame = it.frame(); | 3036 JavaScriptFrame* frame = it.frame(); |
3012 | 3037 |
3013 // Get the actual number of provided arguments. | 3038 // Get the actual number of provided arguments. |
(...skipping 2495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5509 // might have elements. Can either return keys or intervals. Keys can have | 5534 // might have elements. Can either return keys or intervals. Keys can have |
5510 // gaps in (undefined). Intervals can also span over some undefined keys. | 5535 // gaps in (undefined). Intervals can also span over some undefined keys. |
5511 static Object* Runtime_GetArrayKeys(Arguments args) { | 5536 static Object* Runtime_GetArrayKeys(Arguments args) { |
5512 ASSERT(args.length() == 2); | 5537 ASSERT(args.length() == 2); |
5513 HandleScope scope; | 5538 HandleScope scope; |
5514 CONVERT_ARG_CHECKED(JSObject, array, 0); | 5539 CONVERT_ARG_CHECKED(JSObject, array, 0); |
5515 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); | 5540 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); |
5516 if (array->elements()->IsDictionary()) { | 5541 if (array->elements()->IsDictionary()) { |
5517 // Create an array and get all the keys into it, then remove all the | 5542 // Create an array and get all the keys into it, then remove all the |
5518 // keys that are not integers in the range 0 to length-1. | 5543 // keys that are not integers in the range 0 to length-1. |
5519 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array); | 5544 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array, INCLUDE_PROTOS); |
5520 int keys_length = keys->length(); | 5545 int keys_length = keys->length(); |
5521 for (int i = 0; i < keys_length; i++) { | 5546 for (int i = 0; i < keys_length; i++) { |
5522 Object* key = keys->get(i); | 5547 Object* key = keys->get(i); |
5523 uint32_t index; | 5548 uint32_t index; |
5524 if (!Array::IndexFromObject(key, &index) || index >= length) { | 5549 if (!Array::IndexFromObject(key, &index) || index >= length) { |
5525 // Zap invalid keys. | 5550 // Zap invalid keys. |
5526 keys->set_undefined(i); | 5551 keys->set_undefined(i); |
5527 } | 5552 } |
5528 } | 5553 } |
5529 return *Factory::NewJSArrayWithElements(keys); | 5554 return *Factory::NewJSArrayWithElements(keys); |
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5731 Handle<FixedArray> details = Factory::NewFixedArray(2); | 5756 Handle<FixedArray> details = Factory::NewFixedArray(2); |
5732 details->set(0, Runtime::GetElementOrCharAt(obj, index)); | 5757 details->set(0, Runtime::GetElementOrCharAt(obj, index)); |
5733 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); | 5758 details->set(1, PropertyDetails(NONE, NORMAL).AsSmi()); |
5734 return *Factory::NewJSArrayWithElements(details); | 5759 return *Factory::NewJSArrayWithElements(details); |
5735 } | 5760 } |
5736 | 5761 |
5737 // Find the number of objects making up this. | 5762 // Find the number of objects making up this. |
5738 int length = LocalPrototypeChainLength(*obj); | 5763 int length = LocalPrototypeChainLength(*obj); |
5739 | 5764 |
5740 // Try local lookup on each of the objects. | 5765 // Try local lookup on each of the objects. |
5741 LookupResult result; | |
5742 Handle<JSObject> jsproto = obj; | 5766 Handle<JSObject> jsproto = obj; |
5743 for (int i = 0; i < length; i++) { | 5767 for (int i = 0; i < length; i++) { |
| 5768 LookupResult result; |
5744 jsproto->LocalLookup(*name, &result); | 5769 jsproto->LocalLookup(*name, &result); |
5745 if (result.IsProperty()) { | 5770 if (result.IsProperty()) { |
5746 break; | 5771 // LookupResult is not GC safe as it holds raw object pointers. |
| 5772 // GC can happen later in this code so put the required fields into |
| 5773 // local variables using handles when required for later use. |
| 5774 PropertyType result_type = result.type(); |
| 5775 Handle<Object> result_callback_obj; |
| 5776 if (result_type == CALLBACKS) { |
| 5777 result_callback_obj = Handle<Object>(result.GetCallbackObject()); |
| 5778 } |
| 5779 Smi* property_details = result.GetPropertyDetails().AsSmi(); |
| 5780 // DebugLookupResultValue can cause GC so details from LookupResult needs |
| 5781 // to be copied to handles before this. |
| 5782 bool caught_exception = false; |
| 5783 Object* raw_value = DebugLookupResultValue(*obj, *name, &result, |
| 5784 &caught_exception); |
| 5785 if (raw_value->IsFailure()) return raw_value; |
| 5786 Handle<Object> value(raw_value); |
| 5787 |
| 5788 // If the callback object is a fixed array then it contains JavaScript |
| 5789 // getter and/or setter. |
| 5790 bool hasJavaScriptAccessors = result_type == CALLBACKS && |
| 5791 result_callback_obj->IsFixedArray(); |
| 5792 Handle<FixedArray> details = |
| 5793 Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); |
| 5794 details->set(0, *value); |
| 5795 details->set(1, property_details); |
| 5796 if (hasJavaScriptAccessors) { |
| 5797 details->set(2, |
| 5798 caught_exception ? Heap::true_value() |
| 5799 : Heap::false_value()); |
| 5800 details->set(3, FixedArray::cast(*result_callback_obj)->get(0)); |
| 5801 details->set(4, FixedArray::cast(*result_callback_obj)->get(1)); |
| 5802 } |
| 5803 |
| 5804 return *Factory::NewJSArrayWithElements(details); |
5747 } | 5805 } |
5748 if (i < length - 1) { | 5806 if (i < length - 1) { |
5749 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 5807 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
5750 } | 5808 } |
5751 } | 5809 } |
5752 | 5810 |
5753 if (result.IsProperty()) { | |
5754 // LookupResult is not GC safe as all its members are raw object pointers. | |
5755 // When calling DebugLookupResultValue GC can happen as this might invoke | |
5756 // callbacks. After the call to DebugLookupResultValue the callback object | |
5757 // in the LookupResult might still be needed. Put it into a handle for later | |
5758 // use. | |
5759 PropertyType result_type = result.type(); | |
5760 Handle<Object> result_callback_obj; | |
5761 if (result_type == CALLBACKS) { | |
5762 result_callback_obj = Handle<Object>(result.GetCallbackObject()); | |
5763 } | |
5764 | |
5765 // Find the actual value. Don't use result after this call as it's content | |
5766 // can be invalid. | |
5767 bool caught_exception = false; | |
5768 Object* value = DebugLookupResultValue(*obj, *name, &result, | |
5769 &caught_exception); | |
5770 if (value->IsFailure()) return value; | |
5771 Handle<Object> value_handle(value); | |
5772 | |
5773 // If the callback object is a fixed array then it contains JavaScript | |
5774 // getter and/or setter. | |
5775 bool hasJavaScriptAccessors = result_type == CALLBACKS && | |
5776 result_callback_obj->IsFixedArray(); | |
5777 Handle<FixedArray> details = | |
5778 Factory::NewFixedArray(hasJavaScriptAccessors ? 5 : 2); | |
5779 details->set(0, *value_handle); | |
5780 details->set(1, result.GetPropertyDetails().AsSmi()); | |
5781 if (hasJavaScriptAccessors) { | |
5782 details->set(2, | |
5783 caught_exception ? Heap::true_value() : Heap::false_value()); | |
5784 details->set(3, FixedArray::cast(result.GetCallbackObject())->get(0)); | |
5785 details->set(4, FixedArray::cast(result.GetCallbackObject())->get(1)); | |
5786 } | |
5787 | |
5788 return *Factory::NewJSArrayWithElements(details); | |
5789 } | |
5790 return Heap::undefined_value(); | 5811 return Heap::undefined_value(); |
5791 } | 5812 } |
5792 | 5813 |
5793 | 5814 |
5794 static Object* Runtime_DebugGetProperty(Arguments args) { | 5815 static Object* Runtime_DebugGetProperty(Arguments args) { |
5795 HandleScope scope; | 5816 HandleScope scope; |
5796 | 5817 |
5797 ASSERT(args.length() == 2); | 5818 ASSERT(args.length() == 2); |
5798 | 5819 |
5799 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 5820 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6264 Handle<Context> function_context(frame_context->fcontext()); | 6285 Handle<Context> function_context(frame_context->fcontext()); |
6265 CopyContextLocalsToScopeObject(code, scope_info, | 6286 CopyContextLocalsToScopeObject(code, scope_info, |
6266 function_context, local_scope); | 6287 function_context, local_scope); |
6267 | 6288 |
6268 // Finally copy any properties from the function context extension. This will | 6289 // Finally copy any properties from the function context extension. This will |
6269 // be variables introduced by eval. | 6290 // be variables introduced by eval. |
6270 if (function_context->closure() == *function) { | 6291 if (function_context->closure() == *function) { |
6271 if (function_context->has_extension() && | 6292 if (function_context->has_extension() && |
6272 !function_context->IsGlobalContext()) { | 6293 !function_context->IsGlobalContext()) { |
6273 Handle<JSObject> ext(JSObject::cast(function_context->extension())); | 6294 Handle<JSObject> ext(JSObject::cast(function_context->extension())); |
6274 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext); | 6295 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); |
6275 for (int i = 0; i < keys->length(); i++) { | 6296 for (int i = 0; i < keys->length(); i++) { |
6276 // Names of variables introduced by eval are strings. | 6297 // Names of variables introduced by eval are strings. |
6277 ASSERT(keys->get(i)->IsString()); | 6298 ASSERT(keys->get(i)->IsString()); |
6278 Handle<String> key(String::cast(keys->get(i))); | 6299 Handle<String> key(String::cast(keys->get(i))); |
6279 SetProperty(local_scope, key, GetProperty(ext, key), NONE); | 6300 SetProperty(local_scope, key, GetProperty(ext, key), NONE); |
6280 } | 6301 } |
6281 } | 6302 } |
6282 } | 6303 } |
6283 return local_scope; | 6304 return local_scope; |
6284 } | 6305 } |
(...skipping 28 matching lines...) Expand all Loading... |
6313 } | 6334 } |
6314 } | 6335 } |
6315 | 6336 |
6316 // Fill all context locals to the context extension. | 6337 // Fill all context locals to the context extension. |
6317 CopyContextLocalsToScopeObject(code, scope_info, context, closure_scope); | 6338 CopyContextLocalsToScopeObject(code, scope_info, context, closure_scope); |
6318 | 6339 |
6319 // Finally copy any properties from the function context extension. This will | 6340 // Finally copy any properties from the function context extension. This will |
6320 // be variables introduced by eval. | 6341 // be variables introduced by eval. |
6321 if (context->has_extension()) { | 6342 if (context->has_extension()) { |
6322 Handle<JSObject> ext(JSObject::cast(context->extension())); | 6343 Handle<JSObject> ext(JSObject::cast(context->extension())); |
6323 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext); | 6344 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS); |
6324 for (int i = 0; i < keys->length(); i++) { | 6345 for (int i = 0; i < keys->length(); i++) { |
6325 // Names of variables introduced by eval are strings. | 6346 // Names of variables introduced by eval are strings. |
6326 ASSERT(keys->get(i)->IsString()); | 6347 ASSERT(keys->get(i)->IsString()); |
6327 Handle<String> key(String::cast(keys->get(i))); | 6348 Handle<String> key(String::cast(keys->get(i))); |
6328 SetProperty(closure_scope, key, GetProperty(ext, key), NONE); | 6349 SetProperty(closure_scope, key, GetProperty(ext, key), NONE); |
6329 } | 6350 } |
6330 } | 6351 } |
6331 | 6352 |
6332 return closure_scope; | 6353 return closure_scope; |
6333 } | 6354 } |
(...skipping 1375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7709 } else { | 7730 } else { |
7710 // Handle last resort GC and make sure to allow future allocations | 7731 // Handle last resort GC and make sure to allow future allocations |
7711 // to grow the heap without causing GCs (if possible). | 7732 // to grow the heap without causing GCs (if possible). |
7712 Counters::gc_last_resort_from_js.Increment(); | 7733 Counters::gc_last_resort_from_js.Increment(); |
7713 Heap::CollectAllGarbage(false); | 7734 Heap::CollectAllGarbage(false); |
7714 } | 7735 } |
7715 } | 7736 } |
7716 | 7737 |
7717 | 7738 |
7718 } } // namespace v8::internal | 7739 } } // namespace v8::internal |
OLD | NEW |