| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 return holder->GetPropertyWithInterceptor(recvr, name, attributes); | 525 return holder->GetPropertyWithInterceptor(recvr, name, attributes); |
| 526 } | 526 } |
| 527 default: | 527 default: |
| 528 UNREACHABLE(); | 528 UNREACHABLE(); |
| 529 return NULL; | 529 return NULL; |
| 530 } | 530 } |
| 531 } | 531 } |
| 532 | 532 |
| 533 | 533 |
| 534 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { | 534 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { |
| 535 // Non-JS objects do not have integer indexed properties. | 535 if (IsJSObject()) { |
| 536 if (!IsJSObject()) return Heap::undefined_value(); | 536 return JSObject::cast(this)->GetElementWithReceiver(receiver, index); |
| 537 return JSObject::cast(this)->GetElementWithReceiver(JSObject::cast(receiver), | 537 } |
| 538 index); | 538 |
| 539 Object* holder = NULL; |
| 540 Context* global_context = Top::context()->global_context(); |
| 541 if (IsString()) { |
| 542 holder = global_context->string_function()->instance_prototype(); |
| 543 } else if (IsNumber()) { |
| 544 holder = global_context->number_function()->instance_prototype(); |
| 545 } else if (IsBoolean()) { |
| 546 holder = global_context->boolean_function()->instance_prototype(); |
| 547 } else { |
| 548 // Undefined and null have no indexed properties. |
| 549 ASSERT(IsUndefined() || IsNull()); |
| 550 return Heap::undefined_value(); |
| 551 } |
| 552 |
| 553 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index); |
| 539 } | 554 } |
| 540 | 555 |
| 541 | 556 |
| 542 Object* Object::GetPrototype() { | 557 Object* Object::GetPrototype() { |
| 543 // The object is either a number, a string, a boolean, or a real JS object. | 558 // The object is either a number, a string, a boolean, or a real JS object. |
| 544 if (IsJSObject()) return JSObject::cast(this)->map()->prototype(); | 559 if (IsJSObject()) return JSObject::cast(this)->map()->prototype(); |
| 545 Context* context = Top::context()->global_context(); | 560 Context* context = Top::context()->global_context(); |
| 546 | 561 |
| 547 if (IsNumber()) return context->number_function()->instance_prototype(); | 562 if (IsNumber()) return context->number_function()->instance_prototype(); |
| 548 if (IsString()) return context->string_function()->instance_prototype(); | 563 if (IsString()) return context->string_function()->instance_prototype(); |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 switch (map()->instance_type()) { | 954 switch (map()->instance_type()) { |
| 940 case MAP_TYPE: | 955 case MAP_TYPE: |
| 941 accumulator->Add("<Map>"); | 956 accumulator->Add("<Map>"); |
| 942 break; | 957 break; |
| 943 case FIXED_ARRAY_TYPE: | 958 case FIXED_ARRAY_TYPE: |
| 944 accumulator->Add("<FixedArray[%u]>", FixedArray::cast(this)->length()); | 959 accumulator->Add("<FixedArray[%u]>", FixedArray::cast(this)->length()); |
| 945 break; | 960 break; |
| 946 case BYTE_ARRAY_TYPE: | 961 case BYTE_ARRAY_TYPE: |
| 947 accumulator->Add("<ByteArray[%u]>", ByteArray::cast(this)->length()); | 962 accumulator->Add("<ByteArray[%u]>", ByteArray::cast(this)->length()); |
| 948 break; | 963 break; |
| 949 case PIXEL_ARRAY_TYPE: | 964 case EXTERNAL_PIXEL_ARRAY_TYPE: |
| 950 accumulator->Add("<PixelArray[%u]>", PixelArray::cast(this)->length()); | 965 accumulator->Add("<ExternalPixelArray[%u]>", |
| 966 ExternalPixelArray::cast(this)->length()); |
| 951 break; | 967 break; |
| 952 case EXTERNAL_BYTE_ARRAY_TYPE: | 968 case EXTERNAL_BYTE_ARRAY_TYPE: |
| 953 accumulator->Add("<ExternalByteArray[%u]>", | 969 accumulator->Add("<ExternalByteArray[%u]>", |
| 954 ExternalByteArray::cast(this)->length()); | 970 ExternalByteArray::cast(this)->length()); |
| 955 break; | 971 break; |
| 956 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: | 972 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: |
| 957 accumulator->Add("<ExternalUnsignedByteArray[%u]>", | 973 accumulator->Add("<ExternalUnsignedByteArray[%u]>", |
| 958 ExternalUnsignedByteArray::cast(this)->length()); | 974 ExternalUnsignedByteArray::cast(this)->length()); |
| 959 break; | 975 break; |
| 960 case EXTERNAL_SHORT_ARRAY_TYPE: | 976 case EXTERNAL_SHORT_ARRAY_TYPE: |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1091 break; | 1107 break; |
| 1092 case CODE_TYPE: | 1108 case CODE_TYPE: |
| 1093 reinterpret_cast<Code*>(this)->CodeIterateBody(v); | 1109 reinterpret_cast<Code*>(this)->CodeIterateBody(v); |
| 1094 break; | 1110 break; |
| 1095 case JS_GLOBAL_PROPERTY_CELL_TYPE: | 1111 case JS_GLOBAL_PROPERTY_CELL_TYPE: |
| 1096 JSGlobalPropertyCell::BodyDescriptor::IterateBody(this, v); | 1112 JSGlobalPropertyCell::BodyDescriptor::IterateBody(this, v); |
| 1097 break; | 1113 break; |
| 1098 case HEAP_NUMBER_TYPE: | 1114 case HEAP_NUMBER_TYPE: |
| 1099 case FILLER_TYPE: | 1115 case FILLER_TYPE: |
| 1100 case BYTE_ARRAY_TYPE: | 1116 case BYTE_ARRAY_TYPE: |
| 1101 case PIXEL_ARRAY_TYPE: | 1117 case EXTERNAL_PIXEL_ARRAY_TYPE: |
| 1102 case EXTERNAL_BYTE_ARRAY_TYPE: | 1118 case EXTERNAL_BYTE_ARRAY_TYPE: |
| 1103 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: | 1119 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: |
| 1104 case EXTERNAL_SHORT_ARRAY_TYPE: | 1120 case EXTERNAL_SHORT_ARRAY_TYPE: |
| 1105 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: | 1121 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: |
| 1106 case EXTERNAL_INT_ARRAY_TYPE: | 1122 case EXTERNAL_INT_ARRAY_TYPE: |
| 1107 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: | 1123 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: |
| 1108 case EXTERNAL_FLOAT_ARRAY_TYPE: | 1124 case EXTERNAL_FLOAT_ARRAY_TYPE: |
| 1109 break; | 1125 break; |
| 1110 case SHARED_FUNCTION_INFO_TYPE: | 1126 case SHARED_FUNCTION_INFO_TYPE: |
| 1111 SharedFunctionInfo::BodyDescriptor::IterateBody(this, v); | 1127 SharedFunctionInfo::BodyDescriptor::IterateBody(this, v); |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1423 } | 1439 } |
| 1424 } | 1440 } |
| 1425 } | 1441 } |
| 1426 return AddSlowProperty(name, value, attributes); | 1442 return AddSlowProperty(name, value, attributes); |
| 1427 } | 1443 } |
| 1428 | 1444 |
| 1429 | 1445 |
| 1430 MaybeObject* JSObject::SetPropertyPostInterceptor( | 1446 MaybeObject* JSObject::SetPropertyPostInterceptor( |
| 1431 String* name, | 1447 String* name, |
| 1432 Object* value, | 1448 Object* value, |
| 1433 PropertyAttributes attributes) { | 1449 PropertyAttributes attributes, |
| 1450 StrictModeFlag strict_mode) { |
| 1434 // Check local property, ignore interceptor. | 1451 // Check local property, ignore interceptor. |
| 1435 LookupResult result; | 1452 LookupResult result; |
| 1436 LocalLookupRealNamedProperty(name, &result); | 1453 LocalLookupRealNamedProperty(name, &result); |
| 1437 if (result.IsFound()) { | 1454 if (result.IsFound()) { |
| 1438 // An existing property, a map transition or a null descriptor was | 1455 // An existing property, a map transition or a null descriptor was |
| 1439 // found. Use set property to handle all these cases. | 1456 // found. Use set property to handle all these cases. |
| 1440 return SetProperty(&result, name, value, attributes); | 1457 return SetProperty(&result, name, value, attributes, strict_mode); |
| 1441 } | 1458 } |
| 1442 // Add a new real property. | 1459 // Add a new real property. |
| 1443 return AddProperty(name, value, attributes); | 1460 return AddProperty(name, value, attributes); |
| 1444 } | 1461 } |
| 1445 | 1462 |
| 1446 | 1463 |
| 1447 MaybeObject* JSObject::ReplaceSlowProperty(String* name, | 1464 MaybeObject* JSObject::ReplaceSlowProperty(String* name, |
| 1448 Object* value, | 1465 Object* value, |
| 1449 PropertyAttributes attributes) { | 1466 PropertyAttributes attributes) { |
| 1450 StringDictionary* dictionary = property_dictionary(); | 1467 StringDictionary* dictionary = property_dictionary(); |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1555 set_properties(FixedArray::cast(new_properties)); | 1572 set_properties(FixedArray::cast(new_properties)); |
| 1556 } | 1573 } |
| 1557 return FastPropertyAtPut(index, new_value); | 1574 return FastPropertyAtPut(index, new_value); |
| 1558 } | 1575 } |
| 1559 | 1576 |
| 1560 | 1577 |
| 1561 | 1578 |
| 1562 MaybeObject* JSObject::SetPropertyWithInterceptor( | 1579 MaybeObject* JSObject::SetPropertyWithInterceptor( |
| 1563 String* name, | 1580 String* name, |
| 1564 Object* value, | 1581 Object* value, |
| 1565 PropertyAttributes attributes) { | 1582 PropertyAttributes attributes, |
| 1583 StrictModeFlag strict_mode) { |
| 1566 HandleScope scope; | 1584 HandleScope scope; |
| 1567 Handle<JSObject> this_handle(this); | 1585 Handle<JSObject> this_handle(this); |
| 1568 Handle<String> name_handle(name); | 1586 Handle<String> name_handle(name); |
| 1569 Handle<Object> value_handle(value); | 1587 Handle<Object> value_handle(value); |
| 1570 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 1588 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
| 1571 if (!interceptor->setter()->IsUndefined()) { | 1589 if (!interceptor->setter()->IsUndefined()) { |
| 1572 LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name)); | 1590 LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name)); |
| 1573 CustomArguments args(interceptor->data(), this, this); | 1591 CustomArguments args(interceptor->data(), this, this); |
| 1574 v8::AccessorInfo info(args.end()); | 1592 v8::AccessorInfo info(args.end()); |
| 1575 v8::NamedPropertySetter setter = | 1593 v8::NamedPropertySetter setter = |
| 1576 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); | 1594 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); |
| 1577 v8::Handle<v8::Value> result; | 1595 v8::Handle<v8::Value> result; |
| 1578 { | 1596 { |
| 1579 // Leaving JavaScript. | 1597 // Leaving JavaScript. |
| 1580 VMState state(EXTERNAL); | 1598 VMState state(EXTERNAL); |
| 1581 Handle<Object> value_unhole(value->IsTheHole() ? | 1599 Handle<Object> value_unhole(value->IsTheHole() ? |
| 1582 Heap::undefined_value() : | 1600 Heap::undefined_value() : |
| 1583 value); | 1601 value); |
| 1584 result = setter(v8::Utils::ToLocal(name_handle), | 1602 result = setter(v8::Utils::ToLocal(name_handle), |
| 1585 v8::Utils::ToLocal(value_unhole), | 1603 v8::Utils::ToLocal(value_unhole), |
| 1586 info); | 1604 info); |
| 1587 } | 1605 } |
| 1588 RETURN_IF_SCHEDULED_EXCEPTION(); | 1606 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 1589 if (!result.IsEmpty()) return *value_handle; | 1607 if (!result.IsEmpty()) return *value_handle; |
| 1590 } | 1608 } |
| 1591 MaybeObject* raw_result = | 1609 MaybeObject* raw_result = |
| 1592 this_handle->SetPropertyPostInterceptor(*name_handle, | 1610 this_handle->SetPropertyPostInterceptor(*name_handle, |
| 1593 *value_handle, | 1611 *value_handle, |
| 1594 attributes); | 1612 attributes, |
| 1613 strict_mode); |
| 1595 RETURN_IF_SCHEDULED_EXCEPTION(); | 1614 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 1596 return raw_result; | 1615 return raw_result; |
| 1597 } | 1616 } |
| 1598 | 1617 |
| 1599 | 1618 |
| 1600 MaybeObject* JSObject::SetProperty(String* name, | 1619 MaybeObject* JSObject::SetProperty(String* name, |
| 1601 Object* value, | 1620 Object* value, |
| 1602 PropertyAttributes attributes) { | 1621 PropertyAttributes attributes, |
| 1622 StrictModeFlag strict_mode) { |
| 1603 LookupResult result; | 1623 LookupResult result; |
| 1604 LocalLookup(name, &result); | 1624 LocalLookup(name, &result); |
| 1605 return SetProperty(&result, name, value, attributes); | 1625 return SetProperty(&result, name, value, attributes, strict_mode); |
| 1606 } | 1626 } |
| 1607 | 1627 |
| 1608 | 1628 |
| 1609 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, | 1629 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, |
| 1610 String* name, | 1630 String* name, |
| 1611 Object* value, | 1631 Object* value, |
| 1612 JSObject* holder) { | 1632 JSObject* holder) { |
| 1613 HandleScope scope; | 1633 HandleScope scope; |
| 1614 | 1634 |
| 1615 // We should never get here to initialize a const with the hole | 1635 // We should never get here to initialize a const with the hole |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1875 HandleScope scope; | 1895 HandleScope scope; |
| 1876 Handle<Object> value_handle(value); | 1896 Handle<Object> value_handle(value); |
| 1877 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 1897 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 1878 return *value_handle; | 1898 return *value_handle; |
| 1879 } | 1899 } |
| 1880 | 1900 |
| 1881 | 1901 |
| 1882 MaybeObject* JSObject::SetProperty(LookupResult* result, | 1902 MaybeObject* JSObject::SetProperty(LookupResult* result, |
| 1883 String* name, | 1903 String* name, |
| 1884 Object* value, | 1904 Object* value, |
| 1885 PropertyAttributes attributes) { | 1905 PropertyAttributes attributes, |
| 1906 StrictModeFlag strict_mode) { |
| 1886 // Make sure that the top context does not change when doing callbacks or | 1907 // Make sure that the top context does not change when doing callbacks or |
| 1887 // interceptor calls. | 1908 // interceptor calls. |
| 1888 AssertNoContextChange ncc; | 1909 AssertNoContextChange ncc; |
| 1889 | 1910 |
| 1890 // Optimization for 2-byte strings often used as keys in a decompression | 1911 // Optimization for 2-byte strings often used as keys in a decompression |
| 1891 // dictionary. We make these short keys into symbols to avoid constantly | 1912 // dictionary. We make these short keys into symbols to avoid constantly |
| 1892 // reallocating them. | 1913 // reallocating them. |
| 1893 if (!name->IsSymbol() && name->length() <= 2) { | 1914 if (!name->IsSymbol() && name->length() <= 2) { |
| 1894 Object* symbol_version; | 1915 Object* symbol_version; |
| 1895 { MaybeObject* maybe_symbol_version = Heap::LookupSymbol(name); | 1916 { MaybeObject* maybe_symbol_version = Heap::LookupSymbol(name); |
| 1896 if (maybe_symbol_version->ToObject(&symbol_version)) { | 1917 if (maybe_symbol_version->ToObject(&symbol_version)) { |
| 1897 name = String::cast(symbol_version); | 1918 name = String::cast(symbol_version); |
| 1898 } | 1919 } |
| 1899 } | 1920 } |
| 1900 } | 1921 } |
| 1901 | 1922 |
| 1902 // Check access rights if needed. | 1923 // Check access rights if needed. |
| 1903 if (IsAccessCheckNeeded() | 1924 if (IsAccessCheckNeeded() |
| 1904 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { | 1925 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| 1905 return SetPropertyWithFailedAccessCheck(result, name, value, true); | 1926 return SetPropertyWithFailedAccessCheck(result, name, value, true); |
| 1906 } | 1927 } |
| 1907 | 1928 |
| 1908 if (IsJSGlobalProxy()) { | 1929 if (IsJSGlobalProxy()) { |
| 1909 Object* proto = GetPrototype(); | 1930 Object* proto = GetPrototype(); |
| 1910 if (proto->IsNull()) return value; | 1931 if (proto->IsNull()) return value; |
| 1911 ASSERT(proto->IsJSGlobalObject()); | 1932 ASSERT(proto->IsJSGlobalObject()); |
| 1912 return JSObject::cast(proto)->SetProperty(result, name, value, attributes); | 1933 return JSObject::cast(proto)->SetProperty( |
| 1934 result, name, value, attributes, strict_mode); |
| 1913 } | 1935 } |
| 1914 | 1936 |
| 1915 if (!result->IsProperty() && !IsJSContextExtensionObject()) { | 1937 if (!result->IsProperty() && !IsJSContextExtensionObject()) { |
| 1916 // We could not find a local property so let's check whether there is an | 1938 // We could not find a local property so let's check whether there is an |
| 1917 // accessor that wants to handle the property. | 1939 // accessor that wants to handle the property. |
| 1918 LookupResult accessor_result; | 1940 LookupResult accessor_result; |
| 1919 LookupCallbackSetterInPrototypes(name, &accessor_result); | 1941 LookupCallbackSetterInPrototypes(name, &accessor_result); |
| 1920 if (accessor_result.IsProperty()) { | 1942 if (accessor_result.IsProperty()) { |
| 1921 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), | 1943 return SetPropertyWithCallback(accessor_result.GetCallbackObject(), |
| 1922 name, | 1944 name, |
| 1923 value, | 1945 value, |
| 1924 accessor_result.holder()); | 1946 accessor_result.holder()); |
| 1925 } | 1947 } |
| 1926 } | 1948 } |
| 1927 if (!result->IsFound()) { | 1949 if (!result->IsFound()) { |
| 1928 // Neither properties nor transitions found. | 1950 // Neither properties nor transitions found. |
| 1929 return AddProperty(name, value, attributes); | 1951 return AddProperty(name, value, attributes); |
| 1930 } | 1952 } |
| 1931 if (result->IsReadOnly() && result->IsProperty()) return value; | 1953 if (result->IsReadOnly() && result->IsProperty()) { |
| 1954 if (strict_mode == kStrictMode) { |
| 1955 HandleScope scope; |
| 1956 Handle<String> key(name); |
| 1957 Handle<Object> holder(this); |
| 1958 Handle<Object> args[2] = { key, holder }; |
| 1959 return Top::Throw(*Factory::NewTypeError("strict_read_only_property", |
| 1960 HandleVector(args, 2))); |
| 1961 } else { |
| 1962 return value; |
| 1963 } |
| 1964 } |
| 1932 // This is a real property that is not read-only, or it is a | 1965 // This is a real property that is not read-only, or it is a |
| 1933 // transition or null descriptor and there are no setters in the prototypes. | 1966 // transition or null descriptor and there are no setters in the prototypes. |
| 1934 switch (result->type()) { | 1967 switch (result->type()) { |
| 1935 case NORMAL: | 1968 case NORMAL: |
| 1936 return SetNormalizedProperty(result, value); | 1969 return SetNormalizedProperty(result, value); |
| 1937 case FIELD: | 1970 case FIELD: |
| 1938 return FastPropertyAtPut(result->GetFieldIndex(), value); | 1971 return FastPropertyAtPut(result->GetFieldIndex(), value); |
| 1939 case MAP_TRANSITION: | 1972 case MAP_TRANSITION: |
| 1940 if (attributes == result->GetAttributes()) { | 1973 if (attributes == result->GetAttributes()) { |
| 1941 // Only use map transition if the attributes match. | 1974 // Only use map transition if the attributes match. |
| 1942 return AddFastPropertyUsingMap(result->GetTransitionMap(), | 1975 return AddFastPropertyUsingMap(result->GetTransitionMap(), |
| 1943 name, | 1976 name, |
| 1944 value); | 1977 value); |
| 1945 } | 1978 } |
| 1946 return ConvertDescriptorToField(name, value, attributes); | 1979 return ConvertDescriptorToField(name, value, attributes); |
| 1947 case CONSTANT_FUNCTION: | 1980 case CONSTANT_FUNCTION: |
| 1948 // Only replace the function if necessary. | 1981 // Only replace the function if necessary. |
| 1949 if (value == result->GetConstantFunction()) return value; | 1982 if (value == result->GetConstantFunction()) return value; |
| 1950 // Preserve the attributes of this existing property. | 1983 // Preserve the attributes of this existing property. |
| 1951 attributes = result->GetAttributes(); | 1984 attributes = result->GetAttributes(); |
| 1952 return ConvertDescriptorToField(name, value, attributes); | 1985 return ConvertDescriptorToField(name, value, attributes); |
| 1953 case CALLBACKS: | 1986 case CALLBACKS: |
| 1954 return SetPropertyWithCallback(result->GetCallbackObject(), | 1987 return SetPropertyWithCallback(result->GetCallbackObject(), |
| 1955 name, | 1988 name, |
| 1956 value, | 1989 value, |
| 1957 result->holder()); | 1990 result->holder()); |
| 1958 case INTERCEPTOR: | 1991 case INTERCEPTOR: |
| 1959 return SetPropertyWithInterceptor(name, value, attributes); | 1992 return SetPropertyWithInterceptor(name, value, attributes, strict_mode); |
| 1960 case CONSTANT_TRANSITION: { | 1993 case CONSTANT_TRANSITION: { |
| 1961 // If the same constant function is being added we can simply | 1994 // If the same constant function is being added we can simply |
| 1962 // transition to the target map. | 1995 // transition to the target map. |
| 1963 Map* target_map = result->GetTransitionMap(); | 1996 Map* target_map = result->GetTransitionMap(); |
| 1964 DescriptorArray* target_descriptors = target_map->instance_descriptors(); | 1997 DescriptorArray* target_descriptors = target_map->instance_descriptors(); |
| 1965 int number = target_descriptors->SearchWithCache(name); | 1998 int number = target_descriptors->SearchWithCache(name); |
| 1966 ASSERT(number != DescriptorArray::kNotFound); | 1999 ASSERT(number != DescriptorArray::kNotFound); |
| 1967 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION); | 2000 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION); |
| 1968 JSFunction* function = | 2001 JSFunction* function = |
| 1969 JSFunction::cast(target_descriptors->GetValue(number)); | 2002 JSFunction::cast(target_descriptors->GetValue(number)); |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2398 | 2431 |
| 2399 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { | 2432 MaybeObject* JSObject::TransformToFastProperties(int unused_property_fields) { |
| 2400 if (HasFastProperties()) return this; | 2433 if (HasFastProperties()) return this; |
| 2401 ASSERT(!IsGlobalObject()); | 2434 ASSERT(!IsGlobalObject()); |
| 2402 return property_dictionary()-> | 2435 return property_dictionary()-> |
| 2403 TransformPropertiesToFastFor(this, unused_property_fields); | 2436 TransformPropertiesToFastFor(this, unused_property_fields); |
| 2404 } | 2437 } |
| 2405 | 2438 |
| 2406 | 2439 |
| 2407 MaybeObject* JSObject::NormalizeElements() { | 2440 MaybeObject* JSObject::NormalizeElements() { |
| 2408 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); | 2441 ASSERT(!HasExternalArrayElements()); |
| 2409 if (HasDictionaryElements()) return this; | 2442 if (HasDictionaryElements()) return this; |
| 2410 ASSERT(map()->has_fast_elements()); | 2443 ASSERT(map()->has_fast_elements()); |
| 2411 | 2444 |
| 2412 Object* obj; | 2445 Object* obj; |
| 2413 { MaybeObject* maybe_obj = map()->GetSlowElementsMap(); | 2446 { MaybeObject* maybe_obj = map()->GetSlowElementsMap(); |
| 2414 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2447 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2415 } | 2448 } |
| 2416 Map* new_map = Map::cast(obj); | 2449 Map* new_map = Map::cast(obj); |
| 2417 | 2450 |
| 2418 // Get number of entries. | 2451 // Get number of entries. |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2500 } | 2533 } |
| 2501 MaybeObject* raw_result = | 2534 MaybeObject* raw_result = |
| 2502 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); | 2535 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); |
| 2503 RETURN_IF_SCHEDULED_EXCEPTION(); | 2536 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 2504 return raw_result; | 2537 return raw_result; |
| 2505 } | 2538 } |
| 2506 | 2539 |
| 2507 | 2540 |
| 2508 MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index, | 2541 MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index, |
| 2509 DeleteMode mode) { | 2542 DeleteMode mode) { |
| 2510 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); | 2543 ASSERT(!HasExternalArrayElements()); |
| 2511 switch (GetElementsKind()) { | 2544 switch (GetElementsKind()) { |
| 2512 case FAST_ELEMENTS: { | 2545 case FAST_ELEMENTS: { |
| 2513 Object* obj; | 2546 Object* obj; |
| 2514 { MaybeObject* maybe_obj = EnsureWritableFastElements(); | 2547 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
| 2515 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2548 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2516 } | 2549 } |
| 2517 uint32_t length = IsJSArray() ? | 2550 uint32_t length = IsJSArray() ? |
| 2518 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | 2551 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : |
| 2519 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 2552 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 2520 if (index < length) { | 2553 if (index < length) { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2599 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2632 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 2600 } | 2633 } |
| 2601 uint32_t length = IsJSArray() ? | 2634 uint32_t length = IsJSArray() ? |
| 2602 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | 2635 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : |
| 2603 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 2636 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 2604 if (index < length) { | 2637 if (index < length) { |
| 2605 FixedArray::cast(elements())->set_the_hole(index); | 2638 FixedArray::cast(elements())->set_the_hole(index); |
| 2606 } | 2639 } |
| 2607 break; | 2640 break; |
| 2608 } | 2641 } |
| 2609 case PIXEL_ELEMENTS: | 2642 case EXTERNAL_PIXEL_ELEMENTS: |
| 2610 case EXTERNAL_BYTE_ELEMENTS: | 2643 case EXTERNAL_BYTE_ELEMENTS: |
| 2611 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 2644 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 2612 case EXTERNAL_SHORT_ELEMENTS: | 2645 case EXTERNAL_SHORT_ELEMENTS: |
| 2613 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 2646 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 2614 case EXTERNAL_INT_ELEMENTS: | 2647 case EXTERNAL_INT_ELEMENTS: |
| 2615 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 2648 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 2616 case EXTERNAL_FLOAT_ELEMENTS: | 2649 case EXTERNAL_FLOAT_ELEMENTS: |
| 2617 // Pixel and external array elements cannot be deleted. Just | 2650 // Pixel and external array elements cannot be deleted. Just |
| 2618 // silently ignore here. | 2651 // silently ignore here. |
| 2619 break; | 2652 break; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2714 } | 2747 } |
| 2715 | 2748 |
| 2716 // Check if the object is among the named properties. | 2749 // Check if the object is among the named properties. |
| 2717 Object* key = SlowReverseLookup(obj); | 2750 Object* key = SlowReverseLookup(obj); |
| 2718 if (key != Heap::undefined_value()) { | 2751 if (key != Heap::undefined_value()) { |
| 2719 return true; | 2752 return true; |
| 2720 } | 2753 } |
| 2721 | 2754 |
| 2722 // Check if the object is among the indexed properties. | 2755 // Check if the object is among the indexed properties. |
| 2723 switch (GetElementsKind()) { | 2756 switch (GetElementsKind()) { |
| 2724 case PIXEL_ELEMENTS: | 2757 case EXTERNAL_PIXEL_ELEMENTS: |
| 2725 case EXTERNAL_BYTE_ELEMENTS: | 2758 case EXTERNAL_BYTE_ELEMENTS: |
| 2726 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 2759 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 2727 case EXTERNAL_SHORT_ELEMENTS: | 2760 case EXTERNAL_SHORT_ELEMENTS: |
| 2728 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 2761 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 2729 case EXTERNAL_INT_ELEMENTS: | 2762 case EXTERNAL_INT_ELEMENTS: |
| 2730 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 2763 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 2731 case EXTERNAL_FLOAT_ELEMENTS: | 2764 case EXTERNAL_FLOAT_ELEMENTS: |
| 2732 // Raw pixels and external arrays do not reference other | 2765 // Raw pixels and external arrays do not reference other |
| 2733 // objects. | 2766 // objects. |
| 2734 break; | 2767 break; |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2792 return context->extension()->ReferencesObject(obj); | 2825 return context->extension()->ReferencesObject(obj); |
| 2793 } | 2826 } |
| 2794 } | 2827 } |
| 2795 | 2828 |
| 2796 // No references to object. | 2829 // No references to object. |
| 2797 return false; | 2830 return false; |
| 2798 } | 2831 } |
| 2799 | 2832 |
| 2800 | 2833 |
| 2801 MaybeObject* JSObject::PreventExtensions() { | 2834 MaybeObject* JSObject::PreventExtensions() { |
| 2835 if (IsAccessCheckNeeded() && |
| 2836 !Top::MayNamedAccess(this, Heap::undefined_value(), v8::ACCESS_KEYS)) { |
| 2837 Top::ReportFailedAccessCheck(this, v8::ACCESS_KEYS); |
| 2838 return Heap::false_value(); |
| 2839 } |
| 2840 |
| 2802 if (IsJSGlobalProxy()) { | 2841 if (IsJSGlobalProxy()) { |
| 2803 Object* proto = GetPrototype(); | 2842 Object* proto = GetPrototype(); |
| 2804 if (proto->IsNull()) return this; | 2843 if (proto->IsNull()) return this; |
| 2805 ASSERT(proto->IsJSGlobalObject()); | 2844 ASSERT(proto->IsJSGlobalObject()); |
| 2806 return JSObject::cast(proto)->PreventExtensions(); | 2845 return JSObject::cast(proto)->PreventExtensions(); |
| 2807 } | 2846 } |
| 2808 | 2847 |
| 2809 // If there are fast elements we normalize. | 2848 // If there are fast elements we normalize. |
| 2810 if (HasFastElements()) { | 2849 if (HasFastElements()) { |
| 2811 Object* ok; | 2850 Object* ok; |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2968 return Heap::undefined_value(); | 3007 return Heap::undefined_value(); |
| 2969 } | 3008 } |
| 2970 | 3009 |
| 2971 uint32_t index = 0; | 3010 uint32_t index = 0; |
| 2972 bool is_element = name->AsArrayIndex(&index); | 3011 bool is_element = name->AsArrayIndex(&index); |
| 2973 | 3012 |
| 2974 if (is_element) { | 3013 if (is_element) { |
| 2975 switch (GetElementsKind()) { | 3014 switch (GetElementsKind()) { |
| 2976 case FAST_ELEMENTS: | 3015 case FAST_ELEMENTS: |
| 2977 break; | 3016 break; |
| 2978 case PIXEL_ELEMENTS: | 3017 case EXTERNAL_PIXEL_ELEMENTS: |
| 2979 case EXTERNAL_BYTE_ELEMENTS: | 3018 case EXTERNAL_BYTE_ELEMENTS: |
| 2980 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3019 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 2981 case EXTERNAL_SHORT_ELEMENTS: | 3020 case EXTERNAL_SHORT_ELEMENTS: |
| 2982 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3021 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 2983 case EXTERNAL_INT_ELEMENTS: | 3022 case EXTERNAL_INT_ELEMENTS: |
| 2984 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3023 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 2985 case EXTERNAL_FLOAT_ELEMENTS: | 3024 case EXTERNAL_FLOAT_ELEMENTS: |
| 2986 // Ignore getters and setters on pixel and external array | 3025 // Ignore getters and setters on pixel and external array |
| 2987 // elements. | 3026 // elements. |
| 2988 return Heap::undefined_value(); | 3027 return Heap::undefined_value(); |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3192 uint32_t index = 0; | 3231 uint32_t index = 0; |
| 3193 bool is_element = name->AsArrayIndex(&index); | 3232 bool is_element = name->AsArrayIndex(&index); |
| 3194 | 3233 |
| 3195 if (is_element) { | 3234 if (is_element) { |
| 3196 if (IsJSArray()) return Heap::undefined_value(); | 3235 if (IsJSArray()) return Heap::undefined_value(); |
| 3197 | 3236 |
| 3198 // Accessors overwrite previous callbacks (cf. with getters/setters). | 3237 // Accessors overwrite previous callbacks (cf. with getters/setters). |
| 3199 switch (GetElementsKind()) { | 3238 switch (GetElementsKind()) { |
| 3200 case FAST_ELEMENTS: | 3239 case FAST_ELEMENTS: |
| 3201 break; | 3240 break; |
| 3202 case PIXEL_ELEMENTS: | 3241 case EXTERNAL_PIXEL_ELEMENTS: |
| 3203 case EXTERNAL_BYTE_ELEMENTS: | 3242 case EXTERNAL_BYTE_ELEMENTS: |
| 3204 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3243 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 3205 case EXTERNAL_SHORT_ELEMENTS: | 3244 case EXTERNAL_SHORT_ELEMENTS: |
| 3206 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3245 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 3207 case EXTERNAL_INT_ELEMENTS: | 3246 case EXTERNAL_INT_ELEMENTS: |
| 3208 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3247 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 3209 case EXTERNAL_FLOAT_ELEMENTS: | 3248 case EXTERNAL_FLOAT_ELEMENTS: |
| 3210 // Ignore getters and setters on pixel and external array | 3249 // Ignore getters and setters on pixel and external array |
| 3211 // elements. | 3250 // elements. |
| 3212 return Heap::undefined_value(); | 3251 return Heap::undefined_value(); |
| (...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3773 if (element->IsString() && | 3812 if (element->IsString() && |
| 3774 key->IsString() && String::cast(element)->Equals(String::cast(key))) { | 3813 key->IsString() && String::cast(element)->Equals(String::cast(key))) { |
| 3775 return true; | 3814 return true; |
| 3776 } | 3815 } |
| 3777 } | 3816 } |
| 3778 return false; | 3817 return false; |
| 3779 } | 3818 } |
| 3780 | 3819 |
| 3781 | 3820 |
| 3782 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { | 3821 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { |
| 3783 ASSERT(!array->HasPixelElements() && !array->HasExternalArrayElements()); | 3822 ASSERT(!array->HasExternalArrayElements()); |
| 3784 switch (array->GetElementsKind()) { | 3823 switch (array->GetElementsKind()) { |
| 3785 case JSObject::FAST_ELEMENTS: | 3824 case JSObject::FAST_ELEMENTS: |
| 3786 return UnionOfKeys(FixedArray::cast(array->elements())); | 3825 return UnionOfKeys(FixedArray::cast(array->elements())); |
| 3787 case JSObject::DICTIONARY_ELEMENTS: { | 3826 case JSObject::DICTIONARY_ELEMENTS: { |
| 3788 NumberDictionary* dict = array->element_dictionary(); | 3827 NumberDictionary* dict = array->element_dictionary(); |
| 3789 int size = dict->NumberOfElements(); | 3828 int size = dict->NumberOfElements(); |
| 3790 | 3829 |
| 3791 // Allocate a temporary fixed array. | 3830 // Allocate a temporary fixed array. |
| 3792 Object* object; | 3831 Object* object; |
| 3793 { MaybeObject* maybe_object = Heap::AllocateFixedArray(size); | 3832 { MaybeObject* maybe_object = Heap::AllocateFixedArray(size); |
| (...skipping 1399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5193 bool String::IsTwoByteEqualTo(Vector<const uc16> str) { | 5232 bool String::IsTwoByteEqualTo(Vector<const uc16> str) { |
| 5194 int slen = length(); | 5233 int slen = length(); |
| 5195 if (str.length() != slen) return false; | 5234 if (str.length() != slen) return false; |
| 5196 for (int i = 0; i < slen; i++) { | 5235 for (int i = 0; i < slen; i++) { |
| 5197 if (Get(i) != str[i]) return false; | 5236 if (Get(i) != str[i]) return false; |
| 5198 } | 5237 } |
| 5199 return true; | 5238 return true; |
| 5200 } | 5239 } |
| 5201 | 5240 |
| 5202 | 5241 |
| 5203 template <typename schar> | |
| 5204 static inline uint32_t HashSequentialString(const schar* chars, int length) { | |
| 5205 StringHasher hasher(length); | |
| 5206 if (!hasher.has_trivial_hash()) { | |
| 5207 int i; | |
| 5208 for (i = 0; hasher.is_array_index() && (i < length); i++) { | |
| 5209 hasher.AddCharacter(chars[i]); | |
| 5210 } | |
| 5211 for (; i < length; i++) { | |
| 5212 hasher.AddCharacterNoIndex(chars[i]); | |
| 5213 } | |
| 5214 } | |
| 5215 return hasher.GetHashField(); | |
| 5216 } | |
| 5217 | |
| 5218 | |
| 5219 uint32_t String::ComputeAndSetHash() { | 5242 uint32_t String::ComputeAndSetHash() { |
| 5220 // Should only be called if hash code has not yet been computed. | 5243 // Should only be called if hash code has not yet been computed. |
| 5221 ASSERT(!HasHashCode()); | 5244 ASSERT(!HasHashCode()); |
| 5222 | 5245 |
| 5223 const int len = length(); | 5246 const int len = length(); |
| 5224 | 5247 |
| 5225 // Compute the hash code. | 5248 // Compute the hash code. |
| 5226 uint32_t field = 0; | 5249 uint32_t field = 0; |
| 5227 if (StringShape(this).IsSequentialAscii()) { | 5250 if (StringShape(this).IsSequentialAscii()) { |
| 5228 field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), len); | 5251 field = HashSequentialString(SeqAsciiString::cast(this)->GetChars(), len); |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5449 if (source->IsUndefined()) hash = String::cast(source)->Hash(); | 5472 if (source->IsUndefined()) hash = String::cast(source)->Hash(); |
| 5450 } | 5473 } |
| 5451 hash ^= ComputeIntegerHash(shared()->start_position_and_type()); | 5474 hash ^= ComputeIntegerHash(shared()->start_position_and_type()); |
| 5452 hash += ComputeIntegerHash(shared()->end_position()); | 5475 hash += ComputeIntegerHash(shared()->end_position()); |
| 5453 return hash; | 5476 return hash; |
| 5454 } | 5477 } |
| 5455 | 5478 |
| 5456 | 5479 |
| 5457 bool JSFunction::IsInlineable() { | 5480 bool JSFunction::IsInlineable() { |
| 5458 if (IsBuiltin()) return false; | 5481 if (IsBuiltin()) return false; |
| 5482 SharedFunctionInfo* shared_info = shared(); |
| 5459 // Check that the function has a script associated with it. | 5483 // Check that the function has a script associated with it. |
| 5460 if (!shared()->script()->IsScript()) return false; | 5484 if (!shared_info->script()->IsScript()) return false; |
| 5461 Code* code = shared()->code(); | 5485 if (shared_info->optimization_disabled()) return false; |
| 5486 Code* code = shared_info->code(); |
| 5462 if (code->kind() == Code::OPTIMIZED_FUNCTION) return true; | 5487 if (code->kind() == Code::OPTIMIZED_FUNCTION) return true; |
| 5463 // If we never ran this (unlikely) then lets try to optimize it. | 5488 // If we never ran this (unlikely) then lets try to optimize it. |
| 5464 if (code->kind() != Code::FUNCTION) return true; | 5489 if (code->kind() != Code::FUNCTION) return true; |
| 5465 return code->optimizable(); | 5490 return code->optimizable(); |
| 5466 } | 5491 } |
| 5467 | 5492 |
| 5468 | 5493 |
| 5469 Object* JSFunction::SetInstancePrototype(Object* value) { | 5494 Object* JSFunction::SetInstancePrototype(Object* value) { |
| 5470 ASSERT(value->IsJSObject()); | 5495 ASSERT(value->IsJSObject()); |
| 5471 | 5496 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5505 Top::context()->global_context()->initial_object_prototype(); | 5530 Top::context()->global_context()->initial_object_prototype(); |
| 5506 } else { | 5531 } else { |
| 5507 map()->set_non_instance_prototype(false); | 5532 map()->set_non_instance_prototype(false); |
| 5508 } | 5533 } |
| 5509 | 5534 |
| 5510 return SetInstancePrototype(construct_prototype); | 5535 return SetInstancePrototype(construct_prototype); |
| 5511 } | 5536 } |
| 5512 | 5537 |
| 5513 | 5538 |
| 5514 Object* JSFunction::RemovePrototype() { | 5539 Object* JSFunction::RemovePrototype() { |
| 5540 if (map() == context()->global_context()->function_without_prototype_map()) { |
| 5541 // Be idempotent. |
| 5542 return this; |
| 5543 } |
| 5515 ASSERT(map() == context()->global_context()->function_map()); | 5544 ASSERT(map() == context()->global_context()->function_map()); |
| 5516 set_map(context()->global_context()->function_without_prototype_map()); | 5545 set_map(context()->global_context()->function_without_prototype_map()); |
| 5517 set_prototype_or_initial_map(Heap::the_hole_value()); | 5546 set_prototype_or_initial_map(Heap::the_hole_value()); |
| 5518 return this; | 5547 return this; |
| 5519 } | 5548 } |
| 5520 | 5549 |
| 5521 | 5550 |
| 5522 Object* JSFunction::SetInstanceClassName(String* name) { | 5551 Object* JSFunction::SetInstanceClassName(String* name) { |
| 5523 shared()->set_instance_class_name(name); | 5552 shared()->set_instance_class_name(name); |
| 5524 return this; | 5553 return this; |
| (...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6205 | 6234 |
| 6206 // Identify kind of code. | 6235 // Identify kind of code. |
| 6207 const char* Code::Kind2String(Kind kind) { | 6236 const char* Code::Kind2String(Kind kind) { |
| 6208 switch (kind) { | 6237 switch (kind) { |
| 6209 case FUNCTION: return "FUNCTION"; | 6238 case FUNCTION: return "FUNCTION"; |
| 6210 case OPTIMIZED_FUNCTION: return "OPTIMIZED_FUNCTION"; | 6239 case OPTIMIZED_FUNCTION: return "OPTIMIZED_FUNCTION"; |
| 6211 case STUB: return "STUB"; | 6240 case STUB: return "STUB"; |
| 6212 case BUILTIN: return "BUILTIN"; | 6241 case BUILTIN: return "BUILTIN"; |
| 6213 case LOAD_IC: return "LOAD_IC"; | 6242 case LOAD_IC: return "LOAD_IC"; |
| 6214 case KEYED_LOAD_IC: return "KEYED_LOAD_IC"; | 6243 case KEYED_LOAD_IC: return "KEYED_LOAD_IC"; |
| 6244 case KEYED_EXTERNAL_ARRAY_LOAD_IC: return "KEYED_EXTERNAL_ARRAY_LOAD_IC"; |
| 6215 case STORE_IC: return "STORE_IC"; | 6245 case STORE_IC: return "STORE_IC"; |
| 6216 case KEYED_STORE_IC: return "KEYED_STORE_IC"; | 6246 case KEYED_STORE_IC: return "KEYED_STORE_IC"; |
| 6247 case KEYED_EXTERNAL_ARRAY_STORE_IC: return "KEYED_EXTERNAL_ARRAY_STORE_IC"; |
| 6217 case CALL_IC: return "CALL_IC"; | 6248 case CALL_IC: return "CALL_IC"; |
| 6218 case KEYED_CALL_IC: return "KEYED_CALL_IC"; | 6249 case KEYED_CALL_IC: return "KEYED_CALL_IC"; |
| 6219 case BINARY_OP_IC: return "BINARY_OP_IC"; | 6250 case BINARY_OP_IC: return "BINARY_OP_IC"; |
| 6220 case TYPE_RECORDING_BINARY_OP_IC: return "TYPE_RECORDING_BINARY_OP_IC"; | 6251 case TYPE_RECORDING_BINARY_OP_IC: return "TYPE_RECORDING_BINARY_OP_IC"; |
| 6221 case COMPARE_IC: return "COMPARE_IC"; | 6252 case COMPARE_IC: return "COMPARE_IC"; |
| 6222 } | 6253 } |
| 6223 UNREACHABLE(); | 6254 UNREACHABLE(); |
| 6224 return NULL; | 6255 return NULL; |
| 6225 } | 6256 } |
| 6226 | 6257 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6258 | 6289 |
| 6259 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) { | 6290 void Code::PrintExtraICState(FILE* out, Kind kind, ExtraICState extra) { |
| 6260 const char* name = NULL; | 6291 const char* name = NULL; |
| 6261 switch (kind) { | 6292 switch (kind) { |
| 6262 case CALL_IC: | 6293 case CALL_IC: |
| 6263 if (extra == STRING_INDEX_OUT_OF_BOUNDS) { | 6294 if (extra == STRING_INDEX_OUT_OF_BOUNDS) { |
| 6264 name = "STRING_INDEX_OUT_OF_BOUNDS"; | 6295 name = "STRING_INDEX_OUT_OF_BOUNDS"; |
| 6265 } | 6296 } |
| 6266 break; | 6297 break; |
| 6267 case STORE_IC: | 6298 case STORE_IC: |
| 6268 if (extra == StoreIC::kStoreICStrict) { | 6299 case KEYED_STORE_IC: |
| 6300 if (extra == kStrictMode) { |
| 6269 name = "STRICT"; | 6301 name = "STRICT"; |
| 6270 } | 6302 } |
| 6271 break; | 6303 break; |
| 6272 default: | 6304 default: |
| 6273 break; | 6305 break; |
| 6274 } | 6306 } |
| 6275 if (name != NULL) { | 6307 if (name != NULL) { |
| 6276 PrintF(out, "extra_ic_state = %s\n", name); | 6308 PrintF(out, "extra_ic_state = %s\n", name); |
| 6277 } else { | 6309 } else { |
| 6278 PrintF(out, "etra_ic_state = %d\n", extra); | 6310 PrintF(out, "etra_ic_state = %d\n", extra); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6355 PrintF("RelocInfo (size = %d)\n", relocation_size()); | 6387 PrintF("RelocInfo (size = %d)\n", relocation_size()); |
| 6356 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out); | 6388 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out); |
| 6357 PrintF(out, "\n"); | 6389 PrintF(out, "\n"); |
| 6358 } | 6390 } |
| 6359 #endif // ENABLE_DISASSEMBLER | 6391 #endif // ENABLE_DISASSEMBLER |
| 6360 | 6392 |
| 6361 | 6393 |
| 6362 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity, | 6394 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity, |
| 6363 int length) { | 6395 int length) { |
| 6364 // We should never end in here with a pixel or external array. | 6396 // We should never end in here with a pixel or external array. |
| 6365 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); | 6397 ASSERT(!HasExternalArrayElements()); |
| 6366 | 6398 |
| 6367 Object* obj; | 6399 Object* obj; |
| 6368 { MaybeObject* maybe_obj = Heap::AllocateFixedArrayWithHoles(capacity); | 6400 { MaybeObject* maybe_obj = Heap::AllocateFixedArrayWithHoles(capacity); |
| 6369 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6401 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6370 } | 6402 } |
| 6371 FixedArray* elems = FixedArray::cast(obj); | 6403 FixedArray* elems = FixedArray::cast(obj); |
| 6372 | 6404 |
| 6373 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); | 6405 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); |
| 6374 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6406 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 6375 } | 6407 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6409 if (IsJSArray()) { | 6441 if (IsJSArray()) { |
| 6410 JSArray::cast(this)->set_length(Smi::FromInt(length)); | 6442 JSArray::cast(this)->set_length(Smi::FromInt(length)); |
| 6411 } | 6443 } |
| 6412 | 6444 |
| 6413 return this; | 6445 return this; |
| 6414 } | 6446 } |
| 6415 | 6447 |
| 6416 | 6448 |
| 6417 MaybeObject* JSObject::SetSlowElements(Object* len) { | 6449 MaybeObject* JSObject::SetSlowElements(Object* len) { |
| 6418 // We should never end in here with a pixel or external array. | 6450 // We should never end in here with a pixel or external array. |
| 6419 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); | 6451 ASSERT(!HasExternalArrayElements()); |
| 6420 | 6452 |
| 6421 uint32_t new_length = static_cast<uint32_t>(len->Number()); | 6453 uint32_t new_length = static_cast<uint32_t>(len->Number()); |
| 6422 | 6454 |
| 6423 switch (GetElementsKind()) { | 6455 switch (GetElementsKind()) { |
| 6424 case FAST_ELEMENTS: { | 6456 case FAST_ELEMENTS: { |
| 6425 // Make sure we never try to shrink dense arrays into sparse arrays. | 6457 // Make sure we never try to shrink dense arrays into sparse arrays. |
| 6426 ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <= | 6458 ASSERT(static_cast<uint32_t>(FixedArray::cast(elements())->length()) <= |
| 6427 new_length); | 6459 new_length); |
| 6428 Object* obj; | 6460 Object* obj; |
| 6429 { MaybeObject* maybe_obj = NormalizeElements(); | 6461 { MaybeObject* maybe_obj = NormalizeElements(); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6474 Handle<FixedArray> old_backing(FixedArray::cast(elements())); | 6506 Handle<FixedArray> old_backing(FixedArray::cast(elements())); |
| 6475 int old_size = old_backing->length(); | 6507 int old_size = old_backing->length(); |
| 6476 int new_size = required_size > old_size ? required_size : old_size; | 6508 int new_size = required_size > old_size ? required_size : old_size; |
| 6477 Handle<FixedArray> new_backing = Factory::NewFixedArray(new_size); | 6509 Handle<FixedArray> new_backing = Factory::NewFixedArray(new_size); |
| 6478 // Can't use this any more now because we may have had a GC! | 6510 // Can't use this any more now because we may have had a GC! |
| 6479 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); | 6511 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); |
| 6480 self->SetContent(*new_backing); | 6512 self->SetContent(*new_backing); |
| 6481 } | 6513 } |
| 6482 | 6514 |
| 6483 | 6515 |
| 6484 // Computes the new capacity when expanding the elements of a JSObject. | |
| 6485 static int NewElementsCapacity(int old_capacity) { | |
| 6486 // (old_capacity + 50%) + 16 | |
| 6487 return old_capacity + (old_capacity >> 1) + 16; | |
| 6488 } | |
| 6489 | |
| 6490 | |
| 6491 static Failure* ArrayLengthRangeError() { | 6516 static Failure* ArrayLengthRangeError() { |
| 6492 HandleScope scope; | 6517 HandleScope scope; |
| 6493 return Top::Throw(*Factory::NewRangeError("invalid_array_length", | 6518 return Top::Throw(*Factory::NewRangeError("invalid_array_length", |
| 6494 HandleVector<Object>(NULL, 0))); | 6519 HandleVector<Object>(NULL, 0))); |
| 6495 } | 6520 } |
| 6496 | 6521 |
| 6497 | 6522 |
| 6498 MaybeObject* JSObject::SetElementsLength(Object* len) { | 6523 MaybeObject* JSObject::SetElementsLength(Object* len) { |
| 6499 // We should never end in here with a pixel or external array. | 6524 // We should never end in here with a pixel or external array. |
| 6500 ASSERT(AllowsSetElementsLength()); | 6525 ASSERT(AllowsSetElementsLength()); |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6638 uint32_t length = IsJSArray() ? | 6663 uint32_t length = IsJSArray() ? |
| 6639 static_cast<uint32_t> | 6664 static_cast<uint32_t> |
| 6640 (Smi::cast(JSArray::cast(this)->length())->value()) : | 6665 (Smi::cast(JSArray::cast(this)->length())->value()) : |
| 6641 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 6666 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 6642 if ((index < length) && | 6667 if ((index < length) && |
| 6643 !FixedArray::cast(elements())->get(index)->IsTheHole()) { | 6668 !FixedArray::cast(elements())->get(index)->IsTheHole()) { |
| 6644 return true; | 6669 return true; |
| 6645 } | 6670 } |
| 6646 break; | 6671 break; |
| 6647 } | 6672 } |
| 6648 case PIXEL_ELEMENTS: { | 6673 case EXTERNAL_PIXEL_ELEMENTS: { |
| 6649 // TODO(iposva): Add testcase. | 6674 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
| 6650 PixelArray* pixels = PixelArray::cast(elements()); | |
| 6651 if (index < static_cast<uint32_t>(pixels->length())) { | 6675 if (index < static_cast<uint32_t>(pixels->length())) { |
| 6652 return true; | 6676 return true; |
| 6653 } | 6677 } |
| 6654 break; | 6678 break; |
| 6655 } | 6679 } |
| 6656 case EXTERNAL_BYTE_ELEMENTS: | 6680 case EXTERNAL_BYTE_ELEMENTS: |
| 6657 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 6681 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 6658 case EXTERNAL_SHORT_ELEMENTS: | 6682 case EXTERNAL_SHORT_ELEMENTS: |
| 6659 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 6683 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 6660 case EXTERNAL_INT_ELEMENTS: | 6684 case EXTERNAL_INT_ELEMENTS: |
| 6661 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 6685 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 6662 case EXTERNAL_FLOAT_ELEMENTS: { | 6686 case EXTERNAL_FLOAT_ELEMENTS: { |
| 6663 // TODO(kbr): Add testcase. | |
| 6664 ExternalArray* array = ExternalArray::cast(elements()); | 6687 ExternalArray* array = ExternalArray::cast(elements()); |
| 6665 if (index < static_cast<uint32_t>(array->length())) { | 6688 if (index < static_cast<uint32_t>(array->length())) { |
| 6666 return true; | 6689 return true; |
| 6667 } | 6690 } |
| 6668 break; | 6691 break; |
| 6669 } | 6692 } |
| 6670 case DICTIONARY_ELEMENTS: { | 6693 case DICTIONARY_ELEMENTS: { |
| 6671 if (element_dictionary()->FindEntry(index) | 6694 if (element_dictionary()->FindEntry(index) |
| 6672 != NumberDictionary::kNotFound) { | 6695 != NumberDictionary::kNotFound) { |
| 6673 return true; | 6696 return true; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6759 uint32_t length = IsJSArray() ? | 6782 uint32_t length = IsJSArray() ? |
| 6760 static_cast<uint32_t> | 6783 static_cast<uint32_t> |
| 6761 (Smi::cast(JSArray::cast(this)->length())->value()) : | 6784 (Smi::cast(JSArray::cast(this)->length())->value()) : |
| 6762 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 6785 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 6763 if ((index < length) && | 6786 if ((index < length) && |
| 6764 !FixedArray::cast(elements())->get(index)->IsTheHole()) { | 6787 !FixedArray::cast(elements())->get(index)->IsTheHole()) { |
| 6765 return FAST_ELEMENT; | 6788 return FAST_ELEMENT; |
| 6766 } | 6789 } |
| 6767 break; | 6790 break; |
| 6768 } | 6791 } |
| 6769 case PIXEL_ELEMENTS: { | 6792 case EXTERNAL_PIXEL_ELEMENTS: { |
| 6770 PixelArray* pixels = PixelArray::cast(elements()); | 6793 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
| 6771 if (index < static_cast<uint32_t>(pixels->length())) return FAST_ELEMENT; | 6794 if (index < static_cast<uint32_t>(pixels->length())) return FAST_ELEMENT; |
| 6772 break; | 6795 break; |
| 6773 } | 6796 } |
| 6774 case EXTERNAL_BYTE_ELEMENTS: | 6797 case EXTERNAL_BYTE_ELEMENTS: |
| 6775 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 6798 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 6776 case EXTERNAL_SHORT_ELEMENTS: | 6799 case EXTERNAL_SHORT_ELEMENTS: |
| 6777 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 6800 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 6778 case EXTERNAL_INT_ELEMENTS: | 6801 case EXTERNAL_INT_ELEMENTS: |
| 6779 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 6802 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 6780 case EXTERNAL_FLOAT_ELEMENTS: { | 6803 case EXTERNAL_FLOAT_ELEMENTS: { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6814 switch (GetElementsKind()) { | 6837 switch (GetElementsKind()) { |
| 6815 case FAST_ELEMENTS: { | 6838 case FAST_ELEMENTS: { |
| 6816 uint32_t length = IsJSArray() ? | 6839 uint32_t length = IsJSArray() ? |
| 6817 static_cast<uint32_t> | 6840 static_cast<uint32_t> |
| 6818 (Smi::cast(JSArray::cast(this)->length())->value()) : | 6841 (Smi::cast(JSArray::cast(this)->length())->value()) : |
| 6819 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 6842 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 6820 if ((index < length) && | 6843 if ((index < length) && |
| 6821 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true; | 6844 !FixedArray::cast(elements())->get(index)->IsTheHole()) return true; |
| 6822 break; | 6845 break; |
| 6823 } | 6846 } |
| 6824 case PIXEL_ELEMENTS: { | 6847 case EXTERNAL_PIXEL_ELEMENTS: { |
| 6825 PixelArray* pixels = PixelArray::cast(elements()); | 6848 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
| 6826 if (index < static_cast<uint32_t>(pixels->length())) { | 6849 if (index < static_cast<uint32_t>(pixels->length())) { |
| 6827 return true; | 6850 return true; |
| 6828 } | 6851 } |
| 6829 break; | 6852 break; |
| 6830 } | 6853 } |
| 6831 case EXTERNAL_BYTE_ELEMENTS: | 6854 case EXTERNAL_BYTE_ELEMENTS: |
| 6832 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 6855 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 6833 case EXTERNAL_SHORT_ELEMENTS: | 6856 case EXTERNAL_SHORT_ELEMENTS: |
| 6834 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 6857 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 6835 case EXTERNAL_INT_ELEMENTS: | 6858 case EXTERNAL_INT_ELEMENTS: |
| (...skipping 21 matching lines...) Expand all Loading... |
| 6857 if (this->IsStringObjectWithCharacterAt(index)) return true; | 6880 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 6858 | 6881 |
| 6859 Object* pt = GetPrototype(); | 6882 Object* pt = GetPrototype(); |
| 6860 if (pt == Heap::null_value()) return false; | 6883 if (pt == Heap::null_value()) return false; |
| 6861 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 6884 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
| 6862 } | 6885 } |
| 6863 | 6886 |
| 6864 | 6887 |
| 6865 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, | 6888 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, |
| 6866 Object* value, | 6889 Object* value, |
| 6890 StrictModeFlag strict_mode, |
| 6867 bool check_prototype) { | 6891 bool check_prototype) { |
| 6868 // Make sure that the top context does not change when doing | 6892 // Make sure that the top context does not change when doing |
| 6869 // callbacks or interceptor calls. | 6893 // callbacks or interceptor calls. |
| 6870 AssertNoContextChange ncc; | 6894 AssertNoContextChange ncc; |
| 6871 HandleScope scope; | 6895 HandleScope scope; |
| 6872 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 6896 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
| 6873 Handle<JSObject> this_handle(this); | 6897 Handle<JSObject> this_handle(this); |
| 6874 Handle<Object> value_handle(value); | 6898 Handle<Object> value_handle(value); |
| 6875 if (!interceptor->setter()->IsUndefined()) { | 6899 if (!interceptor->setter()->IsUndefined()) { |
| 6876 v8::IndexedPropertySetter setter = | 6900 v8::IndexedPropertySetter setter = |
| 6877 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); | 6901 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); |
| 6878 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); | 6902 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); |
| 6879 CustomArguments args(interceptor->data(), this, this); | 6903 CustomArguments args(interceptor->data(), this, this); |
| 6880 v8::AccessorInfo info(args.end()); | 6904 v8::AccessorInfo info(args.end()); |
| 6881 v8::Handle<v8::Value> result; | 6905 v8::Handle<v8::Value> result; |
| 6882 { | 6906 { |
| 6883 // Leaving JavaScript. | 6907 // Leaving JavaScript. |
| 6884 VMState state(EXTERNAL); | 6908 VMState state(EXTERNAL); |
| 6885 result = setter(index, v8::Utils::ToLocal(value_handle), info); | 6909 result = setter(index, v8::Utils::ToLocal(value_handle), info); |
| 6886 } | 6910 } |
| 6887 RETURN_IF_SCHEDULED_EXCEPTION(); | 6911 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 6888 if (!result.IsEmpty()) return *value_handle; | 6912 if (!result.IsEmpty()) return *value_handle; |
| 6889 } | 6913 } |
| 6890 MaybeObject* raw_result = | 6914 MaybeObject* raw_result = |
| 6891 this_handle->SetElementWithoutInterceptor(index, | 6915 this_handle->SetElementWithoutInterceptor(index, |
| 6892 *value_handle, | 6916 *value_handle, |
| 6917 strict_mode, |
| 6893 check_prototype); | 6918 check_prototype); |
| 6894 RETURN_IF_SCHEDULED_EXCEPTION(); | 6919 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 6895 return raw_result; | 6920 return raw_result; |
| 6896 } | 6921 } |
| 6897 | 6922 |
| 6898 | 6923 |
| 6899 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, | 6924 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, |
| 6900 Object* structure, | 6925 Object* structure, |
| 6901 uint32_t index, | 6926 uint32_t index, |
| 6902 Object* holder) { | 6927 Object* holder) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6996 UNREACHABLE(); | 7021 UNREACHABLE(); |
| 6997 return NULL; | 7022 return NULL; |
| 6998 } | 7023 } |
| 6999 | 7024 |
| 7000 | 7025 |
| 7001 // Adding n elements in fast case is O(n*n). | 7026 // Adding n elements in fast case is O(n*n). |
| 7002 // Note: revisit design to have dual undefined values to capture absent | 7027 // Note: revisit design to have dual undefined values to capture absent |
| 7003 // elements. | 7028 // elements. |
| 7004 MaybeObject* JSObject::SetFastElement(uint32_t index, | 7029 MaybeObject* JSObject::SetFastElement(uint32_t index, |
| 7005 Object* value, | 7030 Object* value, |
| 7031 StrictModeFlag strict_mode, |
| 7006 bool check_prototype) { | 7032 bool check_prototype) { |
| 7007 ASSERT(HasFastElements()); | 7033 ASSERT(HasFastElements()); |
| 7008 | 7034 |
| 7009 Object* elms_obj; | 7035 Object* elms_obj; |
| 7010 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); | 7036 { MaybeObject* maybe_elms_obj = EnsureWritableFastElements(); |
| 7011 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; | 7037 if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj; |
| 7012 } | 7038 } |
| 7013 FixedArray* elms = FixedArray::cast(elms_obj); | 7039 FixedArray* elms = FixedArray::cast(elms_obj); |
| 7014 uint32_t elms_length = static_cast<uint32_t>(elms->length()); | 7040 uint32_t elms_length = static_cast<uint32_t>(elms->length()); |
| 7015 | 7041 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7052 return value; | 7078 return value; |
| 7053 } | 7079 } |
| 7054 } | 7080 } |
| 7055 | 7081 |
| 7056 // Otherwise default to slow case. | 7082 // Otherwise default to slow case. |
| 7057 Object* obj; | 7083 Object* obj; |
| 7058 { MaybeObject* maybe_obj = NormalizeElements(); | 7084 { MaybeObject* maybe_obj = NormalizeElements(); |
| 7059 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 7085 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 7060 } | 7086 } |
| 7061 ASSERT(HasDictionaryElements()); | 7087 ASSERT(HasDictionaryElements()); |
| 7062 return SetElement(index, value, check_prototype); | 7088 return SetElement(index, value, strict_mode, check_prototype); |
| 7063 } | 7089 } |
| 7064 | 7090 |
| 7065 | 7091 |
| 7066 MaybeObject* JSObject::SetElement(uint32_t index, | 7092 MaybeObject* JSObject::SetElement(uint32_t index, |
| 7067 Object* value, | 7093 Object* value, |
| 7094 StrictModeFlag strict_mode, |
| 7068 bool check_prototype) { | 7095 bool check_prototype) { |
| 7069 // Check access rights if needed. | 7096 // Check access rights if needed. |
| 7070 if (IsAccessCheckNeeded() && | 7097 if (IsAccessCheckNeeded() && |
| 7071 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 7098 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
| 7072 HandleScope scope; | 7099 HandleScope scope; |
| 7073 Handle<Object> value_handle(value); | 7100 Handle<Object> value_handle(value); |
| 7074 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 7101 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 7075 return *value_handle; | 7102 return *value_handle; |
| 7076 } | 7103 } |
| 7077 | 7104 |
| 7078 if (IsJSGlobalProxy()) { | 7105 if (IsJSGlobalProxy()) { |
| 7079 Object* proto = GetPrototype(); | 7106 Object* proto = GetPrototype(); |
| 7080 if (proto->IsNull()) return value; | 7107 if (proto->IsNull()) return value; |
| 7081 ASSERT(proto->IsJSGlobalObject()); | 7108 ASSERT(proto->IsJSGlobalObject()); |
| 7082 return JSObject::cast(proto)->SetElement(index, value, check_prototype); | 7109 return JSObject::cast(proto)->SetElement(index, |
| 7110 value, |
| 7111 strict_mode, |
| 7112 check_prototype); |
| 7083 } | 7113 } |
| 7084 | 7114 |
| 7085 // Check for lookup interceptor | 7115 // Check for lookup interceptor |
| 7086 if (HasIndexedInterceptor()) { | 7116 if (HasIndexedInterceptor()) { |
| 7087 return SetElementWithInterceptor(index, value, check_prototype); | 7117 return SetElementWithInterceptor(index, |
| 7118 value, |
| 7119 strict_mode, |
| 7120 check_prototype); |
| 7088 } | 7121 } |
| 7089 | 7122 |
| 7090 return SetElementWithoutInterceptor(index, value, check_prototype); | 7123 return SetElementWithoutInterceptor(index, |
| 7124 value, |
| 7125 strict_mode, |
| 7126 check_prototype); |
| 7091 } | 7127 } |
| 7092 | 7128 |
| 7093 | 7129 |
| 7094 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 7130 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, |
| 7095 Object* value, | 7131 Object* value, |
| 7132 StrictModeFlag strict_mode, |
| 7096 bool check_prototype) { | 7133 bool check_prototype) { |
| 7097 switch (GetElementsKind()) { | 7134 switch (GetElementsKind()) { |
| 7098 case FAST_ELEMENTS: | 7135 case FAST_ELEMENTS: |
| 7099 // Fast case. | 7136 // Fast case. |
| 7100 return SetFastElement(index, value, check_prototype); | 7137 return SetFastElement(index, value, strict_mode, check_prototype); |
| 7101 case PIXEL_ELEMENTS: { | 7138 case EXTERNAL_PIXEL_ELEMENTS: { |
| 7102 PixelArray* pixels = PixelArray::cast(elements()); | 7139 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
| 7103 return pixels->SetValue(index, value); | 7140 return pixels->SetValue(index, value); |
| 7104 } | 7141 } |
| 7105 case EXTERNAL_BYTE_ELEMENTS: { | 7142 case EXTERNAL_BYTE_ELEMENTS: { |
| 7106 ExternalByteArray* array = ExternalByteArray::cast(elements()); | 7143 ExternalByteArray* array = ExternalByteArray::cast(elements()); |
| 7107 return array->SetValue(index, value); | 7144 return array->SetValue(index, value); |
| 7108 } | 7145 } |
| 7109 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { | 7146 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: { |
| 7110 ExternalUnsignedByteArray* array = | 7147 ExternalUnsignedByteArray* array = |
| 7111 ExternalUnsignedByteArray::cast(elements()); | 7148 ExternalUnsignedByteArray::cast(elements()); |
| 7112 return array->SetValue(index, value); | 7149 return array->SetValue(index, value); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 7139 NumberDictionary* dictionary = NumberDictionary::cast(elms); | 7176 NumberDictionary* dictionary = NumberDictionary::cast(elms); |
| 7140 | 7177 |
| 7141 int entry = dictionary->FindEntry(index); | 7178 int entry = dictionary->FindEntry(index); |
| 7142 if (entry != NumberDictionary::kNotFound) { | 7179 if (entry != NumberDictionary::kNotFound) { |
| 7143 Object* element = dictionary->ValueAt(entry); | 7180 Object* element = dictionary->ValueAt(entry); |
| 7144 PropertyDetails details = dictionary->DetailsAt(entry); | 7181 PropertyDetails details = dictionary->DetailsAt(entry); |
| 7145 if (details.type() == CALLBACKS) { | 7182 if (details.type() == CALLBACKS) { |
| 7146 return SetElementWithCallback(element, index, value, this); | 7183 return SetElementWithCallback(element, index, value, this); |
| 7147 } else { | 7184 } else { |
| 7148 dictionary->UpdateMaxNumberKey(index); | 7185 dictionary->UpdateMaxNumberKey(index); |
| 7149 dictionary->ValueAtPut(entry, value); | 7186 // If put fails instrict mode, throw exception. |
| 7187 if (!dictionary->ValueAtPut(entry, value) && |
| 7188 strict_mode == kStrictMode) { |
| 7189 Handle<Object> number(Factory::NewNumberFromUint(index)); |
| 7190 Handle<Object> holder(this); |
| 7191 Handle<Object> args[2] = { number, holder }; |
| 7192 return Top::Throw( |
| 7193 *Factory::NewTypeError("strict_read_only_property", |
| 7194 HandleVector(args, 2))); |
| 7195 } |
| 7150 } | 7196 } |
| 7151 } else { | 7197 } else { |
| 7152 // Index not already used. Look for an accessor in the prototype chain. | 7198 // Index not already used. Look for an accessor in the prototype chain. |
| 7153 if (check_prototype) { | 7199 if (check_prototype) { |
| 7154 bool found; | 7200 bool found; |
| 7155 MaybeObject* result = | 7201 MaybeObject* result = |
| 7202 // Strict mode not needed. No-setter case already handled. |
| 7156 SetElementWithCallbackSetterInPrototypes(index, value, &found); | 7203 SetElementWithCallbackSetterInPrototypes(index, value, &found); |
| 7157 if (found) return result; | 7204 if (found) return result; |
| 7158 } | 7205 } |
| 7159 // When we set the is_extensible flag to false we always force | 7206 // When we set the is_extensible flag to false we always force |
| 7160 // the element into dictionary mode (and force them to stay there). | 7207 // the element into dictionary mode (and force them to stay there). |
| 7161 if (!map()->is_extensible()) { | 7208 if (!map()->is_extensible()) { |
| 7162 Handle<Object> number(Factory::NewNumberFromUint(index)); | 7209 Handle<Object> number(Factory::NewNumberFromUint(index)); |
| 7163 Handle<String> index_string(Factory::NumberToString(number)); | 7210 Handle<String> index_string(Factory::NumberToString(number)); |
| 7164 Handle<Object> args[1] = { index_string }; | 7211 Handle<Object> args[1] = { index_string }; |
| 7165 return Top::Throw(*Factory::NewTypeError("object_not_extensible", | 7212 return Top::Throw(*Factory::NewTypeError("object_not_extensible", |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7231 { MaybeObject* maybe_len = | 7278 { MaybeObject* maybe_len = |
| 7232 Heap::NumberFromDouble(static_cast<double>(index) + 1); | 7279 Heap::NumberFromDouble(static_cast<double>(index) + 1); |
| 7233 if (!maybe_len->ToObject(&len)) return maybe_len; | 7280 if (!maybe_len->ToObject(&len)) return maybe_len; |
| 7234 } | 7281 } |
| 7235 set_length(len); | 7282 set_length(len); |
| 7236 } | 7283 } |
| 7237 return value; | 7284 return value; |
| 7238 } | 7285 } |
| 7239 | 7286 |
| 7240 | 7287 |
| 7241 MaybeObject* JSObject::GetElementPostInterceptor(JSObject* receiver, | 7288 MaybeObject* JSObject::GetElementPostInterceptor(Object* receiver, |
| 7242 uint32_t index) { | 7289 uint32_t index) { |
| 7243 // Get element works for both JSObject and JSArray since | 7290 // Get element works for both JSObject and JSArray since |
| 7244 // JSArray::length cannot change. | 7291 // JSArray::length cannot change. |
| 7245 switch (GetElementsKind()) { | 7292 switch (GetElementsKind()) { |
| 7246 case FAST_ELEMENTS: { | 7293 case FAST_ELEMENTS: { |
| 7247 FixedArray* elms = FixedArray::cast(elements()); | 7294 FixedArray* elms = FixedArray::cast(elements()); |
| 7248 if (index < static_cast<uint32_t>(elms->length())) { | 7295 if (index < static_cast<uint32_t>(elms->length())) { |
| 7249 Object* value = elms->get(index); | 7296 Object* value = elms->get(index); |
| 7250 if (!value->IsTheHole()) return value; | 7297 if (!value->IsTheHole()) return value; |
| 7251 } | 7298 } |
| 7252 break; | 7299 break; |
| 7253 } | 7300 } |
| 7254 case PIXEL_ELEMENTS: { | 7301 case EXTERNAL_PIXEL_ELEMENTS: |
| 7255 // TODO(iposva): Add testcase and implement. | |
| 7256 UNIMPLEMENTED(); | |
| 7257 break; | |
| 7258 } | |
| 7259 case EXTERNAL_BYTE_ELEMENTS: | 7302 case EXTERNAL_BYTE_ELEMENTS: |
| 7260 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 7303 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 7261 case EXTERNAL_SHORT_ELEMENTS: | 7304 case EXTERNAL_SHORT_ELEMENTS: |
| 7262 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 7305 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 7263 case EXTERNAL_INT_ELEMENTS: | 7306 case EXTERNAL_INT_ELEMENTS: |
| 7264 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 7307 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 7265 case EXTERNAL_FLOAT_ELEMENTS: { | 7308 case EXTERNAL_FLOAT_ELEMENTS: { |
| 7266 // TODO(kbr): Add testcase and implement. | 7309 MaybeObject* maybe_value = GetExternalElement(index); |
| 7267 UNIMPLEMENTED(); | 7310 Object* value; |
| 7311 if (!maybe_value->ToObject(&value)) return maybe_value; |
| 7312 if (!value->IsUndefined()) return value; |
| 7268 break; | 7313 break; |
| 7269 } | 7314 } |
| 7270 case DICTIONARY_ELEMENTS: { | 7315 case DICTIONARY_ELEMENTS: { |
| 7271 NumberDictionary* dictionary = element_dictionary(); | 7316 NumberDictionary* dictionary = element_dictionary(); |
| 7272 int entry = dictionary->FindEntry(index); | 7317 int entry = dictionary->FindEntry(index); |
| 7273 if (entry != NumberDictionary::kNotFound) { | 7318 if (entry != NumberDictionary::kNotFound) { |
| 7274 Object* element = dictionary->ValueAt(entry); | 7319 Object* element = dictionary->ValueAt(entry); |
| 7275 PropertyDetails details = dictionary->DetailsAt(entry); | 7320 PropertyDetails details = dictionary->DetailsAt(entry); |
| 7276 if (details.type() == CALLBACKS) { | 7321 if (details.type() == CALLBACKS) { |
| 7277 return GetElementWithCallback(receiver, | 7322 return GetElementWithCallback(receiver, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 7288 break; | 7333 break; |
| 7289 } | 7334 } |
| 7290 | 7335 |
| 7291 // Continue searching via the prototype chain. | 7336 // Continue searching via the prototype chain. |
| 7292 Object* pt = GetPrototype(); | 7337 Object* pt = GetPrototype(); |
| 7293 if (pt == Heap::null_value()) return Heap::undefined_value(); | 7338 if (pt == Heap::null_value()) return Heap::undefined_value(); |
| 7294 return pt->GetElementWithReceiver(receiver, index); | 7339 return pt->GetElementWithReceiver(receiver, index); |
| 7295 } | 7340 } |
| 7296 | 7341 |
| 7297 | 7342 |
| 7298 MaybeObject* JSObject::GetElementWithInterceptor(JSObject* receiver, | 7343 MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, |
| 7299 uint32_t index) { | 7344 uint32_t index) { |
| 7300 // Make sure that the top context does not change when doing | 7345 // Make sure that the top context does not change when doing |
| 7301 // callbacks or interceptor calls. | 7346 // callbacks or interceptor calls. |
| 7302 AssertNoContextChange ncc; | 7347 AssertNoContextChange ncc; |
| 7303 HandleScope scope; | 7348 HandleScope scope; |
| 7304 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 7349 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
| 7305 Handle<JSObject> this_handle(receiver); | 7350 Handle<Object> this_handle(receiver); |
| 7306 Handle<JSObject> holder_handle(this); | 7351 Handle<JSObject> holder_handle(this); |
| 7307 | 7352 |
| 7308 if (!interceptor->getter()->IsUndefined()) { | 7353 if (!interceptor->getter()->IsUndefined()) { |
| 7309 v8::IndexedPropertyGetter getter = | 7354 v8::IndexedPropertyGetter getter = |
| 7310 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); | 7355 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); |
| 7311 LOG(ApiIndexedPropertyAccess("interceptor-indexed-get", this, index)); | 7356 LOG(ApiIndexedPropertyAccess("interceptor-indexed-get", this, index)); |
| 7312 CustomArguments args(interceptor->data(), receiver, this); | 7357 CustomArguments args(interceptor->data(), receiver, this); |
| 7313 v8::AccessorInfo info(args.end()); | 7358 v8::AccessorInfo info(args.end()); |
| 7314 v8::Handle<v8::Value> result; | 7359 v8::Handle<v8::Value> result; |
| 7315 { | 7360 { |
| 7316 // Leaving JavaScript. | 7361 // Leaving JavaScript. |
| 7317 VMState state(EXTERNAL); | 7362 VMState state(EXTERNAL); |
| 7318 result = getter(index, info); | 7363 result = getter(index, info); |
| 7319 } | 7364 } |
| 7320 RETURN_IF_SCHEDULED_EXCEPTION(); | 7365 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 7321 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); | 7366 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); |
| 7322 } | 7367 } |
| 7323 | 7368 |
| 7324 MaybeObject* raw_result = | 7369 MaybeObject* raw_result = |
| 7325 holder_handle->GetElementPostInterceptor(*this_handle, index); | 7370 holder_handle->GetElementPostInterceptor(*this_handle, index); |
| 7326 RETURN_IF_SCHEDULED_EXCEPTION(); | 7371 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 7327 return raw_result; | 7372 return raw_result; |
| 7328 } | 7373 } |
| 7329 | 7374 |
| 7330 | 7375 |
| 7331 MaybeObject* JSObject::GetElementWithReceiver(JSObject* receiver, | 7376 MaybeObject* JSObject::GetElementWithReceiver(Object* receiver, |
| 7332 uint32_t index) { | 7377 uint32_t index) { |
| 7333 // Check access rights if needed. | 7378 // Check access rights if needed. |
| 7334 if (IsAccessCheckNeeded() && | 7379 if (IsAccessCheckNeeded() && |
| 7335 !Top::MayIndexedAccess(this, index, v8::ACCESS_GET)) { | 7380 !Top::MayIndexedAccess(this, index, v8::ACCESS_GET)) { |
| 7336 Top::ReportFailedAccessCheck(this, v8::ACCESS_GET); | 7381 Top::ReportFailedAccessCheck(this, v8::ACCESS_GET); |
| 7337 return Heap::undefined_value(); | 7382 return Heap::undefined_value(); |
| 7338 } | 7383 } |
| 7339 | 7384 |
| 7340 if (HasIndexedInterceptor()) { | 7385 if (HasIndexedInterceptor()) { |
| 7341 return GetElementWithInterceptor(receiver, index); | 7386 return GetElementWithInterceptor(receiver, index); |
| 7342 } | 7387 } |
| 7343 | 7388 |
| 7344 // Get element works for both JSObject and JSArray since | 7389 // Get element works for both JSObject and JSArray since |
| 7345 // JSArray::length cannot change. | 7390 // JSArray::length cannot change. |
| 7346 switch (GetElementsKind()) { | 7391 switch (GetElementsKind()) { |
| 7347 case FAST_ELEMENTS: { | 7392 case FAST_ELEMENTS: { |
| 7348 FixedArray* elms = FixedArray::cast(elements()); | 7393 FixedArray* elms = FixedArray::cast(elements()); |
| 7349 if (index < static_cast<uint32_t>(elms->length())) { | 7394 if (index < static_cast<uint32_t>(elms->length())) { |
| 7350 Object* value = elms->get(index); | 7395 Object* value = elms->get(index); |
| 7351 if (!value->IsTheHole()) return value; | 7396 if (!value->IsTheHole()) return value; |
| 7352 } | 7397 } |
| 7353 break; | 7398 break; |
| 7354 } | 7399 } |
| 7355 case PIXEL_ELEMENTS: { | 7400 case EXTERNAL_PIXEL_ELEMENTS: |
| 7356 PixelArray* pixels = PixelArray::cast(elements()); | 7401 case EXTERNAL_BYTE_ELEMENTS: |
| 7402 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 7403 case EXTERNAL_SHORT_ELEMENTS: |
| 7404 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 7405 case EXTERNAL_INT_ELEMENTS: |
| 7406 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 7407 case EXTERNAL_FLOAT_ELEMENTS: { |
| 7408 MaybeObject* maybe_value = GetExternalElement(index); |
| 7409 Object* value; |
| 7410 if (!maybe_value->ToObject(&value)) return maybe_value; |
| 7411 if (!value->IsUndefined()) return value; |
| 7412 break; |
| 7413 } |
| 7414 case DICTIONARY_ELEMENTS: { |
| 7415 NumberDictionary* dictionary = element_dictionary(); |
| 7416 int entry = dictionary->FindEntry(index); |
| 7417 if (entry != NumberDictionary::kNotFound) { |
| 7418 Object* element = dictionary->ValueAt(entry); |
| 7419 PropertyDetails details = dictionary->DetailsAt(entry); |
| 7420 if (details.type() == CALLBACKS) { |
| 7421 return GetElementWithCallback(receiver, |
| 7422 element, |
| 7423 index, |
| 7424 this); |
| 7425 } |
| 7426 return element; |
| 7427 } |
| 7428 break; |
| 7429 } |
| 7430 } |
| 7431 |
| 7432 Object* pt = GetPrototype(); |
| 7433 if (pt == Heap::null_value()) return Heap::undefined_value(); |
| 7434 return pt->GetElementWithReceiver(receiver, index); |
| 7435 } |
| 7436 |
| 7437 |
| 7438 MaybeObject* JSObject::GetExternalElement(uint32_t index) { |
| 7439 // Get element works for both JSObject and JSArray since |
| 7440 // JSArray::length cannot change. |
| 7441 switch (GetElementsKind()) { |
| 7442 case EXTERNAL_PIXEL_ELEMENTS: { |
| 7443 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
| 7357 if (index < static_cast<uint32_t>(pixels->length())) { | 7444 if (index < static_cast<uint32_t>(pixels->length())) { |
| 7358 uint8_t value = pixels->get(index); | 7445 uint8_t value = pixels->get(index); |
| 7359 return Smi::FromInt(value); | 7446 return Smi::FromInt(value); |
| 7360 } | 7447 } |
| 7361 break; | 7448 break; |
| 7362 } | 7449 } |
| 7363 case EXTERNAL_BYTE_ELEMENTS: { | 7450 case EXTERNAL_BYTE_ELEMENTS: { |
| 7364 ExternalByteArray* array = ExternalByteArray::cast(elements()); | 7451 ExternalByteArray* array = ExternalByteArray::cast(elements()); |
| 7365 if (index < static_cast<uint32_t>(array->length())) { | 7452 if (index < static_cast<uint32_t>(array->length())) { |
| 7366 int8_t value = array->get(index); | 7453 int8_t value = array->get(index); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7412 break; | 7499 break; |
| 7413 } | 7500 } |
| 7414 case EXTERNAL_FLOAT_ELEMENTS: { | 7501 case EXTERNAL_FLOAT_ELEMENTS: { |
| 7415 ExternalFloatArray* array = ExternalFloatArray::cast(elements()); | 7502 ExternalFloatArray* array = ExternalFloatArray::cast(elements()); |
| 7416 if (index < static_cast<uint32_t>(array->length())) { | 7503 if (index < static_cast<uint32_t>(array->length())) { |
| 7417 float value = array->get(index); | 7504 float value = array->get(index); |
| 7418 return Heap::AllocateHeapNumber(value); | 7505 return Heap::AllocateHeapNumber(value); |
| 7419 } | 7506 } |
| 7420 break; | 7507 break; |
| 7421 } | 7508 } |
| 7422 case DICTIONARY_ELEMENTS: { | 7509 case FAST_ELEMENTS: |
| 7423 NumberDictionary* dictionary = element_dictionary(); | 7510 case DICTIONARY_ELEMENTS: |
| 7424 int entry = dictionary->FindEntry(index); | 7511 UNREACHABLE(); |
| 7425 if (entry != NumberDictionary::kNotFound) { | |
| 7426 Object* element = dictionary->ValueAt(entry); | |
| 7427 PropertyDetails details = dictionary->DetailsAt(entry); | |
| 7428 if (details.type() == CALLBACKS) { | |
| 7429 return GetElementWithCallback(receiver, | |
| 7430 element, | |
| 7431 index, | |
| 7432 this); | |
| 7433 } | |
| 7434 return element; | |
| 7435 } | |
| 7436 break; | 7512 break; |
| 7437 } | |
| 7438 } | 7513 } |
| 7439 | 7514 return Heap::undefined_value(); |
| 7440 Object* pt = GetPrototype(); | |
| 7441 if (pt == Heap::null_value()) return Heap::undefined_value(); | |
| 7442 return pt->GetElementWithReceiver(receiver, index); | |
| 7443 } | 7515 } |
| 7444 | 7516 |
| 7445 | 7517 |
| 7446 bool JSObject::HasDenseElements() { | 7518 bool JSObject::HasDenseElements() { |
| 7447 int capacity = 0; | 7519 int capacity = 0; |
| 7448 int number_of_elements = 0; | 7520 int number_of_elements = 0; |
| 7449 | 7521 |
| 7450 switch (GetElementsKind()) { | 7522 switch (GetElementsKind()) { |
| 7451 case FAST_ELEMENTS: { | 7523 case FAST_ELEMENTS: { |
| 7452 FixedArray* elms = FixedArray::cast(elements()); | 7524 FixedArray* elms = FixedArray::cast(elements()); |
| 7453 capacity = elms->length(); | 7525 capacity = elms->length(); |
| 7454 for (int i = 0; i < capacity; i++) { | 7526 for (int i = 0; i < capacity; i++) { |
| 7455 if (!elms->get(i)->IsTheHole()) number_of_elements++; | 7527 if (!elms->get(i)->IsTheHole()) number_of_elements++; |
| 7456 } | 7528 } |
| 7457 break; | 7529 break; |
| 7458 } | 7530 } |
| 7459 case PIXEL_ELEMENTS: | 7531 case EXTERNAL_PIXEL_ELEMENTS: |
| 7460 case EXTERNAL_BYTE_ELEMENTS: | 7532 case EXTERNAL_BYTE_ELEMENTS: |
| 7461 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 7533 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 7462 case EXTERNAL_SHORT_ELEMENTS: | 7534 case EXTERNAL_SHORT_ELEMENTS: |
| 7463 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 7535 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 7464 case EXTERNAL_INT_ELEMENTS: | 7536 case EXTERNAL_INT_ELEMENTS: |
| 7465 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 7537 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 7466 case EXTERNAL_FLOAT_ELEMENTS: { | 7538 case EXTERNAL_FLOAT_ELEMENTS: { |
| 7467 return true; | 7539 return true; |
| 7468 } | 7540 } |
| 7469 case DICTIONARY_ELEMENTS: { | 7541 case DICTIONARY_ELEMENTS: { |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7677 | 7749 |
| 7678 switch (GetElementsKind()) { | 7750 switch (GetElementsKind()) { |
| 7679 case FAST_ELEMENTS: { | 7751 case FAST_ELEMENTS: { |
| 7680 uint32_t length = IsJSArray() ? | 7752 uint32_t length = IsJSArray() ? |
| 7681 static_cast<uint32_t>( | 7753 static_cast<uint32_t>( |
| 7682 Smi::cast(JSArray::cast(this)->length())->value()) : | 7754 Smi::cast(JSArray::cast(this)->length())->value()) : |
| 7683 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 7755 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 7684 return (index < length) && | 7756 return (index < length) && |
| 7685 !FixedArray::cast(elements())->get(index)->IsTheHole(); | 7757 !FixedArray::cast(elements())->get(index)->IsTheHole(); |
| 7686 } | 7758 } |
| 7687 case PIXEL_ELEMENTS: { | 7759 case EXTERNAL_PIXEL_ELEMENTS: { |
| 7688 PixelArray* pixels = PixelArray::cast(elements()); | 7760 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
| 7689 return index < static_cast<uint32_t>(pixels->length()); | 7761 return index < static_cast<uint32_t>(pixels->length()); |
| 7690 } | 7762 } |
| 7691 case EXTERNAL_BYTE_ELEMENTS: | 7763 case EXTERNAL_BYTE_ELEMENTS: |
| 7692 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 7764 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 7693 case EXTERNAL_SHORT_ELEMENTS: | 7765 case EXTERNAL_SHORT_ELEMENTS: |
| 7694 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 7766 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 7695 case EXTERNAL_INT_ELEMENTS: | 7767 case EXTERNAL_INT_ELEMENTS: |
| 7696 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 7768 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 7697 case EXTERNAL_FLOAT_ELEMENTS: { | 7769 case EXTERNAL_FLOAT_ELEMENTS: { |
| 7698 ExternalArray* array = ExternalArray::cast(elements()); | 7770 ExternalArray* array = ExternalArray::cast(elements()); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7909 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { | 7981 if (!FixedArray::cast(elements())->get(i)->IsTheHole()) { |
| 7910 if (storage != NULL) { | 7982 if (storage != NULL) { |
| 7911 storage->set(counter, Smi::FromInt(i)); | 7983 storage->set(counter, Smi::FromInt(i)); |
| 7912 } | 7984 } |
| 7913 counter++; | 7985 counter++; |
| 7914 } | 7986 } |
| 7915 } | 7987 } |
| 7916 ASSERT(!storage || storage->length() >= counter); | 7988 ASSERT(!storage || storage->length() >= counter); |
| 7917 break; | 7989 break; |
| 7918 } | 7990 } |
| 7919 case PIXEL_ELEMENTS: { | 7991 case EXTERNAL_PIXEL_ELEMENTS: { |
| 7920 int length = PixelArray::cast(elements())->length(); | 7992 int length = ExternalPixelArray::cast(elements())->length(); |
| 7921 while (counter < length) { | 7993 while (counter < length) { |
| 7922 if (storage != NULL) { | 7994 if (storage != NULL) { |
| 7923 storage->set(counter, Smi::FromInt(counter)); | 7995 storage->set(counter, Smi::FromInt(counter)); |
| 7924 } | 7996 } |
| 7925 counter++; | 7997 counter++; |
| 7926 } | 7998 } |
| 7927 ASSERT(!storage || storage->length() >= counter); | 7999 ASSERT(!storage || storage->length() >= counter); |
| 7928 break; | 8000 break; |
| 7929 } | 8001 } |
| 7930 case EXTERNAL_BYTE_ELEMENTS: | 8002 case EXTERNAL_BYTE_ELEMENTS: |
| (...skipping 720 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8651 result_double->set_value(static_cast<double>(result)); | 8723 result_double->set_value(static_cast<double>(result)); |
| 8652 return result_double; | 8724 return result_double; |
| 8653 } | 8725 } |
| 8654 | 8726 |
| 8655 | 8727 |
| 8656 // Collects all defined (non-hole) and non-undefined (array) elements at | 8728 // Collects all defined (non-hole) and non-undefined (array) elements at |
| 8657 // the start of the elements array. | 8729 // the start of the elements array. |
| 8658 // If the object is in dictionary mode, it is converted to fast elements | 8730 // If the object is in dictionary mode, it is converted to fast elements |
| 8659 // mode. | 8731 // mode. |
| 8660 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { | 8732 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { |
| 8661 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); | 8733 ASSERT(!HasExternalArrayElements()); |
| 8662 | 8734 |
| 8663 if (HasDictionaryElements()) { | 8735 if (HasDictionaryElements()) { |
| 8664 // Convert to fast elements containing only the existing properties. | 8736 // Convert to fast elements containing only the existing properties. |
| 8665 // Ordering is irrelevant, since we are going to sort anyway. | 8737 // Ordering is irrelevant, since we are going to sort anyway. |
| 8666 NumberDictionary* dict = element_dictionary(); | 8738 NumberDictionary* dict = element_dictionary(); |
| 8667 if (IsJSArray() || dict->requires_slow_elements() || | 8739 if (IsJSArray() || dict->requires_slow_elements() || |
| 8668 dict->max_number_key() >= limit) { | 8740 dict->max_number_key() >= limit) { |
| 8669 return PrepareSlowElementsForSort(limit); | 8741 return PrepareSlowElementsForSort(limit); |
| 8670 } | 8742 } |
| 8671 // Convert to fast elements. | 8743 // Convert to fast elements. |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8763 | 8835 |
| 8764 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { | 8836 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { |
| 8765 return Smi::FromInt(static_cast<int>(result)); | 8837 return Smi::FromInt(static_cast<int>(result)); |
| 8766 } | 8838 } |
| 8767 ASSERT_NE(NULL, result_double); | 8839 ASSERT_NE(NULL, result_double); |
| 8768 result_double->set_value(static_cast<double>(result)); | 8840 result_double->set_value(static_cast<double>(result)); |
| 8769 return result_double; | 8841 return result_double; |
| 8770 } | 8842 } |
| 8771 | 8843 |
| 8772 | 8844 |
| 8773 Object* PixelArray::SetValue(uint32_t index, Object* value) { | 8845 Object* ExternalPixelArray::SetValue(uint32_t index, Object* value) { |
| 8774 uint8_t clamped_value = 0; | 8846 uint8_t clamped_value = 0; |
| 8775 if (index < static_cast<uint32_t>(length())) { | 8847 if (index < static_cast<uint32_t>(length())) { |
| 8776 if (value->IsSmi()) { | 8848 if (value->IsSmi()) { |
| 8777 int int_value = Smi::cast(value)->value(); | 8849 int int_value = Smi::cast(value)->value(); |
| 8778 if (int_value < 0) { | 8850 if (int_value < 0) { |
| 8779 clamped_value = 0; | 8851 clamped_value = 0; |
| 8780 } else if (int_value > 255) { | 8852 } else if (int_value > 255) { |
| 8781 clamped_value = 255; | 8853 clamped_value = 255; |
| 8782 } else { | 8854 } else { |
| 8783 clamped_value = static_cast<uint8_t>(int_value); | 8855 clamped_value = static_cast<uint8_t>(int_value); |
| (...skipping 1187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9971 if (break_point_objects()->IsUndefined()) return 0; | 10043 if (break_point_objects()->IsUndefined()) return 0; |
| 9972 // Single beak point. | 10044 // Single beak point. |
| 9973 if (!break_point_objects()->IsFixedArray()) return 1; | 10045 if (!break_point_objects()->IsFixedArray()) return 1; |
| 9974 // Multiple break points. | 10046 // Multiple break points. |
| 9975 return FixedArray::cast(break_point_objects())->length(); | 10047 return FixedArray::cast(break_point_objects())->length(); |
| 9976 } | 10048 } |
| 9977 #endif | 10049 #endif |
| 9978 | 10050 |
| 9979 | 10051 |
| 9980 } } // namespace v8::internal | 10052 } } // namespace v8::internal |
| OLD | NEW |