Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/objects.cc

Issue 1306303003: [es6] Implement spec compliant ToPrimitive in the runtime. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/objects.h" 5 #include "src/objects.h"
6 6
7 #include <iomanip> 7 #include <iomanip>
8 #include <sstream> 8 #include <sstream>
9 9
10 #include "src/accessors.h" 10 #include "src/accessors.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 constructor = handle( 83 constructor = handle(
84 JSFunction::cast(native_context->get(constructor_function_index)), 84 JSFunction::cast(native_context->get(constructor_function_index)),
85 isolate); 85 isolate);
86 } 86 }
87 Handle<JSObject> result = isolate->factory()->NewJSObject(constructor); 87 Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
88 Handle<JSValue>::cast(result)->set_value(*object); 88 Handle<JSValue>::cast(result)->set_value(*object);
89 return result; 89 return result;
90 } 90 }
91 91
92 92
93 MaybeHandle<Name> Object::ToName(Isolate* isolate, Handle<Object> object) { 93 // static
94 if (object->IsName()) { 94 MaybeHandle<Object> Object::ToNumber(Isolate* isolate, Handle<Object> input) {
95 return Handle<Name>::cast(object); 95 while (true) {
96 } else { 96 if (input->IsNumber()) {
97 Handle<Object> converted; 97 return input;
98 ASSIGN_RETURN_ON_EXCEPTION(isolate, converted, 98 }
99 Execution::ToString(isolate, object), Name); 99 if (input->IsOddball()) {
100 return Handle<Name>::cast(converted); 100 return handle(Handle<Oddball>::cast(input)->to_number(), isolate);
101 }
102 if (input->IsString()) {
103 return String::ToNumber(Handle<String>::cast(input));
104 }
105 if (input->IsSymbol()) {
106 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToNumber),
107 Object);
108 }
109 if (input->IsSimd128Value()) {
110 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSimdToNumber),
111 Object);
112 }
113 ASSIGN_RETURN_ON_EXCEPTION(
114 isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input),
115 ToPrimitiveHint::kNumber),
116 Object);
101 } 117 }
102 } 118 }
103 119
120
121 // static
122 MaybeHandle<String> Object::ToString(Isolate* isolate, Handle<Object> input) {
123 while (true) {
124 if (input->IsString()) {
125 return Handle<String>::cast(input);
126 }
127 if (input->IsOddball()) {
128 return handle(Handle<Oddball>::cast(input)->to_string(), isolate);
129 }
130 if (input->IsNumber()) {
131 return isolate->factory()->NumberToString(input);
132 }
133 if (input->IsSymbol()) {
134 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToString),
135 String);
136 }
137 if (input->IsSimd128Value()) {
138 return Simd128Value::ToString(Handle<Simd128Value>::cast(input));
139 }
140 ASSIGN_RETURN_ON_EXCEPTION(
141 isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input),
142 ToPrimitiveHint::kString),
143 String);
144 }
145 }
146
104 147
105 bool Object::BooleanValue() { 148 bool Object::BooleanValue() {
106 if (IsBoolean()) return IsTrue(); 149 if (IsBoolean()) return IsTrue();
107 if (IsSmi()) return Smi::cast(this)->value() != 0; 150 if (IsSmi()) return Smi::cast(this)->value() != 0;
108 if (IsUndefined() || IsNull()) return false; 151 if (IsUndefined() || IsNull()) return false;
109 if (IsUndetectableObject()) return false; // Undetectable object is false. 152 if (IsUndetectableObject()) return false; // Undetectable object is false.
110 if (IsString()) return String::cast(this)->length() != 0; 153 if (IsString()) return String::cast(this)->length() != 0;
111 if (IsHeapNumber()) return HeapNumber::cast(this)->HeapNumberBooleanValue(); 154 if (IsHeapNumber()) return HeapNumber::cast(this)->HeapNumberBooleanValue();
112 if (IsSimd128Value()) return true; // Simd value types evaluate to true.
113 return true; 155 return true;
114 } 156 }
115 157
116 158
117 bool Object::StrictEquals(Object* that) { 159 bool Object::StrictEquals(Object* that) {
118 if (this->IsNumber()) { 160 if (this->IsNumber()) {
119 if (!that->IsNumber()) return false; 161 if (!that->IsNumber()) return false;
120 double const x = this->Number(); 162 double const x = this->Number();
121 double const y = that->Number(); 163 double const y = that->Number();
122 // Must check explicitly for NaN:s on Windows, but -0 works fine. 164 // Must check explicitly for NaN:s on Windows, but -0 works fine.
(...skipping 27 matching lines...) Expand all
150 if (js_object->map()->is_access_check_needed()) return false; 192 if (js_object->map()->is_access_check_needed()) return false;
151 auto isolate = js_object->GetIsolate(); 193 auto isolate = js_object->GetIsolate();
152 // TODO(dcarney): this should just be read from the symbol registry so as not 194 // TODO(dcarney): this should just be read from the symbol registry so as not
153 // to be context dependent. 195 // to be context dependent.
154 auto key = isolate->factory()->promise_status_symbol(); 196 auto key = isolate->factory()->promise_status_symbol();
155 // Shouldn't be possible to throw here. 197 // Shouldn't be possible to throw here.
156 return JSObject::HasRealNamedProperty(js_object, key).FromJust(); 198 return JSObject::HasRealNamedProperty(js_object, key).FromJust();
157 } 199 }
158 200
159 201
202 // static
203 MaybeHandle<Object> Object::GetMethod(Handle<JSReceiver> receiver,
204 Handle<Name> name) {
205 Handle<Object> func;
206 Isolate* isolate = receiver->GetIsolate();
207 ASSIGN_RETURN_ON_EXCEPTION(isolate, func,
208 JSReceiver::GetProperty(receiver, name), Object);
209 if (func->IsNull() || func->IsUndefined()) {
210 return isolate->factory()->undefined_value();
211 }
212 if (!func->IsCallable()) {
213 // TODO(bmeurer): Better error message here?
214 THROW_NEW_ERROR(isolate,
215 NewTypeError(MessageTemplate::kCalledNonCallable, func),
216 Object);
217 }
218 return func;
219 }
220
221
160 MaybeHandle<Object> Object::GetProperty(LookupIterator* it, 222 MaybeHandle<Object> Object::GetProperty(LookupIterator* it,
161 LanguageMode language_mode) { 223 LanguageMode language_mode) {
162 for (; it->IsFound(); it->Next()) { 224 for (; it->IsFound(); it->Next()) {
163 switch (it->state()) { 225 switch (it->state()) {
164 case LookupIterator::NOT_FOUND: 226 case LookupIterator::NOT_FOUND:
165 case LookupIterator::TRANSITION: 227 case LookupIterator::TRANSITION:
166 UNREACHABLE(); 228 UNREACHABLE();
167 case LookupIterator::JSPROXY: 229 case LookupIterator::JSPROXY:
168 return JSProxy::GetPropertyWithHandler( 230 return JSProxy::GetPropertyWithHandler(
169 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName()); 231 it->GetHolder<JSProxy>(), it->GetReceiver(), it->GetName());
(...skipping 1308 matching lines...) Expand 10 before | Expand all | Expand 10 after
1478 #define READ_INT32_FIELD(p, offset) \ 1540 #define READ_INT32_FIELD(p, offset) \
1479 (*reinterpret_cast<const int32_t*>(FIELD_ADDR_CONST(p, offset))) 1541 (*reinterpret_cast<const int32_t*>(FIELD_ADDR_CONST(p, offset)))
1480 1542
1481 #define READ_INT64_FIELD(p, offset) \ 1543 #define READ_INT64_FIELD(p, offset) \
1482 (*reinterpret_cast<const int64_t*>(FIELD_ADDR_CONST(p, offset))) 1544 (*reinterpret_cast<const int64_t*>(FIELD_ADDR_CONST(p, offset)))
1483 1545
1484 #define READ_BYTE_FIELD(p, offset) \ 1546 #define READ_BYTE_FIELD(p, offset) \
1485 (*reinterpret_cast<const byte*>(FIELD_ADDR_CONST(p, offset))) 1547 (*reinterpret_cast<const byte*>(FIELD_ADDR_CONST(p, offset)))
1486 1548
1487 1549
1550 // static
1551 Handle<String> Simd128Value::ToString(Handle<Simd128Value> input) {
1552 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \
1553 if (input->Is##Type()) return Type::ToString(Handle<Type>::cast(input));
1554 SIMD128_TYPES(SIMD128_TYPE)
1555 #undef SIMD128_TYPE
1556 UNREACHABLE();
1557 return Handle<String>::null();
1558 }
1559
1560
1561 // static
1562 Handle<String> Float32x4::ToString(Handle<Float32x4> input) {
1563 Isolate* const isolate = input->GetIsolate();
1564 char arr[100];
1565 Vector<char> buffer(arr, arraysize(arr));
1566 std::ostringstream os;
1567 os << "SIMD.Float32x4("
1568 << std::string(DoubleToCString(input->get_lane(0), buffer)) << ", "
1569 << std::string(DoubleToCString(input->get_lane(1), buffer)) << ", "
1570 << std::string(DoubleToCString(input->get_lane(2), buffer)) << ", "
1571 << std::string(DoubleToCString(input->get_lane(3), buffer)) << ")";
1572 return isolate->factory()->NewStringFromAsciiChecked(os.str().c_str());
1573 }
1574
1575
1576 #define SIMD128_BOOL_TO_STRING(Type, lane_count) \
1577 Handle<String> Type::ToString(Handle<Type> input) { \
1578 Isolate* const isolate = input->GetIsolate(); \
1579 std::ostringstream os; \
1580 os << "SIMD." #Type "("; \
1581 os << (input->get_lane(0) ? "true" : "false"); \
1582 for (int i = 1; i < lane_count; i++) { \
1583 os << ", " << (input->get_lane(i) ? "true" : "false"); \
1584 } \
1585 os << ")"; \
1586 return isolate->factory()->NewStringFromAsciiChecked(os.str().c_str()); \
1587 }
1588 SIMD128_BOOL_TO_STRING(Bool32x4, 4)
1589 SIMD128_BOOL_TO_STRING(Bool16x8, 8)
1590 SIMD128_BOOL_TO_STRING(Bool8x16, 16)
1591 #undef SIMD128_BOOL_TO_STRING
1592
1593
1594 #define SIMD128_INT_TO_STRING(Type, lane_count) \
1595 Handle<String> Type::ToString(Handle<Type> input) { \
1596 Isolate* const isolate = input->GetIsolate(); \
1597 char arr[100]; \
1598 Vector<char> buffer(arr, arraysize(arr)); \
1599 std::ostringstream os; \
1600 os << "SIMD." #Type "("; \
1601 os << IntToCString(input->get_lane(0), buffer); \
1602 for (int i = 1; i < lane_count; i++) { \
1603 os << ", " << IntToCString(input->get_lane(i), buffer); \
1604 } \
1605 os << ")"; \
1606 return isolate->factory()->NewStringFromAsciiChecked(os.str().c_str()); \
1607 }
1608 SIMD128_INT_TO_STRING(Int32x4, 4)
1609 SIMD128_INT_TO_STRING(Uint32x4, 4)
1610 SIMD128_INT_TO_STRING(Int16x8, 8)
1611 SIMD128_INT_TO_STRING(Uint16x8, 8)
1612 SIMD128_INT_TO_STRING(Int8x16, 16)
1613 SIMD128_INT_TO_STRING(Uint8x16, 16)
1614 #undef SIMD128_INT_TO_STRING
1615
1616
1488 bool Simd128Value::BitwiseEquals(const Simd128Value* other) const { 1617 bool Simd128Value::BitwiseEquals(const Simd128Value* other) const {
1489 return READ_INT64_FIELD(this, kValueOffset) == 1618 return READ_INT64_FIELD(this, kValueOffset) ==
1490 READ_INT64_FIELD(other, kValueOffset) && 1619 READ_INT64_FIELD(other, kValueOffset) &&
1491 READ_INT64_FIELD(this, kValueOffset + kInt64Size) == 1620 READ_INT64_FIELD(this, kValueOffset + kInt64Size) ==
1492 READ_INT64_FIELD(other, kValueOffset + kInt64Size); 1621 READ_INT64_FIELD(other, kValueOffset + kInt64Size);
1493 } 1622 }
1494 1623
1495 1624
1496 uint32_t Simd128Value::Hash() const { 1625 uint32_t Simd128Value::Hash() const {
1497 uint32_t seed = v8::internal::kZeroHashSeed; 1626 uint32_t seed = v8::internal::kZeroHashSeed;
(...skipping 1774 matching lines...) Expand 10 before | Expand all | Expand 10 after
3272 (it->IsElement() || 3401 (it->IsElement() ||
3273 !it->isolate()->IsInternallyUsedPropertyName(it->name())); 3402 !it->isolate()->IsInternallyUsedPropertyName(it->name()));
3274 MaybeHandle<Object> maybe_old; 3403 MaybeHandle<Object> maybe_old;
3275 if (is_observed) maybe_old = it->GetDataValue(); 3404 if (is_observed) maybe_old = it->GetDataValue();
3276 3405
3277 Handle<Object> to_assign = value; 3406 Handle<Object> to_assign = value;
3278 // Convert the incoming value to a number for storing into typed arrays. 3407 // Convert the incoming value to a number for storing into typed arrays.
3279 if (it->IsElement() && receiver->HasFixedTypedArrayElements()) { 3408 if (it->IsElement() && receiver->HasFixedTypedArrayElements()) {
3280 if (!value->IsNumber() && !value->IsUndefined()) { 3409 if (!value->IsNumber() && !value->IsUndefined()) {
3281 ASSIGN_RETURN_ON_EXCEPTION(it->isolate(), to_assign, 3410 ASSIGN_RETURN_ON_EXCEPTION(it->isolate(), to_assign,
3282 Execution::ToNumber(it->isolate(), value), 3411 Object::ToNumber(it->isolate(), value),
3283 Object); 3412 Object);
3284 // ToNumber above might modify the receiver, causing the cached 3413 // ToNumber above might modify the receiver, causing the cached
3285 // holder_map to mismatch the actual holder->map() after this point. 3414 // holder_map to mismatch the actual holder->map() after this point.
3286 // Reload the map to be in consistent state. Other cached state cannot 3415 // Reload the map to be in consistent state. Other cached state cannot
3287 // have been invalidated since typed array elements cannot be reconfigured 3416 // have been invalidated since typed array elements cannot be reconfigured
3288 // in any way. 3417 // in any way.
3289 it->ReloadHolderMap(); 3418 it->ReloadHolderMap();
3290 3419
3291 // We have to recheck the length. However, it can only change if the 3420 // We have to recheck the length. However, it can only change if the
3292 // underlying buffer was neutered, so just check that. 3421 // underlying buffer was neutered, so just check that.
(...skipping 2581 matching lines...) Expand 10 before | Expand all | Expand 10 after
5874 AllocationSiteUsageContext* site_context, 6003 AllocationSiteUsageContext* site_context,
5875 DeepCopyHints hints) { 6004 DeepCopyHints hints) {
5876 JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, true, hints); 6005 JSObjectWalkVisitor<AllocationSiteUsageContext> v(site_context, true, hints);
5877 MaybeHandle<JSObject> copy = v.StructureWalk(object); 6006 MaybeHandle<JSObject> copy = v.StructureWalk(object);
5878 Handle<JSObject> for_assert; 6007 Handle<JSObject> for_assert;
5879 DCHECK(!copy.ToHandle(&for_assert) || !for_assert.is_identical_to(object)); 6008 DCHECK(!copy.ToHandle(&for_assert) || !for_assert.is_identical_to(object));
5880 return copy; 6009 return copy;
5881 } 6010 }
5882 6011
5883 6012
6013 // static
6014 MaybeHandle<Object> JSReceiver::ToPrimitive(Handle<JSReceiver> receiver,
6015 ToPrimitiveHint hint) {
6016 Isolate* const isolate = receiver->GetIsolate();
6017 Handle<Object> exoticToPrim;
Michael Starzinger 2015/08/28 08:52:13 nit: not likey camelCase here.
Benedikt Meurer 2015/08/28 08:54:53 Done.
6018 ASSIGN_RETURN_ON_EXCEPTION(
6019 isolate, exoticToPrim,
6020 GetMethod(receiver, isolate->factory()->to_primitive_symbol()), Object);
6021 if (!exoticToPrim->IsUndefined()) {
6022 Handle<Object> hint_string;
6023 switch (hint) {
6024 case ToPrimitiveHint::kDefault:
6025 hint_string = isolate->factory()->default_string();
6026 break;
6027 case ToPrimitiveHint::kNumber:
6028 hint_string = isolate->factory()->number_string();
6029 break;
6030 case ToPrimitiveHint::kString:
6031 hint_string = isolate->factory()->string_string();
6032 break;
6033 }
6034 Handle<Object> result;
6035 ASSIGN_RETURN_ON_EXCEPTION(
6036 isolate, result,
6037 Execution::Call(isolate, exoticToPrim, receiver, 1, &hint_string),
6038 Object);
6039 if (result->IsPrimitive()) return result;
6040 THROW_NEW_ERROR(isolate,
6041 NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
6042 Object);
6043 }
6044 return OrdinaryToPrimitive(receiver,
6045 (hint == ToPrimitiveHint::kString)
6046 ? isolate->factory()->string_string()
6047 : isolate->factory()->number_string());
6048 }
6049
6050
6051 // static
6052 MaybeHandle<Object> JSReceiver::OrdinaryToPrimitive(Handle<JSReceiver> receiver,
6053 Handle<String> hint) {
6054 Isolate* const isolate = receiver->GetIsolate();
6055 Handle<String> methodNames[2];
Michael Starzinger 2015/08/28 08:52:13 nit: s/methodName/method_names/
Benedikt Meurer 2015/08/28 08:54:53 Done.
6056 if (hint.is_identical_to(isolate->factory()->number_string())) {
6057 methodNames[0] = isolate->factory()->valueOf_string();
6058 methodNames[1] = isolate->factory()->toString_string();
6059 } else {
6060 DCHECK(hint.is_identical_to(isolate->factory()->string_string()));
6061 methodNames[0] = isolate->factory()->toString_string();
6062 methodNames[1] = isolate->factory()->valueOf_string();
6063 }
6064 for (Handle<String> name : methodNames) {
6065 Handle<Object> method;
6066 ASSIGN_RETURN_ON_EXCEPTION(isolate, method,
6067 JSReceiver::GetProperty(receiver, name), Object);
6068 if (method->IsCallable()) {
6069 Handle<Object> result;
6070 ASSIGN_RETURN_ON_EXCEPTION(
6071 isolate, result, Execution::Call(isolate, method, receiver, 0, NULL),
6072 Object);
6073 if (result->IsPrimitive()) return result;
6074 }
6075 }
6076 THROW_NEW_ERROR(isolate,
6077 NewTypeError(MessageTemplate::kCannotConvertToPrimitive),
6078 Object);
6079 }
6080
6081
5884 // Tests for the fast common case for property enumeration: 6082 // Tests for the fast common case for property enumeration:
5885 // - This object and all prototypes has an enum cache (which means that 6083 // - This object and all prototypes has an enum cache (which means that
5886 // it is no proxy, has no interceptors and needs no access checks). 6084 // it is no proxy, has no interceptors and needs no access checks).
5887 // - This object has no elements. 6085 // - This object has no elements.
5888 // - No prototype has enumerable properties/elements. 6086 // - No prototype has enumerable properties/elements.
5889 bool JSReceiver::IsSimpleEnum() { 6087 bool JSReceiver::IsSimpleEnum() {
5890 for (PrototypeIterator iter(GetIsolate(), this, 6088 for (PrototypeIterator iter(GetIsolate(), this,
5891 PrototypeIterator::START_AT_RECEIVER); 6089 PrototypeIterator::START_AT_RECEIVER);
5892 !iter.IsAtEnd(); iter.Advance()) { 6090 !iter.IsAtEnd(); iter.Advance()) {
5893 if (!iter.GetCurrent()->IsJSObject()) return false; 6091 if (!iter.GetCurrent()->IsJSObject()) return false;
(...skipping 2251 matching lines...) Expand 10 before | Expand all | Expand 10 after
8145 } 8343 }
8146 #endif 8344 #endif
8147 8345
8148 8346
8149 bool String::LooksValid() { 8347 bool String::LooksValid() {
8150 if (!GetIsolate()->heap()->Contains(this)) return false; 8348 if (!GetIsolate()->heap()->Contains(this)) return false;
8151 return true; 8349 return true;
8152 } 8350 }
8153 8351
8154 8352
8353 namespace {
8354
8355 bool AreDigits(const uint8_t* s, int from, int to) {
8356 for (int i = from; i < to; i++) {
8357 if (s[i] < '0' || s[i] > '9') return false;
8358 }
8359
8360 return true;
8361 }
8362
8363
8364 int ParseDecimalInteger(const uint8_t* s, int from, int to) {
8365 DCHECK(to - from < 10); // Overflow is not possible.
8366 DCHECK(from < to);
8367 int d = s[from] - '0';
8368
8369 for (int i = from + 1; i < to; i++) {
8370 d = 10 * d + (s[i] - '0');
8371 }
8372
8373 return d;
8374 }
8375
8376 } // namespace
8377
8378
8379 // static
8380 Handle<Object> String::ToNumber(Handle<String> subject) {
8381 Isolate* const isolate = subject->GetIsolate();
8382
8383 // Flatten {subject} string first.
8384 subject = String::Flatten(subject);
8385
8386 // Fast array index case.
8387 uint32_t index;
8388 if (subject->AsArrayIndex(&index)) {
8389 return isolate->factory()->NewNumberFromUint(index);
8390 }
8391
8392 // Fast case: short integer or some sorts of junk values.
8393 if (subject->IsSeqOneByteString()) {
8394 int len = subject->length();
8395 if (len == 0) return handle(Smi::FromInt(0), isolate);
8396
8397 DisallowHeapAllocation no_gc;
8398 uint8_t const* data = Handle<SeqOneByteString>::cast(subject)->GetChars();
8399 bool minus = (data[0] == '-');
8400 int start_pos = (minus ? 1 : 0);
8401
8402 if (start_pos == len) {
8403 return isolate->factory()->nan_value();
8404 } else if (data[start_pos] > '9') {
8405 // Fast check for a junk value. A valid string may start from a
8406 // whitespace, a sign ('+' or '-'), the decimal point, a decimal digit
8407 // or the 'I' character ('Infinity'). All of that have codes not greater
8408 // than '9' except 'I' and &nbsp;.
8409 if (data[start_pos] != 'I' && data[start_pos] != 0xa0) {
8410 return isolate->factory()->nan_value();
8411 }
8412 } else if (len - start_pos < 10 && AreDigits(data, start_pos, len)) {
8413 // The maximal/minimal smi has 10 digits. If the string has less digits
8414 // we know it will fit into the smi-data type.
8415 int d = ParseDecimalInteger(data, start_pos, len);
8416 if (minus) {
8417 if (d == 0) return isolate->factory()->minus_zero_value();
8418 d = -d;
8419 } else if (!subject->HasHashCode() && len <= String::kMaxArrayIndexSize &&
8420 (len == 1 || data[0] != '0')) {
8421 // String hash is not calculated yet but all the data are present.
8422 // Update the hash field to speed up sequential convertions.
8423 uint32_t hash = StringHasher::MakeArrayIndexHash(d, len);
8424 #ifdef DEBUG
8425 subject->Hash(); // Force hash calculation.
8426 DCHECK_EQ(static_cast<int>(subject->hash_field()),
8427 static_cast<int>(hash));
8428 #endif
8429 subject->set_hash_field(hash);
8430 }
8431 return handle(Smi::FromInt(d), isolate);
8432 }
8433 }
8434
8435 // Slower case.
8436 int flags = ALLOW_HEX | ALLOW_OCTAL | ALLOW_BINARY;
8437 return isolate->factory()->NewNumber(
8438 StringToDouble(isolate->unicode_cache(), subject, flags));
8439 }
8440
8441
8155 String::FlatContent String::GetFlatContent() { 8442 String::FlatContent String::GetFlatContent() {
8156 DCHECK(!AllowHeapAllocation::IsAllowed()); 8443 DCHECK(!AllowHeapAllocation::IsAllowed());
8157 int length = this->length(); 8444 int length = this->length();
8158 StringShape shape(this); 8445 StringShape shape(this);
8159 String* string = this; 8446 String* string = this;
8160 int offset = 0; 8447 int offset = 0;
8161 if (shape.representation_tag() == kConsStringTag) { 8448 if (shape.representation_tag() == kConsStringTag) {
8162 ConsString* cons = ConsString::cast(string); 8449 ConsString* cons = ConsString::cast(string);
8163 if (cons->second()->length() != 0) { 8450 if (cons->second()->length() != 0) {
8164 return FlatContent(); 8451 return FlatContent();
(...skipping 7674 matching lines...) Expand 10 before | Expand all | Expand 10 after
15839 if (cell->value() != *new_value) { 16126 if (cell->value() != *new_value) {
15840 cell->set_value(*new_value); 16127 cell->set_value(*new_value);
15841 Isolate* isolate = cell->GetIsolate(); 16128 Isolate* isolate = cell->GetIsolate();
15842 cell->dependent_code()->DeoptimizeDependentCodeGroup( 16129 cell->dependent_code()->DeoptimizeDependentCodeGroup(
15843 isolate, DependentCode::kPropertyCellChangedGroup); 16130 isolate, DependentCode::kPropertyCellChangedGroup);
15844 } 16131 }
15845 } 16132 }
15846 16133
15847 } // namespace internal 16134 } // namespace internal
15848 } // namespace v8 16135 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698