| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 if (input->IsString()) { | 151 if (input->IsString()) { |
| 152 return String::ToNumber(Handle<String>::cast(input)); | 152 return String::ToNumber(Handle<String>::cast(input)); |
| 153 } | 153 } |
| 154 if (input->IsOddball()) { | 154 if (input->IsOddball()) { |
| 155 return Oddball::ToNumber(Handle<Oddball>::cast(input)); | 155 return Oddball::ToNumber(Handle<Oddball>::cast(input)); |
| 156 } | 156 } |
| 157 if (input->IsSymbol()) { | 157 if (input->IsSymbol()) { |
| 158 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToNumber), | 158 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToNumber), |
| 159 Object); | 159 Object); |
| 160 } | 160 } |
| 161 if (input->IsSimd128Value()) { | |
| 162 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSimdToNumber), | |
| 163 Object); | |
| 164 } | |
| 165 ASSIGN_RETURN_ON_EXCEPTION( | 161 ASSIGN_RETURN_ON_EXCEPTION( |
| 166 isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input), | 162 isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input), |
| 167 ToPrimitiveHint::kNumber), | 163 ToPrimitiveHint::kNumber), |
| 168 Object); | 164 Object); |
| 169 } | 165 } |
| 170 } | 166 } |
| 171 | 167 |
| 172 // static | 168 // static |
| 173 MaybeHandle<Object> Object::ConvertToInteger(Isolate* isolate, | 169 MaybeHandle<Object> Object::ConvertToInteger(Isolate* isolate, |
| 174 Handle<Object> input) { | 170 Handle<Object> input) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 if (input->IsOddball()) { | 234 if (input->IsOddball()) { |
| 239 return handle(Handle<Oddball>::cast(input)->to_string(), isolate); | 235 return handle(Handle<Oddball>::cast(input)->to_string(), isolate); |
| 240 } | 236 } |
| 241 if (input->IsNumber()) { | 237 if (input->IsNumber()) { |
| 242 return isolate->factory()->NumberToString(input); | 238 return isolate->factory()->NumberToString(input); |
| 243 } | 239 } |
| 244 if (input->IsSymbol()) { | 240 if (input->IsSymbol()) { |
| 245 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToString), | 241 THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kSymbolToString), |
| 246 String); | 242 String); |
| 247 } | 243 } |
| 248 if (input->IsSimd128Value()) { | |
| 249 return Simd128Value::ToString(Handle<Simd128Value>::cast(input)); | |
| 250 } | |
| 251 ASSIGN_RETURN_ON_EXCEPTION( | 244 ASSIGN_RETURN_ON_EXCEPTION( |
| 252 isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input), | 245 isolate, input, JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(input), |
| 253 ToPrimitiveHint::kString), | 246 ToPrimitiveHint::kString), |
| 254 String); | 247 String); |
| 255 // The previous isString() check happened in Object::ToString and thus we | 248 // The previous isString() check happened in Object::ToString and thus we |
| 256 // put it at the end of the loop in this helper. | 249 // put it at the end of the loop in this helper. |
| 257 if (input->IsString()) { | 250 if (input->IsString()) { |
| 258 return Handle<String>::cast(input); | 251 return Handle<String>::cast(input); |
| 259 } | 252 } |
| 260 } | 253 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 return builder.Finish().ToHandleChecked(); | 290 return builder.Finish().ToHandleChecked(); |
| 298 } | 291 } |
| 299 | 292 |
| 300 } // namespace | 293 } // namespace |
| 301 | 294 |
| 302 // static | 295 // static |
| 303 Handle<String> Object::NoSideEffectsToString(Isolate* isolate, | 296 Handle<String> Object::NoSideEffectsToString(Isolate* isolate, |
| 304 Handle<Object> input) { | 297 Handle<Object> input) { |
| 305 DisallowJavascriptExecution no_js(isolate); | 298 DisallowJavascriptExecution no_js(isolate); |
| 306 | 299 |
| 307 if (input->IsString() || input->IsNumber() || input->IsOddball() || | 300 if (input->IsString() || input->IsNumber() || input->IsOddball()) { |
| 308 input->IsSimd128Value()) { | |
| 309 return Object::ToString(isolate, input).ToHandleChecked(); | 301 return Object::ToString(isolate, input).ToHandleChecked(); |
| 310 } else if (input->IsFunction()) { | 302 } else if (input->IsFunction()) { |
| 311 // -- F u n c t i o n | 303 // -- F u n c t i o n |
| 312 Handle<String> fun_str; | 304 Handle<String> fun_str; |
| 313 if (input->IsJSBoundFunction()) { | 305 if (input->IsJSBoundFunction()) { |
| 314 fun_str = JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(input)); | 306 fun_str = JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(input)); |
| 315 } else { | 307 } else { |
| 316 DCHECK(input->IsJSFunction()); | 308 DCHECK(input->IsJSFunction()); |
| 317 fun_str = JSFunction::ToString(Handle<JSFunction>::cast(input)); | 309 fun_str = JSFunction::ToString(Handle<JSFunction>::cast(input)); |
| 318 } | 310 } |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 if (y->IsSymbol()) { | 565 if (y->IsSymbol()) { |
| 574 return Just(x.is_identical_to(y)); | 566 return Just(x.is_identical_to(y)); |
| 575 } else if (y->IsJSReceiver()) { | 567 } else if (y->IsJSReceiver()) { |
| 576 if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y)) | 568 if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y)) |
| 577 .ToHandle(&y)) { | 569 .ToHandle(&y)) { |
| 578 return Nothing<bool>(); | 570 return Nothing<bool>(); |
| 579 } | 571 } |
| 580 } else { | 572 } else { |
| 581 return Just(false); | 573 return Just(false); |
| 582 } | 574 } |
| 583 } else if (x->IsSimd128Value()) { | |
| 584 if (y->IsSimd128Value()) { | |
| 585 return Just(Simd128Value::Equals(Handle<Simd128Value>::cast(x), | |
| 586 Handle<Simd128Value>::cast(y))); | |
| 587 } else if (y->IsJSReceiver()) { | |
| 588 if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(y)) | |
| 589 .ToHandle(&y)) { | |
| 590 return Nothing<bool>(); | |
| 591 } | |
| 592 } else { | |
| 593 return Just(false); | |
| 594 } | |
| 595 } else if (x->IsJSReceiver()) { | 575 } else if (x->IsJSReceiver()) { |
| 596 if (y->IsJSReceiver()) { | 576 if (y->IsJSReceiver()) { |
| 597 return Just(x.is_identical_to(y)); | 577 return Just(x.is_identical_to(y)); |
| 598 } else if (y->IsUndetectable()) { | 578 } else if (y->IsUndetectable()) { |
| 599 return Just(x->IsUndetectable()); | 579 return Just(x->IsUndetectable()); |
| 600 } else if (y->IsBoolean()) { | 580 } else if (y->IsBoolean()) { |
| 601 y = Oddball::ToNumber(Handle<Oddball>::cast(y)); | 581 y = Oddball::ToNumber(Handle<Oddball>::cast(y)); |
| 602 } else if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(x)) | 582 } else if (!JSReceiver::ToPrimitive(Handle<JSReceiver>::cast(x)) |
| 603 .ToHandle(&x)) { | 583 .ToHandle(&x)) { |
| 604 return Nothing<bool>(); | 584 return Nothing<bool>(); |
| 605 } | 585 } |
| 606 } else { | 586 } else { |
| 607 return Just(x->IsUndetectable() && y->IsUndetectable()); | 587 return Just(x->IsUndetectable() && y->IsUndetectable()); |
| 608 } | 588 } |
| 609 } | 589 } |
| 610 } | 590 } |
| 611 | 591 |
| 612 | 592 |
| 613 bool Object::StrictEquals(Object* that) { | 593 bool Object::StrictEquals(Object* that) { |
| 614 if (this->IsNumber()) { | 594 if (this->IsNumber()) { |
| 615 if (!that->IsNumber()) return false; | 595 if (!that->IsNumber()) return false; |
| 616 return NumberEquals(this, that); | 596 return NumberEquals(this, that); |
| 617 } else if (this->IsString()) { | 597 } else if (this->IsString()) { |
| 618 if (!that->IsString()) return false; | 598 if (!that->IsString()) return false; |
| 619 return String::cast(this)->Equals(String::cast(that)); | 599 return String::cast(this)->Equals(String::cast(that)); |
| 620 } else if (this->IsSimd128Value()) { | |
| 621 if (!that->IsSimd128Value()) return false; | |
| 622 return Simd128Value::cast(this)->Equals(Simd128Value::cast(that)); | |
| 623 } | 600 } |
| 624 return this == that; | 601 return this == that; |
| 625 } | 602 } |
| 626 | 603 |
| 627 | 604 |
| 628 // static | 605 // static |
| 629 Handle<String> Object::TypeOf(Isolate* isolate, Handle<Object> object) { | 606 Handle<String> Object::TypeOf(Isolate* isolate, Handle<Object> object) { |
| 630 if (object->IsNumber()) return isolate->factory()->number_string(); | 607 if (object->IsNumber()) return isolate->factory()->number_string(); |
| 631 if (object->IsOddball()) return handle(Oddball::cast(*object)->type_of()); | 608 if (object->IsOddball()) return handle(Oddball::cast(*object)->type_of()); |
| 632 if (object->IsUndetectable()) { | 609 if (object->IsUndetectable()) { |
| 633 return isolate->factory()->undefined_string(); | 610 return isolate->factory()->undefined_string(); |
| 634 } | 611 } |
| 635 if (object->IsString()) return isolate->factory()->string_string(); | 612 if (object->IsString()) return isolate->factory()->string_string(); |
| 636 if (object->IsSymbol()) return isolate->factory()->symbol_string(); | 613 if (object->IsSymbol()) return isolate->factory()->symbol_string(); |
| 637 if (object->IsString()) return isolate->factory()->string_string(); | 614 if (object->IsString()) return isolate->factory()->string_string(); |
| 638 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ | |
| 639 if (object->Is##Type()) return isolate->factory()->type##_string(); | |
| 640 SIMD128_TYPES(SIMD128_TYPE) | |
| 641 #undef SIMD128_TYPE | |
| 642 if (object->IsCallable()) return isolate->factory()->function_string(); | 615 if (object->IsCallable()) return isolate->factory()->function_string(); |
| 643 return isolate->factory()->object_string(); | 616 return isolate->factory()->object_string(); |
| 644 } | 617 } |
| 645 | 618 |
| 646 | 619 |
| 647 // static | 620 // static |
| 648 MaybeHandle<Object> Object::Multiply(Isolate* isolate, Handle<Object> lhs, | 621 MaybeHandle<Object> Object::Multiply(Isolate* isolate, Handle<Object> lhs, |
| 649 Handle<Object> rhs) { | 622 Handle<Object> rhs) { |
| 650 if (!lhs->IsNumber() || !rhs->IsNumber()) { | 623 if (!lhs->IsNumber() || !rhs->IsNumber()) { |
| 651 ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object); | 624 ASSIGN_RETURN_ON_EXCEPTION(isolate, lhs, Object::ToNumber(lhs), Object); |
| (...skipping 1522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2174 return Just(true); | 2147 return Just(true); |
| 2175 } | 2148 } |
| 2176 | 2149 |
| 2177 Map* Object::GetPrototypeChainRootMap(Isolate* isolate) { | 2150 Map* Object::GetPrototypeChainRootMap(Isolate* isolate) { |
| 2178 DisallowHeapAllocation no_alloc; | 2151 DisallowHeapAllocation no_alloc; |
| 2179 if (IsSmi()) { | 2152 if (IsSmi()) { |
| 2180 Context* native_context = isolate->context()->native_context(); | 2153 Context* native_context = isolate->context()->native_context(); |
| 2181 return native_context->number_function()->initial_map(); | 2154 return native_context->number_function()->initial_map(); |
| 2182 } | 2155 } |
| 2183 | 2156 |
| 2184 // The object is either a number, a string, a symbol, a boolean, a SIMD value, | 2157 // The object is either a number, a string, a symbol, a boolean, a real JS |
| 2185 // a real JS object, or a Harmony proxy. | 2158 // object, or a Harmony proxy. |
| 2186 HeapObject* heap_object = HeapObject::cast(this); | 2159 HeapObject* heap_object = HeapObject::cast(this); |
| 2187 return heap_object->map()->GetPrototypeChainRootMap(isolate); | 2160 return heap_object->map()->GetPrototypeChainRootMap(isolate); |
| 2188 } | 2161 } |
| 2189 | 2162 |
| 2190 Map* Map::GetPrototypeChainRootMap(Isolate* isolate) { | 2163 Map* Map::GetPrototypeChainRootMap(Isolate* isolate) { |
| 2191 DisallowHeapAllocation no_alloc; | 2164 DisallowHeapAllocation no_alloc; |
| 2192 if (IsJSReceiverMap()) { | 2165 if (IsJSReceiverMap()) { |
| 2193 return this; | 2166 return this; |
| 2194 } | 2167 } |
| 2195 int constructor_function_index = GetConstructorFunctionIndex(); | 2168 int constructor_function_index = GetConstructorFunctionIndex(); |
| 2196 if (constructor_function_index != Map::kNoConstructorFunctionIndex) { | 2169 if (constructor_function_index != Map::kNoConstructorFunctionIndex) { |
| 2197 Context* native_context = isolate->context()->native_context(); | 2170 Context* native_context = isolate->context()->native_context(); |
| 2198 JSFunction* constructor_function = | 2171 JSFunction* constructor_function = |
| 2199 JSFunction::cast(native_context->get(constructor_function_index)); | 2172 JSFunction::cast(native_context->get(constructor_function_index)); |
| 2200 return constructor_function->initial_map(); | 2173 return constructor_function->initial_map(); |
| 2201 } | 2174 } |
| 2202 return isolate->heap()->null_value()->map(); | 2175 return isolate->heap()->null_value()->map(); |
| 2203 } | 2176 } |
| 2204 | 2177 |
| 2205 namespace { | 2178 namespace { |
| 2206 | 2179 |
| 2207 // Returns a non-SMI for JSObjects, but returns the hash code for simple | 2180 // Returns a non-SMI for JSObjects, but returns the hash code for simple |
| 2208 // objects. This avoids a double lookup in the cases where we know we will | 2181 // objects. This avoids a double lookup in the cases where we know we will |
| 2209 // add the hash to the JSObject if it does not already exist. | 2182 // add the hash to the JSObject if it does not already exist. |
| 2210 Object* GetSimpleHash(Object* object) { | 2183 Object* GetSimpleHash(Object* object) { |
| 2211 // The object is either a Smi, a HeapNumber, a name, an odd-ball, | 2184 // The object is either a Smi, a HeapNumber, a name, an odd-ball, a real JS |
| 2212 // a SIMD value type, a real JS object, or a Harmony proxy. | 2185 // object, or a Harmony proxy. |
| 2213 if (object->IsSmi()) { | 2186 if (object->IsSmi()) { |
| 2214 uint32_t hash = | 2187 uint32_t hash = |
| 2215 ComputeIntegerHash(Smi::cast(object)->value(), kZeroHashSeed); | 2188 ComputeIntegerHash(Smi::cast(object)->value(), kZeroHashSeed); |
| 2216 return Smi::FromInt(hash & Smi::kMaxValue); | 2189 return Smi::FromInt(hash & Smi::kMaxValue); |
| 2217 } | 2190 } |
| 2218 if (object->IsHeapNumber()) { | 2191 if (object->IsHeapNumber()) { |
| 2219 double num = HeapNumber::cast(object)->value(); | 2192 double num = HeapNumber::cast(object)->value(); |
| 2220 if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue); | 2193 if (std::isnan(num)) return Smi::FromInt(Smi::kMaxValue); |
| 2221 if (i::IsMinusZero(num)) num = 0; | 2194 if (i::IsMinusZero(num)) num = 0; |
| 2222 if (IsSmiDouble(num)) { | 2195 if (IsSmiDouble(num)) { |
| 2223 return Smi::FromInt(FastD2I(num))->GetHash(); | 2196 return Smi::FromInt(FastD2I(num))->GetHash(); |
| 2224 } | 2197 } |
| 2225 uint32_t hash = ComputeLongHash(double_to_uint64(num)); | 2198 uint32_t hash = ComputeLongHash(double_to_uint64(num)); |
| 2226 return Smi::FromInt(hash & Smi::kMaxValue); | 2199 return Smi::FromInt(hash & Smi::kMaxValue); |
| 2227 } | 2200 } |
| 2228 if (object->IsName()) { | 2201 if (object->IsName()) { |
| 2229 uint32_t hash = Name::cast(object)->Hash(); | 2202 uint32_t hash = Name::cast(object)->Hash(); |
| 2230 return Smi::FromInt(hash); | 2203 return Smi::FromInt(hash); |
| 2231 } | 2204 } |
| 2232 if (object->IsOddball()) { | 2205 if (object->IsOddball()) { |
| 2233 uint32_t hash = Oddball::cast(object)->to_string()->Hash(); | 2206 uint32_t hash = Oddball::cast(object)->to_string()->Hash(); |
| 2234 return Smi::FromInt(hash); | 2207 return Smi::FromInt(hash); |
| 2235 } | 2208 } |
| 2236 if (object->IsSimd128Value()) { | |
| 2237 uint32_t hash = Simd128Value::cast(object)->Hash(); | |
| 2238 return Smi::FromInt(hash & Smi::kMaxValue); | |
| 2239 } | |
| 2240 DCHECK(object->IsJSReceiver()); | 2209 DCHECK(object->IsJSReceiver()); |
| 2241 // Simply return the receiver as it is guaranteed to not be a SMI. | 2210 // Simply return the receiver as it is guaranteed to not be a SMI. |
| 2242 return object; | 2211 return object; |
| 2243 } | 2212 } |
| 2244 | 2213 |
| 2245 } // namespace | 2214 } // namespace |
| 2246 | 2215 |
| 2247 Object* Object::GetHash() { | 2216 Object* Object::GetHash() { |
| 2248 Object* hash = GetSimpleHash(this); | 2217 Object* hash = GetSimpleHash(this); |
| 2249 if (hash->IsSmi()) return hash; | 2218 if (hash->IsSmi()) return hash; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2276 // SameValue(NaN, NaN) is true. | 2245 // SameValue(NaN, NaN) is true. |
| 2277 if (this_value != other_value) { | 2246 if (this_value != other_value) { |
| 2278 return std::isnan(this_value) && std::isnan(other_value); | 2247 return std::isnan(this_value) && std::isnan(other_value); |
| 2279 } | 2248 } |
| 2280 // SameValue(0.0, -0.0) is false. | 2249 // SameValue(0.0, -0.0) is false. |
| 2281 return (std::signbit(this_value) == std::signbit(other_value)); | 2250 return (std::signbit(this_value) == std::signbit(other_value)); |
| 2282 } | 2251 } |
| 2283 if (IsString() && other->IsString()) { | 2252 if (IsString() && other->IsString()) { |
| 2284 return String::cast(this)->Equals(String::cast(other)); | 2253 return String::cast(this)->Equals(String::cast(other)); |
| 2285 } | 2254 } |
| 2286 if (IsFloat32x4() && other->IsFloat32x4()) { | |
| 2287 Float32x4* a = Float32x4::cast(this); | |
| 2288 Float32x4* b = Float32x4::cast(other); | |
| 2289 for (int i = 0; i < 4; i++) { | |
| 2290 float x = a->get_lane(i); | |
| 2291 float y = b->get_lane(i); | |
| 2292 // Implements the ES5 SameValue operation for floating point types. | |
| 2293 // http://www.ecma-international.org/ecma-262/6.0/#sec-samevalue | |
| 2294 if (x != y && !(std::isnan(x) && std::isnan(y))) return false; | |
| 2295 if (std::signbit(x) != std::signbit(y)) return false; | |
| 2296 } | |
| 2297 return true; | |
| 2298 } else if (IsSimd128Value() && other->IsSimd128Value()) { | |
| 2299 Simd128Value* a = Simd128Value::cast(this); | |
| 2300 Simd128Value* b = Simd128Value::cast(other); | |
| 2301 return a->map() == b->map() && a->BitwiseEquals(b); | |
| 2302 } | |
| 2303 return false; | 2255 return false; |
| 2304 } | 2256 } |
| 2305 | 2257 |
| 2306 | 2258 |
| 2307 bool Object::SameValueZero(Object* other) { | 2259 bool Object::SameValueZero(Object* other) { |
| 2308 if (other == this) return true; | 2260 if (other == this) return true; |
| 2309 | 2261 |
| 2310 // The object is either a number, a name, an odd-ball, | 2262 // The object is either a number, a name, an odd-ball, |
| 2311 // a real JS object, or a Harmony proxy. | 2263 // a real JS object, or a Harmony proxy. |
| 2312 if (IsNumber() && other->IsNumber()) { | 2264 if (IsNumber() && other->IsNumber()) { |
| 2313 double this_value = Number(); | 2265 double this_value = Number(); |
| 2314 double other_value = other->Number(); | 2266 double other_value = other->Number(); |
| 2315 // +0 == -0 is true | 2267 // +0 == -0 is true |
| 2316 return this_value == other_value || | 2268 return this_value == other_value || |
| 2317 (std::isnan(this_value) && std::isnan(other_value)); | 2269 (std::isnan(this_value) && std::isnan(other_value)); |
| 2318 } | 2270 } |
| 2319 if (IsString() && other->IsString()) { | 2271 if (IsString() && other->IsString()) { |
| 2320 return String::cast(this)->Equals(String::cast(other)); | 2272 return String::cast(this)->Equals(String::cast(other)); |
| 2321 } | 2273 } |
| 2322 if (IsFloat32x4() && other->IsFloat32x4()) { | |
| 2323 Float32x4* a = Float32x4::cast(this); | |
| 2324 Float32x4* b = Float32x4::cast(other); | |
| 2325 for (int i = 0; i < 4; i++) { | |
| 2326 float x = a->get_lane(i); | |
| 2327 float y = b->get_lane(i); | |
| 2328 // Implements the ES6 SameValueZero operation for floating point types. | |
| 2329 // http://www.ecma-international.org/ecma-262/6.0/#sec-samevaluezero | |
| 2330 if (x != y && !(std::isnan(x) && std::isnan(y))) return false; | |
| 2331 // SameValueZero doesn't distinguish between 0 and -0. | |
| 2332 } | |
| 2333 return true; | |
| 2334 } else if (IsSimd128Value() && other->IsSimd128Value()) { | |
| 2335 Simd128Value* a = Simd128Value::cast(this); | |
| 2336 Simd128Value* b = Simd128Value::cast(other); | |
| 2337 return a->map() == b->map() && a->BitwiseEquals(b); | |
| 2338 } | |
| 2339 return false; | 2274 return false; |
| 2340 } | 2275 } |
| 2341 | 2276 |
| 2342 | 2277 |
| 2343 MaybeHandle<Object> Object::ArraySpeciesConstructor( | 2278 MaybeHandle<Object> Object::ArraySpeciesConstructor( |
| 2344 Isolate* isolate, Handle<Object> original_array) { | 2279 Isolate* isolate, Handle<Object> original_array) { |
| 2345 Handle<Object> default_species = isolate->array_function(); | 2280 Handle<Object> default_species = isolate->array_function(); |
| 2346 if (original_array->IsJSArray() && | 2281 if (original_array->IsJSArray() && |
| 2347 Handle<JSArray>::cast(original_array)->HasArrayPrototype(isolate) && | 2282 Handle<JSArray>::cast(original_array)->HasArrayPrototype(isolate) && |
| 2348 isolate->IsArraySpeciesLookupChainIntact()) { | 2283 isolate->IsArraySpeciesLookupChainIntact()) { |
| (...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3070 HeapNumber::cast(this)->HeapNumberPrint(os); | 3005 HeapNumber::cast(this)->HeapNumberPrint(os); |
| 3071 os << ">"; | 3006 os << ">"; |
| 3072 break; | 3007 break; |
| 3073 } | 3008 } |
| 3074 case MUTABLE_HEAP_NUMBER_TYPE: { | 3009 case MUTABLE_HEAP_NUMBER_TYPE: { |
| 3075 os << "<MutableNumber: "; | 3010 os << "<MutableNumber: "; |
| 3076 HeapNumber::cast(this)->HeapNumberPrint(os); | 3011 HeapNumber::cast(this)->HeapNumberPrint(os); |
| 3077 os << '>'; | 3012 os << '>'; |
| 3078 break; | 3013 break; |
| 3079 } | 3014 } |
| 3080 case SIMD128_VALUE_TYPE: { | |
| 3081 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ | |
| 3082 if (Is##Type()) { \ | |
| 3083 os << "<" #Type ">"; \ | |
| 3084 break; \ | |
| 3085 } | |
| 3086 SIMD128_TYPES(SIMD128_TYPE) | |
| 3087 #undef SIMD128_TYPE | |
| 3088 UNREACHABLE(); | |
| 3089 break; | |
| 3090 } | |
| 3091 case JS_PROXY_TYPE: | 3015 case JS_PROXY_TYPE: |
| 3092 os << "<JSProxy>"; | 3016 os << "<JSProxy>"; |
| 3093 break; | 3017 break; |
| 3094 case FOREIGN_TYPE: | 3018 case FOREIGN_TYPE: |
| 3095 os << "<Foreign>"; | 3019 os << "<Foreign>"; |
| 3096 break; | 3020 break; |
| 3097 case CELL_TYPE: { | 3021 case CELL_TYPE: { |
| 3098 os << "Cell for "; | 3022 os << "Cell for "; |
| 3099 HeapStringAllocator allocator; | 3023 HeapStringAllocator allocator; |
| 3100 StringStream accumulator(&allocator); | 3024 StringStream accumulator(&allocator); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3171 | 3095 |
| 3172 #define READ_INT32_FIELD(p, offset) \ | 3096 #define READ_INT32_FIELD(p, offset) \ |
| 3173 (*reinterpret_cast<const int32_t*>(FIELD_ADDR_CONST(p, offset))) | 3097 (*reinterpret_cast<const int32_t*>(FIELD_ADDR_CONST(p, offset))) |
| 3174 | 3098 |
| 3175 #define READ_INT64_FIELD(p, offset) \ | 3099 #define READ_INT64_FIELD(p, offset) \ |
| 3176 (*reinterpret_cast<const int64_t*>(FIELD_ADDR_CONST(p, offset))) | 3100 (*reinterpret_cast<const int64_t*>(FIELD_ADDR_CONST(p, offset))) |
| 3177 | 3101 |
| 3178 #define READ_BYTE_FIELD(p, offset) \ | 3102 #define READ_BYTE_FIELD(p, offset) \ |
| 3179 (*reinterpret_cast<const byte*>(FIELD_ADDR_CONST(p, offset))) | 3103 (*reinterpret_cast<const byte*>(FIELD_ADDR_CONST(p, offset))) |
| 3180 | 3104 |
| 3181 | |
| 3182 // static | |
| 3183 Handle<String> Simd128Value::ToString(Handle<Simd128Value> input) { | |
| 3184 #define SIMD128_TYPE(TYPE, Type, type, lane_count, lane_type) \ | |
| 3185 if (input->Is##Type()) return Type::ToString(Handle<Type>::cast(input)); | |
| 3186 SIMD128_TYPES(SIMD128_TYPE) | |
| 3187 #undef SIMD128_TYPE | |
| 3188 UNREACHABLE(); | |
| 3189 return Handle<String>::null(); | |
| 3190 } | |
| 3191 | |
| 3192 | |
| 3193 // static | |
| 3194 Handle<String> Float32x4::ToString(Handle<Float32x4> input) { | |
| 3195 Isolate* const isolate = input->GetIsolate(); | |
| 3196 char arr[100]; | |
| 3197 Vector<char> buffer(arr, arraysize(arr)); | |
| 3198 std::ostringstream os; | |
| 3199 os << "SIMD.Float32x4(" | |
| 3200 << std::string(DoubleToCString(input->get_lane(0), buffer)) << ", " | |
| 3201 << std::string(DoubleToCString(input->get_lane(1), buffer)) << ", " | |
| 3202 << std::string(DoubleToCString(input->get_lane(2), buffer)) << ", " | |
| 3203 << std::string(DoubleToCString(input->get_lane(3), buffer)) << ")"; | |
| 3204 return isolate->factory()->NewStringFromAsciiChecked(os.str().c_str()); | |
| 3205 } | |
| 3206 | |
| 3207 | |
| 3208 #define SIMD128_BOOL_TO_STRING(Type, lane_count) \ | |
| 3209 Handle<String> Type::ToString(Handle<Type> input) { \ | |
| 3210 Isolate* const isolate = input->GetIsolate(); \ | |
| 3211 std::ostringstream os; \ | |
| 3212 os << "SIMD." #Type "("; \ | |
| 3213 os << (input->get_lane(0) ? "true" : "false"); \ | |
| 3214 for (int i = 1; i < lane_count; i++) { \ | |
| 3215 os << ", " << (input->get_lane(i) ? "true" : "false"); \ | |
| 3216 } \ | |
| 3217 os << ")"; \ | |
| 3218 return isolate->factory()->NewStringFromAsciiChecked(os.str().c_str()); \ | |
| 3219 } | |
| 3220 SIMD128_BOOL_TO_STRING(Bool32x4, 4) | |
| 3221 SIMD128_BOOL_TO_STRING(Bool16x8, 8) | |
| 3222 SIMD128_BOOL_TO_STRING(Bool8x16, 16) | |
| 3223 #undef SIMD128_BOOL_TO_STRING | |
| 3224 | |
| 3225 | |
| 3226 #define SIMD128_INT_TO_STRING(Type, lane_count) \ | |
| 3227 Handle<String> Type::ToString(Handle<Type> input) { \ | |
| 3228 Isolate* const isolate = input->GetIsolate(); \ | |
| 3229 char arr[100]; \ | |
| 3230 Vector<char> buffer(arr, arraysize(arr)); \ | |
| 3231 std::ostringstream os; \ | |
| 3232 os << "SIMD." #Type "("; \ | |
| 3233 os << IntToCString(input->get_lane(0), buffer); \ | |
| 3234 for (int i = 1; i < lane_count; i++) { \ | |
| 3235 os << ", " << IntToCString(input->get_lane(i), buffer); \ | |
| 3236 } \ | |
| 3237 os << ")"; \ | |
| 3238 return isolate->factory()->NewStringFromAsciiChecked(os.str().c_str()); \ | |
| 3239 } | |
| 3240 SIMD128_INT_TO_STRING(Int32x4, 4) | |
| 3241 SIMD128_INT_TO_STRING(Uint32x4, 4) | |
| 3242 SIMD128_INT_TO_STRING(Int16x8, 8) | |
| 3243 SIMD128_INT_TO_STRING(Uint16x8, 8) | |
| 3244 SIMD128_INT_TO_STRING(Int8x16, 16) | |
| 3245 SIMD128_INT_TO_STRING(Uint8x16, 16) | |
| 3246 #undef SIMD128_INT_TO_STRING | |
| 3247 | |
| 3248 | |
| 3249 bool Simd128Value::BitwiseEquals(const Simd128Value* other) const { | |
| 3250 return READ_INT64_FIELD(this, kValueOffset) == | |
| 3251 READ_INT64_FIELD(other, kValueOffset) && | |
| 3252 READ_INT64_FIELD(this, kValueOffset + kInt64Size) == | |
| 3253 READ_INT64_FIELD(other, kValueOffset + kInt64Size); | |
| 3254 } | |
| 3255 | |
| 3256 | |
| 3257 uint32_t Simd128Value::Hash() const { | |
| 3258 uint32_t seed = v8::internal::kZeroHashSeed; | |
| 3259 uint32_t hash; | |
| 3260 hash = ComputeIntegerHash(READ_INT32_FIELD(this, kValueOffset), seed); | |
| 3261 hash = ComputeIntegerHash( | |
| 3262 READ_INT32_FIELD(this, kValueOffset + 1 * kInt32Size), hash * 31); | |
| 3263 hash = ComputeIntegerHash( | |
| 3264 READ_INT32_FIELD(this, kValueOffset + 2 * kInt32Size), hash * 31); | |
| 3265 hash = ComputeIntegerHash( | |
| 3266 READ_INT32_FIELD(this, kValueOffset + 3 * kInt32Size), hash * 31); | |
| 3267 return hash; | |
| 3268 } | |
| 3269 | |
| 3270 | |
| 3271 void Simd128Value::CopyBits(void* destination) const { | |
| 3272 memcpy(destination, &READ_BYTE_FIELD(this, kValueOffset), kSimd128Size); | |
| 3273 } | |
| 3274 | |
| 3275 | |
| 3276 String* JSReceiver::class_name() { | 3105 String* JSReceiver::class_name() { |
| 3277 if (IsFunction()) { | 3106 if (IsFunction()) { |
| 3278 return GetHeap()->Function_string(); | 3107 return GetHeap()->Function_string(); |
| 3279 } | 3108 } |
| 3280 Object* maybe_constructor = map()->GetConstructor(); | 3109 Object* maybe_constructor = map()->GetConstructor(); |
| 3281 if (maybe_constructor->IsJSFunction()) { | 3110 if (maybe_constructor->IsJSFunction()) { |
| 3282 JSFunction* constructor = JSFunction::cast(maybe_constructor); | 3111 JSFunction* constructor = JSFunction::cast(maybe_constructor); |
| 3283 return String::cast(constructor->shared()->instance_class_name()); | 3112 return String::cast(constructor->shared()->instance_class_name()); |
| 3284 } | 3113 } |
| 3285 // If the constructor is not present, return "Object". | 3114 // If the constructor is not present, return "Object". |
| (...skipping 9436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12722 case HEAP_NUMBER_TYPE: | 12551 case HEAP_NUMBER_TYPE: |
| 12723 case JS_BOUND_FUNCTION_TYPE: | 12552 case JS_BOUND_FUNCTION_TYPE: |
| 12724 case JS_GLOBAL_OBJECT_TYPE: | 12553 case JS_GLOBAL_OBJECT_TYPE: |
| 12725 case JS_GLOBAL_PROXY_TYPE: | 12554 case JS_GLOBAL_PROXY_TYPE: |
| 12726 case JS_PROXY_TYPE: | 12555 case JS_PROXY_TYPE: |
| 12727 case MAP_TYPE: | 12556 case MAP_TYPE: |
| 12728 case MUTABLE_HEAP_NUMBER_TYPE: | 12557 case MUTABLE_HEAP_NUMBER_TYPE: |
| 12729 case ODDBALL_TYPE: | 12558 case ODDBALL_TYPE: |
| 12730 case PROPERTY_CELL_TYPE: | 12559 case PROPERTY_CELL_TYPE: |
| 12731 case SHARED_FUNCTION_INFO_TYPE: | 12560 case SHARED_FUNCTION_INFO_TYPE: |
| 12732 case SIMD128_VALUE_TYPE: | |
| 12733 case SYMBOL_TYPE: | 12561 case SYMBOL_TYPE: |
| 12734 case WEAK_CELL_TYPE: | 12562 case WEAK_CELL_TYPE: |
| 12735 | 12563 |
| 12736 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 12564 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
| 12737 case FIXED_##TYPE##_ARRAY_TYPE: | 12565 case FIXED_##TYPE##_ARRAY_TYPE: |
| 12738 #undef TYPED_ARRAY_CASE | 12566 #undef TYPED_ARRAY_CASE |
| 12739 | 12567 |
| 12740 #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: | 12568 #define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: |
| 12741 STRUCT_LIST(MAKE_STRUCT_CASE) | 12569 STRUCT_LIST(MAKE_STRUCT_CASE) |
| 12742 #undef MAKE_STRUCT_CASE | 12570 #undef MAKE_STRUCT_CASE |
| (...skipping 7489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 20232 // depend on this. | 20060 // depend on this. |
| 20233 return DICTIONARY_ELEMENTS; | 20061 return DICTIONARY_ELEMENTS; |
| 20234 } | 20062 } |
| 20235 DCHECK_LE(kind, LAST_ELEMENTS_KIND); | 20063 DCHECK_LE(kind, LAST_ELEMENTS_KIND); |
| 20236 return kind; | 20064 return kind; |
| 20237 } | 20065 } |
| 20238 } | 20066 } |
| 20239 | 20067 |
| 20240 } // namespace internal | 20068 } // namespace internal |
| 20241 } // namespace v8 | 20069 } // namespace v8 |
| OLD | NEW |