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 5271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5282 } | 5282 } |
5283 } | 5283 } |
5284 | 5284 |
5285 | 5285 |
5286 // Returns an array that tells you where in the [0, length) interval an array | 5286 // Returns an array that tells you where in the [0, length) interval an array |
5287 // might have elements. Can either return keys or intervals. Keys can have | 5287 // might have elements. Can either return keys or intervals. Keys can have |
5288 // gaps in (undefined). Intervals can also span over some undefined keys. | 5288 // gaps in (undefined). Intervals can also span over some undefined keys. |
5289 static Object* Runtime_GetArrayKeys(Arguments args) { | 5289 static Object* Runtime_GetArrayKeys(Arguments args) { |
5290 ASSERT(args.length() == 2); | 5290 ASSERT(args.length() == 2); |
5291 HandleScope scope; | 5291 HandleScope scope; |
5292 CONVERT_CHECKED(JSArray, raw_array, args[0]); | 5292 CONVERT_ARG_CHECKED(JSObject, array, 0); |
5293 Handle<JSArray> array(raw_array); | |
5294 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); | 5293 CONVERT_NUMBER_CHECKED(uint32_t, length, Uint32, args[1]); |
5295 if (array->elements()->IsDictionary()) { | 5294 if (array->elements()->IsDictionary()) { |
5296 // Create an array and get all the keys into it, then remove all the | 5295 // Create an array and get all the keys into it, then remove all the |
5297 // keys that are not integers in the range 0 to length-1. | 5296 // keys that are not integers in the range 0 to length-1. |
5298 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array); | 5297 Handle<FixedArray> keys = GetKeysInFixedArrayFor(array); |
5299 int keys_length = keys->length(); | 5298 int keys_length = keys->length(); |
5300 for (int i = 0; i < keys_length; i++) { | 5299 for (int i = 0; i < keys_length; i++) { |
5301 Object* key = keys->get(i); | 5300 Object* key = keys->get(i); |
5302 uint32_t index; | 5301 uint32_t index; |
5303 if (!Array::IndexFromObject(key, &index) || index >= length) { | 5302 if (!Array::IndexFromObject(key, &index) || index >= length) { |
5304 // Zap invalid keys. | 5303 // Zap invalid keys. |
5305 keys->set_undefined(i); | 5304 keys->set_undefined(i); |
5306 } | 5305 } |
5307 } | 5306 } |
5308 return *Factory::NewJSArrayWithElements(keys); | 5307 return *Factory::NewJSArrayWithElements(keys); |
5309 } else { | 5308 } else { |
5310 Handle<FixedArray> single_interval = Factory::NewFixedArray(2); | 5309 Handle<FixedArray> single_interval = Factory::NewFixedArray(2); |
5311 // -1 means start of array. | 5310 // -1 means start of array. |
5312 single_interval->set(0, | 5311 single_interval->set(0, |
5313 Smi::FromInt(-1), | 5312 Smi::FromInt(-1), |
5314 SKIP_WRITE_BARRIER); | 5313 SKIP_WRITE_BARRIER); |
| 5314 uint32_t actual_length = static_cast<uint32_t>(array->elements()->length()); |
| 5315 uint32_t min_length = actual_length < length ? actual_length : length; |
5315 Handle<Object> length_object = | 5316 Handle<Object> length_object = |
5316 Factory::NewNumber(static_cast<double>(length)); | 5317 Factory::NewNumber(static_cast<double>(min_length)); |
5317 single_interval->set(1, *length_object); | 5318 single_interval->set(1, *length_object); |
5318 return *Factory::NewJSArrayWithElements(single_interval); | 5319 return *Factory::NewJSArrayWithElements(single_interval); |
5319 } | 5320 } |
5320 } | 5321 } |
5321 | 5322 |
5322 | 5323 |
5323 // DefineAccessor takes an optional final argument which is the | 5324 // DefineAccessor takes an optional final argument which is the |
5324 // property attributes (eg, DONT_ENUM, DONT_DELETE). IMPORTANT: due | 5325 // property attributes (eg, DONT_ENUM, DONT_DELETE). IMPORTANT: due |
5325 // to the way accessors are implemented, it is set for both the getter | 5326 // to the way accessors are implemented, it is set for both the getter |
5326 // and setter on the first call to DefineAccessor and ignored on | 5327 // and setter on the first call to DefineAccessor and ignored on |
(...skipping 1676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7003 } else { | 7004 } else { |
7004 // Handle last resort GC and make sure to allow future allocations | 7005 // Handle last resort GC and make sure to allow future allocations |
7005 // to grow the heap without causing GCs (if possible). | 7006 // to grow the heap without causing GCs (if possible). |
7006 Counters::gc_last_resort_from_js.Increment(); | 7007 Counters::gc_last_resort_from_js.Increment(); |
7007 Heap::CollectAllGarbage(); | 7008 Heap::CollectAllGarbage(); |
7008 } | 7009 } |
7009 } | 7010 } |
7010 | 7011 |
7011 | 7012 |
7012 } } // namespace v8::internal | 7013 } } // namespace v8::internal |
OLD | NEW |