mirror of
https://github.com/openharmony/ark_js_runtime.git
synced 2026-08-27 02:31:17 -04:00
9ccd71388b
Signed-off-by: getingke <getingke@huawei.com> Change-Id: I2f0c61448663bd45f097210dcfe8fc37e4d92f07
524 lines
19 KiB
C++
524 lines
19 KiB
C++
/*
|
|
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "common_stubs.h"
|
|
|
|
#include "ecmascript/base/number_helper.h"
|
|
#include "ecmascript/compiler/llvm_ir_builder.h"
|
|
#include "ecmascript/compiler/variable_type.h"
|
|
#include "ecmascript/js_array.h"
|
|
#include "ecmascript/message_string.h"
|
|
#include "ecmascript/tagged_hash_table.h"
|
|
#include "stub-inl.h"
|
|
|
|
namespace panda::ecmascript::kungfu {
|
|
using namespace panda::ecmascript;
|
|
|
|
#ifndef NDEBUG
|
|
void MulGCTestStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
auto env = GetEnvironment();
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef x = Int64Argument(1);
|
|
GateRef y = Int64Argument(2); // 2: 3rd argument
|
|
|
|
DEFVARIABLE(intX, VariableType::INT64(), Int64(0));
|
|
DEFVARIABLE(intY, VariableType::INT64(), Int64(0));
|
|
DEFVARIABLE(valuePtr, VariableType::INT64(), Int64(0));
|
|
DEFVARIABLE(doubleX, VariableType::FLOAT64(), Double(0));
|
|
DEFVARIABLE(doubleY, VariableType::FLOAT64(), Double(0));
|
|
Label xIsNumber(env);
|
|
Label xNotNumberOryNotNumber(env);
|
|
Label xIsNumberAndyIsNumber(env);
|
|
Label xIsDoubleAndyIsDouble(env);
|
|
Branch(TaggedIsNumber(x), &xIsNumber, &xNotNumberOryNotNumber);
|
|
Bind(&xIsNumber);
|
|
{
|
|
Label yIsNumber(env);
|
|
// if right.IsNumber()
|
|
Branch(TaggedIsNumber(y), &yIsNumber, &xNotNumberOryNotNumber);
|
|
Bind(&yIsNumber);
|
|
{
|
|
Label xIsInt(env);
|
|
Label xNotInt(env);
|
|
Branch(TaggedIsInt(x), &xIsInt, &xNotInt);
|
|
Bind(&xIsInt);
|
|
{
|
|
intX = TaggedCastToInt64(x);
|
|
doubleX = CastInt64ToFloat64(*intX);
|
|
Jump(&xIsNumberAndyIsNumber);
|
|
}
|
|
Bind(&xNotInt);
|
|
{
|
|
doubleX = TaggedCastToDouble(x);
|
|
Jump(&xIsNumberAndyIsNumber);
|
|
}
|
|
}
|
|
}
|
|
Bind(&xNotNumberOryNotNumber);
|
|
Return(Hole(VariableType::JS_ANY()));
|
|
Label yIsInt(env);
|
|
Label yNotInt(env);
|
|
Bind(&xIsNumberAndyIsNumber);
|
|
{
|
|
Branch(TaggedIsInt(y), &yIsInt, &yNotInt);
|
|
Bind(&yIsInt);
|
|
{
|
|
intY = TaggedCastToInt64(y);
|
|
doubleY = CastInt64ToFloat64(*intY);
|
|
Jump(&xIsDoubleAndyIsDouble);
|
|
}
|
|
Bind(&yNotInt);
|
|
{
|
|
doubleY = TaggedCastToDouble(y);
|
|
Jump(&xIsDoubleAndyIsDouble);
|
|
}
|
|
}
|
|
Bind(&xIsDoubleAndyIsDouble);
|
|
doubleX = DoubleMul(*doubleX, *doubleY);
|
|
GateRef ptr1 = CallRuntime(glue, RTSTUB_ID(GetTaggedArrayPtrTest), {Int64(JSTaggedValue::VALUE_UNDEFINED)});
|
|
GateRef ptr2 = CallRuntime(glue, RTSTUB_ID(GetTaggedArrayPtrTest), {ptr1});
|
|
auto value1 = GetValueFromTaggedArray(VariableType::INT64(), ptr1, Int32(0));
|
|
GateRef tmp = CastInt64ToFloat64(value1);
|
|
doubleX = DoubleMul(*doubleX, tmp);
|
|
auto value2 = GetValueFromTaggedArray(VariableType::INT64(), ptr2, Int32(1));
|
|
tmp = CastInt64ToFloat64(value2);
|
|
doubleX = DoubleMul(*doubleX, tmp);
|
|
Return(DoubleBuildTaggedWithNoGC(*doubleX));
|
|
}
|
|
#endif
|
|
|
|
void AddStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
(void)glue;
|
|
GateRef x = TaggedArgument(1);
|
|
GateRef y = TaggedArgument(2);
|
|
Return(FastAdd(x, y));
|
|
}
|
|
|
|
void SubStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
(void)glue;
|
|
GateRef x = TaggedArgument(1);
|
|
GateRef y = TaggedArgument(2);
|
|
Return(FastSub(x, y));
|
|
}
|
|
|
|
void MulStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
(void)glue;
|
|
GateRef x = TaggedArgument(1);
|
|
GateRef y = TaggedArgument(2);
|
|
Return(FastMul(x, y));
|
|
}
|
|
|
|
void DivStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
(void)glue;
|
|
GateRef x = TaggedArgument(1);
|
|
GateRef y = TaggedArgument(2);
|
|
Return(FastDiv(x, y));
|
|
}
|
|
|
|
void ModStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef x = TaggedArgument(1);
|
|
GateRef y = TaggedArgument(2); // 2: 3rd argument
|
|
Return(FastMod(glue, x, y));
|
|
}
|
|
|
|
void TypeOfStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef obj = TaggedArgument(1);
|
|
Return(FastTypeOf(glue, obj));
|
|
}
|
|
|
|
void EqualStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
(void)glue;
|
|
GateRef x = TaggedArgument(1);
|
|
GateRef y = TaggedArgument(2);
|
|
Return(FastEqual(x, y));
|
|
}
|
|
|
|
void GetPropertyByIndexStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef receiver = TaggedArgument(1);
|
|
GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */
|
|
Return(GetPropertyByIndex(glue, receiver, index));
|
|
}
|
|
|
|
void SetPropertyByIndexStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef receiver = TaggedArgument(1);
|
|
GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */
|
|
GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */
|
|
Return(SetPropertyByIndex(glue, receiver, index, value, false));
|
|
}
|
|
|
|
void SetPropertyByIndexWithOwnStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef receiver = TaggedArgument(1);
|
|
GateRef index = Int32Argument(2); /* 2 : 3rd parameter is index */
|
|
GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */
|
|
Return(SetPropertyByIndex(glue, receiver, index, value, true));
|
|
}
|
|
|
|
void GetPropertyByNameStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef receiver = TaggedArgument(1);
|
|
GateRef key = TaggedArgument(2); // 2 : 3rd para
|
|
Return(GetPropertyByName(glue, receiver, key));
|
|
}
|
|
|
|
void SetPropertyByNameStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef receiver = TaggedArgument(1);
|
|
GateRef key = TaggedArgument(2); // 2 : 3rd para
|
|
GateRef value = TaggedArgument(3); // 3 : 4th para
|
|
Return(SetPropertyByName(glue, receiver, key, value, false));
|
|
}
|
|
|
|
void SetPropertyByNameWithOwnStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef receiver = TaggedArgument(1);
|
|
GateRef key = TaggedArgument(2); // 2 : 3rd para
|
|
GateRef value = TaggedArgument(3); // 3 : 4th para
|
|
Return(SetPropertyByName(glue, receiver, key, value, true));
|
|
}
|
|
|
|
void GetPropertyByValueStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef receiver = TaggedArgument(1);
|
|
GateRef key = TaggedArgument(2); // 2 : 3rd para
|
|
Return(GetPropertyByValue(glue, receiver, key));
|
|
}
|
|
|
|
void SetPropertyByValueStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef receiver = TaggedArgument(1);
|
|
GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is key */
|
|
GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */
|
|
Return(SetPropertyByValue(glue, receiver, key, value, false));
|
|
}
|
|
|
|
void SetPropertyByValueWithOwnStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef receiver = TaggedArgument(1);
|
|
GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is key */
|
|
GateRef value = TaggedArgument(3); /* 3 : 4th parameter is value */
|
|
Return(SetPropertyByValue(glue, receiver, key, value, true));
|
|
}
|
|
|
|
void TryLoadICByNameStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
auto env = GetEnvironment();
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef receiver = TaggedArgument(1);
|
|
GateRef firstValue = TaggedArgument(2); /* 2 : 3rd parameter is value */
|
|
GateRef secondValue = TaggedArgument(3); /* 3 : 4th parameter is value */
|
|
|
|
Label receiverIsHeapObject(env);
|
|
Label receiverNotHeapObject(env);
|
|
Label hclassEqualFirstValue(env);
|
|
Label hclassNotEqualFirstValue(env);
|
|
Label cachedHandlerNotHole(env);
|
|
Branch(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject);
|
|
Bind(&receiverIsHeapObject);
|
|
{
|
|
GateRef hclass = LoadHClass(receiver);
|
|
Branch(Int64Equal(TaggedCastToWeakReferentUnChecked(firstValue), hclass),
|
|
&hclassEqualFirstValue, &hclassNotEqualFirstValue);
|
|
Bind(&hclassEqualFirstValue);
|
|
{
|
|
Return(LoadICWithHandler(glue, receiver, receiver, secondValue));
|
|
}
|
|
Bind(&hclassNotEqualFirstValue);
|
|
{
|
|
GateRef cachedHandler = CheckPolyHClass(firstValue, hclass);
|
|
Branch(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole);
|
|
Bind(&cachedHandlerNotHole);
|
|
{
|
|
Return(LoadICWithHandler(glue, receiver, receiver, cachedHandler));
|
|
}
|
|
}
|
|
}
|
|
Bind(&receiverNotHeapObject);
|
|
{
|
|
Return(Hole());
|
|
}
|
|
}
|
|
|
|
void TryLoadICByValueStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
auto env = GetEnvironment();
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef receiver = TaggedArgument(1);
|
|
GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is value */
|
|
GateRef firstValue = TaggedArgument(3); /* 3 : 4th parameter is value */
|
|
GateRef secondValue = TaggedArgument(4); /* 4 : 5th parameter is value */
|
|
|
|
Label receiverIsHeapObject(env);
|
|
Label receiverNotHeapObject(env);
|
|
Label hclassEqualFirstValue(env);
|
|
Label hclassNotEqualFirstValue(env);
|
|
Label firstValueEqualKey(env);
|
|
Label cachedHandlerNotHole(env);
|
|
Branch(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject);
|
|
Bind(&receiverIsHeapObject);
|
|
{
|
|
GateRef hclass = LoadHClass(receiver);
|
|
Branch(Int64Equal(TaggedCastToWeakReferentUnChecked(firstValue), hclass),
|
|
&hclassEqualFirstValue, &hclassNotEqualFirstValue);
|
|
Bind(&hclassEqualFirstValue);
|
|
Return(LoadElement(receiver, key));
|
|
Bind(&hclassNotEqualFirstValue);
|
|
{
|
|
Branch(Int64Equal(firstValue, key), &firstValueEqualKey, &receiverNotHeapObject);
|
|
Bind(&firstValueEqualKey);
|
|
{
|
|
auto cachedHandler = CheckPolyHClass(secondValue, hclass);
|
|
Branch(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole);
|
|
Bind(&cachedHandlerNotHole);
|
|
Return(LoadICWithHandler(glue, receiver, receiver, cachedHandler));
|
|
}
|
|
}
|
|
}
|
|
Bind(&receiverNotHeapObject);
|
|
Return(Hole());
|
|
}
|
|
|
|
void TryStoreICByNameStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
auto env = GetEnvironment();
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef receiver = TaggedArgument(1);
|
|
GateRef firstValue = TaggedArgument(2); /* 2 : 3rd parameter is value */
|
|
GateRef secondValue = TaggedArgument(3); /* 3 : 4th parameter is value */
|
|
GateRef value = TaggedArgument(4); /* 4 : 5th parameter is value */
|
|
Label receiverIsHeapObject(env);
|
|
Label receiverNotHeapObject(env);
|
|
Label hclassEqualFirstValue(env);
|
|
Label hclassNotEqualFirstValue(env);
|
|
Label cachedHandlerNotHole(env);
|
|
Branch(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject);
|
|
Bind(&receiverIsHeapObject);
|
|
{
|
|
GateRef hclass = LoadHClass(receiver);
|
|
Branch(Int64Equal(TaggedCastToWeakReferentUnChecked(firstValue), hclass),
|
|
&hclassEqualFirstValue, &hclassNotEqualFirstValue);
|
|
Bind(&hclassEqualFirstValue);
|
|
{
|
|
Return(StoreICWithHandler(glue, receiver, receiver, value, secondValue));
|
|
}
|
|
Bind(&hclassNotEqualFirstValue);
|
|
{
|
|
GateRef cachedHandler = CheckPolyHClass(firstValue, hclass);
|
|
Branch(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole);
|
|
Bind(&cachedHandlerNotHole);
|
|
{
|
|
Return(StoreICWithHandler(glue, receiver, receiver, value, cachedHandler));
|
|
}
|
|
}
|
|
}
|
|
Bind(&receiverNotHeapObject);
|
|
Return(Hole(VariableType::INT64()));
|
|
}
|
|
|
|
void TryStoreICByValueStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
auto env = GetEnvironment();
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef receiver = TaggedArgument(1);
|
|
GateRef key = TaggedArgument(2); /* 2 : 3rd parameter is value */
|
|
GateRef firstValue = TaggedArgument(3); /* 3 : 4th parameter is value */
|
|
GateRef secondValue = TaggedArgument(4); /* 4 : 5th parameter is value */
|
|
GateRef value = TaggedArgument(5); /* 5 : 6th parameter is value */
|
|
Label receiverIsHeapObject(env);
|
|
Label receiverNotHeapObject(env);
|
|
Label hclassEqualFirstValue(env);
|
|
Label hclassNotEqualFirstValue(env);
|
|
Label firstValueEqualKey(env);
|
|
Label cachedHandlerNotHole(env);
|
|
Branch(TaggedIsHeapObject(receiver), &receiverIsHeapObject, &receiverNotHeapObject);
|
|
Bind(&receiverIsHeapObject);
|
|
{
|
|
GateRef hclass = LoadHClass(receiver);
|
|
Branch(Int64Equal(TaggedCastToWeakReferentUnChecked(firstValue), hclass),
|
|
&hclassEqualFirstValue, &hclassNotEqualFirstValue);
|
|
Bind(&hclassEqualFirstValue);
|
|
Return(ICStoreElement(glue, receiver, key, value, secondValue));
|
|
Bind(&hclassNotEqualFirstValue);
|
|
{
|
|
Branch(Int64Equal(firstValue, key), &firstValueEqualKey, &receiverNotHeapObject);
|
|
Bind(&firstValueEqualKey);
|
|
{
|
|
GateRef cachedHandler = CheckPolyHClass(secondValue, hclass);
|
|
Branch(TaggedIsHole(cachedHandler), &receiverNotHeapObject, &cachedHandlerNotHole);
|
|
Bind(&cachedHandlerNotHole);
|
|
Return(StoreICWithHandler(glue, receiver, receiver, value, cachedHandler));
|
|
}
|
|
}
|
|
}
|
|
Bind(&receiverNotHeapObject);
|
|
Return(Hole(VariableType::INT64()));
|
|
}
|
|
|
|
void SetValueWithBarrierStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef obj = TaggedArgument(1);
|
|
GateRef offset = PtrArgument(2); // 2 : 3rd para
|
|
GateRef value = TaggedArgument(3); // 3 : 4th para
|
|
SetValueWithBarrier(glue, obj, offset, value);
|
|
Return();
|
|
}
|
|
|
|
void TestAbsoluteAddressRelocationStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
auto env = GetEnvironment();
|
|
GateRef a = Int64Argument(0);
|
|
GateRef b = Int64Argument(1);
|
|
Label start(env);
|
|
Jump(&start);
|
|
Bind(&start);
|
|
GateRef globalValueC = RelocatableData(0xabc);
|
|
GateRef globalValueD = RelocatableData(0xbcd);
|
|
GateRef dummyValueC = Load(VariableType::INT64(), globalValueC);
|
|
GateRef dummyValueD = Load(VariableType::INT64(), globalValueD);
|
|
// Load from same relocatable data twice to see if it breaks constant fold opt. Result shows it doesn't.
|
|
GateRef dummyValueC1 = Load(VariableType::INT64(), globalValueC);
|
|
GateRef result = Int64Add(a, Int64Add(b, Int64Add(dummyValueC, Int64Add(dummyValueD, dummyValueC1))));
|
|
Return(result);
|
|
}
|
|
|
|
void JsProxyCallInternalStub::GenerateCircuit(const CompilationConfig *cfg)
|
|
{
|
|
Stub::GenerateCircuit(cfg);
|
|
auto env = GetEnvironment();
|
|
Label exit(env);
|
|
Label isNull(env);
|
|
Label notNull(env);
|
|
Label isUndefined(env);
|
|
Label isNotUndefined(env);
|
|
|
|
GateRef glue = PtrArgument(0);
|
|
GateRef argc = Int64Argument(1);
|
|
GateRef proxy = TaggedPointerArgument(2); // callTarget
|
|
GateRef argv = PtrArgument(3);
|
|
|
|
DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
|
|
|
|
GateRef handler = GetHandlerFromJSProxy(proxy);
|
|
Branch(TaggedIsNull(handler), &isNull, ¬Null);
|
|
Bind(&isNull);
|
|
{
|
|
ThrowTypeAndReturn(glue, GET_MESSAGE_STRING_ID(NonCallable), Exception());
|
|
}
|
|
Bind(¬Null);
|
|
{
|
|
GateRef target = GetTargetFromJSProxy(proxy);
|
|
GateRef globalConstOffset = IntPtr(JSThread::GlueData::GetGlobalConstOffset(env->Is32Bit()));
|
|
GateRef keyOffset = PtrAdd(globalConstOffset,
|
|
PtrMul(IntPtr(static_cast<int64_t>(ConstantIndex::APPLY_STRING_INDEX)),
|
|
IntPtr(sizeof(JSTaggedValue))));
|
|
GateRef key = Load(VariableType::JS_ANY(), glue, keyOffset);
|
|
GateRef method = CallNGCRuntime(glue, RTSTUB_ID(JSObjectGetMethod), {glue, handler, key});
|
|
ReturnExceptionIfAbruptCompletion(glue);
|
|
|
|
Branch(TaggedIsUndefined(method), &isUndefined, &isNotUndefined);
|
|
Bind(&isUndefined);
|
|
{
|
|
result = CallNGCRuntime(glue, RTSTUB_ID(JSProxyCallInternalWithArgV), {glue, argc, target, argv});
|
|
Return(*result);
|
|
}
|
|
Bind(&isNotUndefined);
|
|
{
|
|
GateRef arrHandle = CallRuntime(glue, RTSTUB_ID(CreateArrayFromList), argc, argv);
|
|
GateRef thisArg = Load(VariableType::JS_POINTER(), argv, IntPtr(2*sizeof(JSTaggedValue)));
|
|
GateRef numArgs = Int64(JSPROXY_NUM_ARGS + NUM_MANDATORY_JSFUNC_ARGS);
|
|
GateRef lexEnv = Load(VariableType::JS_POINTER(), method, IntPtr(JSFunction::LEXICAL_ENV_OFFSET));
|
|
result = CallNGCRuntime(glue, RTSTUB_ID(JSCall),
|
|
{glue, lexEnv, numArgs, method, Undefined(), handler, target, thisArg, arrHandle});
|
|
Jump(&exit);
|
|
}
|
|
}
|
|
Bind(&exit);
|
|
Return(*result);
|
|
}
|
|
|
|
CallSignature CommonStubCSigns::callSigns_[CommonStubCSigns::NUM_OF_STUBS];
|
|
|
|
void CommonStubCSigns::Initialize()
|
|
{
|
|
#define INIT_SIGNATURES(name, counter) \
|
|
name##CallSignature::Initialize(&callSigns_[name]); \
|
|
callSigns_[name].SetID(name); \
|
|
callSigns_[name].SetConstructor( \
|
|
[](void* ciruit) { \
|
|
return static_cast<void*>(new name##Stub(static_cast<Circuit*>(ciruit))); \
|
|
});
|
|
|
|
COMMON_STUB_ID_LIST(INIT_SIGNATURES)
|
|
#undef INIT_SIGNATURES
|
|
}
|
|
|
|
void CommonStubCSigns::GetCSigns(std::vector<const CallSignature*>& outCSigns)
|
|
{
|
|
for (size_t i = 0; i < NUM_OF_STUBS; i++) {
|
|
outCSigns.push_back(&callSigns_[i]);
|
|
}
|
|
}
|
|
} // namespace panda::ecmascript::kungfu
|