mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-26 19:50:55 +00:00
[feature]:dataview.prototype.get arraybuffer.isview aot nativeinline
[issue]:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I9CQIH Signed-off-by: luobinghao <luobinghao@huawei.com> Change-Id: I14b564d828a926198ad558874c90a043a5ea7f24
This commit is contained in:
parent
e806c4560c
commit
c2a8fe67e6
@ -141,7 +141,7 @@ public:
|
||||
const uint8_t *end, JSTaggedValue string);
|
||||
static double StringToDouble(const uint8_t *start, const uint8_t *end, uint8_t radix, uint32_t flags = NO_FLAGS);
|
||||
static int32_t DoubleToInt(double d, size_t bits);
|
||||
static int32_t DoubleInRangeInt32(double d);
|
||||
static int32_t PUBLIC_API DoubleInRangeInt32(double d);
|
||||
static JSTaggedValue StringToDoubleWithRadix(const uint8_t *start, const uint8_t *end, int radix, bool *negative);
|
||||
static CString IntToString(int number);
|
||||
static CString IntegerToString(double number, int radix);
|
||||
|
@ -2271,7 +2271,14 @@ void Builtins::InitializeArrayBuffer(const JSHandle<GlobalEnv> &env, const JSHan
|
||||
SetFunction(env, arrayBufferFuncPrototype, "slice", ArrayBuffer::Slice, FunctionLength::TWO);
|
||||
|
||||
// ArrayBuffer method
|
||||
SetFunction(env, arrayBufferFunction, "isView", ArrayBuffer::IsView, FunctionLength::ONE);
|
||||
for (const base::BuiltinFunctionEntry& entry: ArrayBuffer::GetArrayBufferFunctions()) {
|
||||
SetFunction(env,
|
||||
arrayBufferFunction,
|
||||
entry.GetName(),
|
||||
entry.GetEntrypoint(),
|
||||
entry.GetLength(),
|
||||
entry.GetBuiltinStubId());
|
||||
}
|
||||
|
||||
// 24.1.3.3 get ArrayBuffer[@@species]
|
||||
JSHandle<JSTaggedValue> speciesSymbol = env->GetSpeciesSymbol();
|
||||
|
@ -21,6 +21,14 @@
|
||||
#include "ecmascript/js_dataview.h"
|
||||
#include "ecmascript/js_typed_array.h"
|
||||
|
||||
// List of functions in ArrayBuffer, excluding the '@@' properties.
|
||||
// V(name, func, length, stubIndex)
|
||||
// where BuiltinsArrayBuffer::func refers to the native implementation of ArrayBuffer[name].
|
||||
// kungfu::BuiltinsStubCSigns::stubIndex refers to the builtin stub index, or INVALID if no stub available.
|
||||
#define BUILTIN_ARRAY_BUFFER_FUNCTIONS(V) \
|
||||
/* ArrayBuffer.isView ( arg ) */ \
|
||||
V("isView", IsView, 1, ArrayBufferIsView)
|
||||
|
||||
namespace panda::ecmascript::builtins {
|
||||
static constexpr double NUMBER_HALF = 0.5;
|
||||
static constexpr uint32_t BITS_EIGHT = 8;
|
||||
@ -72,6 +80,12 @@ public:
|
||||
// es12 25.1.2.7 IsBigIntElementType ( type )
|
||||
static bool IsBigIntElementType(DataViewType type);
|
||||
|
||||
// Excluding the '@@' internal properties
|
||||
static Span<const base::BuiltinFunctionEntry> GetArrayBufferFunctions()
|
||||
{
|
||||
return Span<const base::BuiltinFunctionEntry>(ARRAY_BUFFER_FUNCTIONS);
|
||||
}
|
||||
|
||||
static JSTaggedValue FastSetValueInBuffer(JSThread* thread, JSTaggedValue arrBuf, uint32_t byteIndex,
|
||||
DataViewType type, double val, bool littleEndian);
|
||||
static JSTaggedValue TryFastSetValueInBuffer(JSThread *thread, JSTaggedValue arrBuf, uint32_t byteBeginOffset,
|
||||
@ -98,6 +112,12 @@ public:
|
||||
static void *GetDataPointFromBuffer(JSTaggedValue arrBuf, uint32_t byteOffset = 0);
|
||||
|
||||
private:
|
||||
#define BUILTIN_ARRAY_BUFFER_ENTRY(name, func, length, id) \
|
||||
base::BuiltinFunctionEntry::Create((name), (BuiltinsArrayBuffer::func), (length), (kungfu::BuiltinsStubCSigns::id)),
|
||||
|
||||
static constexpr std::array ARRAY_BUFFER_FUNCTIONS = {BUILTIN_ARRAY_BUFFER_FUNCTIONS(BUILTIN_ARRAY_BUFFER_ENTRY)};
|
||||
#undef BUILTIN_ARRAY_BUFFER_ENTRY
|
||||
|
||||
template <typename T>
|
||||
static T LittleEndianToBigEndian(T liValue);
|
||||
template<typename T>
|
||||
|
@ -28,29 +28,29 @@
|
||||
/* DataView.prototype.get%Type% ( byteOffset ) */ \
|
||||
/* For %Type% of 2 or more bytes: */ \
|
||||
/* DataView.prototype.get%Type% ( byteOffset [ , littleEndian ] ) */ \
|
||||
V("getFloat32", GetFloat32, 1, INVALID) \
|
||||
V("getFloat64", GetFloat64, 1, INVALID) \
|
||||
V("getInt8", GetInt8, 1, INVALID) \
|
||||
V("getInt16", GetInt16, 1, INVALID) \
|
||||
V("getInt32", GetInt32, 1, INVALID) \
|
||||
V("getBigInt64", GetBigInt64, 1, INVALID) \
|
||||
V("getUint16", GetUint16, 1, INVALID) \
|
||||
V("getUint32", GetUint32, 1, INVALID) \
|
||||
V("getUint8", GetUint8, 1, INVALID) \
|
||||
V("getBigUint64", GetBigUint64, 1, INVALID) \
|
||||
V("getFloat32", GetFloat32, 1, DataViewGetFloat32 ) \
|
||||
V("getFloat64", GetFloat64, 1, DataViewGetFloat64 ) \
|
||||
V("getInt8", GetInt8, 1, DataViewGetInt8 ) \
|
||||
V("getInt16", GetInt16, 1, DataViewGetInt16 ) \
|
||||
V("getInt32", GetInt32, 1, DataViewGetInt32 ) \
|
||||
V("getBigInt64", GetBigInt64, 1, INVALID ) \
|
||||
V("getUint16", GetUint16, 1, DataViewGetUint16 ) \
|
||||
V("getUint32", GetUint32, 1, DataViewGetUint32 ) \
|
||||
V("getUint8", GetUint8, 1, DataViewGetUint8 ) \
|
||||
V("getBigUint64", GetBigUint64, 1, INVALID ) \
|
||||
/* For %Type% of 1 bytes: */ \
|
||||
/* DataView.prototype.setInt8 ( byteOffset, value ) */ \
|
||||
/* For %Type% of 2 or more bytes: */ \
|
||||
/* DataView.prototype.setInt16 ( byteOffset, value [ , littleEndian ] ) */ \
|
||||
V("setFloat32", SetFloat32, 2, INVALID) \
|
||||
V("setFloat64", SetFloat64, 2, INVALID) \
|
||||
V("setInt8", SetInt8, 2, INVALID) \
|
||||
V("setInt16", SetInt16, 2, INVALID) \
|
||||
V("setInt32", SetInt32, 2, INVALID) \
|
||||
V("setFloat32", SetFloat32, 2, DataViewSetFloat32) \
|
||||
V("setFloat64", SetFloat64, 2, DataViewSetFloat64) \
|
||||
V("setInt8", SetInt8, 2, DataViewSetInt8) \
|
||||
V("setInt16", SetInt16, 2, DataViewSetInt16) \
|
||||
V("setInt32", SetInt32, 2, DataViewSetInt32) \
|
||||
V("setBigInt64", SetBigInt64, 2, INVALID) \
|
||||
V("setUint8", SetUint8, 2, INVALID) \
|
||||
V("setUint16", SetUint16, 2, INVALID) \
|
||||
V("setUint32", SetUint32, 2, INVALID) \
|
||||
V("setUint8", SetUint8, 2, DataViewSetUint8) \
|
||||
V("setUint16", SetUint16, 2, DataViewSetUint16) \
|
||||
V("setUint32", SetUint32, 2, DataViewSetUint32) \
|
||||
V("setBigUint64", SetBigUint64, 2, INVALID)
|
||||
|
||||
namespace panda::ecmascript::builtins {
|
||||
|
@ -203,8 +203,25 @@ namespace panda::ecmascript::kungfu {
|
||||
V(MathImul) \
|
||||
V(GlobalIsFinite) \
|
||||
V(GlobalIsNan) \
|
||||
V(ArrayBufferIsView) \
|
||||
V(DataViewGetFloat32) \
|
||||
V(DataViewGetFloat64) \
|
||||
V(DataViewGetInt8) \
|
||||
V(DataViewGetInt16) \
|
||||
V(DataViewGetInt32) \
|
||||
V(DataViewGetUint16) \
|
||||
V(DataViewGetUint32) \
|
||||
V(DataViewGetUint8) \
|
||||
V(DataViewSetFloat32) \
|
||||
V(DataViewSetFloat64) \
|
||||
V(DataViewSetInt8) \
|
||||
V(DataViewSetInt16) \
|
||||
V(DataViewSetInt32) \
|
||||
V(DataViewSetUint8) \
|
||||
V(DataViewSetUint16) \
|
||||
V(DataViewSetUint32) \
|
||||
V(TYPED_BUILTINS_INLINE_FIRST = MathAcos) \
|
||||
V(TYPED_BUILTINS_INLINE_LAST = GlobalIsNan)
|
||||
V(TYPED_BUILTINS_INLINE_LAST = DataViewSetUint32)
|
||||
|
||||
class BuiltinsStubCSigns {
|
||||
public:
|
||||
@ -400,6 +417,40 @@ public:
|
||||
return ConstantIndex::GLOBAL_IS_FINITE_INDEX;
|
||||
case BuiltinsStubCSigns::ID::GlobalIsNan:
|
||||
return ConstantIndex::GLOBAL_IS_NAN_INDEX;
|
||||
case BuiltinsStubCSigns::ID::ArrayBufferIsView:
|
||||
return ConstantIndex::ARRAY_BUFFER_IS_VIEW_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewGetFloat32:
|
||||
return ConstantIndex::DATA_VIEW_GET_FLOAT32_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewGetFloat64:
|
||||
return ConstantIndex::DATA_VIEW_GET_FLOAT64_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt8:
|
||||
return ConstantIndex::DATA_VIEW_GET_INT8_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt16:
|
||||
return ConstantIndex::DATA_VIEW_GET_INT16_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt32:
|
||||
return ConstantIndex::DATA_VIEW_GET_INT32_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint16:
|
||||
return ConstantIndex::DATA_VIEW_GET_UINT16_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint32:
|
||||
return ConstantIndex::DATA_VIEW_GET_UINT32_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint8:
|
||||
return ConstantIndex::DATA_VIEW_GET_UINT8_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewSetFloat32:
|
||||
return ConstantIndex::DATA_VIEW_SET_FLOAT32_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewSetFloat64:
|
||||
return ConstantIndex::DATA_VIEW_SET_FLOAT64_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewSetInt8:
|
||||
return ConstantIndex::DATA_VIEW_SET_INT8_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewSetInt16:
|
||||
return ConstantIndex::DATA_VIEW_SET_INT16_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewSetInt32:
|
||||
return ConstantIndex::DATA_VIEW_SET_INT32_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewSetUint8:
|
||||
return ConstantIndex::DATA_VIEW_SET_UINT8_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewSetUint16:
|
||||
return ConstantIndex::DATA_VIEW_SET_UINT16_INDEX;
|
||||
case BuiltinsStubCSigns::ID::DataViewSetUint32:
|
||||
return ConstantIndex::DATA_VIEW_SET_UINT32_INDEX;
|
||||
default:
|
||||
LOG_COMPILER(FATAL) << "this branch is unreachable";
|
||||
UNREACHABLE();
|
||||
|
@ -22,16 +22,17 @@
|
||||
#include "ecmascript/compiler/lcr_circuit_builder.h"
|
||||
#include "ecmascript/compiler/mcr_circuit_builder.h"
|
||||
#include "ecmascript/compiler/rt_call_signature.h"
|
||||
#include "ecmascript/compiler/share_gate_meta_data.h"
|
||||
#include "ecmascript/deoptimizer/deoptimizer.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/ic/proto_change_details.h"
|
||||
#include "ecmascript/js_array_iterator.h"
|
||||
#include "ecmascript/js_for_in_iterator.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/jspandafile/program_object.h"
|
||||
#include "ecmascript/mem/region.h"
|
||||
#include "ecmascript/method.h"
|
||||
#include "ecmascript/js_array_iterator.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
|
||||
@ -738,6 +739,28 @@ GateRef CircuitBuilder::IsEcmaObject(GateRef obj)
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::CheckJSType(GateRef object, JSType jsType)
|
||||
{
|
||||
Label entryPass(env_);
|
||||
SubCfgEntry(&entryPass);
|
||||
DEFVALUE(result, env_, VariableType::BOOL(), False());
|
||||
Label heapObj(env_);
|
||||
Label exit(env_);
|
||||
GateRef isHeapObject = TaggedIsHeapObject(object);
|
||||
BRANCH_CIR2(isHeapObject, &heapObj, &exit);
|
||||
Bind(&heapObj);
|
||||
{
|
||||
GateRef objectType = GetObjectType(LoadHClass(object));
|
||||
GateRef checkType = Int32Equal(objectType, Int32(static_cast<int32_t>(jsType)));
|
||||
result = LogicAnd(isHeapObject, checkType);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&exit);
|
||||
auto ret = *result;
|
||||
SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::GetObjectFromConstPool(GateRef glue, GateRef hirGate, GateRef constPool, GateRef module,
|
||||
GateRef index, ConstPoolType type)
|
||||
{
|
||||
|
@ -19,19 +19,20 @@
|
||||
#include "ecmascript/base/number_helper.h"
|
||||
#include "ecmascript/compiler/assembler/assembler.h"
|
||||
#include "ecmascript/compiler/builtins/builtins_call_signature.h"
|
||||
#include "ecmascript/compiler/circuit.h"
|
||||
#include "ecmascript/compiler/call_signature.h"
|
||||
#include "ecmascript/compiler/circuit.h"
|
||||
#include "ecmascript/compiler/gate.h"
|
||||
#include "ecmascript/compiler/gate_accessor.h"
|
||||
#include "ecmascript/compiler/lcr_gate_meta_data.h"
|
||||
#include "ecmascript/compiler/pgo_type/pgo_type_location.h"
|
||||
#include "ecmascript/compiler/share_gate_meta_data.h"
|
||||
#include "ecmascript/compiler/variable_type.h"
|
||||
#include "ecmascript/global_env_constants.h"
|
||||
#include "ecmascript/compiler/pgo_type/pgo_type_location.h"
|
||||
#include "ecmascript/jspandafile/constpool_value.h"
|
||||
#include "ecmascript/js_hclass.h"
|
||||
#include "ecmascript/js_runtime_options.h"
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
#include "ecmascript/jspandafile/constpool_value.h"
|
||||
#include "ecmascript/tagged_array.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
using namespace panda::ecmascript;
|
||||
@ -106,6 +107,7 @@ class PostSchedule;
|
||||
V(CastDoubleToInt64, Bitcast, MachineType::I64) \
|
||||
V(CastInt64ToFloat64, Bitcast, MachineType::F64) \
|
||||
V(CastInt32ToFloat32, Bitcast, MachineType::F32) \
|
||||
V(CaseFloat32ToInt32, Bitcast, MachineType::I32) \
|
||||
V(SExtInt32ToInt64, Sext, MachineType::I64) \
|
||||
V(SExtInt1ToInt64, Sext, MachineType::I64) \
|
||||
V(SExtInt1ToInt32, Sext, MachineType::I32) \
|
||||
@ -218,6 +220,7 @@ public:
|
||||
GateRef IsJsCOWArray(GateRef obj);
|
||||
GateRef IsCOWArray(GateRef objectType);
|
||||
GateRef IsTaggedArray(GateRef object);
|
||||
GateRef CheckJSType(GateRef object, JSType jsType);
|
||||
GateRef IsMutantTaggedArray(GateRef objectType);
|
||||
GateRef SwitchCase(GateRef switchBranch, int64_t value);
|
||||
GateRef Int8(int8_t val);
|
||||
@ -530,6 +533,9 @@ public:
|
||||
GateRef LexVarIsHoleCheck(GateRef value);
|
||||
GateRef IsUndefinedOrHoleCheck(GateRef value);
|
||||
GateRef IsNotUndefinedOrHoleCheck(GateRef value);
|
||||
GateRef IsEcmaObjectCheck(GateRef obj);
|
||||
GateRef IsDataViewCheck(GateRef obj);
|
||||
GateRef IsTaggedBooleanCheck(GateRef value);
|
||||
GateRef Int32UnsignedUpperBoundCheck(GateRef value, GateRef upperBound);
|
||||
GateRef Int32DivWithCheck(GateRef left, GateRef right);
|
||||
GateType GetGateTypeOfValueType(ValueType type);
|
||||
@ -692,6 +698,8 @@ public:
|
||||
inline GateRef TaggedObjectIsShared(GateRef obj);
|
||||
inline GateRef TaggedObjectBothAreString(GateRef x, GateRef y);
|
||||
inline GateRef TaggedObjectIsEcmaObject(GateRef obj);
|
||||
inline GateRef TaggedObjectIsByteArray(GateRef obj);
|
||||
inline GateRef TaggedObjectIsDataView(GateRef obj);
|
||||
inline GateRef IsSpecialHole(GateRef x);
|
||||
inline GateRef IsNotSpecialHole(GateRef x);
|
||||
inline GateRef TaggedTrue();
|
||||
@ -728,6 +736,15 @@ public:
|
||||
GateRef charSize, VariableType type);
|
||||
void SetRawHashcode(GateRef glue, GateRef str, GateRef rawHashcode, GateRef isInteger);
|
||||
GateRef StringFromSingleCharCode(GateRef gate);
|
||||
GateRef ArrayBufferIsView(GateRef gate);
|
||||
GateRef DataViewGet(
|
||||
GateRef thisobj, GateRef index, GateRef dataViewCallID, GateRef isLittleEndian, GateRef frameState);
|
||||
GateRef DataViewSet(GateRef thisobj,
|
||||
GateRef index,
|
||||
GateRef value,
|
||||
GateRef dataViewCallID,
|
||||
GateRef isLittleEndian,
|
||||
GateRef frameState);
|
||||
GateRef ToNumber(GateRef gate, GateRef value, GateRef glue);
|
||||
GateRef IsASCIICharacter(GateRef gate);
|
||||
|
||||
@ -778,6 +795,9 @@ public:
|
||||
MemoryOrder order = MemoryOrder::Default());
|
||||
|
||||
// cast operation
|
||||
inline GateRef Int16ToBigEndianInt16(GateRef x);
|
||||
inline GateRef Int32ToBigEndianInt32(GateRef x);
|
||||
inline GateRef Int64ToBigEndianInt64(GateRef x);
|
||||
inline GateRef GetInt64OfTInt(GateRef x);
|
||||
inline GateRef GetInt32OfTInt(GateRef x);
|
||||
inline GateRef TaggedCastToIntPtr(GateRef x);
|
||||
@ -787,6 +807,8 @@ public:
|
||||
inline GateRef GetDoubleOfTNumber(GateRef x);
|
||||
inline GateRef DoubleToInt(GateRef x, Label *exit);
|
||||
inline GateRef DoubleToInt(GateRef glue, GateRef x, size_t typeBits);
|
||||
inline GateRef DoubleCheckINFInRangeInt32(GateRef x);
|
||||
inline GateRef DoubleInRangeInt32(GateRef x);
|
||||
inline GateRef Int32ToTaggedPtr(GateRef x);
|
||||
inline GateRef Int64ToTaggedPtr(GateRef x);
|
||||
inline GateRef Int32ToTaggedInt(GateRef x);
|
||||
|
@ -16,7 +16,9 @@
|
||||
#ifndef ECMASCRIPT_COMPILER_LCR_CIRCUIT_BUILDER_H
|
||||
#define ECMASCRIPT_COMPILER_LCR_CIRCUIT_BUILDER_H
|
||||
|
||||
#include "ecmascript/compiler/circuit_builder.h"
|
||||
#include "ecmascript/compiler/circuit_builder_helper.h"
|
||||
#include "ecmascript/compiler/share_gate_meta_data.h"
|
||||
#include "ecmascript/mem/region.h"
|
||||
#include "ecmascript/method.h"
|
||||
|
||||
@ -74,6 +76,51 @@ GateRef CircuitBuilder::IntPtrLSL(GateRef x, GateRef y)
|
||||
return BinaryArithmetic(circuit_->Lsl(), ptrSize, x, y);
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::Int16ToBigEndianInt16(GateRef x)
|
||||
{
|
||||
GateRef int16toint32 = ZExtInt16ToInt32(x);
|
||||
GateRef high8bits = Int32LSL(Int32And(int16toint32, Int32(0x00FF)), Int32(8));
|
||||
GateRef low8bits = Int32LSR(Int32And(int16toint32, Int32(0xFF00)), Int32(8));
|
||||
return TruncInt32ToInt16(Int32Add(high8bits, low8bits));
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::Int32ToBigEndianInt32(GateRef x)
|
||||
{
|
||||
GateRef first8bits = Int32LSL(Int32And(x, Int32(0x000000FF)), Int32(24));
|
||||
GateRef second8bits = Int32LSL(Int32And(x, Int32(0x0000FF00)), Int32(8));
|
||||
GateRef third8bits = Int32LSR(Int32And(x, Int32(0x00FF0000)), Int32(8));
|
||||
GateRef fourth8bits = Int32LSR(Int32And(x, Int32(0xFF000000)), Int32(24));
|
||||
GateRef firstHalf = Int32Add(first8bits, second8bits);
|
||||
GateRef secondHalf = Int32Add(third8bits, fourth8bits);
|
||||
return Int32Add(firstHalf, secondHalf);
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::Int64ToBigEndianInt64(GateRef x)
|
||||
{
|
||||
GateRef first8bits = Int64LSL(Int64And(x, Int64(0x00000000000000FF)), Int64(56));
|
||||
GateRef second8bits = Int64LSL(Int64And(x, Int64(0x000000000000FF00)), Int64(40));
|
||||
// 0-16bits
|
||||
GateRef first16bits = Int64Add(first8bits, second8bits);
|
||||
GateRef third8bits = Int64LSL(Int64And(x, Int64(0x0000000000FF0000)), Int64(24));
|
||||
GateRef fourth8bits = Int64LSL(Int64And(x, Int64(0x00000000FF000000)), Int64(8));
|
||||
// 16-32bits
|
||||
GateRef second16bits = Int64Add(third8bits, fourth8bits);
|
||||
// 0-32bits
|
||||
GateRef firstHalf = Int64Add(first16bits, second16bits);
|
||||
GateRef fifth8bits = Int64LSR(Int64And(x, Int64(0x000000FF00000000)), Int64(8));
|
||||
GateRef sixth8bits = Int64LSR(Int64And(x, Int64(0x0000FF0000000000)), Int64(24));
|
||||
//32-48bits
|
||||
GateRef third16bits = Int64Add(fifth8bits, sixth8bits);
|
||||
GateRef seventh8bits = Int64LSR(Int64And(x, Int64(0x00FF000000000000)), Int64(40));
|
||||
GateRef eighth8bits = Int64LSR(Int64And(x, Int64(0xFF00000000000000)), Int64(56));
|
||||
//48-64bits
|
||||
GateRef fourth16bits = Int64Add(seventh8bits, eighth8bits);
|
||||
//32-64bits
|
||||
GateRef secondHalf = Int64Add(third16bits, fourth16bits);
|
||||
//0-64bits
|
||||
return Int64Add(firstHalf, secondHalf);
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::IntPtrOr(GateRef x, GateRef y)
|
||||
{
|
||||
auto ptrsize = env_->Is32Bit() ? MachineType::I32 : MachineType::I64;
|
||||
@ -208,6 +255,73 @@ GateRef CircuitBuilder::DoubleToInt(GateRef glue, GateRef x, size_t typeBits)
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::DoubleCheckINFInRangeInt32(GateRef x)
|
||||
{
|
||||
Label entry(env_);
|
||||
env_->SubCfgEntry(&entry);
|
||||
Label exit(env_);
|
||||
Label isInfinity(env_);
|
||||
Label positiveInf(env_);
|
||||
Label negativeInf(env_);
|
||||
|
||||
DEFVALUE(result, env_, VariableType::INT32(), DoubleInRangeInt32(x));
|
||||
GateRef Max = Double(INT32_MAX);
|
||||
GateRef Min = Double(INT32_MIN);
|
||||
GateRef pInfinity = Double(base::POSITIVE_INFINITY);
|
||||
Branch(DoubleIsINF(x), &isInfinity, &exit);
|
||||
Bind(&isInfinity);
|
||||
{
|
||||
Branch(DoubleEqual(x, pInfinity), &positiveInf, &negativeInf);
|
||||
Bind(&positiveInf);
|
||||
{
|
||||
result = ChangeFloat64ToInt32(Max);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&negativeInf);
|
||||
{
|
||||
result = ChangeFloat64ToInt32(Min);
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
Bind(&exit);
|
||||
auto ret = *result;
|
||||
env_->SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::DoubleInRangeInt32(GateRef x)
|
||||
{
|
||||
Label entry(env_);
|
||||
env_->SubCfgEntry(&entry);
|
||||
Label exit(env_);
|
||||
Label overflow(env_);
|
||||
Label checkUnderflow(env_);
|
||||
Label underflow(env_);
|
||||
|
||||
DEFVALUE(result, env_, VariableType::INT32(), ChangeFloat64ToInt32(x));
|
||||
GateRef Max = Double(INT32_MAX);
|
||||
GateRef Min = Double(INT32_MIN);
|
||||
Branch(DoubleGreaterThan(x, Max), &overflow, &checkUnderflow);
|
||||
Bind(&overflow);
|
||||
{
|
||||
result = ChangeFloat64ToInt32(Max);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&checkUnderflow);
|
||||
{
|
||||
Branch(DoubleLessThan(x, Min), &underflow, &exit);
|
||||
Bind(&underflow);
|
||||
{
|
||||
result = ChangeFloat64ToInt32(Min);
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
Bind(&exit);
|
||||
auto ret = *result;
|
||||
env_->SubCfgExit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::Int32ToTaggedInt(GateRef x)
|
||||
{
|
||||
GateRef val = SExtInt32ToInt64(x);
|
||||
|
@ -16,6 +16,9 @@
|
||||
#include "libpandabase/utils/hash.h"
|
||||
|
||||
#include "ecmascript/compiler/mcr_circuit_builder.h"
|
||||
|
||||
#include "ecmascript/compiler/circuit_builder.h"
|
||||
#include "ecmascript/compiler/share_gate_meta_data.h"
|
||||
#include "ecmascript/message_string.h"
|
||||
#include "ecmascript/stubs/runtime_stubs-inl.h"
|
||||
#include "ecmascript/stubs/runtime_stubs.h"
|
||||
@ -714,6 +717,51 @@ GateRef CircuitBuilder::IsNotUndefinedOrHoleCheck(GateRef value)
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::IsEcmaObjectCheck(GateRef gate)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
auto frameState = acc_.FindNearestFrameState(currentDepend);
|
||||
GateRef ret = GetCircuit()->NewGate(circuit_->IsEcmaObjectCheck(),
|
||||
MachineType::I1,
|
||||
{currentControl, currentDepend, gate, frameState},
|
||||
GateType::NJSValue());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::IsDataViewCheck(GateRef gate)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
auto frameState = acc_.FindNearestFrameState(currentDepend);
|
||||
GateRef ret = GetCircuit()->NewGate(circuit_->IsDataViewCheck(),
|
||||
MachineType::I1,
|
||||
{currentControl, currentDepend, gate, frameState},
|
||||
GateType::NJSValue());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::IsTaggedBooleanCheck(GateRef value)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
auto frameState = acc_.FindNearestFrameState(currentDepend);
|
||||
GateRef ret = GetCircuit()->NewGate(circuit_->IsTaggedBooleanCheck(),
|
||||
MachineType::I1,
|
||||
{currentControl, currentDepend, value, frameState},
|
||||
GateType::NJSValue());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::ValueCheckNegOverflow(GateRef value)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
@ -1636,6 +1684,50 @@ GateRef CircuitBuilder::StringFromSingleCharCode(GateRef gate)
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::ArrayBufferIsView(GateRef gate)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
GateRef ret = GetCircuit()->NewGate(
|
||||
circuit_->ArrayBufferIsView(), MachineType::I64, {currentControl, currentDepend, gate}, GateType::AnyType());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::DataViewGet(
|
||||
GateRef thisobj, GateRef index, GateRef dataViewCallID, GateRef isLittleEndian, GateRef frameState)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
GateRef ret = GetCircuit()->NewGate(
|
||||
circuit_->DataViewGet(),
|
||||
MachineType::I64,
|
||||
{currentControl, currentDepend, thisobj, index, dataViewCallID, isLittleEndian, frameState},
|
||||
GateType::AnyType());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::DataViewSet(
|
||||
GateRef thisobj, GateRef index, GateRef value, GateRef dataViewCallID, GateRef isLittleEndian, GateRef frameState)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentControl = currentLabel->GetControl();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
GateRef ret = GetCircuit()->NewGate(
|
||||
circuit_->DataViewSet(),
|
||||
MachineType::I64,
|
||||
{currentControl, currentDepend, thisobj, index, value, dataViewCallID, isLittleEndian, frameState},
|
||||
GateType::TaggedValue());
|
||||
currentLabel->SetControl(ret);
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::IsASCIICharacter(GateRef gate)
|
||||
{
|
||||
return Int32UnsignedLessThan(Int32Sub(gate, Int32(1)), Int32(base::utf_helper::UTF8_1B_MAX));
|
||||
|
@ -88,6 +88,18 @@ GateRef CircuitBuilder::TaggedObjectIsEcmaObject(GateRef obj)
|
||||
Int32GreaterThanOrEqual(objectType, Int32(static_cast<int32_t>(JSType::ECMA_OBJECT_FIRST))));
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::TaggedObjectIsByteArray(GateRef obj)
|
||||
{
|
||||
GateRef objectType = GetObjectType(LoadHClass(obj));
|
||||
return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::BYTE_ARRAY)));
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::TaggedObjectIsDataView(GateRef obj)
|
||||
{
|
||||
GateRef objectType = GetObjectType(LoadHClass(obj));
|
||||
return Int32Equal(objectType, Int32(static_cast<int32_t>(JSType::JS_DATA_VIEW)));
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::IsSpecialSlicedString(GateRef obj)
|
||||
{
|
||||
GateRef objectType = GetObjectType(LoadHClass(obj));
|
||||
|
@ -13,14 +13,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "ecmascript/compiler/mcr_lowering.h"
|
||||
#include "ecmascript/compiler/argument_accessor.h"
|
||||
#include "ecmascript/compiler/bytecodes.h"
|
||||
#include "ecmascript/compiler/share_gate_meta_data.h"
|
||||
#include "ecmascript/compiler/share_opcodes.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
#include "ecmascript/jspandafile/program_object.h"
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/js_hclass.h"
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/jspandafile/program_object.h"
|
||||
#include "ecmascript/message_string.h"
|
||||
#include "ecmascript/compiler/argument_accessor.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
|
||||
@ -103,6 +105,15 @@ GateRef MCRLowering::VisitGate(GateRef gate)
|
||||
case OpCode::IS_NOT_UNDEFINED_OR_HOLE_CHECK:
|
||||
LowerIsNotUndefinedOrHoleCheck(gate);
|
||||
break;
|
||||
case OpCode::IS_ECMA_OBJECT_CHECK:
|
||||
LowerIsEcmaObjectCheck(gate);
|
||||
break;
|
||||
case OpCode::IS_TAGGED_BOOLEAN_CHECK:
|
||||
LowerIsTaggedBooleanCheck(gate);
|
||||
break;
|
||||
case OpCode::IS_DATA_VIEW_CHECK:
|
||||
LowerIsDataViewCheck(gate);
|
||||
break;
|
||||
case OpCode::STORE_MEMORY:
|
||||
LowerStoreMemory(gate);
|
||||
break;
|
||||
@ -914,6 +925,36 @@ void MCRLowering::LowerIsNotUndefinedOrHoleCheck(GateRef gate)
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
|
||||
}
|
||||
|
||||
void MCRLowering::LowerIsEcmaObjectCheck(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef frameState = acc_.GetFrameState(gate);
|
||||
GateRef obj = acc_.GetValueIn(gate, 0);
|
||||
GateRef isEcmaObject = builder_.IsEcmaObject(obj);
|
||||
builder_.DeoptCheck(isEcmaObject, frameState, DeoptType::ISNOTECMAOBJECT);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
|
||||
}
|
||||
|
||||
void MCRLowering::LowerIsDataViewCheck(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef frameState = acc_.GetFrameState(gate);
|
||||
GateRef obj = acc_.GetValueIn(gate, 0);
|
||||
GateRef isDataView = builder_.CheckJSType(obj, JSType::JS_DATA_VIEW);
|
||||
builder_.DeoptCheck(isDataView, frameState, DeoptType::ISNOTDATAVIEW);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
|
||||
}
|
||||
|
||||
void MCRLowering::LowerIsTaggedBooleanCheck(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef frameState = acc_.GetFrameState(gate);
|
||||
GateRef value = acc_.GetValueIn(gate, 0);
|
||||
GateRef taggedIsBoolean = builder_.TaggedIsBoolean(value);
|
||||
builder_.DeoptCheck(taggedIsBoolean, frameState, DeoptType::ISNOTTAGGEDBOOLEAN);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), Circuit::NullGate());
|
||||
}
|
||||
|
||||
void MCRLowering::LowerValueCheckNegOverflow(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
|
@ -73,6 +73,9 @@ private:
|
||||
void LowerLexVarIsHoleCheck(GateRef gate);
|
||||
void LowerIsUndefinedOrHoleCheck(GateRef gate);
|
||||
void LowerIsNotUndefinedOrHoleCheck(GateRef gate);
|
||||
void LowerIsEcmaObjectCheck(GateRef gate);
|
||||
void LowerIsDataViewCheck(GateRef gate);
|
||||
void LowerIsTaggedBooleanCheck(GateRef gate);
|
||||
void LowerStoreMemory(GateRef gate);
|
||||
void LowerCheckNullAndConvert(GateRef gate, GateRef frameState);
|
||||
void LowerUndefinedAndConvert(GateRef gate, GateRef frameState);
|
||||
|
@ -29,6 +29,9 @@ namespace panda::ecmascript::kungfu {
|
||||
V(LexVarIsHoleCheck, LEX_VAR_IS_HOLE_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(IsUndefinedOrHoleCheck, IS_UNDEFINED_OR_HOLE_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(IsNotUndefinedOrHoleCheck, IS_NOT_UNDEFINED_OR_HOLE_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(IsEcmaObjectCheck, IS_ECMA_OBJECT_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(IsDataViewCheck, IS_DATA_VIEW_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(IsTaggedBooleanCheck, IS_TAGGED_BOOLEAN_CHECK, GateFlags::CHECKABLE, 1, 1, 1) \
|
||||
V(TaggedIsHeapObject, TAGGED_IS_HEAP_OBJECT, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(IsMarkerCellValid, IS_MARKER_CELL_VALID, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(StringEqual, STRING_EQUAL, GateFlags::NO_WRITE, 1, 1, 2)
|
||||
@ -106,6 +109,9 @@ namespace panda::ecmascript::kungfu {
|
||||
V(MathImul, MATH_IMUL, GateFlags::NO_WRITE, 1, 1, 2) \
|
||||
V(GlobalIsFinite, GLOBAL_IS_FINITE, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(GlobalIsNan, GLOBAL_IS_NAN, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(ArrayBufferIsView, ARRAY_BUFFER_IS_VIEW, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(DataViewGet, DATA_VIEW_GET, GateFlags::NO_WRITE, 1, 1, 5) \
|
||||
V(DataViewSet, DATA_VIEW_SET, GateFlags::NO_WRITE, 1, 1, 6) \
|
||||
MCR_BINARY_GATE_META_DATA_CACHE_LIST(V)
|
||||
|
||||
#define MCR_GATE_META_DATA_LIST_WITH_PC_OFFSET(V) \
|
||||
|
@ -13,9 +13,12 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "ecmascript/compiler/native_inline_lowering.h"
|
||||
#include "ecmascript/base/number_helper.h"
|
||||
#include "ecmascript/compiler/circuit.h"
|
||||
#include "ecmascript/compiler/circuit_builder-inl.h"
|
||||
#include "ecmascript/compiler/circuit_builder_helper.h"
|
||||
#include "ecmascript/compiler/circuit.h"
|
||||
#include "ecmascript/compiler/share_gate_meta_data.h"
|
||||
#include "ecmascript/js_dataview.h"
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/message_string.h"
|
||||
|
||||
@ -179,6 +182,29 @@ void NativeInlineLowering::RunNativeInlineLowering()
|
||||
case BuiltinsStubCSigns::ID::MathFloor:
|
||||
TryInlineMathUnaryBuiltin(gate, argc, id, circuit_->MathFloor(), skipThis);
|
||||
break;
|
||||
case BuiltinsStubCSigns::ID::ArrayBufferIsView:
|
||||
TryInlineArrayBufferIsView(gate, argc, id, skipThis);
|
||||
break;
|
||||
case BuiltinsStubCSigns::ID::DataViewGetFloat32:
|
||||
case BuiltinsStubCSigns::ID::DataViewGetFloat64:
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt8:
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt16:
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt32:
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint16:
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint32:
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint8:
|
||||
TryInlineDataViewGet(gate, argc, id);
|
||||
break;
|
||||
case BuiltinsStubCSigns::ID::DataViewSetFloat32:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetFloat64:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetInt8:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetInt16:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetInt32:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetUint8:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetUint16:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetUint32:
|
||||
TryInlineDataViewSet(gate, argc, id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -357,4 +383,83 @@ void NativeInlineLowering::TryInlineMathMinMaxBuiltin(GateRef gate, size_t argc,
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
|
||||
}
|
||||
|
||||
void NativeInlineLowering::TryInlineArrayBufferIsView(GateRef gate,
|
||||
size_t argc,
|
||||
BuiltinsStubCSigns::ID id,
|
||||
bool skipThis)
|
||||
{
|
||||
if (!skipThis) {
|
||||
return;
|
||||
}
|
||||
if (argc != 1) {
|
||||
return;
|
||||
}
|
||||
CallThis1TypeInfoAccessor tacc(thread_, circuit_, gate);
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
if (!Uncheck()) {
|
||||
builder_.CallTargetCheck(gate, tacc.GetFunc(), builder_.IntPtr(static_cast<int64_t>(id)), {tacc.GetArg0()});
|
||||
}
|
||||
GateRef arg0 = tacc.GetArg0();
|
||||
GateRef ret = builder_.ArrayBufferIsView(arg0);
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
|
||||
}
|
||||
|
||||
void NativeInlineLowering::TryInlineDataViewGet(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id)
|
||||
{
|
||||
if (argc != 1 && argc != 2) { // number of args must be 1/2
|
||||
return;
|
||||
}
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
if (!Uncheck()) {
|
||||
builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
|
||||
}
|
||||
GateRef thisObj = acc_.GetValueIn(gate, 0); // 0: this
|
||||
builder_.IsEcmaObjectCheck(thisObj);
|
||||
builder_.IsDataViewCheck(thisObj);
|
||||
GateRef dataViewCallID = builder_.Int32(id);
|
||||
GateRef index = acc_.GetValueIn(gate, 1); // 1: index of dataView
|
||||
GateRef ret = Circuit::NullGate();
|
||||
GateRef frameState = acc_.GetFrameState(gate);
|
||||
if (argc == 1) { // if not provide isLittleEndian, default use big endian
|
||||
ret = builder_.DataViewGet(thisObj, index, dataViewCallID, builder_.TaggedFalse(), frameState);
|
||||
} else if (argc == 2) { // 2: provide isLittleEndian
|
||||
GateRef isLittleEndian = acc_.GetValueIn(gate, 2); // 2: is little endian mode
|
||||
builder_.IsTaggedBooleanCheck(isLittleEndian);
|
||||
ret = builder_.DataViewGet(thisObj, index, dataViewCallID, isLittleEndian, frameState);
|
||||
}
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
|
||||
}
|
||||
|
||||
void NativeInlineLowering::TryInlineDataViewSet(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id)
|
||||
{
|
||||
if (argc != 1 && argc != 2 && argc != 3) { // number of args must be 1/2/3
|
||||
return;
|
||||
}
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
if (!Uncheck()) {
|
||||
builder_.CallTargetCheck(gate, acc_.GetValueIn(gate, argc + 1), builder_.IntPtr(static_cast<int64_t>(id)));
|
||||
}
|
||||
GateRef thisObj = acc_.GetValueIn(gate, 0); // 0: this
|
||||
builder_.IsEcmaObjectCheck(thisObj);
|
||||
builder_.IsDataViewCheck(thisObj);
|
||||
GateRef dataViewCallID = builder_.Int32(id);
|
||||
GateRef index = acc_.GetValueIn(gate, 1); // 1: index
|
||||
|
||||
GateRef ret = Circuit::NullGate();
|
||||
GateRef frameState = acc_.GetFrameState(gate);
|
||||
if (argc == 1) { // arg counts is 1
|
||||
ret = builder_.DataViewSet(
|
||||
thisObj, index, builder_.Double(base::NAN_VALUE), dataViewCallID, builder_.TaggedFalse(), frameState);
|
||||
} else if (argc == 2) { // arg counts is 2
|
||||
GateRef value = acc_.GetValueIn(gate, 2); // 2: value
|
||||
ret = builder_.DataViewSet(thisObj, index, value, dataViewCallID, builder_.TaggedFalse(), frameState);
|
||||
} else if (argc == 3) { // arg counts is 3
|
||||
GateRef value = acc_.GetValueIn(gate, 2); // 2: value
|
||||
GateRef isLittleEndian = acc_.GetValueIn(gate, 3); // 3: is little endian mode
|
||||
builder_.IsTaggedBooleanCheck(isLittleEndian);
|
||||
ret = builder_.DataViewSet(thisObj, index, value, dataViewCallID, isLittleEndian, frameState);
|
||||
}
|
||||
acc_.ReplaceHirAndDeleteIfException(gate, builder_.GetStateDepend(), ret);
|
||||
}
|
||||
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -16,10 +16,14 @@
|
||||
#ifndef ECMASCRIPT_COMPILER_BUILTIN_INLINE_H
|
||||
#define ECMASCRIPT_COMPILER_BUILTIN_INLINE_H
|
||||
|
||||
#include "ecmascript/compiler/builtins/builtins_call_signature.h"
|
||||
#include "ecmascript/compiler/circuit_builder.h"
|
||||
#include "ecmascript/compiler/gate_accessor.h"
|
||||
#include "ecmascript/compiler/graph_linearizer.h"
|
||||
#include "ecmascript/compiler/pass_manager.h"
|
||||
#include "ecmascript/compiler/share_gate_meta_data.h"
|
||||
#include "ecmascript/compiler/type_info_accessors.h"
|
||||
#include "ecmascript/js_dataview.h"
|
||||
#include "ecmascript/ts_types/ts_manager.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
@ -55,6 +59,9 @@ private:
|
||||
void TryInlineMathMinMaxBuiltin(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, const GateMetaData* op,
|
||||
double defaultValue, bool skipThis);
|
||||
void TryInlineMathClz32Builtin(GateRef gate, size_t argc, bool skipThis);
|
||||
void TryInlineArrayBufferIsView(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id, bool skipThis);
|
||||
void TryInlineDataViewGet(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id);
|
||||
void TryInlineDataViewSet(GateRef gate, size_t argc, BuiltinsStubCSigns::ID id);
|
||||
|
||||
bool EnableLog() const
|
||||
{
|
||||
|
@ -14,11 +14,17 @@
|
||||
*/
|
||||
|
||||
#include "ecmascript/compiler/number_speculative_retype.h"
|
||||
|
||||
#include "ecmascript/compiler/builtins/builtins_call_signature.h"
|
||||
#include "ecmascript/compiler/circuit.h"
|
||||
#include "ecmascript/compiler/circuit_builder-inl.h"
|
||||
#include "ecmascript/compiler/share_gate_meta_data.h"
|
||||
#include "ecmascript/compiler/circuit_builder.h"
|
||||
#include "ecmascript/compiler/number_gate_info.h"
|
||||
#include "ecmascript/compiler/rt_call_signature.h"
|
||||
#include "ecmascript/compiler/share_gate_meta_data.h"
|
||||
#include "ecmascript/compiler/share_opcodes.h"
|
||||
#include "ecmascript/compiler/type.h"
|
||||
#include <cstdint>
|
||||
#include "ecmascript/compiler/variable_type.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
GateRef NumberSpeculativeRetype::SetOutputType(GateRef gate, GateType gateType)
|
||||
@ -216,6 +222,10 @@ GateRef NumberSpeculativeRetype::VisitGate(GateRef gate)
|
||||
return VisitGlobalBuiltin<true>(gate);
|
||||
case OpCode::MATH_IMUL:
|
||||
return VisitMathImul(gate);
|
||||
case OpCode::DATA_VIEW_GET:
|
||||
return VisitDataViewGet(gate);
|
||||
case OpCode::DATA_VIEW_SET:
|
||||
return VisitDataViewSet(gate);
|
||||
case OpCode::JS_BYTECODE:
|
||||
case OpCode::RUNTIME_CALL:
|
||||
case OpCode::PRIMITIVE_TYPE_CHECK:
|
||||
@ -940,6 +950,38 @@ GateRef NumberSpeculativeRetype::TryConvertConstant(GateRef gate, bool needInt32
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
|
||||
GateRef NumberSpeculativeRetype::TryConvertConstantToInt32(GateRef gate)
|
||||
{
|
||||
if (acc_.GetOpCode(gate) != OpCode::CONSTANT) {
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
|
||||
if (acc_.GetGateType(gate).IsNJSValueType()) {
|
||||
MachineType mType = acc_.GetMachineType(gate);
|
||||
if (mType == MachineType::I32) {
|
||||
int32_t rawValue = acc_.GetInt32FromConstant(gate);
|
||||
return builder_.Int32(rawValue);
|
||||
} else if (mType == MachineType::F64) {
|
||||
double rawValue = acc_.GetFloat64FromConstant(gate);
|
||||
int32_t int32Value = base::NumberHelper::DoubleInRangeInt32(rawValue);
|
||||
return builder_.Int32(int32Value);
|
||||
} else {
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
}
|
||||
|
||||
JSTaggedValue value(acc_.GetConstantValue(gate));
|
||||
if (value.IsInt()) {
|
||||
int32_t rawValue = value.GetInt();
|
||||
return builder_.Int32(rawValue);
|
||||
} else if (value.IsDouble()) {
|
||||
double rawValue = value.GetDouble();
|
||||
int32_t int32Value = base::NumberHelper::DoubleInRangeInt32(rawValue);
|
||||
return builder_.Int32(int32Value);
|
||||
}
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
|
||||
GateRef NumberSpeculativeRetype::CheckAndConvertToInt32(GateRef gate, GateType gateType, ConvertSupport support,
|
||||
OpType type)
|
||||
{
|
||||
@ -1006,6 +1048,70 @@ GateRef NumberSpeculativeRetype::CheckAndConvertToInt32(GateRef gate, GateType g
|
||||
return result;
|
||||
}
|
||||
|
||||
GateRef NumberSpeculativeRetype::CheckBoundAndConvertToInt32(GateRef gate, ConvertSupport support, OpType type)
|
||||
{
|
||||
auto result = TryConvertConstantToInt32(gate);
|
||||
GateType gateType = acc_.GetGateType(gate);
|
||||
if (result != Circuit::NullGate()) {
|
||||
acc_.DeleteGateIfNoUse(gate);
|
||||
ResizeAndSetTypeInfo(result, TypeInfo::INT32);
|
||||
return result;
|
||||
}
|
||||
TypeInfo output = GetOutputTypeInfo(gate);
|
||||
switch (output) {
|
||||
case TypeInfo::INT1:
|
||||
result = builder_.ConvertBoolToInt32(gate, support);
|
||||
break;
|
||||
case TypeInfo::CHAR:
|
||||
case TypeInfo::INT32:
|
||||
return gate;
|
||||
case TypeInfo::UINT32: {
|
||||
result = builder_.CheckUInt32AndConvertToInt32(gate);
|
||||
break;
|
||||
}
|
||||
case TypeInfo::FLOAT64: {
|
||||
result = builder_.DoubleCheckINFInRangeInt32(gate);
|
||||
break;
|
||||
}
|
||||
case TypeInfo::HOLE_INT:
|
||||
result = builder_.CheckHoleIntAndConvertToInt32(gate);
|
||||
break;
|
||||
case TypeInfo::HOLE_DOUBLE:
|
||||
result = builder_.CheckHoleDoubleAndConvertToInt32(gate);
|
||||
break;
|
||||
case TypeInfo::NONE:
|
||||
case TypeInfo::TAGGED: {
|
||||
if (gateType.IsIntType()) {
|
||||
result = builder_.CheckTaggedIntAndConvertToInt32(gate);
|
||||
} else if (gateType.IsDoubleType()) {
|
||||
GateRef doubleValue = builder_.CheckTaggedDoubleAndConvertToFloat64(gate);
|
||||
result = builder_.DoubleInRangeInt32(doubleValue);
|
||||
} else if (gateType.IsNullType()) {
|
||||
result = builder_.CheckNullAndConvertToInt32(gate);
|
||||
} else if (gateType.IsBooleanType()) {
|
||||
result = builder_.CheckTaggedBooleanAndConvertToInt32(gate);
|
||||
} else if (gateType.IsUndefinedType()) {
|
||||
if (type == OpType::SHIFT_AND_LOGICAL) {
|
||||
result = builder_.CheckUndefinedAndConvertToInt32(gate);
|
||||
} else {
|
||||
LOG_ECMA(FATAL) << "undefined cannot convert to int type";
|
||||
}
|
||||
} else {
|
||||
GateRef doubleValue = builder_.CheckTaggedNumberAndConvertToFloat64(gate);
|
||||
result = builder_.DoubleInRangeInt32(doubleValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LOG_ECMA(FATAL) << "this branch is unreachable";
|
||||
UNREACHABLE();
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
}
|
||||
ResizeAndSetTypeInfo(result, TypeInfo::INT32);
|
||||
return result;
|
||||
}
|
||||
|
||||
GateRef NumberSpeculativeRetype::CheckAndConvertToFloat64(GateRef gate, GateType gateType,
|
||||
ConvertToNumber convert)
|
||||
{
|
||||
@ -1047,7 +1153,6 @@ GateRef NumberSpeculativeRetype::CheckAndConvertToFloat64(GateRef gate, GateType
|
||||
} else if (gateType.IsUndefinedType()) {
|
||||
result = builder_.CheckUndefinedAndConvertToFloat64(gate);
|
||||
} else {
|
||||
ASSERT(gateType.IsNumberType());
|
||||
if (convert == ConvertToNumber::ALL) {
|
||||
GateRef glue = acc_.GetGlueFromArgList();
|
||||
GateRef number = builder_.ToNumber(glue, gate, glue);
|
||||
@ -1614,7 +1719,60 @@ GateRef NumberSpeculativeRetype::VisitMathImul(GateRef gate)
|
||||
|
||||
acc_.SetGateType(gate, GateType::NJSValue());
|
||||
acc_.SetMachineType(gate, MachineType::I32);
|
||||
acc_.ReplaceStateIn(gate, builder_.GetState());
|
||||
acc_.ReplaceDependIn(gate, builder_.GetDepend());
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
|
||||
GateRef NumberSpeculativeRetype::VisitDataViewGet(GateRef gate)
|
||||
{
|
||||
GateRef builtinsID = acc_.GetValueIn(gate, 2);
|
||||
auto ID = static_cast<BuiltinsStubCSigns::ID>(acc_.GetConstantValue(builtinsID));
|
||||
if (IsRetype()) {
|
||||
switch (ID) {
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt8:
|
||||
return SetOutputType(gate, GateType::IntType());
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint8:
|
||||
return SetOutputType(gate, GateType::IntType());
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt16:
|
||||
return SetOutputType(gate, GateType::IntType());
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint16:
|
||||
return SetOutputType(gate, GateType::IntType());
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt32:
|
||||
return SetOutputType(gate, GateType::IntType());
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint32:
|
||||
return SetOutputType(gate, TypeInfo::UINT32);
|
||||
case BuiltinsStubCSigns::ID::DataViewGetFloat32:
|
||||
return SetOutputType(gate, GateType::DoubleType());
|
||||
case BuiltinsStubCSigns::ID::DataViewGetFloat64:
|
||||
return SetOutputType(gate, GateType::DoubleType());
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
ASSERT(IsConvert());
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef index = acc_.GetValueIn(gate, 1);
|
||||
GateRef input = CheckBoundAndConvertToInt32(index, ConvertSupport::ENABLE, OpType::SHIFT_AND_LOGICAL);
|
||||
acc_.ReplaceValueIn(gate, input, 1);
|
||||
acc_.ReplaceStateIn(gate, builder_.GetState());
|
||||
acc_.ReplaceDependIn(gate, builder_.GetDepend());
|
||||
return Circuit::NullGate();
|
||||
}
|
||||
|
||||
GateRef NumberSpeculativeRetype::VisitDataViewSet(GateRef gate)
|
||||
{
|
||||
if (IsRetype()) {
|
||||
return SetOutputType(gate, GateType::UndefinedType());
|
||||
}
|
||||
ASSERT(IsConvert());
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef index = acc_.GetValueIn(gate, 1);
|
||||
GateRef inputIndex = CheckBoundAndConvertToInt32(index, ConvertSupport::ENABLE, OpType::SHIFT_AND_LOGICAL);
|
||||
GateRef value = acc_.GetValueIn(gate, 2);
|
||||
GateRef inputValue = CheckAndConvertToFloat64(value, acc_.GetGateType(value), ConvertToNumber::BOOL_ONLY);
|
||||
acc_.ReplaceValueIn(gate, inputIndex, 1); // replace index of dataview to Int32
|
||||
acc_.ReplaceValueIn(gate, inputValue, 2); // replace input value to Double64
|
||||
acc_.ReplaceStateIn(gate, builder_.GetState());
|
||||
acc_.ReplaceDependIn(gate, builder_.GetDepend());
|
||||
return Circuit::NullGate();
|
||||
|
@ -108,6 +108,9 @@ private:
|
||||
GateRef VisitStoreProperty(GateRef gate);
|
||||
GateRef VisitLoadProperty(GateRef gate);
|
||||
GateRef VisitNumberRelated(GateRef gate);
|
||||
GateRef VisitCallBuiltins(GateRef gate);
|
||||
GateRef VisitDataViewGet(GateRef gate);
|
||||
GateRef VisitDataViewSet(GateRef gate);
|
||||
GateRef VisitOthers(GateRef gate);
|
||||
GateRef VisitTypeConvert(GateRef gate);
|
||||
GateRef VisitFrameState(GateRef gate);
|
||||
@ -134,12 +137,16 @@ private:
|
||||
|
||||
GateRef CheckAndConvertToInt32(GateRef gate, GateType gateType, ConvertSupport support = ConvertSupport::ENABLE,
|
||||
OpType type = OpType::NORMAL);
|
||||
GateRef CheckBoundAndConvertToInt32(GateRef gate,
|
||||
ConvertSupport support = ConvertSupport::ENABLE,
|
||||
OpType type = OpType::NORMAL);
|
||||
GateRef CheckAndConvertToFloat64(GateRef gate, GateType gateType,
|
||||
ConvertToNumber convert = ConvertToNumber::BOOL_ONLY);
|
||||
GateRef CheckAndConvertToTagged(GateRef gate, GateType gateType, ConvertToNumber convert);
|
||||
GateRef CheckAndConvertToBool(GateRef gate, GateType gateType);
|
||||
GateRef ConvertToTagged(GateRef gate);
|
||||
GateRef TryConvertConstant(GateRef gate, bool needInt32);
|
||||
GateRef TryConvertConstantToInt32(GateRef gate);
|
||||
GateRef ConvertTaggedToNJSValue(GateRef gate, TypeInfo output);
|
||||
TypeInfo GetOuputForPhi(GateRef gate, bool ignoreConstant);
|
||||
|
||||
|
@ -114,6 +114,12 @@ enum class TypedCallTargetCheckOp : uint8_t;
|
||||
V(IsNotUndefinedOrHole, ISNOTUNDEFINEDORHOLE) \
|
||||
V(BuiltinInliningTypeGuard, BUILTIN_INLINING_TYPE_GUARD) \
|
||||
V(OsrLoopExit, OSRLOOPEXIT) \
|
||||
V(IsNotEcmaObject, ISNOTECMAOBJECT) \
|
||||
V(IsNotDataView, ISNOTDATAVIEW) \
|
||||
V(IsNotTaggedBoolean, ISNOTTAGGEDBOOLEAN) \
|
||||
V(IndexLessZeroOrInfinity, INDEXLESSZEROORINFINITY) \
|
||||
V(ArrayBufferIsDetached, ARRAYBUFFERISDETACHED) \
|
||||
V(TotalSizeOverflow, TOTALSIZEOVERFLOW)
|
||||
|
||||
enum class DeoptType : uint8_t {
|
||||
NOTCHECK = 0,
|
||||
|
@ -136,7 +136,7 @@ namespace panda::ecmascript::kungfu {
|
||||
MCR_GATE_OPCODE_LIST(V) \
|
||||
HCR_GATE_OPCODE_LIST(V)
|
||||
|
||||
enum class OpCode : uint8_t {
|
||||
enum class OpCode : uint16_t {
|
||||
NOP = 0,
|
||||
#define DECLARE_GATE_OPCODE(NAME, OP, R, S, D, V) OP,
|
||||
IMMUTABLE_META_DATA_CACHE_LIST(DECLARE_GATE_OPCODE)
|
||||
|
@ -13,8 +13,26 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "ecmascript/compiler/typed_native_inline_lowering.h"
|
||||
#include "ecmascript/compiler/circuit_builder_helper.h"
|
||||
#include "ecmascript/base/number_helper.h"
|
||||
#include "ecmascript/builtins/builtins_errors.h"
|
||||
#include "ecmascript/byte_array.h"
|
||||
#include "ecmascript/compiler/assembler/assembler.h"
|
||||
#include "ecmascript/compiler/builtins/builtins_call_signature.h"
|
||||
#include "ecmascript/compiler/circuit.h"
|
||||
#include "ecmascript/compiler/circuit_builder-inl.h"
|
||||
#include "ecmascript/compiler/circuit_builder.h"
|
||||
#include "ecmascript/compiler/circuit_builder_helper.h"
|
||||
#include "ecmascript/compiler/gate.h"
|
||||
#include "ecmascript/compiler/rt_call_signature.h"
|
||||
#include "ecmascript/compiler/share_gate_meta_data.h"
|
||||
#include "ecmascript/compiler/share_opcodes.h"
|
||||
#include "ecmascript/compiler/variable_type.h"
|
||||
#include "ecmascript/js_arraybuffer.h"
|
||||
#include "ecmascript/js_dataview.h"
|
||||
#include "ecmascript/js_hclass.h"
|
||||
#include "ecmascript/js_native_pointer.h"
|
||||
#include "ecmascript/message_string.h"
|
||||
#include "macros.h"
|
||||
|
||||
namespace panda::ecmascript::kungfu {
|
||||
GateRef TypedNativeInlineLowering::VisitGate(GateRef gate)
|
||||
@ -151,6 +169,15 @@ GateRef TypedNativeInlineLowering::VisitGate(GateRef gate)
|
||||
case OpCode::GLOBAL_IS_NAN:
|
||||
LowerGlobalIsNan(gate);
|
||||
break;
|
||||
case OpCode::DATA_VIEW_GET:
|
||||
LowerDataViewProtoFunc(gate, DataViewProtoFunc::GET);
|
||||
break;
|
||||
case OpCode::DATA_VIEW_SET:
|
||||
LowerDataViewProtoFunc(gate, DataViewProtoFunc::SET);
|
||||
break;
|
||||
case OpCode::ARRAY_BUFFER_IS_VIEW:
|
||||
LowerArrayBufferIsView(gate);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -835,6 +862,461 @@ void TypedNativeInlineLowering::LowerMathSqrt(GateRef gate)
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), ret);
|
||||
}
|
||||
|
||||
void TypedNativeInlineLowering::LowerArrayBufferIsView(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
|
||||
GateRef arg = acc_.GetValueIn(gate, 0);
|
||||
DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.TaggedFalse());
|
||||
Label exit(&builder_);
|
||||
Label isDataViewOrTypedArray(&builder_);
|
||||
Label returnTaggedTrue(&builder_);
|
||||
BRANCH_CIR(builder_.IsEcmaObject(arg), &isDataViewOrTypedArray, &exit);
|
||||
builder_.Bind(&isDataViewOrTypedArray);
|
||||
{
|
||||
GateRef isDataView = builder_.CheckJSType(arg, JSType::JS_DATA_VIEW);
|
||||
GateRef isTypedArray = builder_.TaggedObjectIsTypedArray(arg);
|
||||
BRANCH_CIR(builder_.BoolOr(isDataView, isTypedArray), &returnTaggedTrue, &exit);
|
||||
}
|
||||
builder_.Bind(&returnTaggedTrue);
|
||||
{
|
||||
result = builder_.TaggedTrue();
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
void TypedNativeInlineLowering::LowerDataViewProtoFunc(GateRef gate, DataViewProtoFunc func)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
|
||||
Label isNotDetachedBuffer(&builder_);
|
||||
Label isNotByteArray(&builder_);
|
||||
Label getPointFromByteArray(&builder_);
|
||||
Label getPointFromNotByteArray(&builder_);
|
||||
Label getValueFromBuffer(&builder_);
|
||||
Label bufferByteLengthIsZero(&builder_);
|
||||
Label bufferByteLengthIsNotZero(&builder_);
|
||||
GateRef thisobj = acc_.GetValueIn(gate, 0);
|
||||
GateRef requestIndex = acc_.GetValueIn(gate, 1); // 1: requestIndex
|
||||
GateRef builtinId = Circuit::NullGate();
|
||||
GateRef isLittleEndian = Circuit::NullGate();
|
||||
GateRef frameState = Circuit::NullGate();
|
||||
ASSERT(func == DataViewProtoFunc::GET || func == DataViewProtoFunc::SET);
|
||||
if (func == DataViewProtoFunc::GET) {
|
||||
builtinId = acc_.GetValueIn(gate, 2); // 2: builtinId
|
||||
isLittleEndian = acc_.GetValueIn(gate, 3); // 3: isLittleEndian
|
||||
frameState = acc_.GetValueIn(gate, 4); // 4: frameState
|
||||
} else if (func == DataViewProtoFunc::SET) {
|
||||
builtinId = acc_.GetValueIn(gate, 3); // 3: builtinId
|
||||
isLittleEndian = acc_.GetValueIn(gate, 4); // 4: isLittleEndian
|
||||
frameState = acc_.GetValueIn(gate, 5); // 5: frameState
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
GateRef resultfinal = Circuit::NullGate();
|
||||
|
||||
DEFVALUE(dataPointer, (&builder_), VariableType::NATIVE_POINTER(), builder_.IntPtr(0));
|
||||
|
||||
builder_.DeoptCheck(builder_.Int32UnsignedLessThan(requestIndex, builder_.Int32(INT32_MAX)),
|
||||
frameState,
|
||||
DeoptType::INDEXLESSZEROORINFINITY);
|
||||
GateRef viewedArrayBufferOffset = builder_.IntPtr(JSDataView::VIEW_ARRAY_BUFFER_OFFSET);
|
||||
GateRef buffer = builder_.Load(VariableType::JS_ANY(), thisobj, viewedArrayBufferOffset);
|
||||
BRANCH_CIR(builder_.CheckJSType(buffer, JSType::BYTE_ARRAY), &isNotDetachedBuffer, &isNotByteArray);
|
||||
builder_.Bind(&isNotByteArray);
|
||||
{
|
||||
GateRef dataOffset = builder_.IntPtr(JSArrayBuffer::DATA_OFFSET);
|
||||
GateRef dataSlot = builder_.Load(VariableType::JS_ANY(), buffer, dataOffset);
|
||||
builder_.DeoptCheck(builder_.TaggedIsNotNull(dataSlot), frameState, DeoptType::ARRAYBUFFERISDETACHED);
|
||||
builder_.Jump(&isNotDetachedBuffer);
|
||||
}
|
||||
builder_.Bind(&isNotDetachedBuffer);
|
||||
GateRef byteOffset = builder_.IntPtr(JSDataView::BYTE_OFFSET_OFFSET);
|
||||
GateRef offset = builder_.Load(VariableType::INT32(), thisobj, byteOffset);
|
||||
GateRef sizeOffset = builder_.IntPtr(JSDataView::BYTE_LENGTH_OFFSET);
|
||||
GateRef size = builder_.Load(VariableType::INT32(), thisobj, sizeOffset);
|
||||
GateRef elementSize = BuiltinIdToSize(builtinId);
|
||||
GateRef totalSize = builder_.Int32Add(requestIndex, elementSize);
|
||||
|
||||
builder_.DeoptCheck(builder_.Int32LessThan(totalSize, size), frameState, DeoptType::TOTALSIZEOVERFLOW);
|
||||
GateRef bufferIndex = builder_.Int32Add(requestIndex, offset);
|
||||
BRANCH_CIR(builder_.CheckJSType(buffer, JSType::BYTE_ARRAY), &getPointFromByteArray, &getPointFromNotByteArray);
|
||||
builder_.Bind(&getPointFromByteArray);
|
||||
{
|
||||
dataPointer = builder_.Load(VariableType::NATIVE_POINTER(), buffer, builder_.IntPtr(ByteArray::DATA_OFFSET));
|
||||
builder_.Jump(&getValueFromBuffer);
|
||||
}
|
||||
builder_.Bind(&getPointFromNotByteArray);
|
||||
{
|
||||
GateRef arrayBufferByteLengthOffset = builder_.IntPtr(JSArrayBuffer::BYTE_LENGTH_OFFSET);
|
||||
GateRef arrayBufferByteLength = builder_.Load(VariableType::INT32(), buffer, arrayBufferByteLengthOffset);
|
||||
BRANCH_CIR(builder_.Int32Equal(arrayBufferByteLength, builder_.Int32(0)),
|
||||
&bufferByteLengthIsZero,
|
||||
&bufferByteLengthIsNotZero);
|
||||
builder_.Bind(&bufferByteLengthIsZero);
|
||||
{
|
||||
dataPointer = builder_.IntPtr(0);
|
||||
builder_.Jump(&getValueFromBuffer);
|
||||
}
|
||||
builder_.Bind(&bufferByteLengthIsNotZero);
|
||||
{
|
||||
GateRef bufferDataOffset = builder_.IntPtr(JSArrayBuffer::DATA_OFFSET);
|
||||
GateRef data = builder_.Load(VariableType::JS_ANY(), buffer, bufferDataOffset);
|
||||
GateRef externalPointerOffset = builder_.IntPtr(JSNativePointer::POINTER_OFFSET);
|
||||
GateRef externalPointer = builder_.Load(VariableType::NATIVE_POINTER(), data, externalPointerOffset);
|
||||
dataPointer = externalPointer;
|
||||
builder_.Jump(&getValueFromBuffer);
|
||||
}
|
||||
}
|
||||
builder_.Bind(&getValueFromBuffer);
|
||||
ASSERT(func == DataViewProtoFunc::GET || func == DataViewProtoFunc::SET);
|
||||
if (func == DataViewProtoFunc::GET) {
|
||||
resultfinal = GetValueFromBuffer(bufferIndex, *dataPointer, isLittleEndian, builtinId);
|
||||
} else if (func == DataViewProtoFunc::SET) {
|
||||
GateRef value = acc_.GetValueIn(gate, 2); // 2: value
|
||||
resultfinal =
|
||||
SetValueInBuffer(bufferIndex, value, *dataPointer, isLittleEndian, builtinId, acc_.GetGlueFromArgList());
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), resultfinal);
|
||||
}
|
||||
|
||||
GateRef TypedNativeInlineLowering::BuiltinIdToSize(GateRef ID)
|
||||
{
|
||||
auto builtinsID = static_cast<BuiltinsStubCSigns::ID>(acc_.GetConstantValue(ID));
|
||||
switch (builtinsID) {
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt8:
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint8:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetUint8:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetInt8:
|
||||
return builder_.Int32(ElmentSize::BITS_8);
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt16:
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint16:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetInt16:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetUint16:
|
||||
return builder_.Int32(ElmentSize::BITS_16);
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint32:
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt32:
|
||||
case BuiltinsStubCSigns::ID::DataViewGetFloat32:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetUint32:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetInt32:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetFloat32:
|
||||
return builder_.Int32(ElmentSize::BITS_32);
|
||||
case BuiltinsStubCSigns::ID::DataViewGetFloat64:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetFloat64:
|
||||
return builder_.Int32(ElmentSize::BITS_64);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
GateRef TypedNativeInlineLowering::GetValueFromBuffer(GateRef bufferIndex,
|
||||
GateRef dataPointer,
|
||||
GateRef isLittleEndian,
|
||||
GateRef ID)
|
||||
{
|
||||
Label entry(&builder_);
|
||||
builder_.SubCfgEntry(&entry);
|
||||
Label exit(&builder_);
|
||||
Label littleEndian(&builder_);
|
||||
Label bigEndian(&builder_);
|
||||
Label passResult(&builder_);
|
||||
GateRef finalResult = builder_.NullConstant();
|
||||
BuiltinsStubCSigns::ID builtinsID = static_cast<BuiltinsStubCSigns::ID>(acc_.GetConstantValue(ID));
|
||||
switch (builtinsID) {
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint8: {
|
||||
GateRef uint8Res = builder_.Load(VariableType::INT8(), dataPointer, builder_.ZExtInt32ToPtr(bufferIndex));
|
||||
finalResult = builder_.ZExtInt8ToInt64(uint8Res);
|
||||
builder_.Jump(&exit);
|
||||
break;
|
||||
}
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt8: {
|
||||
GateRef int8res = builder_.Load(VariableType::INT8(), dataPointer, builder_.ZExtInt32ToPtr(bufferIndex));
|
||||
finalResult = builder_.SExtInt8ToInt64(int8res);
|
||||
builder_.Jump(&exit);
|
||||
break;
|
||||
}
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint16: {
|
||||
DEFVALUE(tempRes, (&builder_), VariableType::INT32(), builder_.Int32(0));
|
||||
GateRef uint16Res = builder_.Load(VariableType::INT16(), dataPointer, builder_.ZExtInt32ToPtr(bufferIndex));
|
||||
BRANCH_CIR(builder_.TaggedIsFalse(isLittleEndian), &bigEndian, &littleEndian);
|
||||
builder_.Bind(&littleEndian);
|
||||
{
|
||||
tempRes = builder_.ZExtInt16ToInt32(uint16Res);
|
||||
builder_.Jump(&passResult);
|
||||
}
|
||||
builder_.Bind(&bigEndian);
|
||||
{
|
||||
GateRef bigEndianInt16 = builder_.Int16ToBigEndianInt16(uint16Res);
|
||||
tempRes = builder_.ZExtInt16ToInt32(bigEndianInt16);
|
||||
builder_.Jump(&passResult);
|
||||
}
|
||||
builder_.Bind(&passResult);
|
||||
{
|
||||
finalResult = *tempRes;
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt16: {
|
||||
DEFVALUE(tempRes, (&builder_), VariableType::INT16(), builder_.Int16(0));
|
||||
GateRef int16Res = builder_.Load(VariableType::INT16(), dataPointer, builder_.ZExtInt32ToPtr(bufferIndex));
|
||||
BRANCH_CIR(builder_.TaggedIsFalse(isLittleEndian), &bigEndian, &littleEndian);
|
||||
builder_.Bind(&littleEndian);
|
||||
{
|
||||
tempRes = int16Res;
|
||||
builder_.Jump(&passResult);
|
||||
}
|
||||
builder_.Bind(&bigEndian);
|
||||
{
|
||||
tempRes = builder_.Int16ToBigEndianInt16(int16Res);
|
||||
builder_.Jump(&passResult);
|
||||
}
|
||||
builder_.Bind(&passResult);
|
||||
{
|
||||
finalResult = *tempRes;
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BuiltinsStubCSigns::ID::DataViewGetUint32: {
|
||||
DEFVALUE(tempRes, (&builder_), VariableType::INT32(), builder_.Int32(0));
|
||||
GateRef uint32Res = builder_.Load(VariableType::INT32(), dataPointer, builder_.ZExtInt32ToPtr(bufferIndex));
|
||||
BRANCH_CIR(builder_.TaggedIsFalse(isLittleEndian), &bigEndian, &littleEndian);
|
||||
builder_.Bind(&littleEndian);
|
||||
{
|
||||
tempRes = uint32Res;
|
||||
builder_.Jump(&passResult);
|
||||
}
|
||||
builder_.Bind(&bigEndian);
|
||||
{
|
||||
tempRes = builder_.Int32ToBigEndianInt32(uint32Res);
|
||||
builder_.Jump(&passResult);
|
||||
}
|
||||
builder_.Bind(&passResult);
|
||||
{
|
||||
finalResult = *tempRes;
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BuiltinsStubCSigns::ID::DataViewGetInt32: {
|
||||
DEFVALUE(tempRes, (&builder_), VariableType::INT32(), builder_.Int32(0));
|
||||
GateRef int32Res = builder_.Load(VariableType::INT32(), dataPointer, builder_.ZExtInt32ToPtr(bufferIndex));
|
||||
BRANCH_CIR(builder_.TaggedIsFalse(isLittleEndian), &bigEndian, &littleEndian);
|
||||
builder_.Bind(&littleEndian);
|
||||
{
|
||||
tempRes = int32Res;
|
||||
builder_.Jump(&passResult);
|
||||
}
|
||||
builder_.Bind(&bigEndian);
|
||||
{
|
||||
tempRes = builder_.Int32ToBigEndianInt32(int32Res);
|
||||
builder_.Jump(&passResult);
|
||||
}
|
||||
builder_.Bind(&passResult);
|
||||
{
|
||||
finalResult = *tempRes;
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BuiltinsStubCSigns::ID::DataViewGetFloat32: {
|
||||
DEFVALUE(tempRes, (&builder_), VariableType::FLOAT64(), builder_.Double(base::NAN_VALUE));
|
||||
Label notNaN(&builder_);
|
||||
GateRef int32Res = builder_.Load(VariableType::INT32(), dataPointer, builder_.ZExtInt32ToPtr(bufferIndex));
|
||||
BRANCH_CIR(builder_.TaggedIsFalse(isLittleEndian), &bigEndian, &littleEndian);
|
||||
builder_.Bind(&littleEndian);
|
||||
{
|
||||
GateRef float32Res = builder_.CastInt32ToFloat32(int32Res);
|
||||
tempRes = builder_.ExtFloat32ToDouble(float32Res);
|
||||
builder_.Jump(&passResult);
|
||||
}
|
||||
builder_.Bind(&bigEndian);
|
||||
{
|
||||
GateRef originFloat32Res = builder_.CastInt32ToFloat32(int32Res);
|
||||
GateRef originDoubleRes = builder_.ExtFloat32ToDouble(originFloat32Res);
|
||||
BRANCH_CIR(builder_.DoubleIsNAN(originDoubleRes), &passResult, ¬NaN);
|
||||
builder_.Bind(¬NaN);
|
||||
{
|
||||
GateRef bigEndianInt32Res = builder_.Int32ToBigEndianInt32(int32Res);
|
||||
GateRef float32Res = builder_.CastInt32ToFloat32(bigEndianInt32Res);
|
||||
tempRes = builder_.ExtFloat32ToDouble(float32Res);
|
||||
builder_.Jump(&passResult);
|
||||
}
|
||||
}
|
||||
builder_.Bind(&passResult);
|
||||
{
|
||||
finalResult = *tempRes;
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BuiltinsStubCSigns::ID::DataViewGetFloat64: {
|
||||
DEFVALUE(tempRes, (&builder_), VariableType::FLOAT64(), builder_.Double(base::NAN_VALUE));
|
||||
Label notNaN(&builder_);
|
||||
GateRef int64Res = builder_.Load(VariableType::INT64(), dataPointer, builder_.ZExtInt32ToPtr(bufferIndex));
|
||||
BRANCH_CIR(builder_.TaggedIsFalse(isLittleEndian), &bigEndian, &littleEndian);
|
||||
builder_.Bind(&littleEndian);
|
||||
{
|
||||
tempRes = builder_.CastInt64ToFloat64(int64Res);
|
||||
builder_.Jump(&passResult);
|
||||
}
|
||||
builder_.Bind(&bigEndian);
|
||||
{
|
||||
GateRef originFloat64Res = builder_.CastInt64ToFloat64(int64Res);
|
||||
BRANCH_CIR(builder_.DoubleIsNAN(originFloat64Res), &passResult, ¬NaN);
|
||||
builder_.Bind(¬NaN);
|
||||
{
|
||||
GateRef bigEndianInt64Res = builder_.Int64ToBigEndianInt64(int64Res);
|
||||
tempRes = builder_.CastInt64ToFloat64(bigEndianInt64Res);
|
||||
builder_.Jump(&passResult);
|
||||
}
|
||||
}
|
||||
builder_.Bind(&passResult);
|
||||
{
|
||||
finalResult = *tempRes;
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
builder_.SubCfgExit();
|
||||
return finalResult;
|
||||
}
|
||||
|
||||
GateRef TypedNativeInlineLowering::SetValueInBuffer(
|
||||
GateRef bufferIndex, GateRef value, GateRef dataPointer, GateRef isLittleEndian, GateRef ID, GateRef glue)
|
||||
{
|
||||
Label entry(&builder_);
|
||||
builder_.SubCfgEntry(&entry);
|
||||
Label exit(&builder_);
|
||||
|
||||
Label littleEndian(&builder_);
|
||||
Label bigEndian(&builder_);
|
||||
Label passResult(&builder_);
|
||||
GateRef offset = builder_.ZExtInt32ToPtr(bufferIndex);
|
||||
GateRef int64Value = builder_.TruncFloatToInt64(value);
|
||||
BuiltinsStubCSigns::ID builtinsID = static_cast<BuiltinsStubCSigns::ID>(acc_.GetConstantValue(ID));
|
||||
|
||||
switch (builtinsID) {
|
||||
case BuiltinsStubCSigns::ID::DataViewSetUint8:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetInt8: {
|
||||
GateRef int32Value = builder_.TruncInt64ToInt32(int64Value);
|
||||
builder_.Store(VariableType::INT8(), glue, dataPointer, offset, builder_.TruncInt32ToInt8(int32Value));
|
||||
builder_.Jump(&exit);
|
||||
break;
|
||||
}
|
||||
case BuiltinsStubCSigns::ID::DataViewSetUint16:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetInt16: {
|
||||
BRANCH_CIR(builder_.TaggedIsTrue(isLittleEndian), &littleEndian, &bigEndian);
|
||||
builder_.Bind(&littleEndian);
|
||||
{
|
||||
builder_.Store(
|
||||
VariableType::INT16(), glue, dataPointer, offset, builder_.TruncInt64ToInt16(int64Value));
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&bigEndian);
|
||||
{
|
||||
GateRef int16Value = builder_.TruncInt64ToInt16(int64Value);
|
||||
GateRef bigEndianInt16 = builder_.Int16ToBigEndianInt16(int16Value);
|
||||
builder_.Store(VariableType::INT16(), glue, dataPointer, offset, bigEndianInt16);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BuiltinsStubCSigns::ID::DataViewSetFloat32: {
|
||||
Label isNaN(&builder_);
|
||||
Label notNaN(&builder_);
|
||||
GateRef float32Value = builder_.TruncDoubleToFloat32(value);
|
||||
BRANCH_CIR(builder_.DoubleIsNAN(value), &isNaN, ¬NaN);
|
||||
builder_.Bind(&isNaN);
|
||||
{
|
||||
builder_.Store(VariableType::FLOAT32(), glue, dataPointer, offset, float32Value);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(¬NaN);
|
||||
{
|
||||
BRANCH_CIR(builder_.TaggedIsTrue(isLittleEndian), &littleEndian, &bigEndian);
|
||||
builder_.Bind(&littleEndian);
|
||||
{
|
||||
builder_.Store(VariableType::FLOAT32(), glue, dataPointer, offset, float32Value);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&bigEndian);
|
||||
{
|
||||
GateRef int32Value = builder_.CaseFloat32ToInt32(float32Value);
|
||||
GateRef bigEndianInt32Value = builder_.Int32ToBigEndianInt32(int32Value);
|
||||
GateRef bigEndianFloat32Value = builder_.CastInt32ToFloat32(bigEndianInt32Value);
|
||||
builder_.Store(VariableType::FLOAT32(), glue, dataPointer, offset, bigEndianFloat32Value);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BuiltinsStubCSigns::ID::DataViewSetInt32:
|
||||
case BuiltinsStubCSigns::ID::DataViewSetUint32: {
|
||||
BRANCH_CIR(builder_.TaggedIsTrue(isLittleEndian), &littleEndian, &bigEndian);
|
||||
builder_.Bind(&littleEndian);
|
||||
{
|
||||
builder_.Store(
|
||||
VariableType::INT32(), glue, dataPointer, offset, builder_.TruncInt64ToInt32(int64Value));
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&bigEndian);
|
||||
{
|
||||
GateRef int32Value = builder_.TruncInt64ToInt32(int64Value);
|
||||
GateRef bigEndianInt32 = builder_.Int32ToBigEndianInt32(int32Value);
|
||||
builder_.Store(VariableType::INT32(), glue, dataPointer, offset, bigEndianInt32);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BuiltinsStubCSigns::ID::DataViewSetFloat64: {
|
||||
Label isNaN(&builder_);
|
||||
Label notNaN(&builder_);
|
||||
BRANCH_CIR(builder_.DoubleIsNAN(value), &isNaN, ¬NaN);
|
||||
{
|
||||
builder_.Bind(&isNaN);
|
||||
{
|
||||
builder_.Store(VariableType::FLOAT64(), glue, dataPointer, offset, value);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(¬NaN);
|
||||
{
|
||||
BRANCH_CIR(builder_.TaggedIsTrue(isLittleEndian), &littleEndian, &bigEndian);
|
||||
builder_.Bind(&littleEndian);
|
||||
{
|
||||
builder_.Store(VariableType::FLOAT64(), glue, dataPointer, offset, value);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
builder_.Bind(&bigEndian);
|
||||
{
|
||||
GateRef int64bitsValue = builder_.CastDoubleToInt64(value);
|
||||
GateRef bigEndianInt64Value = builder_.Int64ToBigEndianInt64(int64bitsValue);
|
||||
GateRef float64Value = builder_.CastInt64ToFloat64(bigEndianInt64Value);
|
||||
builder_.Store(VariableType::FLOAT64(), glue, dataPointer, offset, float64Value);
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
builder_.Bind(&exit);
|
||||
builder_.SubCfgExit();
|
||||
return builder_.UndefineConstant();
|
||||
}
|
||||
|
||||
static void BuildMathSignDouble(Variable *resVarPtr, CircuitBuilder *builder, GateRef param,
|
||||
std::vector<Label> *labelsForFloatCase)
|
||||
{
|
||||
|
@ -16,9 +16,12 @@
|
||||
#ifndef ECMASCRIPT_COMPILER_TYPED_NATIVE_INLINE_LOWERING_H
|
||||
#define ECMASCRIPT_COMPILER_TYPED_NATIVE_INLINE_LOWERING_H
|
||||
|
||||
#include <cstdint>
|
||||
#include "ecmascript/compiler/circuit.h"
|
||||
#include "ecmascript/compiler/combined_pass_visitor.h"
|
||||
#include "ecmascript/compiler/pass_manager.h"
|
||||
|
||||
#include "ecmascript/compiler/share_gate_meta_data.h"
|
||||
#include "ecmascript/compiler/variable_type.h"
|
||||
namespace panda::ecmascript::kungfu {
|
||||
class TypedNativeInlineLowering : public PassVisitor {
|
||||
public:
|
||||
@ -35,6 +38,10 @@ public:
|
||||
~TypedNativeInlineLowering() = default;
|
||||
GateRef VisitGate(GateRef gate) override;
|
||||
private:
|
||||
enum class DataViewProtoFunc : uint8_t { GET = 0, SET = 1 };
|
||||
|
||||
enum ElmentSize : uint32_t { BITS_8 = 1, BITS_16 = 2, BITS_32 = 4, BITS_64 = 8 };
|
||||
|
||||
void LowerGeneralUnaryMath(GateRef gate, RuntimeStubCSigns::ID stubId);
|
||||
void LowerMathAtan2(GateRef gate);
|
||||
void LowerTrunc(GateRef gate);
|
||||
@ -54,6 +61,16 @@ private:
|
||||
GateRef BuildRounding(GateRef gate, GateRef value, OpCode op);
|
||||
void LowerTaggedRounding(GateRef gate);
|
||||
void LowerDoubleRounding(GateRef gate);
|
||||
void LowerArrayBufferIsView(GateRef gate);
|
||||
void LowerDataViewProtoFunc(GateRef gate, DataViewProtoFunc proto);
|
||||
GateRef BuiltinIdToSize(GateRef ID);
|
||||
GateRef GetValueFromBuffer(GateRef bufferIndex, GateRef dataPointer, GateRef isLittleEndian, GateRef builtinId);
|
||||
GateRef SetValueInBuffer(GateRef bufferIndex,
|
||||
GateRef value,
|
||||
GateRef dataPointer,
|
||||
GateRef isLittleEndian,
|
||||
GateRef builtinId,
|
||||
GateRef glue);
|
||||
|
||||
GateRef BuildIntAbs(GateRef value);
|
||||
GateRef BuildDoubleAbs(GateRef value);
|
||||
|
@ -76,10 +76,11 @@ inline uintptr_t GlobalEnvConstants::GetGlobalConstantAddr(ConstantIndex index)
|
||||
SHARED_GLOBAL_ENV_CONSTANT_STRING(DECL_GET_IMPL_STRING) // NOLINT(readability-const-return-type)
|
||||
SHARED_GLOBAL_ENV_CONSTANT_ACCESSOR(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
SHARED_GLOBAL_ENV_CONSTANT_SPECIAL(DECL_GET_IMPL_WITH_TYPE); // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CONSTANT_CLASS(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CONSTANT_SPECIAL(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CONSTANT_CONSTANT(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CACHES(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CONSTANT_CLASS(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CONSTANT_SPECIAL(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_INLINED_BUILTINS(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CONSTANT_CONSTANT(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CACHES(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
#undef DECL_GET_IMPL_WITH_TYPE
|
||||
#undef DECL_GET_IMPL_STRING
|
||||
#undef DECL_GET_IMPL_COMMON
|
||||
|
@ -153,7 +153,10 @@ class ObjectFactory;
|
||||
V(JSTaggedValue, EmptyLayoutInfo, EMPTY_LAYOUT_INFO_OBJECT_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DefaultSupers, DEFAULT_SUPERS_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, EmptyTaggedQueue, EMPTY_TAGGED_QUEUE_OBJECT_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, UndefinedCompletionRecord, UNDEFINED_COMPLRTION_RECORD_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, UndefinedCompletionRecord, UNDEFINED_COMPLRTION_RECORD_INDEX, ecma_roots_special)
|
||||
|
||||
// Use for builtins inlining
|
||||
#define GLOBAL_ENV_INLINED_BUILTINS(V) \
|
||||
V(JSTaggedValue, MathSqrt, MATH_SQRT_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, MathAcos, MATH_ACOS_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, MathAcosh, MATH_ACOSH_INDEX, ecma_roots_special) \
|
||||
@ -197,7 +200,24 @@ class ObjectFactory;
|
||||
V(JSTaggedValue, StringIteratorProtoNext, STRING_ITERATOR_PROTO_NEXT_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, ArrayIteratorProtoNext, ARRAY_ITERATOR_PROTO_NEXT_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, IteratorProtoReturn, ITERATOR_PROTO_RETURN_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, StringFromCharCode, STRING_FROM_CHAR_CODE_INDEX, ecma_roots_special)
|
||||
V(JSTaggedValue, StringFromCharCode, STRING_FROM_CHAR_CODE_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, ArrayBufferIsView, ARRAY_BUFFER_IS_VIEW_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewGetFloat32, DATA_VIEW_GET_FLOAT32_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewGetFloat64, DATA_VIEW_GET_FLOAT64_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewGetInt8, DATA_VIEW_GET_INT8_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewGetInt16, DATA_VIEW_GET_INT16_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewGetInt32, DATA_VIEW_GET_INT32_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewGetUint16, DATA_VIEW_GET_UINT16_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewGetUint32, DATA_VIEW_GET_UINT32_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewGetUint8, DATA_VIEW_GET_UINT8_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewSetFloat32, DATA_VIEW_SET_FLOAT32_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewSetFloat64, DATA_VIEW_SET_FLOAT64_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewSetInt8, DATA_VIEW_SET_INT8_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewSetInt16, DATA_VIEW_SET_INT16_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewSetInt32, DATA_VIEW_SET_INT32_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewSetUint8, DATA_VIEW_SET_UINT8_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewSetUint16, DATA_VIEW_SET_UINT16_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DataViewSetUint32, DATA_VIEW_SET_UINT32_INDEX, ecma_roots_special)
|
||||
|
||||
// All of type JSTaggedValue
|
||||
#define SHARED_GLOBAL_ENV_CONSTANT_STRING(V) \
|
||||
@ -567,6 +587,7 @@ enum class ConstantIndex : size_t {
|
||||
SHARED_GLOBAL_ENV_CONSTANT_SPECIAL(INDEX_FILTER_WITH_TYPE)
|
||||
GLOBAL_ENV_CONSTANT_CLASS(INDEX_FILTER_WITH_TYPE)
|
||||
GLOBAL_ENV_CONSTANT_SPECIAL(INDEX_FILTER_WITH_TYPE)
|
||||
GLOBAL_ENV_INLINED_BUILTINS(INDEX_FILTER_WITH_TYPE)
|
||||
GLOBAL_ENV_CONSTANT_CONSTANT(INDEX_FILTER_WITH_TYPE)
|
||||
GLOBAL_ENV_CACHES(INDEX_FILTER_WITH_TYPE)
|
||||
#undef INDEX_FILTER_STRING
|
||||
@ -634,6 +655,7 @@ public:
|
||||
SHARED_GLOBAL_ENV_CONSTANT_SPECIAL(DECL_GET_WITH_TYPE)
|
||||
GLOBAL_ENV_CONSTANT_CLASS(DECL_GET_WITH_TYPE)
|
||||
GLOBAL_ENV_CONSTANT_SPECIAL(DECL_GET_WITH_TYPE)
|
||||
GLOBAL_ENV_INLINED_BUILTINS(DECL_GET_WITH_TYPE)
|
||||
GLOBAL_ENV_CONSTANT_CONSTANT(DECL_GET_WITH_TYPE)
|
||||
GLOBAL_ENV_CACHES(DECL_GET_WITH_TYPE)
|
||||
#undef DECL_GET_STRING
|
||||
|
@ -320,6 +320,7 @@
|
||||
panda::ecmascript::TypeLiteralExtractor::TypeLiteralExtractor*;
|
||||
panda::ecmascript::Unlink*;
|
||||
panda::ecmascript::base::utf_helper::ConvertRegionUtf16ToUtf8*;
|
||||
panda::ecmascript::base::NumberHelper::DoubleInRangeInt32*;
|
||||
panda::ecmascript::kungfu::AOTSnapshot::StoreConstantPoolInfo*;
|
||||
panda::ecmascript::kungfu::ArkStackMapBuilder::Collect*;
|
||||
panda::ecmascript::kungfu::ArkStackMapBuilder::GenerateArkStackMap*;
|
||||
|
Loading…
Reference in New Issue
Block a user