diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2010-05-31 11:52:20 -0700 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2010-05-31 11:52:20 -0700 |
commit | f86a214357ce4e54d0d5c56c7db295ec745814c3 (patch) | |
tree | 2c6954837f85bc586ba348678322267a26a14a73 /deps/v8/src/runtime.cc | |
parent | 0c1aa36835fa6a3557843dcbc6ed6714d353a783 (diff) | |
download | node-new-f86a214357ce4e54d0d5c56c7db295ec745814c3.tar.gz |
Upgrade to V8 2.2.13
Diffstat (limited to 'deps/v8/src/runtime.cc')
-rw-r--r-- | deps/v8/src/runtime.cc | 138 |
1 files changed, 108 insertions, 30 deletions
diff --git a/deps/v8/src/runtime.cc b/deps/v8/src/runtime.cc index b421ac7147..d53b13d07f 100644 --- a/deps/v8/src/runtime.cc +++ b/deps/v8/src/runtime.cc @@ -291,7 +291,7 @@ static Handle<Object> CreateObjectLiteralBoilerplate( Handle<String> name(String::cast(*key)); ASSERT(!name->AsArrayIndex(&element_index)); result = SetProperty(boilerplate, name, value, NONE); - } else if (Array::IndexFromObject(*key, &element_index)) { + } else if (key->ToArrayIndex(&element_index)) { // Array index (uint32). result = SetElement(boilerplate, element_index, value); } else { @@ -569,6 +569,18 @@ static void GetOwnPropertyImplementation(JSObject* obj, } +// Enumerator used as indices into the array returned from GetOwnProperty +enum PropertyDescriptorIndices { + IS_ACCESSOR_INDEX, + VALUE_INDEX, + GETTER_INDEX, + SETTER_INDEX, + WRITABLE_INDEX, + ENUMERABLE_INDEX, + CONFIGURABLE_INDEX, + DESCRIPTOR_SIZE +}; + // Returns an array with the property description: // if args[1] is not a property on args[0] // returns undefined @@ -579,18 +591,63 @@ static void GetOwnPropertyImplementation(JSObject* obj, static Object* Runtime_GetOwnProperty(Arguments args) { ASSERT(args.length() == 2); HandleScope scope; - Handle<FixedArray> elms = Factory::NewFixedArray(5); + Handle<FixedArray> elms = Factory::NewFixedArray(DESCRIPTOR_SIZE); Handle<JSArray> desc = Factory::NewJSArrayWithElements(elms); LookupResult result; CONVERT_CHECKED(JSObject, obj, args[0]); CONVERT_CHECKED(String, name, args[1]); + // This could be an element. + uint32_t index; + if (name->AsArrayIndex(&index)) { + if (!obj->HasLocalElement(index)) { + return Heap::undefined_value(); + } + + // Special handling of string objects according to ECMAScript 5 15.5.5.2. + // Note that this might be a string object with elements other than the + // actual string value. This is covered by the subsequent cases. + if (obj->IsStringObjectWithCharacterAt(index)) { + JSValue* js_value = JSValue::cast(obj); + String* str = String::cast(js_value->value()); + elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); + elms->set(VALUE_INDEX, str->SubString(index, index+1)); + elms->set(WRITABLE_INDEX, Heap::false_value()); + elms->set(ENUMERABLE_INDEX, Heap::false_value()); + elms->set(CONFIGURABLE_INDEX, Heap::false_value()); + return *desc; + } + + // This can potentially be an element in the elements dictionary or + // a fast element. + if (obj->HasDictionaryElements()) { + NumberDictionary* dictionary = obj->element_dictionary(); + int entry = dictionary->FindEntry(index); + PropertyDetails details = dictionary->DetailsAt(entry); + elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); + elms->set(VALUE_INDEX, dictionary->ValueAt(entry)); + elms->set(WRITABLE_INDEX, Heap::ToBoolean(!details.IsDontDelete())); + elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!details.IsDontEnum())); + elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!details.IsReadOnly())); + return *desc; + } else { + // Elements that are stored as array elements always has: + // writable: true, configurable: true, enumerable: true. + elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); + elms->set(VALUE_INDEX, obj->GetElement(index)); + elms->set(WRITABLE_INDEX, Heap::true_value()); + elms->set(ENUMERABLE_INDEX, Heap::true_value()); + elms->set(CONFIGURABLE_INDEX, Heap::true_value()); + return *desc; + } + } + // Use recursive implementation to also traverse hidden prototypes GetOwnPropertyImplementation(obj, name, &result); - if (!result.IsProperty()) + if (!result.IsProperty()) { return Heap::undefined_value(); - + } if (result.type() == CALLBACKS) { Object* structure = result.GetCallbackObject(); if (structure->IsProxy() || structure->IsAccessorInfo()) { @@ -598,25 +655,25 @@ static Object* Runtime_GetOwnProperty(Arguments args) { // an API defined callback. Object* value = obj->GetPropertyWithCallback( obj, structure, name, result.holder()); - elms->set(0, Heap::false_value()); - elms->set(1, value); - elms->set(2, Heap::ToBoolean(!result.IsReadOnly())); + elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); + elms->set(VALUE_INDEX, value); + elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); } else if (structure->IsFixedArray()) { // __defineGetter__/__defineSetter__ callback. - elms->set(0, Heap::true_value()); - elms->set(1, FixedArray::cast(structure)->get(0)); - elms->set(2, FixedArray::cast(structure)->get(1)); + elms->set(IS_ACCESSOR_INDEX, Heap::true_value()); + elms->set(GETTER_INDEX, FixedArray::cast(structure)->get(0)); + elms->set(SETTER_INDEX, FixedArray::cast(structure)->get(1)); } else { return Heap::undefined_value(); } } else { - elms->set(0, Heap::false_value()); - elms->set(1, result.GetLazyValue()); - elms->set(2, Heap::ToBoolean(!result.IsReadOnly())); + elms->set(IS_ACCESSOR_INDEX, Heap::false_value()); + elms->set(VALUE_INDEX, result.GetLazyValue()); + elms->set(WRITABLE_INDEX, Heap::ToBoolean(!result.IsReadOnly())); } - elms->set(3, Heap::ToBoolean(!result.IsDontEnum())); - elms->set(4, Heap::ToBoolean(!result.IsDontDelete())); + elms->set(ENUMERABLE_INDEX, Heap::ToBoolean(!result.IsDontEnum())); + elms->set(CONFIGURABLE_INDEX, Heap::ToBoolean(!result.IsDontDelete())); return *desc; } @@ -1583,7 +1640,7 @@ static Object* Runtime_SetCode(Arguments args) { static Object* CharCodeAt(String* subject, Object* index) { uint32_t i = 0; - if (!Array::IndexFromObject(index, &i)) return Heap::nan_value(); + if (!index->ToArrayIndex(&i)) return Heap::nan_value(); // Flatten the string. If someone wants to get a char at an index // in a cons string, it is likely that more indices will be // accessed. @@ -1599,7 +1656,7 @@ static Object* CharCodeAt(String* subject, Object* index) { static Object* CharFromCode(Object* char_code) { uint32_t code; - if (Array::IndexFromObject(char_code, &code)) { + if (char_code->ToArrayIndex(&code)) { if (code <= 0xffff) { return Heap::LookupSingleCharacterStringFromCode(code); } @@ -2780,7 +2837,7 @@ static Object* Runtime_StringIndexOf(Arguments args) { Object* index = args[2]; uint32_t start_index; - if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1); + if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); RUNTIME_ASSERT(start_index <= static_cast<uint32_t>(sub->length())); int position = Runtime::StringMatch(sub, pat, start_index); @@ -2830,7 +2887,7 @@ static Object* Runtime_StringLastIndexOf(Arguments args) { Object* index = args[2]; uint32_t start_index; - if (!Array::IndexFromObject(index, &start_index)) return Smi::FromInt(-1); + if (!index->ToArrayIndex(&start_index)) return Smi::FromInt(-1); uint32_t pat_length = pat->length(); uint32_t sub_length = sub->length(); @@ -3657,7 +3714,7 @@ Object* Runtime::GetObjectProperty(Handle<Object> object, Handle<Object> key) { // Check if the given key is an array index. uint32_t index; - if (Array::IndexFromObject(*key, &index)) { + if (key->ToArrayIndex(&index)) { return GetElementOrCharAt(object, index); } @@ -3843,7 +3900,7 @@ Object* Runtime::SetObjectProperty(Handle<Object> object, // Check if the given key is an array index. uint32_t index; - if (Array::IndexFromObject(*key, &index)) { + if (key->ToArrayIndex(&index)) { // In Firefox/SpiderMonkey, Safari and Opera you can access the characters // of a string using [] notation. We need to support this too in // JavaScript. @@ -3895,7 +3952,7 @@ Object* Runtime::ForceSetObjectProperty(Handle<JSObject> js_object, // Check if the given key is an array index. uint32_t index; - if (Array::IndexFromObject(*key, &index)) { + if (key->ToArrayIndex(&index)) { // In Firefox/SpiderMonkey, Safari and Opera you can access the characters // of a string using [] notation. We need to support this too in // JavaScript. @@ -3942,7 +3999,7 @@ Object* Runtime::ForceDeleteObjectProperty(Handle<JSObject> js_object, // Check if the given key is an array index. uint32_t index; - if (Array::IndexFromObject(*key, &index)) { + if (key->ToArrayIndex(&index)) { // In Firefox/SpiderMonkey, Safari and Opera you can access the // characters of a string using [] notation. In the case of a // String object we just need to redirect the deletion to the @@ -4355,7 +4412,7 @@ static Object* Runtime_GetArgumentsProperty(Arguments args) { // Try to convert the key to an index. If successful and within // index return the the argument from the frame. uint32_t index; - if (Array::IndexFromObject(args[0], &index) && index < n) { + if (args[0]->ToArrayIndex(&index) && index < n) { return frame->GetParameter(index); } @@ -5287,6 +5344,25 @@ static Object* Runtime_NumberToInteger(Arguments args) { } +static Object* Runtime_NumberToIntegerMapMinusZero(Arguments args) { + NoHandleAllocation ha; + ASSERT(args.length() == 1); + + CONVERT_DOUBLE_CHECKED(number, args[0]); + + // We do not include 0 so that we don't have to treat +0 / -0 cases. + if (number > 0 && number <= Smi::kMaxValue) { + return Smi::FromInt(static_cast<int>(number)); + } + + double double_value = DoubleToInteger(number); + // Map both -0 and +0 to +0. + if (double_value == 0) double_value = 0; + + return Heap::NumberFromDouble(double_value); +} + + static Object* Runtime_NumberToJSUint32(Arguments args) { NoHandleAllocation ha; ASSERT(args.length() == 1); @@ -6457,8 +6533,8 @@ static Object* Runtime_NewArgumentsFast(Arguments args) { if (obj->IsFailure()) return obj; AssertNoAllocation no_gc; - reinterpret_cast<Array*>(obj)->set_map(Heap::fixed_array_map()); - FixedArray* array = FixedArray::cast(obj); + FixedArray* array = reinterpret_cast<FixedArray*>(obj); + array->set_map(Heap::fixed_array_map()); array->set_length(length); WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc); @@ -7747,8 +7823,8 @@ static Object* Runtime_SwapElements(Arguments args) { Handle<Object> key2 = args.at<Object>(2); uint32_t index1, index2; - if (!Array::IndexFromObject(*key1, &index1) - || !Array::IndexFromObject(*key2, &index2)) { + if (!key1->ToArrayIndex(&index1) + || !key2->ToArrayIndex(&index2)) { return Top::ThrowIllegalOperation(); } @@ -7779,17 +7855,19 @@ static Object* Runtime_GetArrayKeys(Arguments args) { for (int i = 0; i < keys_length; i++) { Object* key = keys->get(i); uint32_t index; - if (!Array::IndexFromObject(key, &index) || index >= length) { + if (!key->ToArrayIndex(&index) || index >= length) { // Zap invalid keys. keys->set_undefined(i); } } return *Factory::NewJSArrayWithElements(keys); } else { + ASSERT(array->HasFastElements()); Handle<FixedArray> single_interval = Factory::NewFixedArray(2); // -1 means start of array. single_interval->set(0, Smi::FromInt(-1)); - uint32_t actual_length = static_cast<uint32_t>(array->elements()->length()); + uint32_t actual_length = + static_cast<uint32_t>(FixedArray::cast(array->elements())->length()); uint32_t min_length = actual_length < length ? actual_length : length; Handle<Object> length_object = Factory::NewNumber(static_cast<double>(min_length)); |