Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index 6e25e624a9110d2ebe307eb653942c49bc98fe12..0da20dd43de8517e0cd995b410870f3ba6ae33ef 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -77,6 +77,10 @@ MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor, |
MaybeObject* Object::ToObject(Context* native_context) { |
if (IsNumber()) { |
return CreateJSValue(native_context->number_function(), this); |
+ } else if (IsFloat32x4()) { |
+ return CreateJSValue(native_context->float32x4_function(), this); |
+ } else if (IsInt32x4()) { |
+ return CreateJSValue(native_context->int32x4_function(), this); |
} else if (IsBoolean()) { |
return CreateJSValue(native_context->boolean_function(), this); |
} else if (IsString()) { |
@@ -93,6 +97,14 @@ MaybeObject* Object::ToObject(Isolate* isolate) { |
} else if (IsNumber()) { |
Context* native_context = isolate->context()->native_context(); |
return CreateJSValue(native_context->number_function(), this); |
+ } else if (IsFloat32x4()) { |
+ Isolate* isolate = HeapObject::cast(this)->GetIsolate(); |
+ Context* native_context = isolate->context()->native_context(); |
+ return CreateJSValue(native_context->float32x4_function(), this); |
+ } else if (IsInt32x4()) { |
+ Isolate* isolate = HeapObject::cast(this)->GetIsolate(); |
+ Context* native_context = isolate->context()->native_context(); |
+ return CreateJSValue(native_context->int32x4_function(), this); |
} else if (IsBoolean()) { |
Context* native_context = isolate->context()->native_context(); |
return CreateJSValue(native_context->boolean_function(), this); |
@@ -128,6 +140,10 @@ void Object::Lookup(Name* name, LookupResult* result) { |
Context* native_context = result->isolate()->context()->native_context(); |
if (IsNumber()) { |
holder = native_context->number_function()->instance_prototype(); |
+ } else if (IsFloat32x4()) { |
+ holder = native_context->float32x4_function()->instance_prototype(); |
+ } else if (IsInt32x4()) { |
+ holder = native_context->int32x4_function()->instance_prototype(); |
} else if (IsString()) { |
holder = native_context->string_function()->instance_prototype(); |
} else if (IsSymbol()) { |
@@ -977,6 +993,10 @@ MaybeObject* Object::GetElementWithReceiver(Isolate* isolate, |
Context* native_context = isolate->context()->native_context(); |
if (holder->IsNumber()) { |
holder = native_context->number_function()->instance_prototype(); |
+ } else if (holder->IsFloat32x4()) { |
+ holder = native_context->float32x4_function()->instance_prototype(); |
+ } else if (holder->IsInt32x4()) { |
+ holder = native_context->int32x4_function()->instance_prototype(); |
} else if (holder->IsString()) { |
holder = native_context->string_function()->instance_prototype(); |
} else if (holder->IsSymbol()) { |
@@ -1040,6 +1060,12 @@ Object* Object::GetPrototype(Isolate* isolate) { |
if (heap_object->IsHeapNumber()) { |
return context->number_function()->instance_prototype(); |
} |
+ if (heap_object->IsFloat32x4()) { |
+ return context->float32x4_function()->instance_prototype(); |
+ } |
+ if (heap_object->IsInt32x4()) { |
+ return context->int32x4_function()->instance_prototype(); |
+ } |
if (heap_object->IsString()) { |
return context->string_function()->instance_prototype(); |
} |
@@ -1663,6 +1689,14 @@ void HeapObject::HeapObjectShortPrint(StringStream* accumulator) { |
accumulator->Add("<ExternalFloatArray[%u]>", |
ExternalFloatArray::cast(this)->length()); |
break; |
+ case EXTERNAL_FLOAT32x4_ARRAY_TYPE: |
+ accumulator->Add("<ExternalFloat32x4Array[%u]>", |
+ ExternalFloat32x4Array::cast(this)->length()); |
+ break; |
+ case EXTERNAL_INT32x4_ARRAY_TYPE: |
+ accumulator->Add("<ExternalInt32x4Array[%u]>", |
+ ExternalInt32x4Array::cast(this)->length()); |
+ break; |
case EXTERNAL_DOUBLE_ARRAY_TYPE: |
accumulator->Add("<ExternalDoubleArray[%u]>", |
ExternalDoubleArray::cast(this)->length()); |
@@ -1722,6 +1756,16 @@ void HeapObject::HeapObjectShortPrint(StringStream* accumulator) { |
HeapNumber::cast(this)->HeapNumberPrint(accumulator); |
accumulator->Put('>'); |
break; |
+ case FLOAT32x4_TYPE: |
+ accumulator->Add("<Float32x4: "); |
+ Float32x4::cast(this)->Float32x4Print(accumulator); |
+ accumulator->Put('>'); |
+ break; |
+ case INT32x4_TYPE: |
+ accumulator->Add("<Int32x4: "); |
+ Int32x4::cast(this)->Int32x4Print(accumulator); |
+ accumulator->Put('>'); |
+ break; |
case JS_PROXY_TYPE: |
accumulator->Add("<JSProxy>"); |
break; |
@@ -1844,6 +1888,8 @@ void HeapObject::IterateBody(InstanceType type, int object_size, |
Symbol::BodyDescriptor::IterateBody(this, v); |
break; |
case HEAP_NUMBER_TYPE: |
+ case FLOAT32x4_TYPE: |
+ case INT32x4_TYPE: |
case FILLER_TYPE: |
case BYTE_ARRAY_TYPE: |
case FREE_SPACE_TYPE: |
@@ -1855,6 +1901,8 @@ void HeapObject::IterateBody(InstanceType type, int object_size, |
case EXTERNAL_INT_ARRAY_TYPE: |
case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: |
case EXTERNAL_FLOAT_ARRAY_TYPE: |
+ case EXTERNAL_FLOAT32x4_ARRAY_TYPE: |
+ case EXTERNAL_INT32x4_ARRAY_TYPE: |
case EXTERNAL_DOUBLE_ARRAY_TYPE: |
break; |
case SHARED_FUNCTION_INFO_TYPE: { |
@@ -1917,6 +1965,42 @@ void HeapNumber::HeapNumberPrint(StringStream* accumulator) { |
} |
+void Float32x4::Float32x4Print(FILE* out) { |
+ PrintF(out, "%.16g %.16g %.16g %.16g", x(), y(), z(), w()); |
+} |
+ |
+ |
+void Float32x4::Float32x4Print(StringStream* accumulator) { |
+ // The Windows version of vsnprintf can allocate when printing a %g string |
+ // into a buffer that may not be big enough. We don't want random memory |
+ // allocation when producing post-crash stack traces, so we print into a |
+ // buffer that is plenty big enough for any floating point number, then |
+ // print that using vsnprintf (which may truncate but never allocate if |
+ // there is no more space in the buffer). |
+ EmbeddedVector<char, 100> buffer; |
+ OS::SNPrintF(buffer, "%.16g %.16g %.16g %.16g", x(), y(), z(), w()); |
+ accumulator->Add("%s", buffer.start()); |
+} |
+ |
+ |
+void Int32x4::Int32x4Print(FILE* out) { |
+ PrintF(out, "%u %u %u %u", x(), y(), z(), w()); |
+} |
+ |
+ |
+void Int32x4::Int32x4Print(StringStream* accumulator) { |
+ // The Windows version of vsnprintf can allocate when printing a %g string |
+ // into a buffer that may not be big enough. We don't want random memory |
+ // allocation when producing post-crash stack traces, so we print into a |
+ // buffer that is plenty big enough for any floating point number, then |
+ // print that using vsnprintf (which may truncate but never allocate if |
+ // there is no more space in the buffer). |
+ EmbeddedVector<char, 100> buffer; |
+ OS::SNPrintF(buffer, "%u %u %u %u", x(), y(), z(), w()); |
+ accumulator->Add("%s", buffer.start()); |
+} |
+ |
+ |
String* JSReceiver::class_name() { |
if (IsJSFunction() && IsJSFunctionProxy()) { |
return GetHeap()->function_class_string(); |
@@ -2283,6 +2367,8 @@ const char* Representation::Mnemonic() const { |
case kTagged: return "t"; |
case kSmi: return "s"; |
case kDouble: return "d"; |
+ case kFloat32x4: return "float32x4"; |
+ case kInt32x4: return "int32x44"; |
case kInteger32: return "i"; |
case kHeapObject: return "h"; |
case kExternal: return "x"; |
@@ -5366,6 +5452,8 @@ bool JSObject::ReferencesObject(Object* obj) { |
case EXTERNAL_INT_ELEMENTS: |
case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
case EXTERNAL_FLOAT_ELEMENTS: |
+ case EXTERNAL_FLOAT32x4_ELEMENTS: |
+ case EXTERNAL_INT32x4_ELEMENTS: |
case EXTERNAL_DOUBLE_ELEMENTS: |
case FAST_DOUBLE_ELEMENTS: |
case FAST_HOLEY_DOUBLE_ELEMENTS: |
@@ -5861,6 +5949,8 @@ Handle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk( |
case EXTERNAL_INT_ELEMENTS: |
case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
case EXTERNAL_FLOAT_ELEMENTS: |
+ case EXTERNAL_FLOAT32x4_ELEMENTS: |
+ case EXTERNAL_INT32x4_ELEMENTS: |
case EXTERNAL_DOUBLE_ELEMENTS: |
case FAST_DOUBLE_ELEMENTS: |
case FAST_HOLEY_DOUBLE_ELEMENTS: |
@@ -6082,6 +6172,8 @@ void JSObject::DefineElementAccessor(Handle<JSObject> object, |
case EXTERNAL_INT_ELEMENTS: |
case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
case EXTERNAL_FLOAT_ELEMENTS: |
+ case EXTERNAL_FLOAT32x4_ELEMENTS: |
+ case EXTERNAL_INT32x4_ELEMENTS: |
case EXTERNAL_DOUBLE_ELEMENTS: |
// Ignore getters and setters on pixel and external array elements. |
return; |
@@ -6540,6 +6632,8 @@ Handle<Object> JSObject::SetAccessor(Handle<JSObject> object, |
case EXTERNAL_INT_ELEMENTS: |
case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
case EXTERNAL_FLOAT_ELEMENTS: |
+ case EXTERNAL_FLOAT32x4_ELEMENTS: |
+ case EXTERNAL_INT32x4_ELEMENTS: |
case EXTERNAL_DOUBLE_ELEMENTS: |
// Ignore getters and setters on pixel and external array |
// elements. |
@@ -10995,6 +11089,20 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) { |
break; |
} |
+ case Translation::FLOAT32x4_REGISTER: { |
+ int reg_code = iterator.Next(); |
+ PrintF(out, "{input=%s}", |
+ Float32x4Register::AllocationIndexToString(reg_code)); |
+ break; |
+ } |
+ |
+ case Translation::INT32x4_REGISTER: { |
+ int reg_code = iterator.Next(); |
+ PrintF(out, "{input=%s}", |
+ Int32x4Register::AllocationIndexToString(reg_code)); |
+ break; |
+ } |
+ |
case Translation::STACK_SLOT: { |
int input_slot_index = iterator.Next(); |
PrintF(out, "{input=%d}", input_slot_index); |
@@ -11019,6 +11127,18 @@ void DeoptimizationInputData::DeoptimizationInputDataPrint(FILE* out) { |
break; |
} |
+ case Translation::FLOAT32x4_STACK_SLOT: { |
+ int input_slot_index = iterator.Next(); |
+ PrintF(out, "{input=%d}", input_slot_index); |
+ break; |
+ } |
+ |
+ case Translation::INT32x4_STACK_SLOT: { |
+ int input_slot_index = iterator.Next(); |
+ PrintF(out, "{input=%d}", input_slot_index); |
+ break; |
+ } |
+ |
case Translation::LITERAL: { |
unsigned literal_index = iterator.Next(); |
PrintF(out, "{literal_id=%u}", literal_index); |
@@ -12541,7 +12661,10 @@ Handle<Object> JSObject::SetElement(Handle<JSObject> object, |
Isolate* isolate = object->GetIsolate(); |
if (object->HasExternalArrayElements()) { |
- if (!value->IsNumber() && !value->IsUndefined()) { |
+ // TODO(ningxin): Throw an error if setting a Float32x4Array element |
+ // while the value is not Float32x4Object. |
+ if (!value->IsNumber() && !value->IsFloat32x4() && |
+ !value->IsInt32x4() && !value->IsUndefined()) { |
bool has_exception; |
Handle<Object> number = |
Execution::ToNumber(isolate, value, &has_exception); |
@@ -12734,6 +12857,16 @@ Handle<Object> JSObject::SetElementWithoutInterceptor( |
ExternalFloatArray::cast(object->elements())); |
return ExternalFloatArray::SetValue(array, index, value); |
} |
+ case EXTERNAL_FLOAT32x4_ELEMENTS: { |
+ Handle<ExternalFloat32x4Array> array( |
+ ExternalFloat32x4Array::cast(object->elements())); |
+ return ExternalFloat32x4Array::SetValue(array, index, value); |
+ } |
+ case EXTERNAL_INT32x4_ELEMENTS: { |
+ Handle<ExternalInt32x4Array> array( |
+ ExternalInt32x4Array::cast(object->elements())); |
+ return ExternalInt32x4Array::SetValue(array, index, value); |
+ } |
case EXTERNAL_DOUBLE_ELEMENTS: { |
Handle<ExternalDoubleArray> array( |
ExternalDoubleArray::cast(object->elements())); |
@@ -13126,6 +13259,8 @@ void JSObject::GetElementsCapacityAndUsage(int* capacity, int* used) { |
case EXTERNAL_INT_ELEMENTS: |
case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
case EXTERNAL_FLOAT_ELEMENTS: |
+ case EXTERNAL_FLOAT32x4_ELEMENTS: |
+ case EXTERNAL_INT32x4_ELEMENTS: |
case EXTERNAL_DOUBLE_ELEMENTS: |
case EXTERNAL_PIXEL_ELEMENTS: |
// External arrays are considered 100% used. |
@@ -13640,6 +13775,8 @@ int JSObject::GetLocalElementKeys(FixedArray* storage, |
case EXTERNAL_INT_ELEMENTS: |
case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
case EXTERNAL_FLOAT_ELEMENTS: |
+ case EXTERNAL_FLOAT32x4_ELEMENTS: |
+ case EXTERNAL_INT32x4_ELEMENTS: |
case EXTERNAL_DOUBLE_ELEMENTS: { |
int length = ExternalArray::cast(elements())->length(); |
while (counter < length) { |
@@ -14687,6 +14824,10 @@ ExternalArrayType JSTypedArray::type() { |
return kExternalUnsignedIntArray; |
case EXTERNAL_FLOAT_ARRAY_TYPE: |
return kExternalFloatArray; |
+ case EXTERNAL_FLOAT32x4_ARRAY_TYPE: |
+ return kExternalFloat32x4Array; |
+ case EXTERNAL_INT32x4_ARRAY_TYPE: |
+ return kExternalInt32x4Array; |
case EXTERNAL_DOUBLE_ARRAY_TYPE: |
return kExternalDoubleArray; |
case EXTERNAL_PIXEL_ARRAY_TYPE: |
@@ -14713,6 +14854,10 @@ size_t JSTypedArray::element_size() { |
return 4; |
case EXTERNAL_FLOAT_ARRAY_TYPE: |
return 4; |
+ case EXTERNAL_FLOAT32x4_ARRAY_TYPE: |
+ return 16; |
+ case EXTERNAL_INT32x4_ARRAY_TYPE: |
+ return 16; |
case EXTERNAL_DOUBLE_ARRAY_TYPE: |
return 8; |
case EXTERNAL_PIXEL_ARRAY_TYPE: |
@@ -14954,6 +15099,66 @@ MaybeObject* ExternalDoubleArray::SetValue(uint32_t index, Object* value) { |
} |
+Handle<Object> ExternalFloat32x4Array::SetValue( |
+ Handle<ExternalFloat32x4Array> array, |
+ uint32_t index, |
+ Handle<Object> value) { |
+ CALL_HEAP_FUNCTION(array->GetIsolate(), |
+ array->SetValue(index, *value), |
+ Object); |
+} |
+ |
+ |
+MaybeObject* ExternalFloat32x4Array::SetValue(uint32_t index, Object* value) { |
+ float32x4_value_t cast_value; |
+ cast_value.storage[0] = static_cast<float>(OS::nan_value()); |
+ cast_value.storage[1] = static_cast<float>(OS::nan_value()); |
+ cast_value.storage[2] = static_cast<float>(OS::nan_value()); |
+ cast_value.storage[3] = static_cast<float>(OS::nan_value()); |
+ Heap* heap = GetHeap(); |
+ if (index < static_cast<uint32_t>(length())) { |
+ if (value->IsFloat32x4()) { |
+ cast_value = Float32x4::cast(value)->value(); |
+ } else { |
+ // Clamp undefined to NaN (default). All other types have been |
+ // converted to a number type further up in the call chain. |
+ ASSERT(value->IsUndefined()); |
+ } |
+ set(index, cast_value); |
+ } |
+ return heap->AllocateFloat32x4(cast_value); |
+} |
+ |
+ |
+Handle<Object> ExternalInt32x4Array::SetValue( |
+ Handle<ExternalInt32x4Array> array, uint32_t index, Handle<Object> value) { |
+ CALL_HEAP_FUNCTION(array->GetIsolate(), |
+ array->SetValue(index, *value), |
+ Object); |
+} |
+ |
+ |
+MaybeObject* ExternalInt32x4Array::SetValue(uint32_t index, Object* value) { |
+ int32x4_value_t cast_value; |
+ cast_value.storage[0] = 0; |
+ cast_value.storage[1] = 0; |
+ cast_value.storage[2] = 0; |
+ cast_value.storage[3] = 0; |
+ Heap* heap = GetHeap(); |
+ if (index < static_cast<uint32_t>(length())) { |
+ if (value->IsInt32x4()) { |
+ cast_value = Int32x4::cast(value)->value(); |
+ } else { |
+ // Clamp undefined to zero (default). All other types have been |
+ // converted to a number type further up in the call chain. |
+ ASSERT(value->IsUndefined()); |
+ } |
+ set(index, cast_value); |
+ } |
+ return heap->AllocateInt32x4(cast_value); |
+} |
+ |
+ |
PropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { |
ASSERT(!HasFastProperties()); |
Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |