blob: efed36511ac1e4c519b77ddd744bb2fd9fe5e732 [file] [log] [blame]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "RuntimeLibraryPch.h"
namespace Js
{
JavascriptSIMDObject::JavascriptSIMDObject(DynamicType * type)
: DynamicObject(type), value(Js::TaggedInt::ToVarUnchecked(0))
{
Assert(type->GetTypeId() == TypeIds_SIMDObject);
}
JavascriptSIMDObject::JavascriptSIMDObject(Var value, DynamicType * type, TypeId typeDescriptor)
: DynamicObject(type), typeDescriptor(typeDescriptor), value(value)
{
Assert(type->GetTypeId() == TypeIds_SIMDObject);
switch (typeDescriptor)
{
//typeDescriptor is TypeIds_SIMDObject only while initializing the SIMDObject prototypes.
//Dynamically created wrapper objects must have a concrete typeDescriptor of a SIMDType.
case TypeIds_SIMDObject:
numLanes = 0;
break;
case TypeIds_SIMDBool8x16:
case TypeIds_SIMDInt8x16:
case TypeIds_SIMDUint8x16:
numLanes = 16;
break;
case TypeIds_SIMDBool16x8:
case TypeIds_SIMDInt16x8:
case TypeIds_SIMDUint16x8:
numLanes = 8;
break;
case TypeIds_SIMDBool32x4:
case TypeIds_SIMDInt32x4:
case TypeIds_SIMDUint32x4:
case TypeIds_SIMDFloat32x4:
numLanes = 4;
break;
default:
Assert(UNREACHED);
}
}
void JavascriptSIMDObject::SetTypeDescriptor(TypeId tid)
{
Assert(tid != TypeIds_SIMDObject);
typeDescriptor = tid;
switch (typeDescriptor)
{
case TypeIds_SIMDBool8x16:
case TypeIds_SIMDInt8x16:
case TypeIds_SIMDUint8x16:
numLanes = 16;
break;
case TypeIds_SIMDBool16x8:
case TypeIds_SIMDInt16x8:
case TypeIds_SIMDUint16x8:
numLanes = 8;
break;
case TypeIds_SIMDBool32x4:
case TypeIds_SIMDInt32x4:
case TypeIds_SIMDUint32x4:
case TypeIds_SIMDFloat32x4:
numLanes = 4;
break;
default:
Assert(UNREACHED);
}
}
bool JavascriptSIMDObject::Is(Var aValue)
{
return JavascriptOperators::GetTypeId(aValue) == TypeIds_SIMDObject;
}
JavascriptSIMDObject* JavascriptSIMDObject::FromVar(Var aValue)
{
AssertMsg(Is(aValue), "Ensure var is actually a 'JavascriptSIMD'");
return static_cast<JavascriptSIMDObject *>(RecyclableObject::FromVar(aValue));
}
Var JavascriptSIMDObject::Unwrap() const
{
return value;
}
Var JavascriptSIMDObject::ToString(ScriptContext* scriptContext) const
{
Assert(scriptContext);
Assert(typeDescriptor != TypeIds_SIMDObject);
BEGIN_TEMP_ALLOCATOR(tempAllocator, scriptContext, _u("fromCodePoint"));
char16* stringBuffer = AnewArray(tempAllocator, char16, SIMD_STRING_BUFFER_MAX);
SIMDValue simdValue;
switch (typeDescriptor)
{
case TypeIds_SIMDBool8x16:
simdValue = JavascriptSIMDBool8x16::FromVar(value)->GetValue();
JavascriptSIMDBool8x16::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
break;
case TypeIds_SIMDInt8x16:
simdValue = JavascriptSIMDInt8x16::FromVar(value)->GetValue();
JavascriptSIMDInt8x16::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
break;
case TypeIds_SIMDUint8x16:
simdValue = JavascriptSIMDUint8x16::FromVar(value)->GetValue();
JavascriptSIMDUint8x16::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
break;
case TypeIds_SIMDBool16x8:
simdValue = JavascriptSIMDBool16x8::FromVar(value)->GetValue();
JavascriptSIMDBool16x8::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
break;
case TypeIds_SIMDInt16x8:
simdValue = JavascriptSIMDInt16x8::FromVar(value)->GetValue();
JavascriptSIMDInt16x8::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
break;
case TypeIds_SIMDUint16x8:
simdValue = JavascriptSIMDUint16x8::FromVar(value)->GetValue();
JavascriptSIMDUint16x8::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
break;
case TypeIds_SIMDBool32x4:
simdValue = JavascriptSIMDBool32x4::FromVar(value)->GetValue();
JavascriptSIMDBool32x4::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
break;
case TypeIds_SIMDInt32x4:
simdValue = JavascriptSIMDInt32x4::FromVar(value)->GetValue();
JavascriptSIMDInt32x4::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
break;
case TypeIds_SIMDUint32x4:
simdValue = JavascriptSIMDUint32x4::FromVar(value)->GetValue();
JavascriptSIMDUint32x4::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
break;
case TypeIds_SIMDFloat32x4:
simdValue = JavascriptSIMDFloat32x4::FromVar(value)->GetValue();
JavascriptSIMDFloat32x4::ToStringBuffer(simdValue, stringBuffer, SIMD_STRING_BUFFER_MAX, scriptContext);
break;
default:
Assert(UNREACHED);
}
JavascriptString* string = JavascriptString::NewCopySzFromArena(stringBuffer, scriptContext, scriptContext->GeneralAllocator());
END_TEMP_ALLOCATOR(tempAllocator, scriptContext);
return string;
}
template <typename T, size_t N>
Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString, const T (&laneValues)[N],
CallInfo* callInfo, ScriptContext* scriptContext) const
{
Assert(args);
Assert(N == 4 || N == 8 || N == 16);
if (typeDescriptor == TypeIds_SIMDBool8x16 ||
typeDescriptor == TypeIds_SIMDBool16x8 ||
typeDescriptor == TypeIds_SIMDBool32x4)
{
return ToString(scriptContext); //Boolean types does not have toLocaleString.
}
// Creating a new arguments list for the JavascriptNumber generated from each lane.The optional SIMDToLocaleString Args are
//added to this argument list.
Var* newArgs = HeapNewArray(Var, numArgs);
switch (numArgs)
{
case 1:
break;
case 2:
newArgs[1] = args[1];
break;
case 3:
newArgs[1] = args[1];
newArgs[2] = args[2];
break;
default:
Assert(UNREACHED);
}
//Locale specifc seperator??
JavascriptString *seperator = JavascriptString::NewWithSz(_u(", "), scriptContext);
uint idx = 0;
Var laneVar = nullptr;
BEGIN_TEMP_ALLOCATOR(tempAllocator, scriptContext, _u("fromCodePoint"));
char16* stringBuffer = AnewArray(tempAllocator, char16, SIMD_STRING_BUFFER_MAX);
JavascriptString *result = nullptr;
swprintf_s(stringBuffer, 1024, typeString);
result = JavascriptString::NewCopySzFromArena(stringBuffer, scriptContext, scriptContext->GeneralAllocator());
if (typeDescriptor == TypeIds_SIMDFloat32x4)
{
for (; idx < numLanes - 1; ++idx)
{
laneVar = JavascriptNumber::ToVarWithCheck(laneValues[idx], scriptContext);
newArgs[0] = laneVar;
JavascriptString *laneValue = JavascriptNumber::ToLocaleStringIntl(newArgs, *callInfo, scriptContext);
result = JavascriptString::Concat(result, laneValue);
result = JavascriptString::Concat(result, seperator);
}
laneVar = JavascriptNumber::ToVarWithCheck(laneValues[idx], scriptContext);
newArgs[0] = laneVar;
result = JavascriptString::Concat(result, JavascriptNumber::ToLocaleStringIntl(newArgs, *callInfo, scriptContext));
}
else if (typeDescriptor == TypeIds_SIMDInt8x16 || typeDescriptor == TypeIds_SIMDInt16x8 || typeDescriptor == TypeIds_SIMDInt32x4)
{
for (; idx < numLanes - 1; ++idx)
{
laneVar = JavascriptNumber::ToVar(static_cast<int>(laneValues[idx]), scriptContext);
newArgs[0] = laneVar;
JavascriptString *laneValue = JavascriptNumber::ToLocaleStringIntl(newArgs, *callInfo, scriptContext);
result = JavascriptString::Concat(result, laneValue);
result = JavascriptString::Concat(result, seperator);
}
laneVar = JavascriptNumber::ToVar(static_cast<int>(laneValues[idx]), scriptContext);
newArgs[0] = laneVar;
result = JavascriptString::Concat(result, JavascriptNumber::ToLocaleStringIntl(newArgs, *callInfo, scriptContext));
}
else
{
Assert((typeDescriptor == TypeIds_SIMDUint8x16 || typeDescriptor == TypeIds_SIMDUint16x8 || typeDescriptor == TypeIds_SIMDUint32x4));
for (; idx < numLanes - 1; ++idx)
{
laneVar = JavascriptNumber::ToVar(static_cast<uint>(laneValues[idx]), scriptContext);
newArgs[0] = laneVar;
JavascriptString *laneValue = JavascriptNumber::ToLocaleStringIntl(newArgs, *callInfo, scriptContext);
result = JavascriptString::Concat(result, laneValue);
result = JavascriptString::Concat(result, seperator);
}
laneVar = JavascriptNumber::ToVar(static_cast<uint>(laneValues[idx]), scriptContext);
newArgs[0] = laneVar;
result = JavascriptString::Concat(result, JavascriptNumber::ToLocaleStringIntl(newArgs, *callInfo, scriptContext));
}
HeapDeleteArray(numArgs, newArgs);
END_TEMP_ALLOCATOR(tempAllocator, scriptContext);
return JavascriptString::Concat(result, JavascriptString::NewWithSz(_u(")"), scriptContext));
}
template Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString,
const float (&laneValues)[4], CallInfo* callInfo, ScriptContext* scriptContext) const;
template Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString,
const int(&laneValues)[4], CallInfo* callInfo, ScriptContext* scriptContext) const;
template Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString,
const int16(&laneValues)[8], CallInfo* callInfo, ScriptContext* scriptContext) const;
template Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString,
const int8(&laneValues)[16], CallInfo* callInfo, ScriptContext* scriptContext) const;
template Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString,
const uint(&laneValues)[4], CallInfo* callInfo, ScriptContext* scriptContext) const;
template Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString,
const uint16(&laneValues)[8], CallInfo* callInfo, ScriptContext* scriptContext) const;
template Var JavascriptSIMDObject::ToLocaleString(const Var* args, uint numArgs, const char16 *typeString,
const uint8(&laneValues)[16], CallInfo* callInfo, ScriptContext* scriptContext) const;
Var JavascriptSIMDObject::GetValue() const
{
Assert(SIMDUtils::IsSimdType(value));
return value;
}
}