Merge remote-tracking branch 'open/master'

Change-Id: Idf4c31507cf0d772e81d39bb6b9ab17436076aeb
Signed-off-by: wanyanglan <wanyanglan1@huawei.com>
This commit is contained in:
wanyanglan 2021-10-26 15:11:16 +08:00
commit 7fd302d7a4
79 changed files with 2613 additions and 638 deletions

View File

@ -123,11 +123,11 @@ source_set("libark_js_intl_static") {
deps = [
"$ark_root/libpandabase:libarkbase",
"$ark_root/libpandafile:libarkfile",
"$ark_root/runtime:arkruntime_header_deps",
"//third_party/icu/icu4c:shared_icui18n",
"//third_party/icu/icu4c:shared_icuuc",
sdk_libc_secshared_dep,
]
deps += arkruntime_header_gen_deps
}
config("ark_jsruntime_common_config") {
@ -436,14 +436,14 @@ source_set("libark_jsruntime_test_static") {
sources += intl_sources
deps = [
":copy_resource_xml",
":copy_ark_resource",
"$ark_root/libpandabase:libarkbase",
"$ark_root/libpandafile:libarkfile",
"$ark_root/runtime:arkruntime_header_deps",
"//third_party/icu/icu4c:shared_icui18n",
"//third_party/icu/icu4c:shared_icuuc",
sdk_libc_secshared_dep,
]
deps += arkruntime_header_gen_deps
if (is_debug && is_linux && (current_cpu == "x86" || current_cpu == "x64") &&
run_with_asan) {
@ -478,25 +478,28 @@ ohos_shared_library("libark_jsruntime_test") {
subsystem_name = "test"
}
action("copy_resource_xml") {
action("copy_ark_resource") {
deps = []
script = "//ark/js_runtime/test/copy_resource.py"
src_path = "//ark/js_runtime/test/resource/js_runtime/"
src_path = "//ark/js_runtime/test/resource/js_runtime"
src_xml = "ohos_test.xml"
dst_path = "//ark/test/resource/js_runtime/"
args = [
"--src-path",
rebase_path(src_path),
rebase_path("${src_path}/"),
"--src-xml",
src_xml,
"--dst-path",
rebase_path(dst_path),
]
inputs = [ src_path + src_xml ]
inputs = [
src_path,
"${src_path}/${src_xml}",
]
outputs = [ "$target_out_dir" ]
}

View File

@ -399,14 +399,13 @@ JSTaggedValue BuiltinsPromise::PerformPromiseThen(JSThread *thread, const JSHand
if (JSTaggedValue::SameValue(promise->GetPromiseState(),
JSTaggedValue(static_cast<int32_t>(PromiseStatus::PENDING)))) {
JSHandle<TaggedQueue> fulfillReactions(thread, promise->GetPromiseFulfillReactions());
auto result =
JSTaggedValue(TaggedQueue::Push(thread, fulfillReactions, JSHandle<JSTaggedValue>::Cast(fulfillReaction)));
promise->SetPromiseFulfillReactions(thread, result);
TaggedQueue *newQueue =
TaggedQueue::Push(thread, fulfillReactions, JSHandle<JSTaggedValue>::Cast(fulfillReaction));
promise->SetPromiseFulfillReactions(thread, JSTaggedValue(newQueue));
JSHandle<TaggedQueue> rejectReactions(thread, promise->GetPromiseRejectReactions());
result =
JSTaggedValue(TaggedQueue::Push(thread, rejectReactions, JSHandle<JSTaggedValue>::Cast(rejectReaction)));
promise->SetPromiseRejectReactions(thread, result);
newQueue = TaggedQueue::Push(thread, rejectReactions, JSHandle<JSTaggedValue>::Cast(rejectReaction));
promise->SetPromiseRejectReactions(thread, JSTaggedValue(newQueue));
} else if (JSTaggedValue::SameValue(promise->GetPromiseState(),
JSTaggedValue(static_cast<int32_t>(PromiseStatus::FULFILLED)))) {
JSHandle<TaggedArray> argv = factory->NewTaggedArray(2); // 2: 2 means two args stored in array
@ -414,7 +413,7 @@ JSTaggedValue BuiltinsPromise::PerformPromiseThen(JSThread *thread, const JSHand
argv->Set(thread, 1, promise->GetPromiseResult());
JSHandle<JSFunction> promiseReactionsJob(env->GetPromiseReactionJob());
job->EnqueueJob(thread, job::QueueType::QUEUE_PROMISE, promiseReactionsJob, argv);
job::MicroJobQueue::EnqueueJob(thread, job, job::QueueType::QUEUE_PROMISE, promiseReactionsJob, argv);
} else if (JSTaggedValue::SameValue(promise->GetPromiseState(),
JSTaggedValue(static_cast<int32_t>(PromiseStatus::REJECTED)))) {
JSHandle<TaggedArray> argv = factory->NewTaggedArray(2); // 2: 2 means two args stored in array
@ -422,7 +421,7 @@ JSTaggedValue BuiltinsPromise::PerformPromiseThen(JSThread *thread, const JSHand
argv->Set(thread, 1, promise->GetPromiseResult());
JSHandle<JSFunction> promiseReactionsJob(env->GetPromiseReactionJob());
job->EnqueueJob(thread, job::QueueType::QUEUE_PROMISE, promiseReactionsJob, argv);
job::MicroJobQueue::EnqueueJob(thread, job, job::QueueType::QUEUE_PROMISE, promiseReactionsJob, argv);
}
return capability->GetPromise();
}

View File

@ -95,7 +95,7 @@ JSTaggedValue BuiltinsPromiseHandler::Resolve(EcmaRuntimeCallInfo *argv)
JSHandle<JSFunction> promiseResolveThenableJob(env->GetPromiseResolveThenableJob());
JSHandle<job::MicroJobQueue> job = thread->GetEcmaVM()->GetMicroJobQueue();
job->EnqueueJob(thread, job::QueueType::QUEUE_PROMISE, promiseResolveThenableJob, arguments);
job::MicroJobQueue::EnqueueJob(thread, job, job::QueueType::QUEUE_PROMISE, promiseResolveThenableJob, arguments);
// 13. Return undefined.
return JSTaggedValue::Undefined();

View File

@ -449,7 +449,7 @@ HWTEST_F_L0(BuiltinsPromiseTest, Race2)
*/
auto microJobQueue = EcmaVM::Cast(instance)->GetMicroJobQueue();
if (!thread->HasPendingException()) {
microJobQueue->ExecutePendingJob(thread);
job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
}
}
@ -550,7 +550,7 @@ HWTEST_F_L0(BuiltinsPromiseTest, All)
*/
auto microJobQueue = EcmaVM::Cast(instance)->GetMicroJobQueue();
if (!thread->HasPendingException()) {
microJobQueue->ExecutePendingJob(thread);
job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
}
}
@ -606,7 +606,7 @@ HWTEST_F_L0(BuiltinsPromiseTest, Catch)
*/
auto microJobQueue = EcmaVM::Cast(instance)->GetMicroJobQueue();
if (!thread->HasPendingException()) {
microJobQueue->ExecutePendingJob(thread);
job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
}
}
@ -664,7 +664,7 @@ HWTEST_F_L0(BuiltinsPromiseTest, ThenResolve)
*/
auto microJobQueue = EcmaVM::Cast(instance)->GetMicroJobQueue();
if (!thread->HasPendingException()) {
microJobQueue->ExecutePendingJob(thread);
job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
}
}
@ -721,7 +721,7 @@ HWTEST_F_L0(BuiltinsPromiseTest, ThenReject)
*/
auto microJobQueue = EcmaVM::Cast(instance)->GetMicroJobQueue();
if (!thread->HasPendingException()) {
microJobQueue->ExecutePendingJob(thread);
job::MicroJobQueue::ExecutePendingJob(thread, microJobQueue);
}
}
} // namespace panda::test

View File

@ -37,8 +37,8 @@ public:
inline void FreeMethodData(RegionFactory *factory);
DECL_DUMP()
DECL_VISIT_OBJECT(LOCATION_OFFSET, METHODS_DATA_OFFSET)
DECL_DUMP()
};
class LexicalFunction : public ECMAObject {
@ -65,6 +65,7 @@ public:
ACCESSORS(Program, PROGRAM_OFFSET, SIZE)
DECL_VISIT_OBJECT(NAME_OFFSET, SIZE)
DECL_DUMP()
};
class ConstantPool : public TaggedArray {

View File

@ -133,8 +133,8 @@ source_set("libark_jsoptimizer_static") {
deps = [
"$ark_root/libpandabase:libarkbase",
"$ark_root/libpandafile:libarkfile",
"$ark_root/runtime:arkruntime_header_deps",
]
deps += arkruntime_header_gen_deps
}
ohos_shared_library("libark_jsoptimizer") {

View File

@ -658,7 +658,6 @@ void SetElementStub::GenerateCircuit()
void GetPropertyByIndexStub::GenerateCircuit()
{
auto env = GetEnvironment();
env->SetFrameType(FrameType::OPTIMIZED_ENTRY_FRAME);
AddrShift thread = PtrArgument(0);
AddrShift receiver = PtrArgument(1);
AddrShift index = Int32Argument(2); /* 2 : 3rd parameter is index */
@ -771,7 +770,6 @@ void GetPropertyByIndexStub::GenerateCircuit()
void SetPropertyByIndexStub::GenerateCircuit()
{
auto env = GetEnvironment();
env->SetFrameType(FrameType::OPTIMIZED_ENTRY_FRAME);
AddrShift thread = PtrArgument(0);
AddrShift receiver = PtrArgument(1);
AddrShift index = Int32Argument(2); /* 2 : 3rd parameter is index */
@ -1015,8 +1013,9 @@ void GetPropertyByNameStub::GenerateCircuit()
void FastModStub::GenerateCircuit()
{
auto env = GetEnvironment();
AddrShift x = Int64Argument(0);
AddrShift y = Int64Argument(1);
AddrShift thread = PtrArgument(0);
AddrShift x = Int64Argument(1);
AddrShift y = Int64Argument(2);
DEFVARIABLE(intX, MachineType::INT32_TYPE, 0);
DEFVARIABLE(intY, MachineType::INT32_TYPE, 0);
DEFVARIABLE(doubleX, MachineType::FLOAT64_TYPE, 0);
@ -1153,7 +1152,9 @@ void FastModStub::GenerateCircuit()
Jump(&xIsZeroOryIsInf);
Bind(&yNotInf);
{
doubleX = DoubleMod(*doubleX, *doubleY);
StubDescriptor *floatMod = GET_STUBDESCRIPTOR(FloatMod);
doubleX =CallRuntime(floatMod, thread, GetWord64Constant(FAST_STUB_ID(FloatMod)),
{*doubleX, *doubleY});
Return(DoubleBuildTagged(*doubleX));
}
Bind(&xIsZeroOryIsInf);
@ -1226,8 +1227,8 @@ void FastTypeOfStub::GenerateCircuit()
Bind(&defaultLabel);
{
Label objIsHeapObject(env);
Label ObjNotHeapObject(env);
Branch(TaggedIsHeapObject(obj), &objIsHeapObject, &ObjNotHeapObject);
Label objNotHeapObject(env);
Branch(TaggedIsHeapObject(obj), &objIsHeapObject, &objNotHeapObject);
Bind(&objIsHeapObject);
{
Label objIsString(env);
@ -1242,15 +1243,15 @@ void FastTypeOfStub::GenerateCircuit()
Bind(&objNotString);
{
Label objIsSymbol(env);
Label ObjNotSymbol(env);
Branch(IsSymbol(obj), &objIsSymbol, &ObjNotSymbol);
Label objNotSymbol(env);
Branch(IsSymbol(obj), &objIsSymbol, &objNotSymbol);
Bind(&objIsSymbol);
{
resultRep = Load(TAGGED_TYPE, gConstOffset,
GetGlobalConstantString(ConstantIndex::SYMBOL_STRING_INDEX));
Jump(&exit);
}
Bind(&ObjNotSymbol);
Bind(&objNotSymbol);
{
Label objIsCallable(env);
Label objNotCallable(env);
@ -1270,7 +1271,7 @@ void FastTypeOfStub::GenerateCircuit()
}
}
}
Bind(&ObjNotHeapObject);
Bind(&objNotHeapObject);
{
Label objIsNum(env);
Label objNotNum(env);

View File

@ -142,8 +142,11 @@ public:
class FastModStub : public Stub {
public:
// 2 means argument counts
explicit FastModStub(Circuit *circuit) : Stub("FastMod", 2, circuit) {}
// 3 means argument counts
explicit FastModStub(Circuit *circuit) : Stub("FastMod", 3, circuit)
{
circuit->SetFrameType(panda::ecmascript::FrameType::OPTIMIZED_ENTRY_FRAME);
}
~FastModStub() = default;
NO_MOVE_SEMANTIC(FastModStub);
NO_COPY_SEMANTIC(FastModStub);

View File

@ -28,7 +28,8 @@ namespace kungfu {
V(GetHash32, 2) \
V(FindElementWithCache, 4) \
V(Execute, 5) \
V(StringGetHashCode, 1)
V(StringGetHashCode, 1) \
V(FloatMod, 2)
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define FAST_RUNTIME_STUB_LIST(V) \
@ -36,7 +37,7 @@ namespace kungfu {
V(FastSub, 2) \
V(FastMul, 2) \
V(FastDiv, 2) \
V(FastMod, 2) \
V(FastMod, 3) \
V(FastEqual, 2) \
V(FastTypeOf, 2) \
V(FastStrictEqual, 2) \

View File

@ -1,123 +1,125 @@
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 0e85afa82c7..54a9152e44f 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -505,8 +505,15 @@ option(LLVM_BUILD_RUNTIME
"Build the LLVM runtime libraries." ON)
option(LLVM_BUILD_EXAMPLES
"Build the LLVM example programs. If OFF, just generate build targets." OFF)
+option(BUILD_ARK_GC_SUPPORT
+ "ARK support GC. If ON, support GC." OFF)
+if(BUILD_ARK_GC_SUPPORT)
+ add_definitions(-DARK_GC_SUPPORT)
+endif(ARK_SUPPORT_GC)
+
option(LLVM_INCLUDE_EXAMPLES "Generate build targets for the LLVM examples" ON)
+
if(LLVM_BUILD_EXAMPLES)
add_definitions(-DBUILD_EXAMPLES)
endif(LLVM_BUILD_EXAMPLES)
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index 1da20371caf..60d9af0d833 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -31,6 +31,7 @@
#include "llvm/Support/Debug.h"
#include "llvm/Target/TargetOptions.h"
#include <cstdlib>
+#include <iostream>
using namespace llvm;
@@ -1168,6 +1169,28 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
else
MFI.setOffsetAdjustment(-StackSize);
}
+#ifdef ARK_GC_SUPPORT
+ // push marker
+ if (MF.getFunction().hasFnAttribute("js-stub-call"))
+ {
+ int64_t marker = 0x0;
+ MF.getFunction()
+ .getFnAttribute("js-stub-call")
+ .getValueAsString()
+ .getAsInteger(10, marker);//marker 1 break frame
+ std::cout << __LINE__ << " marker:" << std::dec << marker << std::endl;
+
+ BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH64i32))
+ .addImm(marker)
+ .setMIFlag(MachineInstr::FrameSetup);
+ /*reserve thread.fp */
+ if (marker == 1) {
+ BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH64i32))
+ .addImm(marker)
+ .setMIFlag(MachineInstr::FrameSetup);
+ }
+ }
+#endif
// For EH funclets, only allocate enough space for outgoing calls. Save the
// NumBytes value that we would've used for the parent frame.
@@ -1635,6 +1658,27 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
uint64_t SEHStackAllocAmt = NumBytes;
if (HasFP) {
+#ifdef ARK_GC_SUPPORT
+ if (MF.getFunction().hasFnAttribute("js-stub-call"))
+ {
+ int64_t marker = 0x0;
+ MF.getFunction()
+ .getFnAttribute("js-stub-call")
+ .getValueAsString()
+ .getAsInteger(10, marker);//marker 1 break frame
+
+ // pop marker
+ BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
+ MachineFramePtr)
+ .setMIFlag(MachineInstr::FrameDestroy);
+ if (marker == 1) {
+ // pop thread.fp
+ BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
+ MachineFramePtr)
+ .setMIFlag(MachineInstr::FrameDestroy);
+ }
+ }
+#endif
// Pop EBP.
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
MachineFramePtr)
@@ -1993,8 +2037,33 @@ bool X86FrameLowering::assignCalleeSavedSpillSlots(
if (hasFP(MF)) {
// emitPrologue always spills frame register the first thing.
+#ifdef ARK_GC_SUPPORT
+ if (MF.getFunction().hasFnAttribute("js-stub-call")) {
+ int64_t marker = 0x0;
+ MF.getFunction()
+ .getFnAttribute("js-stub-call")
+ .getValueAsString()
+ .getAsInteger(10, marker);//marker 1 break frame
+ if (marker == 1) {
+ SpillSlotOffset -= 3 * SlotSize; // add type and thread.fp
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
+ CalleeSavedFrameSize += 16;
+ } else {
+ SpillSlotOffset -= 2 * SlotSize; // add type
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
+ CalleeSavedFrameSize += 8;
+ }
+ } else {
+ SpillSlotOffset -= SlotSize; // add type and thread.fp
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
+ }
+#else
SpillSlotOffset -= SlotSize;
MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
+#endif
// Since emitPrologue and emitEpilogue will handle spilling and restoring of
// the frame register, we can delete it from CSI list and not have to worry
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 0e85afa82c7..43756892e40 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -505,8 +505,15 @@ option(LLVM_BUILD_RUNTIME
"Build the LLVM runtime libraries." ON)
option(LLVM_BUILD_EXAMPLES
"Build the LLVM example programs. If OFF, just generate build targets." OFF)
+option(BUILD_ARK_GC_SUPPORT
+ "ARK support GC. If ON, support GC." OFF)
+if(BUILD_ARK_GC_SUPPORT)
+ add_definitions(-DARK_GC_SUPPORT)
+endif(BUILD_ARK_GC_SUPPORT)
+
option(LLVM_INCLUDE_EXAMPLES "Generate build targets for the LLVM examples" ON)
+
if(LLVM_BUILD_EXAMPLES)
add_definitions(-DBUILD_EXAMPLES)
endif(LLVM_BUILD_EXAMPLES)
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index 1da20371caf..e0264827556 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -1168,6 +1168,25 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
else
MFI.setOffsetAdjustment(-StackSize);
}
+#ifdef ARK_GC_SUPPORT
+ // push marker
+ if (MF.getFunction().hasFnAttribute("js-stub-call"))
+ {
+ int64_t marker = 0x0;
+ MF.getFunction()
+ .getFnAttribute("js-stub-call")
+ .getValueAsString()
+ .getAsInteger(10, marker);//marker 1 break frame
+ BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64i32 : X86::PUSH32i8))
+ .addImm(marker)
+ .setMIFlag(MachineInstr::FrameSetup);
+ if (marker == JS_ENTRY_FRAME_MARK) {
+ BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64i32 : X86::PUSH32i8))
+ .addImm(marker)
+ .setMIFlag(MachineInstr::FrameSetup);
+ }
+ }
+#endif
// For EH funclets, only allocate enough space for outgoing calls. Save the
// NumBytes value that we would've used for the parent frame.
@@ -1635,6 +1654,27 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
uint64_t SEHStackAllocAmt = NumBytes;
if (HasFP) {
+#ifdef ARK_GC_SUPPORT
+ if (MF.getFunction().hasFnAttribute("js-stub-call"))
+ {
+ int64_t marker = 0x0;
+ MF.getFunction()
+ .getFnAttribute("js-stub-call")
+ .getValueAsString()
+ .getAsInteger(10, marker);//marker 1 break frame
+
+ // pop marker
+ BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
+ MachineFramePtr)
+ .setMIFlag(MachineInstr::FrameDestroy);
+ if (marker == JS_ENTRY_FRAME_MARK) {
+ // pop thread.fp
+ BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
+ MachineFramePtr)
+ .setMIFlag(MachineInstr::FrameDestroy);
+ }
+ }
+#endif
// Pop EBP.
BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r),
MachineFramePtr)
@@ -1993,8 +2033,33 @@ bool X86FrameLowering::assignCalleeSavedSpillSlots(
if (hasFP(MF)) {
// emitPrologue always spills frame register the first thing.
+#ifdef ARK_GC_SUPPORT
+ if (MF.getFunction().hasFnAttribute("js-stub-call")) {
+ int64_t marker = 0x0;
+ MF.getFunction()
+ .getFnAttribute("js-stub-call")
+ .getValueAsString()
+ .getAsInteger(10, marker);//marker 1 break frame
+ if (marker == JS_ENTRY_FRAME_MARK) {
+ SpillSlotOffset -= 3 * SlotSize; // add type and thread.fp
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
+ CalleeSavedFrameSize += (2 * SlotSize);
+ } else {
+ SpillSlotOffset -= 2 * SlotSize; // add type
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
+ CalleeSavedFrameSize += SlotSize;
+ }
+ } else {
+ SpillSlotOffset -= SlotSize; // add type and thread.fp
+ MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
+ }
+#else
SpillSlotOffset -= SlotSize;
MFI.CreateFixedSpillStackObject(SlotSize, SpillSlotOffset);
+#endif
// Since emitPrologue and emitEpilogue will handle spilling and restoring of
// the frame register, we can delete it from CSI list and not have to worry
diff --git a/llvm/lib/Target/X86/X86FrameLowering.h b/llvm/lib/Target/X86/X86FrameLowering.h
index 2103d6471ea..3fd89b0d9ee 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.h
+++ b/llvm/lib/Target/X86/X86FrameLowering.h
@@ -15,6 +15,8 @@
#include "llvm/CodeGen/TargetFrameLowering.h"
+#define JS_ENTRY_FRAME_MARK 1
+
namespace llvm {
class MachineInstrBuilder;

View File

@ -153,6 +153,7 @@ void StubAotCompiler::BuildStubModuleAndSave(const char *triple, panda::ecmascri
SET_STUB_TO_MODULE(module, FastMul) \
SET_STUB_TO_MODULE(module, FastDiv) \
SET_STUB_TO_MODULE(module, FastMod) \
SET_STUB_TO_MODULE(module, FastTypeOf) \
SET_STUB_TO_MODULE(module, FindOwnElement) \
SET_STUB_TO_MODULE(module, GetElement) \
SET_STUB_TO_MODULE(module, FindOwnElement2) \

View File

@ -81,17 +81,32 @@ CALL_STUB_INIT_DESCRIPTOR(FastDiv)
CALL_STUB_INIT_DESCRIPTOR(FastMod)
{
// 2 : 2 input parameters
StubDescriptor fastMod("FastMod", 0, 2, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE);
// 3 : 3 input parameters
StubDescriptor fastMod("FastMod", 0, 3, ArgumentsOrder::DEFAULT_ORDER, UINT64_TYPE);
*descriptor = fastMod;
// 2 : 2 input parameters
std::array<MachineType, 2> params = {
// 3 : 3 input parameters
std::array<MachineType, 3> params = {
MachineType::UINT64_TYPE,
MachineType::UINT64_TYPE,
MachineType::UINT64_TYPE,
};
descriptor->SetParameters(params.data());
}
CALL_STUB_INIT_DESCRIPTOR(FloatMod)
{
// 2 : 2 input parameters
StubDescriptor floatMod("FloatMod", 0, 2, ArgumentsOrder::DEFAULT_ORDER, FLOAT64_TYPE);
*descriptor = floatMod;
// 2 : 2 input parameters
std::array<MachineType, 2> params = {
MachineType::FLOAT64_TYPE,
MachineType::FLOAT64_TYPE,
};
descriptor->SetParameters(params.data());
descriptor->SetStubKind(StubDescriptor::CallStubKind::RUNTIME_STUB);
}
CALL_STUB_INIT_DESCRIPTOR(FastEqual) {}
CALL_STUB_INIT_DESCRIPTOR(FastTypeOf)

View File

@ -442,19 +442,24 @@ HWTEST_F_L0(StubTest, FastModTest)
llvmBuilder.Build();
LLVMAssembler assembler(module, "x86_64-unknown-linux-gnu");
assembler.Run();
auto fn = reinterpret_cast<JSTaggedValue (*)(int64_t, int64_t)>(assembler.GetFuncPtrFromCompiledModule(function));
LLVMDumpModule(module);
auto engine = assembler.GetEngine();
uint64_t stub1Code = LLVMGetFunctionAddress(engine, "FastModStub");
std::map<uint64_t, std::string> addr2name = {{stub1Code, "stub1"}};
assembler.Disassemble(addr2name);
auto fn = reinterpret_cast<JSTaggedValue (*)(JSThread *, int64_t, int64_t)>(
assembler.GetFuncPtrFromCompiledModule(function));
// test left, right are all integer
int x = 7;
int y = 3;
auto result = fn(JSTaggedValue(x).GetRawData(), JSTaggedValue(y).GetRawData());
auto result = fn(thread, JSTaggedValue(x).GetRawData(), JSTaggedValue(y).GetRawData());
JSTaggedValue expectRes = FastRuntimeStub::FastMod(JSTaggedValue(x), JSTaggedValue(y));
EXPECT_EQ(result, expectRes);
// test y == 0.0 || std::isnan(y) || std::isnan(x) || std::isinf(x) return NAN_VALUE
double x2 = 7.3;
int y2 = base::NAN_VALUE;
auto result2 = fn(JSTaggedValue(x2).GetRawData(), JSTaggedValue(y2).GetRawData());
auto result2 = fn(thread, JSTaggedValue(x2).GetRawData(), JSTaggedValue(y2).GetRawData());
auto expectRes2 = FastRuntimeStub::FastMod(JSTaggedValue(x2), JSTaggedValue(y2));
EXPECT_EQ(result2, expectRes2);
LOG_ECMA(INFO) << "result2 for FastMod(7, 'helloworld') = " << result2.GetRawData();
@ -463,14 +468,14 @@ HWTEST_F_L0(StubTest, FastModTest)
// // test modular operation under normal conditions
double x3 = 33.0;
double y3 = 44.0;
auto result3 = fn(JSTaggedValue(x3).GetRawData(), JSTaggedValue(y3).GetRawData());
auto result3 = fn(thread, JSTaggedValue(x3).GetRawData(), JSTaggedValue(y3).GetRawData());
auto expectRes3 = FastRuntimeStub::FastMod(JSTaggedValue(x3), JSTaggedValue(y3));
EXPECT_EQ(result3, expectRes3);
// test x == 0.0 || std::isinf(y) return x
double x4 = base::NAN_VALUE;
int y4 = 7;
auto result4 = fn(JSTaggedValue(x4).GetRawData(), JSTaggedValue(y4).GetRawData());
auto result4 = fn(thread, JSTaggedValue(x4).GetRawData(), JSTaggedValue(y4).GetRawData());
auto expectRes4 = FastRuntimeStub::FastMod(JSTaggedValue(x4), JSTaggedValue(y4));
LOG_ECMA(INFO) << "result4 for FastMod(base::NAN_VALUE, 7) = " << result4.GetRawData();
@ -481,7 +486,7 @@ HWTEST_F_L0(StubTest, FastModTest)
int x5 = 7;
auto *factory = JSThread::Cast(thread)->GetEcmaVM()->GetFactory();
auto y5 = factory->NewFromStdString("hello world");
auto result5 = fn(JSTaggedValue(x5).GetRawData(), y5.GetTaggedValue().GetRawData());
auto result5 = fn(thread, JSTaggedValue(x5).GetRawData(), y5.GetTaggedValue().GetRawData());
EXPECT_EQ(result5, JSTaggedValue::Hole());
auto expectRes5 = FastRuntimeStub::FastMod(JSTaggedValue(x5), y5.GetTaggedValue());
LOG_ECMA(INFO) << "result1 for FastMod(7, 'helloworld') = " << result5.GetRawData();
@ -1183,7 +1188,7 @@ HWTEST_F_L0(StubTest, GetPropertyByNameStub)
HWTEST_F_L0(StubTest, FastTypeOfTest)
{
auto module = stubModule.GetModule();
auto function = stubModule.GetStubFunction(FAST_STUB_ID(FastMod));
auto function = stubModule.GetStubFunction(FAST_STUB_ID(FastTypeOf));
Circuit netOfGates;
FastTypeOfStub optimizer(&netOfGates);
optimizer.GenerateCircuit();

File diff suppressed because it is too large Load Diff

View File

@ -371,14 +371,14 @@
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DECL_VISIT_OBJECT(BEGIN_OFFSET, SIZE) \
void VisitRangeSlot(const EcmaObjectRangeVisitor &visitor) \
void VisitRangeSlot(const EcmaObjectRangeVisitor &visitor) \
{ \
visitor(this, ObjectSlot(ToUintPtr(this) + BEGIN_OFFSET), ObjectSlot(ToUintPtr(this) + SIZE)); \
}
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define DECL_VISIT_OBJECT_FOR_JS_OBJECT(PARENTCLASS, BEGIN_OFFSET, SIZE) \
void VisitRangeSlot(const EcmaObjectRangeVisitor &visitor) \
void VisitRangeSlot(const EcmaObjectRangeVisitor &visitor) \
{ \
VisitObjects(visitor); \
/* visit in object fields */ \
@ -396,4 +396,9 @@
visitor(this, ObjectSlot(ToUintPtr(this) + BEGIN_OFFSET), ObjectSlot(ToUintPtr(this) + SIZE)); \
}
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define CHECK_DUMP_FILEDS(begin, end, num) \
LOG_IF(num != (end - begin) / JSTaggedValue::TaggedTypeSize(), FATAL, RUNTIME) \
<< "Fileds in obj are not in dump list. ";
#endif // ECMASCRIPT_ECMA_MACROS_H

View File

@ -42,12 +42,13 @@ void EcmaModule::AddItem(const JSThread *thread, JSHandle<EcmaModule> module, JS
JSHandle<JSTaggedValue> data(thread, module->GetNameDictionary());
if (data->IsUndefined()) {
JSHandle<NameDictionary> dict(thread, NameDictionary::Create(thread, DICTIONART_CAP));
auto result = dict->Put(thread, dict, itemName, itemValue, PropertyAttributes::Default());
module->SetNameDictionary(thread, JSTaggedValue(result));
NameDictionary *newDict = NameDictionary::Put(thread, dict, itemName, itemValue, PropertyAttributes::Default());
module->SetNameDictionary(thread, JSTaggedValue(newDict));
} else {
JSHandle<NameDictionary> dataDict = JSHandle<NameDictionary>::Cast(data);
auto result = dataDict->Put(thread, dataDict, itemName, itemValue, PropertyAttributes::Default());
module->SetNameDictionary(thread, JSTaggedValue(result));
NameDictionary *newDict =
NameDictionary::Put(thread, dataDict, itemName, itemValue, PropertyAttributes::Default());
module->SetNameDictionary(thread, JSTaggedValue(newDict));
}
}
@ -60,7 +61,7 @@ void EcmaModule::RemoveItem(const JSThread *thread, JSHandle<EcmaModule> module,
JSHandle<NameDictionary> moduleItems(data);
int entry = moduleItems->FindEntry(itemName.GetTaggedValue());
if (entry != -1) {
NameDictionary *newDict = NameDictionary::Remove(thread, moduleItems, entry); // discard return
NameDictionary *newDict = NameDictionary::Remove(thread, moduleItems, entry);
module->SetNameDictionary(thread, JSTaggedValue(newDict));
}
}
@ -117,20 +118,21 @@ ModuleManager::ModuleManager(EcmaVM *vm) : vm_(vm)
// class ModuleManager
void ModuleManager::AddModule(JSHandle<JSTaggedValue> moduleName, JSHandle<JSTaggedValue> module)
{
[[maybe_unused]] EcmaHandleScope scope(vm_->GetJSThread());
JSHandle<NameDictionary> dict(vm_->GetJSThread(), ecmaModules_);
JSThread *thread = vm_->GetJSThread();
[[maybe_unused]] EcmaHandleScope scope(thread);
JSHandle<NameDictionary> dict(thread, ecmaModules_);
ecmaModules_ =
JSTaggedValue(dict->Put(vm_->GetJSThread(), dict, moduleName, module, PropertyAttributes::Default()));
JSTaggedValue(NameDictionary::Put(thread, dict, moduleName, module, PropertyAttributes::Default()));
}
void ModuleManager::RemoveModule(JSHandle<JSTaggedValue> moduleName)
{
[[maybe_unused]] EcmaHandleScope scope(vm_->GetJSThread());
JSThread *thread = vm_->GetJSThread();
[[maybe_unused]] EcmaHandleScope scope(thread);
JSHandle<NameDictionary> moduleItems(thread, ecmaModules_);
int entry = moduleItems->FindEntry(moduleName.GetTaggedValue());
if (entry != -1) {
NameDictionary::Remove(vm_->GetJSThread(), moduleItems, entry); // discard return
ecmaModules_ = JSTaggedValue(NameDictionary::Remove(thread, moduleItems, entry));
}
}

View File

@ -44,6 +44,7 @@ public:
ACCESSORS(NameDictionary, NAME_DICTIONARY_OFFSET, SIZE)
DECL_VISIT_OBJECT_FOR_JS_OBJECT(ECMAObject, NAME_DICTIONARY_OFFSET, SIZE)
DECL_DUMP()
protected:
static void CopyModuleInternal(const JSThread *thread, JSHandle<EcmaModule> dstModule,

View File

@ -449,7 +449,7 @@ Expected<int, Runtime::Error> EcmaVM::InvokeEcmaEntrypoint(const panda_file::Fil
params->MakeArgList(*jsargs);
panda::ecmascript::InvokeJsFunction(thread_, func, global, newTarget, params);
if (!thread_->HasPendingException()) {
job::MicroJobQueue::Cast(microJobQueue_.GetTaggedObject())->ExecutePendingJob(thread_);
job::MicroJobQueue::ExecutePendingJob(thread_, GetMicroJobQueue());
}
// print exception information
@ -650,7 +650,7 @@ void EcmaVM::ClearBufferData()
bool EcmaVM::ExecutePromisePendingJob() const
{
if (!thread_->HasPendingException()) {
job::MicroJobQueue::Cast(microJobQueue_.GetTaggedObject())->ExecutePendingJob(thread_);
job::MicroJobQueue::ExecutePendingJob(thread_, GetMicroJobQueue());
return true;
}
return false;

View File

@ -337,16 +337,6 @@ public:
return moduleManager_;
}
static constexpr uint32_t GetGlobalEnvOffset()
{
return MEMBER_OFFSET(EcmaVM, globalEnv_);
}
static constexpr uint32_t GetMicroJobQueueOffset()
{
return MEMBER_OFFSET(EcmaVM, microJobQueue_);
}
void SetupRegExpResultCache();
JSHandle<JSTaggedValue> GetRegExpCache()
{

View File

@ -217,8 +217,12 @@
#ifdef PANDA_TARGET_AMD64
#define GET_CURRETN_FP(fp) asm("mov %%rbp, %0" : "=rm" (fp))
#define POINTER_CAST(fp, type) static_cast<type>(static_cast<void *>(fp)
#define GET_PREV_FP(fp) reinterpret_cast<uintptr_t *>(*(fp))
#else
#define GET_CURRETN_FP(fp)
#define POINTER_CAST(fp, type) static_cast<type>(static_cast<void *>(fp))
#define GET_PREV_FP(fp) reinterpret_cast<uintptr_t *>(*(POINTER_CAST(fp, uintptr_t *)))
#endif
namespace panda::ecmascript {

View File

@ -34,7 +34,7 @@ HeapProfiler::~HeapProfiler()
jsonSerializer_ = nullptr;
}
bool HeapProfiler::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &filePath)
bool HeapProfiler::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &filePath, bool isVmMode)
{
[[maybe_unused]] bool heapClean = ForceFullGC(thread);
ASSERT(heapClean);
@ -42,7 +42,7 @@ bool HeapProfiler::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, con
size_t heapSize = heap->GetNewSpace()->GetHeapObjectSize() + heap->GetOldSpace()->GetHeapObjectSize()
+ heap->GetNonMovableSpace()->GetHeapObjectSize();
LOG(ERROR, RUNTIME) << "HeapProfiler DumpSnapshot heap size " << heapSize;
HeapSnapShot *snapShot = MakeHeapSnapShot(thread, SampleType::ONE_SHOT);
HeapSnapShot *snapShot = MakeHeapSnapShot(thread, SampleType::ONE_SHOT, isVmMode);
ASSERT(snapShot != nullptr);
std::pair<bool, CString> realPath = FilePathValid(filePath);
if (realPath.first) {
@ -56,9 +56,9 @@ bool HeapProfiler::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, con
UNREACHABLE();
}
bool HeapProfiler::StartHeapTracking(JSThread *thread, double timeInterval)
bool HeapProfiler::StartHeapTracking(JSThread *thread, double timeInterval, bool isVmMode)
{
HeapSnapShot *snapShot = MakeHeapSnapShot(thread, SampleType::REAL_TIME);
HeapSnapShot *snapShot = MakeHeapSnapShot(thread, SampleType::REAL_TIME, isVmMode);
if (snapShot == nullptr) {
return false;
}
@ -158,14 +158,15 @@ bool HeapProfiler::ForceFullGC(JSThread *thread)
return false;
}
HeapSnapShot *HeapProfiler::MakeHeapSnapShot(JSThread *thread, SampleType sampleType)
HeapSnapShot *HeapProfiler::MakeHeapSnapShot(JSThread *thread, SampleType sampleType, bool isVmMode)
{
LOG(ERROR, RUNTIME) << "HeapProfiler::MakeHeapSnapShot";
DISALLOW_GARBAGE_COLLECTION;
heap_->GetSweeper()->EnsureAllTaskFinish();
switch (sampleType) {
case SampleType::ONE_SHOT: {
auto *snapShot = const_cast<RegionFactory *>(heap_->GetRegionFactory())->New<HeapSnapShot>(thread, heap_);
auto *snapShot =
const_cast<RegionFactory *>(heap_->GetRegionFactory())->New<HeapSnapShot>(thread, heap_, isVmMode);
if (snapShot == nullptr) {
LOG_ECMA(FATAL) << "alloc snapshot failed";
UNREACHABLE();
@ -175,7 +176,8 @@ HeapSnapShot *HeapProfiler::MakeHeapSnapShot(JSThread *thread, SampleType sample
return snapShot;
}
case SampleType::REAL_TIME: {
auto *snapShot = const_cast<RegionFactory *>(heap_->GetRegionFactory())->New<HeapSnapShot>(thread, heap_);
auto *snapShot =
const_cast<RegionFactory *>(heap_->GetRegionFactory())->New<HeapSnapShot>(thread, heap_, isVmMode);
if (snapShot == nullptr) {
LOG_ECMA(FATAL) << "alloc snapshot failed";
UNREACHABLE();

View File

@ -44,10 +44,10 @@ public:
/**
* dump the specific snapshot in target format
*/
bool DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &path);
bool DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &path, bool isVmMode = true);
void AddSnapShot(HeapSnapShot *snapshot);
bool StartHeapTracking(JSThread *thread, double timeInterval) override;
bool StartHeapTracking(JSThread *thread, double timeInterval, bool isVmMode = true) override;
bool StopHeapTracking(JSThread *thread, DumpFormat dumpFormat, const CString &filePath) override;
private:
@ -59,7 +59,7 @@ private:
/**
* make a new heap snapshot and put it into a container eg, vector
*/
HeapSnapShot *MakeHeapSnapShot(JSThread *thread, SampleType sampleType);
HeapSnapShot *MakeHeapSnapShot(JSThread *thread, SampleType sampleType, bool isVmMode = true);
std::pair<bool, CString> FilePathValid(const CString &filePath);
CString GenDumpFileName(DumpFormat dumpFormat);
CString GetTimeStamp();

View File

@ -18,7 +18,7 @@
#include "ecmascript/mem/heap.h"
namespace panda::ecmascript {
void HeapProfilerInterface::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &filePath)
void HeapProfilerInterface::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &filePath, bool isVmMode)
{
LOG(ERROR, RUNTIME) << "HeapProfilerInterface::DumpHeapSnapshot";
const Heap *heap = thread->GetEcmaVM()->GetHeap();
@ -27,7 +27,7 @@ void HeapProfilerInterface::DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFo
LOG_ECMA(FATAL) << "alloc hprof failed";
UNREACHABLE();
}
hprof->DumpHeapSnapShot(thread, dumpFormat, filePath);
hprof->DumpHeapSnapShot(thread, dumpFormat, filePath, isVmMode);
const_cast<RegionFactory *>(heap->GetRegionFactory())->Delete(hprof);
}

View File

@ -24,7 +24,8 @@ enum class DumpFormat { JSON, BINARY, OTHER };
class HeapProfilerInterface {
public:
static void DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat, const CString &filePath);
static void DumpHeapSnapShot(JSThread *thread, DumpFormat dumpFormat,
const CString &filePath, bool isVmMode = true);
static HeapProfilerInterface *CreateHeapProfiler(JSThread *thread);
static void Destory(JSThread *thread, HeapProfilerInterface *heapProfiler);
@ -32,7 +33,7 @@ public:
HeapProfilerInterface() = default;
virtual ~HeapProfilerInterface() = default;
virtual bool StartHeapTracking(JSThread *thread, double timeInterval) = 0;
virtual bool StartHeapTracking(JSThread *thread, double timeInterval, bool isVmMode = true) = 0;
virtual bool StopHeapTracking(JSThread *thread, DumpFormat dumpFormat, const CString &filePath) = 0;
NO_MOVE_SEMANTIC(HeapProfilerInterface);

View File

@ -142,204 +142,36 @@ void HeapSnapShot::MoveNode(uintptr_t address, uintptr_t forward_address)
// NOLINTNEXTLINE(readability-function-size)
CString *HeapSnapShot::GenerateNodeName(JSThread *thread, TaggedObject *entry)
{
CString *name = GetString("UnKnownType");
auto *hCls = entry->GetClass();
if (hCls->IsTaggedArray()) {
CString arrayName;
TaggedArray *array = TaggedArray::Cast(entry);
if (hCls->IsDictionary()) {
arrayName = "TaggedDict[";
arrayName.append(ToCString(array->GetLength()));
arrayName.append("]");
} else {
JSType type = hCls->GetObjectType();
switch (type) {
case JSType::TAGGED_ARRAY: {
CString arrayName;
TaggedArray *array = TaggedArray::Cast(entry);
arrayName = "TaggedArray[";
arrayName.append(ToCString(array->GetLength()));
arrayName.append("]");
return GetString(arrayName); // String type was handled singly, see#GenerateStringNode
}
name = GetString(arrayName); // String type was handled singly, see#GenerateStringNode
} else if (hCls->IsHClass()) {
name = GetString("HiddenClass");
} else if (hCls->IsJSNativePointer()) {
name = GetString("JSNativePointer");
} else {
if (hCls->IsRealm()) {
name = GetString("JSRealm");
} else if (hCls->IsString()) {
name = GetString("JsString");
} else if (hCls->IsJSSymbol()) {
name = GetString("JSSymbol");
} else if (hCls->IsJSArray()) {
JSArray *jsArray = JSArray::Cast(entry);
CString arrayName("JSArray[");
arrayName.append(ToCString(jsArray->GetLength().GetInt()));
arrayName.append("]");
name = GetString(arrayName);
} else if (hCls->IsTypedArray()) {
name = GetString("TypedArray");
} else if (hCls->IsJSTypedArray()) {
name = GetString("JSTypedArray");
} else if (hCls->IsJSInt8Array()) {
name = GetString("JSInt8Array");
} else if (hCls->IsJSUint8Array()) {
name = GetString("JSUint8Array");
} else if (hCls->IsJSUint8ClampedArray()) {
name = GetString("JSUint8ClampedArray");
} else if (hCls->IsJSInt16Array()) {
name = GetString("JSInt16Array");
} else if (hCls->IsJSUint16Array()) {
name = GetString("JSUint16Array");
} else if (hCls->IsJSInt32Array()) {
name = GetString("JSInt32Array");
} else if (hCls->IsJSUint32Array()) {
name = GetString("JSUint32Array");
} else if (hCls->IsJSFloat32Array()) {
name = GetString("JSFloat32Array");
} else if (hCls->IsJSFloat64Array()) {
name = GetString("JSFloat64Array");
} else if (hCls->IsJsGlobalEnv()) {
name = GetString("JSGlobalEnv");
} else if (hCls->IsJSFunctionBase()) {
name = GetString("JSFunctionBase");
} else if (hCls->IsJsBoundFunction()) {
name = GetString("JsBoundFunction");
} else if (hCls->IsJSIntlBoundFunction()) {
name = GetString("JSIntlBoundFunction");
} else if (hCls->IsJSProxyRevocFunction()) {
name = GetString("JSProxyRevocFunction");
} else if (hCls->IsJSAsyncFunction()) {
name = GetString("JSAsyncFunction");
} else if (hCls->IsJSAsyncAwaitStatusFunction()) {
name = GetString("JSAsyncAwaitStatusFunction");
} else if (hCls->IsJSPromiseReactionFunction()) {
name = GetString("JSPromiseReactionFunction");
} else if (hCls->IsJSPromiseExecutorFunction()) {
name = GetString("JSPromiseExecutorFuncton");
} else if (hCls->IsJSPromiseAllResolveElementFunction()) {
name = GetString("JSPromiseAllResolveElementFunction");
} else if (hCls->IsJSFunctionExtraInfo()) {
name = GetString("JSFunctionExtraInfo");
} else if (hCls->IsMicroJobQueue()) {
name = GetString("MicroJobQueue");
} else if (hCls->IsPendingJob()) {
name = GetString("PendingJob");
} else if (hCls->IsJsPrimitiveRef()) {
name = GetString("JsPrimitiveRef");
} else if (hCls->IsJSSet()) {
name = GetString("JSSet");
} else if (hCls->IsJSMap()) {
name = GetString("JSMap");
} else if (hCls->IsJSWeakMap()) {
name = GetString("JSWeakMap");
} else if (hCls->IsJSWeakSet()) {
name = GetString("JSWeakSet");
} else if (hCls->IsJSFunction()) {
name = GetString("JSFunction");
} else if (hCls->IsJSError()) {
name = GetString("JSError");
} else if (hCls->IsArguments()) {
name = GetString("Arguments");
} else if (hCls->IsDate()) {
name = GetString("Date");
} else if (hCls->IsJSRegExp()) {
name = GetString("JSRegExp");
} else if (hCls->IsJSProxy()) {
name = GetString("JSProxy");
} else if (hCls->IsJSLocale()) {
name = GetString("JSLocale");
} else if (hCls->IsJSIntl()) {
name = GetString("JSIntl");
} else if (hCls->IsJSDateTimeFormat()) {
name = GetString("JSDateTimeFormat");
} else if (hCls->IsJSRelativeTimeFormat()) {
name = GetString("JSRelativeTimeFormat");
} else if (hCls->IsJSNumberFormat()) {
name = GetString("JSNumberFormat");
} else if (hCls->IsAccessorData()) {
name = GetString("AccessorData");
} else if (hCls->IsInternalAccessor()) {
name = GetString("InternalAccessor");
} else if (hCls->IsIterator()) {
name = GetString("Iterator");
} else if (hCls->IsForinIterator()) {
name = GetString("ForinIterator");
} else if (hCls->IsStringIterator()) {
name = GetString("StringIterator");
} else if (hCls->IsArrayBuffer()) {
name = GetString("ArrayBuffer");
} else if (hCls->IsDataView()) {
name = GetString("DataView");
} else if (hCls->IsJSSetIterator()) {
name = GetString("JSSetIterator");
} else if (hCls->IsJSMapIterator()) {
name = GetString("JSMapIterator");
} else if (hCls->IsJSArrayIterator()) {
name = GetString("JSArrayIterator");
} else if (hCls->IsPrototypeHandler()) {
name = GetString("PrototypeHandler");
} else if (hCls->IsTransitionHandler()) {
name = GetString("TransitionHandler");
} else if (hCls->IsPropertyBox()) {
name = GetString("PropertyBox");
} else if (hCls->IsProtoChangeMarker()) {
name = GetString("ProtoChangeMarker");
} else if (hCls->IsProtoChangeDetails()) {
name = GetString("ProtoChangeDetails");
} else if (hCls->IsProgram()) {
name = GetString("Program");
} else if (hCls->IsEcmaModule()) {
name = GetString("EcmaModule");
} else if (hCls->IsLexicalFunction()) {
name = GetString("LexicalFunction");
} else if (hCls->IsConstructor()) {
name = GetString("Constructor");
} else if (hCls->IsExtensible()) {
name = GetString("Extensible");
} else if (hCls->IsPrototype()) {
name = GetString("Prototype");
} else if (hCls->IsLiteral()) {
name = GetString("Literal");
} else if (hCls->IsClassConstructor()) {
name = GetString("ClassConstructor");
} else if (hCls->IsJSGlobalObject()) {
name = GetString("JSGlobalObject");
} else if (hCls->IsClassPrototype()) {
name = GetString("ClassPrototype");
} else if (hCls->IsGeneratorFunction()) {
name = GetString("GeneratorFunction");
} else if (hCls->IsGeneratorObject()) {
name = GetString("GeneratorObject");
} else if (hCls->IsAsyncFuncObject()) {
name = GetString("AsyncFunction");
} else if (hCls->IsJSPromise()) {
name = GetString("JSPromise");
} else if (hCls->IsResolvingFunctionsRecord()) {
name = GetString("ResolvingFunctionsRecord");
} else if (hCls->IsPromiseRecord()) {
name = GetString("PromiseRecord");
} else if (hCls->IsPromiseIteratorRecord()) {
name = GetString("JSPromiseIteratorRecord");
} else if (hCls->IsPromiseCapability()) {
name = GetString("PromiseCapability");
} else if (hCls->IsPromiseReaction()) {
name = GetString("JSPromiseReaction");
} else if (hCls->IsCompletionRecord()) {
name = GetString("CompletionRecord");
} else if (hCls->IsRecord()) {
name = GetString("Record");
} else if (hCls->IsTemplateMap()) {
name = GetString("TemplateMap");
} else if (hCls->IsFreeObjectWithOneField()) {
name = GetString("FreeObjectWithOneField");
} else if (hCls->IsFreeObjectWithTwoField()) {
name = GetString("FreeObjectWithTwoField");
} else if (hCls->IsJSObject()) {
case JSType::HCLASS:
return GetString("HiddenClass");
case JSType::TAGGED_DICTIONARY: {
CString dictName;
TaggedArray *dict = TaggedArray::Cast(entry);
dictName = "TaggedDict[";
dictName.append(ToCString(dict->GetLength()));
dictName.append("]");
return GetString(dictName);
}
case JSType::STRING:
return GetString("BaseString");
case JSType::JS_OBJECT: {
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
CString objName = CString("JSOBJECT(Ctor="); // Ctor-name
JSTaggedValue proto = JSObject::Cast(entry)->GetPrototype(thread);
JSHandle<JSTaggedValue> protoHandle(thread, proto);
if (protoHandle->IsNull() || protoHandle->IsUndefined()) {
name = GetString("JSObject(Ctor=UnKnown)");
return name;
return GetString("JSObject(Ctor=UnKnown)");
}
JSHandle<JSTaggedValue> ctor =
JSObject::GetProperty(thread, protoHandle, globalConst->GetHandledConstructorString()).GetValue();
@ -348,16 +180,197 @@ CString *HeapSnapShot::GenerateNodeName(JSThread *thread, TaggedObject *entry)
JSHandle<JSTaggedValue> value = JSObject::GetProperty(thread, ctor, nameKey).GetValue();
CString ctorName = EntryVisitor::ConvertKey(value.GetTaggedValue());
objName.append(ctorName).append(")");
name = GetString(objName);
}
} else if (hCls->IsECMAObject()) {
name = GetString("ECMAObject");
} else {
name = GetString("UnEmuratedJSType");
return GetString(objName);
}
return name; // Cached in String-Table
case JSType::FREE_OBJECT_WITH_ONE_FIELD:
case JSType::FREE_OBJECT_WITH_NONE_FIELD:
case JSType::FREE_OBJECT_WITH_TWO_FIELD:
case JSType::JS_NATIVE_POINTER:
{
break;
}
case JSType::JS_FUNCTION_BASE:
return GetString("JSFunctionBase");
case JSType::JS_FUNCTION:
return GetString("JSFunction");
case JSType::JS_ERROR:
return GetString("Error");
case JSType::JS_EVAL_ERROR:
return GetString("Eval Error");
case JSType::JS_RANGE_ERROR:
return GetString("Range Error");
case JSType::JS_TYPE_ERROR:
return GetString("Type Error");
case JSType::JS_REFERENCE_ERROR:
return GetString("Reference Error");
case JSType::JS_URI_ERROR:
return GetString("Uri Error");
case JSType::JS_SYNTAX_ERROR:
return GetString("Syntax Error");
case JSType::JS_REG_EXP:
return GetString("Regexp");
case JSType::JS_SET:
return GetString("Set");
case JSType::JS_MAP:
return GetString("Map");
case JSType::JS_WEAK_SET:
return GetString("WeakSet");
case JSType::JS_WEAK_MAP:
return GetString("WeakMap");
case JSType::JS_DATE:
return GetString("Date");
case JSType::JS_BOUND_FUNCTION:
return GetString("Bound Function");
case JSType::JS_ARRAY: {
JSArray *jsArray = JSArray::Cast(entry);
CString jsArrayName("JSArray[");
jsArrayName.append(ToCString(jsArray->GetLength().GetInt()));
jsArrayName.append("]");
return GetString(jsArrayName);
}
case JSType::JS_TYPED_ARRAY:
return GetString("Typed Array");
case JSType::JS_INT8_ARRAY:
return GetString("Int8 Array");
case JSType::JS_UINT8_ARRAY:
return GetString("Uint8 Array");
case JSType::JS_UINT8_CLAMPED_ARRAY:
return GetString("Uint8 Clamped Array");
case JSType::JS_INT16_ARRAY:
return GetString("Int16 Array");
case JSType::JS_UINT16_ARRAY:
return GetString("Uint16 Array");
case JSType::JS_INT32_ARRAY:
return GetString("Int32 Array");
case JSType::JS_UINT32_ARRAY:
return GetString("Uint32 Array");
case JSType::JS_FLOAT32_ARRAY:
return GetString("Float32 Array");
case JSType::JS_FLOAT64_ARRAY:
return GetString("Float64 Array");
case JSType::JS_ARGUMENTS:
return GetString("Arguments");
case JSType::JS_PROXY:
return GetString("Proxy");
case JSType::JS_PRIMITIVE_REF:
return GetString("Primitive");
case JSType::JS_DATA_VIEW:
return GetString("DataView");
case JSType::JS_ITERATOR:
return GetString("Iterator");
case JSType::JS_FORIN_ITERATOR:
return GetString("ForinInterator");
case JSType::JS_MAP_ITERATOR:
return GetString("MapIterator");
case JSType::JS_SET_ITERATOR:
return GetString("SetIterator");
case JSType::JS_ARRAY_ITERATOR:
return GetString("ArrayIterator");
case JSType::JS_STRING_ITERATOR:
return GetString("StringIterator");
case JSType::JS_ARRAY_BUFFER:
return GetString("ArrayBuffer");
case JSType::JS_PROXY_REVOC_FUNCTION:
return GetString("ProxyRevocFunction");
case JSType::PROMISE_REACTIONS:
return GetString("PromiseReaction");
case JSType::PROMISE_CAPABILITY:
return GetString("PromiseCapability");
case JSType::PROMISE_ITERATOR_RECORD:
return GetString("PromiseIteratorRecord");
case JSType::PROMISE_RECORD:
return GetString("PromiseRecord");
case JSType::RESOLVING_FUNCTIONS_RECORD:
return GetString("ResolvingFunctionsRecord");
case JSType::JS_PROMISE:
return GetString("Promise");
case JSType::JS_PROMISE_REACTIONS_FUNCTION:
return GetString("PromiseReactionsFunction");
case JSType::JS_PROMISE_EXECUTOR_FUNCTION:
return GetString("PromiseExecutorFunction");
case JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION:
return GetString("PromiseAllResolveElementFunction");
case JSType::JS_GENERATOR_FUNCTION:
return GetString("JSGeneratorFunction");
case JSType::SYMBOL:
return GetString("Symbol");
case JSType::JS_ASYNC_FUNCTION:
return GetString("AsyncFunction");
case JSType::JS_INTL_BOUND_FUNCTION:
return GetString("JSIntlBoundFunction");
case JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION:
return GetString("AsyncAwaitStatusFunction");
case JSType::JS_ASYNC_FUNC_OBJECT:
return GetString("AsyncFunctionObject");
case JSType::JS_REALM:
return GetString("Realm");
case JSType::JS_GLOBAL_OBJECT:
return GetString("GlobalObject");
case JSType::JS_INTL:
return GetString("JSIntl");
case JSType::JS_LOCALE:
return GetString("JSLocale");
case JSType::JS_DATE_TIME_FORMAT:
return GetString("JSDateTimeFormat");
case JSType::JS_RELATIVE_TIME_FORMAT:
return GetString("JSRelativeTimeFormat");
case JSType::JS_NUMBER_FORMAT:
return GetString("JSNumberFormat");
case JSType::JS_COLLATOR:
return GetString("JSCollator");
case JSType::JS_PLURAL_RULES:
return GetString("JSPluralRules");
case JSType::JS_GENERATOR_OBJECT:
return GetString("JSGeneratorObject");
case JSType::JS_GENERATOR_CONTEXT:
return GetString("JSGeneratorContext");
case JSType::ACCESSOR_DATA:
return GetString("AccessorData");
case JSType::INTERNAL_ACCESSOR:
return GetString("InternalAccessor");
case JSType::FUNCTION_EXTRA_INFO:
return GetString("FunctionExtraInfo");
case JSType::MICRO_JOB_QUEUE:
return GetString("MicroJobQueue");
case JSType::PENDING_JOB:
return GetString("PendingJob");
case JSType::COMPLETION_RECORD:
return GetString("CompletionRecord");
case JSType::ECMA_MODULE:
return GetString("EcmaModule");
default:
break;
}
return name;
if (IsInVmMode()) {
switch (type) {
case JSType::PROPERTY_BOX:
return GetString("PropertyBox");
case JSType::GLOBAL_ENV:
return GetString("GlobalEnv");
case JSType::PROTOTYPE_HANDLER:
return GetString("ProtoTypeHandler");
case JSType::TRANSITION_HANDLER:
return GetString("TransitionHandler");
case JSType::PROTO_CHANGE_MARKER:
return GetString("ProtoChangeMarker");
case JSType::PROTOTYPE_INFO:
return GetString("ProtoChangeDetails");
case JSType::TEMPLATE_MAP:
return GetString("TemplateMap");
case JSType::PROGRAM:
return GetString("Program");
case JSType::LEXICAL_FUNCTION:
return GetString("LexicalFunction");
case JSType::MACHINE_CODE_OBJECT:
return GetString("MachineCode");
default:
break;
}
} else {
return GetString("Hidden Object");
}
return GetString("UnKnownType");
}
NodeType HeapSnapShot::GenerateNodeType(TaggedObject *entry)
@ -367,7 +380,7 @@ NodeType HeapSnapShot::GenerateNodeType(TaggedObject *entry)
if (hCls->IsTaggedArray()) {
nodeType = NodeType::JS_ARRAY;
} else if (hCls->IsHClass()) {
nodeType = NodeType::PROPERTY_BOX;
nodeType = NodeType::HCLASS;
} else {
nodeType = NodeType(hCls->GetObjectType());
}
@ -489,7 +502,7 @@ void HeapSnapShot::FillEdges(JSThread *thread)
ASSERT(*iter != nullptr);
auto *objFrom = reinterpret_cast<TaggedObject *>((*iter)->GetAddress());
std::vector<std::pair<CString, JSTaggedValue>> nameResources;
JSTaggedValue(objFrom).DumpForSnapshot(thread, nameResources);
JSTaggedValue(objFrom).DumpForSnapshot(thread, nameResources, isVmMode_);
JSTaggedValue objValue(objFrom);
for (auto const &it : nameResources) {
JSTaggedValue toValue = it.second;

View File

@ -236,8 +236,8 @@ public:
static constexpr int SEQ_STEP = 2;
NO_MOVE_SEMANTIC(HeapSnapShot);
NO_COPY_SEMANTIC(HeapSnapShot);
explicit HeapSnapShot(JSThread *thread, const Heap *heap)
: stringTable_(heap), thread_(thread), heap_(heap)
explicit HeapSnapShot(JSThread *thread, const Heap *heap, const bool isVmMode)
: stringTable_(heap), thread_(thread), heap_(heap), isVmMode_(isVmMode)
{
}
~HeapSnapShot();
@ -293,6 +293,11 @@ public:
CString *GetString(const CString &as);
bool IsInVmMode() const
{
return isVmMode_;
}
private:
void FillNodes(JSThread *thread);
Node *GenerateNode(JSThread *thread, JSTaggedValue entry, int sequenceId = -1);
@ -320,6 +325,7 @@ private:
panda::ecmascript::HeapRootVisitor rootVisitor_;
JSThread *thread_;
const Heap *heap_;
bool isVmMode_{true};
};
class EntryVisitor {

View File

@ -16,20 +16,76 @@
#include <cstdio>
#include <fstream>
#include "ecmascript/accessor_data.h"
#include "ecmascript/class_linker/program_object-inl.h"
#include "ecmascript/ecma_module.h"
#include "ecmascript/ecma_vm.h"
#include "ecmascript/global_dictionary-inl.h"
#include "ecmascript/global_env.h"
#include "ecmascript/hprof/heap_profiler.h"
#include "ecmascript/hprof/heap_profiler_interface.h"
#include "ecmascript/hprof/heap_snapshot.h"
#include "ecmascript/hprof/heap_snapshot_json_serializer.h"
#include "ecmascript/hprof/string_hashmap.h"
#include "ecmascript/ic/ic_handler.h"
#include "ecmascript/ic/proto_change_details.h"
#include "ecmascript/ic/property_box.h"
#include "ecmascript/jobs/micro_job_queue.h"
#include "ecmascript/jobs/pending_job.h"
#include "ecmascript/js_arguments.h"
#include "ecmascript/js_array.h"
#include "ecmascript/js_array_iterator.h"
#include "ecmascript/js_arraybuffer.h"
#include "ecmascript/js_async_function.h"
#include "ecmascript/js_collator.h"
#include "ecmascript/js_dataview.h"
#include "ecmascript/js_date.h"
#include "ecmascript/js_date_time_format.h"
#include "ecmascript/js_for_in_iterator.h"
#include "ecmascript/js_function.h"
#include "ecmascript/js_function_extra_info.h"
#include "ecmascript/js_generator_object.h"
#include "ecmascript/js_global_object.h"
#include "ecmascript/js_handle.h"
#include "ecmascript/js_intl.h"
#include "ecmascript/js_locale.h"
#include "ecmascript/js_map.h"
#include "ecmascript/js_map_iterator.h"
#include "ecmascript/js_number_format.h"
#include "ecmascript/js_object-inl.h"
#include "ecmascript/js_plural_rules.h"
#include "ecmascript/js_primitive_ref.h"
#include "ecmascript/js_promise.h"
#include "ecmascript/js_realm.h"
#include "ecmascript/js_regexp.h"
#include "ecmascript/js_relative_time_format.h"
#include "ecmascript/js_set.h"
#include "ecmascript/js_set_iterator.h"
#include "ecmascript/js_string_iterator.h"
#include "ecmascript/js_tagged_number.h"
#include "ecmascript/js_tagged_value-inl.h"
#include "ecmascript/js_thread.h"
#include "ecmascript/js_typed_array.h"
#include "ecmascript/js_weak_container.h"
#include "ecmascript/layout_info-inl.h"
#include "ecmascript/lexical_env.h"
#include "ecmascript/linked_hash_table-inl.h"
#include "ecmascript/mem/assert_scope-inl.h"
#include "ecmascript/mem/c_containers.h"
#include "ecmascript/mem/machine_code.h"
#include "ecmascript/object_factory.h"
#include "ecmascript/tagged_array.h"
#include "ecmascript/tagged_dictionary.h"
#include "ecmascript/template_map.h"
#include "ecmascript/tests/test_helper.h"
#include "ecmascript/transitions_dictionary.h"
using namespace panda::ecmascript;
using namespace panda::ecmascript::base;
namespace panda::test {
using MicroJobQueue = panda::ecmascript::job::MicroJobQueue;
using PendingJob = panda::ecmascript::job::PendingJob;
class HProfTest : public testing::Test {
public:
static void SetUpTestCase()
@ -332,4 +388,502 @@ HWTEST_F_L0(HProfTest, ContrastTraceFunctionInfoCount)
tester.ExtractCountFromPayload("\"trace_function_infos\":"));
ASSERT_TRUE(tester.RemoveExistingFile());
}
static JSHandle<JSMap> NewJSMap(JSThread *thread, ObjectFactory *factory, JSHandle<JSTaggedValue> proto)
{
JSHandle<JSHClass> mapClass = factory->NewEcmaDynClass(JSMap::SIZE, JSType::JS_MAP, proto);
JSHandle<JSMap> jsMap = JSHandle<JSMap>::Cast(factory->NewJSObject(mapClass));
JSHandle<JSTaggedValue> linkedMap(thread, LinkedHashMap::Create(thread));
jsMap->SetLinkedMap(thread, linkedMap);
return jsMap;
}
static JSHandle<JSSet> NewJSSet(JSThread *thread, ObjectFactory *factory, JSHandle<JSTaggedValue> proto)
{
JSHandle<JSHClass> setClass = factory->NewEcmaDynClass(JSSet::SIZE, JSType::JS_SET, proto);
JSHandle<JSSet> jsSet = JSHandle<JSSet>::Cast(factory->NewJSObject(setClass));
JSHandle<JSTaggedValue> linkedSet(thread, LinkedHashSet::Create(thread));
jsSet->SetLinkedSet(thread, linkedSet);
return jsSet;
}
static JSHandle<JSObject> NewJSObject(JSThread *thread, ObjectFactory *factory, JSHandle<GlobalEnv> globalEnv)
{
JSFunction *jsFunc = globalEnv->GetObjectFunction().GetObject<JSFunction>();
JSHandle<JSTaggedValue> jsFunc1(thread, jsFunc);
JSHandle<JSObject> jsObj = factory->NewJSObjectByConstructor(JSHandle<JSFunction>(jsFunc1), jsFunc1);
return jsObj;
}
HWTEST_F_L0(HProfTest, Dump)
{
[[maybe_unused]] ecmascript::EcmaHandleScope scope(thread);
auto factory = thread->GetEcmaVM()->GetFactory();
auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv();
auto globalConst = const_cast<GlobalEnvConstants *>(thread->GlobalConstants());
JSHandle<JSTaggedValue> proto = globalEnv->GetFunctionPrototype();
std::vector<std::pair<CString, JSTaggedValue>> snapshotVector;
#define DUMP_FOR_HANDLE(dumpHandle) \
dumpHandle.GetTaggedValue().Dump(thread); \
dumpHandle.GetTaggedValue().DumpForSnapshot(thread, snapshotVector);
#define NEW_OBJECT_AND_DUMP(ClassName, TypeName) \
JSHandle<JSHClass> class##ClassName = \
factory->NewEcmaDynClass(ClassName::SIZE, JSType::TypeName, proto); \
JSHandle<JSObject> object##ClassName = factory->NewJSObject(class##ClassName); \
object##ClassName.GetTaggedValue().Dump(thread); \
object##ClassName.GetTaggedValue().DumpForSnapshot(thread, snapshotVector);
for (JSType type = JSType::JS_OBJECT; type <= JSType::JS_TYPE_LAST; type = JSType(static_cast<int>(type) + 1)) {
switch (type) {
case JSType::JS_ERROR:
case JSType::JS_EVAL_ERROR:
case JSType::JS_RANGE_ERROR:
case JSType::JS_TYPE_ERROR:
case JSType::JS_REFERENCE_ERROR:
case JSType::JS_URI_ERROR:
case JSType::JS_SYNTAX_ERROR:
case JSType::JS_OBJECT: {
CHECK_DUMP_FILEDS(ECMAObject::SIZE, JSObject::SIZE, 2)
JSHandle<JSObject> jsObj = NewJSObject(thread, factory, globalEnv);
DUMP_FOR_HANDLE(jsObj)
break;
}
case JSType::JS_REALM: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSRealm::SIZE, 2)
JSHandle<JSRealm> jsRealm = factory->NewJSRealm();
DUMP_FOR_HANDLE(jsRealm)
break;
}
case JSType::JS_FUNCTION_BASE: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSFunctionBase::SIZE, 1)
break;
}
case JSType::JS_FUNCTION: {
CHECK_DUMP_FILEDS(JSFunctionBase::SIZE, JSFunction::SIZE, 7)
JSHandle<JSTaggedValue> jsFunc = globalEnv->GetFunctionFunction();
DUMP_FOR_HANDLE(jsFunc)
break;
}
case JSType::JS_PROXY_REVOC_FUNCTION: {
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSProxyRevocFunction::SIZE, 1)
JSHandle<JSHClass> proxyRevocClass =
JSHandle<JSHClass>::Cast(globalEnv->GetProxyRevocFunctionClass());
JSHandle<JSObject> proxyRevocFunc = factory->NewJSObject(proxyRevocClass);
DUMP_FOR_HANDLE(proxyRevocFunc)
break;
}
case JSType::JS_PROMISE_REACTIONS_FUNCTION: {
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSPromiseReactionsFunction::SIZE, 2)
JSHandle<JSHClass> promiseReactClass =
JSHandle<JSHClass>::Cast(globalEnv->GetPromiseReactionFunctionClass());
JSHandle<JSObject> promiseReactFunc = factory->NewJSObject(promiseReactClass);
DUMP_FOR_HANDLE(promiseReactFunc)
break;
}
case JSType::JS_PROMISE_EXECUTOR_FUNCTION: {
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSPromiseExecutorFunction::SIZE, 1)
JSHandle<JSHClass> promiseExeClass =
JSHandle<JSHClass>::Cast(globalEnv->GetPromiseExecutorFunctionClass());
JSHandle<JSObject> promiseExeFunc = factory->NewJSObject(promiseExeClass);
DUMP_FOR_HANDLE(promiseExeFunc)
break;
}
case JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION: {
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSPromiseAllResolveElementFunction::SIZE, 5)
JSHandle<JSHClass> promiseAllClass =
JSHandle<JSHClass>::Cast(globalEnv->GetPromiseAllResolveElementFunctionClass());
JSHandle<JSObject> promiseAllFunc = factory->NewJSObject(promiseAllClass);
DUMP_FOR_HANDLE(promiseAllFunc)
break;
}
case JSType::JS_GENERATOR_FUNCTION: {
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSGeneratorFunction::SIZE, 0)
break;
}
case JSType::JS_ASYNC_FUNCTION: {
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSAsyncFunction::SIZE, 0)
break;
}
case JSType::JS_INTL_BOUND_FUNCTION: {
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSIntlBoundFunction::SIZE, 3)
JSHandle<JSIntlBoundFunction> intlBoundFunc = factory->NewJSIntlBoundFunction();
DUMP_FOR_HANDLE(intlBoundFunc)
break;
}
case JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION: {
CHECK_DUMP_FILEDS(JSFunction::SIZE, JSAsyncAwaitStatusFunction::SIZE, 1)
JSHandle<JSAsyncAwaitStatusFunction> asyncAwaitFunc = factory->NewJSAsyncAwaitStatusFunction();
DUMP_FOR_HANDLE(asyncAwaitFunc)
break;
}
case JSType::JS_BOUND_FUNCTION: {
CHECK_DUMP_FILEDS(JSFunctionBase::SIZE, JSBoundFunction::SIZE, 3)
NEW_OBJECT_AND_DUMP(JSBoundFunction, JS_BOUND_FUNCTION)
break;
}
case JSType::JS_REG_EXP: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSRegExp::SIZE, 5)
NEW_OBJECT_AND_DUMP(JSRegExp, JS_REG_EXP)
break;
}
case JSType::JS_SET: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSSet::SIZE, 1)
JSHandle<JSSet> jsSet = NewJSSet(thread, factory, proto);
DUMP_FOR_HANDLE(jsSet)
break;
}
case JSType::JS_MAP: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSMap::SIZE, 1)
JSHandle<JSMap> jsMap = NewJSMap(thread, factory, proto);
DUMP_FOR_HANDLE(jsMap)
break;
}
case JSType::JS_WEAK_MAP: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSWeakMap::SIZE, 1)
JSHandle<JSHClass> weakMapClass = factory->NewEcmaDynClass(JSWeakMap::SIZE, JSType::JS_WEAK_MAP, proto);
JSHandle<JSWeakMap> jsWeakMap = JSHandle<JSWeakMap>::Cast(factory->NewJSObject(weakMapClass));
JSHandle<JSTaggedValue> weakLinkedMap(thread, LinkedHashMap::Create(thread));
jsWeakMap->SetLinkedMap(thread, weakLinkedMap);
DUMP_FOR_HANDLE(jsWeakMap)
break;
}
case JSType::JS_WEAK_SET: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSWeakSet::SIZE, 1)
JSHandle<JSHClass> weakSetClass = factory->NewEcmaDynClass(JSWeakSet::SIZE, JSType::JS_WEAK_SET, proto);
JSHandle<JSWeakSet> jsWeakSet = JSHandle<JSWeakSet>::Cast(factory->NewJSObject(weakSetClass));
JSHandle<JSTaggedValue> weakLinkedSet(thread, LinkedHashSet::Create(thread));
jsWeakSet->SetLinkedSet(thread, weakLinkedSet);
DUMP_FOR_HANDLE(jsWeakSet)
break;
}
case JSType::JS_DATE: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSDate::SIZE, 2)
JSHandle<JSHClass> dateClass = factory->NewEcmaDynClass(JSDate::SIZE, JSType::JS_DATE, proto);
JSHandle<JSDate> date = JSHandle<JSDate>::Cast(factory->NewJSObject(dateClass));
date->SetTimeValue(thread, JSTaggedValue(0.0));
date->SetLocalOffset(thread, JSTaggedValue(0.0));
DUMP_FOR_HANDLE(date)
break;
}
case JSType::JS_ITERATOR:
// JS Iterate is a tool class, so we don't need to check it.
break;
case JSType::JS_FORIN_ITERATOR: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSForInIterator::SIZE, 4)
JSHandle<JSTaggedValue> array(thread, factory->NewJSArray().GetTaggedValue());
JSHandle<JSForInIterator> forInIter = factory->NewJSForinIterator(array);
DUMP_FOR_HANDLE(forInIter)
break;
}
case JSType::JS_MAP_ITERATOR: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSMapIterator::SIZE, 3)
JSHandle<JSMapIterator> jsMapIter =
factory->NewJSMapIterator(NewJSMap(thread, factory, proto), IterationKind::KEY);
DUMP_FOR_HANDLE(jsMapIter)
break;
}
case JSType::JS_SET_ITERATOR: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSSetIterator::SIZE, 3)
JSHandle<JSSetIterator> jsSetIter =
factory->NewJSSetIterator(NewJSSet(thread, factory, proto), IterationKind::KEY);
DUMP_FOR_HANDLE(jsSetIter)
break;
}
case JSType::JS_ARRAY_ITERATOR: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSArrayIterator::SIZE, 3)
JSHandle<JSArrayIterator> arrayIter =
factory->NewJSArrayIterator(JSHandle<JSObject>::Cast(factory->NewJSArray()), IterationKind::KEY);
DUMP_FOR_HANDLE(arrayIter)
break;
}
case JSType::JS_STRING_ITERATOR: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSStringIterator::SIZE, 2)
JSHandle<JSTaggedValue> stringIter = globalEnv->GetStringIterator();
DUMP_FOR_HANDLE(stringIter)
break;
}
case JSType::JS_INTL: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSIntl::SIZE, 1)
NEW_OBJECT_AND_DUMP(JSIntl, JS_INTL)
break;
}
case JSType::JS_LOCALE: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSLocale::SIZE, 1)
NEW_OBJECT_AND_DUMP(JSLocale, JS_LOCALE)
break;
}
case JSType::JS_DATE_TIME_FORMAT: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSDateTimeFormat::SIZE, 11)
NEW_OBJECT_AND_DUMP(JSDateTimeFormat, JS_DATE_TIME_FORMAT)
break;
}
case JSType::JS_RELATIVE_TIME_FORMAT: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSRelativeTimeFormat::SIZE, 7)
NEW_OBJECT_AND_DUMP(JSRelativeTimeFormat, JS_RELATIVE_TIME_FORMAT)
break;
}
case JSType::JS_NUMBER_FORMAT: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSNumberFormat::SIZE, 20)
NEW_OBJECT_AND_DUMP(JSNumberFormat, JS_NUMBER_FORMAT)
break;
}
case JSType::JS_COLLATOR: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSCollator::SIZE, 9)
NEW_OBJECT_AND_DUMP(JSCollator, JS_COLLATOR)
break;
}
case JSType::JS_PLURAL_RULES: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSPluralRules::SIZE, 11)
NEW_OBJECT_AND_DUMP(JSPluralRules, JS_PLURAL_RULES)
break;
}
case JSType::JS_ARRAY_BUFFER: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSArrayBuffer::SIZE, 3)
NEW_OBJECT_AND_DUMP(JSArrayBuffer, JS_ARRAY_BUFFER)
break;
}
case JSType::JS_PROMISE: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSPromise::SIZE, 5)
NEW_OBJECT_AND_DUMP(JSPromise, JS_PROMISE)
break;
}
case JSType::JS_DATA_VIEW: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSDataView::SIZE, 4)
NEW_OBJECT_AND_DUMP(JSDataView, JS_DATA_VIEW)
break;
}
case JSType::JS_ARGUMENTS: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSArguments::SIZE, 1)
NEW_OBJECT_AND_DUMP(JSArguments, JS_ARGUMENTS)
break;
}
case JSType::JS_GENERATOR_OBJECT: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSGeneratorObject::SIZE, 4)
NEW_OBJECT_AND_DUMP(JSGeneratorObject, JS_GENERATOR_OBJECT)
break;
}
case JSType::JS_ASYNC_FUNC_OBJECT: {
CHECK_DUMP_FILEDS(JSGeneratorObject::SIZE, JSAsyncFuncObject::SIZE, 1)
JSHandle<JSAsyncFuncObject> asyncFuncObject = factory->NewJSAsyncFuncObject();
DUMP_FOR_HANDLE(asyncFuncObject)
break;
}
case JSType::JS_ARRAY: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSArray::SIZE, 1)
JSHandle<JSArray> jsArray = factory->NewJSArray();
DUMP_FOR_HANDLE(jsArray)
break;
}
case JSType::JS_TYPED_ARRAY:
case JSType::JS_INT8_ARRAY:
case JSType::JS_UINT8_ARRAY:
case JSType::JS_UINT8_CLAMPED_ARRAY:
case JSType::JS_INT16_ARRAY:
case JSType::JS_UINT16_ARRAY:
case JSType::JS_INT32_ARRAY:
case JSType::JS_UINT32_ARRAY:
case JSType::JS_FLOAT32_ARRAY:
case JSType::JS_FLOAT64_ARRAY: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSTypedArray::SIZE, 5)
NEW_OBJECT_AND_DUMP(JSTypedArray, JS_TYPED_ARRAY)
break;
}
case JSType::JS_PRIMITIVE_REF: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSPrimitiveRef::SIZE, 1)
NEW_OBJECT_AND_DUMP(JSPrimitiveRef, JS_PRIMITIVE_REF)
break;
}
case JSType::JS_GLOBAL_OBJECT: {
CHECK_DUMP_FILEDS(JSObject::SIZE, JSGlobalObject::SIZE, 0)
JSHandle<JSTaggedValue> globalObject = globalEnv->GetJSGlobalObject();
DUMP_FOR_HANDLE(globalObject)
break;
}
case JSType::JS_PROXY: {
CHECK_DUMP_FILEDS(ECMAObject::SIZE, JSProxy::SIZE, 3)
JSHandle<JSTaggedValue> emptyObj(thread, NewJSObject(thread, factory, globalEnv).GetTaggedValue());
JSHandle<JSProxy> proxy = factory->NewJSProxy(emptyObj, emptyObj);
DUMP_FOR_HANDLE(proxy)
break;
}
case JSType::HCLASS: {
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), JSHClass::SIZE, 9)
JSHandle<JSHClass> hclass = factory->NewEcmaDynClass(JSHClass::SIZE, JSType::HCLASS, proto);
DUMP_FOR_HANDLE(hclass)
break;
}
case JSType::STRING: {
DUMP_FOR_HANDLE(globalEnv->GetObjectFunction())
break;
}
case JSType::TAGGED_ARRAY: {
JSHandle<TaggedArray> taggedArray = factory->NewTaggedArray(4);
DUMP_FOR_HANDLE(taggedArray)
break;
}
case JSType::TAGGED_DICTIONARY: {
JSHandle<TaggedArray> dict = factory->NewDictionaryArray(4);
DUMP_FOR_HANDLE(dict)
break;
}
case JSType::FREE_OBJECT_WITH_ONE_FIELD:
case JSType::FREE_OBJECT_WITH_NONE_FIELD:
case JSType::FREE_OBJECT_WITH_TWO_FIELD:
{
break;
}
case JSType::JS_NATIVE_POINTER: {
break;
}
case JSType::GLOBAL_ENV: {
DUMP_FOR_HANDLE(globalEnv)
break;
}
case JSType::ACCESSOR_DATA:
case JSType::INTERNAL_ACCESSOR: {
CHECK_DUMP_FILEDS(Record::SIZE, AccessorData::SIZE, 2)
JSHandle<AccessorData> accessor = factory->NewAccessorData();
DUMP_FOR_HANDLE(accessor)
break;
}
case JSType::SYMBOL: {
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), JSSymbol::SIZE, 3)
JSHandle<JSSymbol> symbol = factory->NewJSSymbol();
DUMP_FOR_HANDLE(symbol)
break;
}
case JSType::JS_GENERATOR_CONTEXT: {
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), GeneratorContext::SIZE, 7)
JSHandle<GeneratorContext> genContext = factory->NewGeneratorContext();
DUMP_FOR_HANDLE(genContext)
break;
}
case JSType::PROTOTYPE_HANDLER: {
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), PrototypeHandler::SIZE, 3)
JSHandle<PrototypeHandler> protoHandler = factory->NewPrototypeHandler();
DUMP_FOR_HANDLE(protoHandler)
break;
}
case JSType::TRANSITION_HANDLER: {
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), TransitionHandler::SIZE, 2)
JSHandle<TransitionHandler> transitionHandler = factory->NewTransitionHandler();
DUMP_FOR_HANDLE(transitionHandler)
break;
}
case JSType::PROPERTY_BOX: {
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), PropertyBox::SIZE, 1)
JSHandle<PropertyBox> PropertyBox = factory->NewPropertyBox(globalEnv->GetEmptyArray());
DUMP_FOR_HANDLE(PropertyBox)
break;
}
case JSType::PROTO_CHANGE_MARKER: {
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), ProtoChangeMarker::SIZE, 1)
JSHandle<ProtoChangeMarker> protoMaker = factory->NewProtoChangeMarker();
DUMP_FOR_HANDLE(protoMaker)
break;
}
case JSType::PROTOTYPE_INFO: {
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), ProtoChangeDetails::SIZE, 2)
JSHandle<ProtoChangeDetails> protoDetails = factory->NewProtoChangeDetails();
DUMP_FOR_HANDLE(protoDetails)
break;
}
case JSType::TEMPLATE_MAP: {
JSHandle<JSTaggedValue> templateMap = globalEnv->GetTemplateMap();
DUMP_FOR_HANDLE(templateMap)
break;
}
case JSType::PROGRAM: {
CHECK_DUMP_FILEDS(ECMAObject::SIZE, Program::SIZE, 5)
JSHandle<Program> program = factory->NewProgram();
DUMP_FOR_HANDLE(program)
break;
}
case JSType::LEXICAL_FUNCTION: {
CHECK_DUMP_FILEDS(ECMAObject::SIZE, LexicalFunction::SIZE, 5)
// unused
break;
}
case JSType::PROMISE_CAPABILITY: {
CHECK_DUMP_FILEDS(Record::SIZE, PromiseCapability::SIZE, 3)
JSHandle<PromiseCapability> promiseCapa = factory->NewPromiseCapability();
DUMP_FOR_HANDLE(promiseCapa)
break;
}
case JSType::PROMISE_RECORD: {
CHECK_DUMP_FILEDS(Record::SIZE, PromiseRecord::SIZE, 1)
JSHandle<PromiseRecord> promiseRecord = factory->NewPromiseRecord();
DUMP_FOR_HANDLE(promiseRecord)
break;
}
case JSType::RESOLVING_FUNCTIONS_RECORD: {
CHECK_DUMP_FILEDS(Record::SIZE, ResolvingFunctionsRecord::SIZE, 2)
JSHandle<ResolvingFunctionsRecord> ResolvingFunc = factory->NewResolvingFunctionsRecord();
DUMP_FOR_HANDLE(ResolvingFunc)
break;
}
case JSType::PROMISE_REACTIONS: {
CHECK_DUMP_FILEDS(Record::SIZE, PromiseReaction::SIZE, 3)
JSHandle<PromiseReaction> promiseReact = factory->NewPromiseReaction();
DUMP_FOR_HANDLE(promiseReact)
break;
}
case JSType::PROMISE_ITERATOR_RECORD: {
CHECK_DUMP_FILEDS(Record::SIZE, PromiseIteratorRecord::SIZE, 2)
JSHandle<JSTaggedValue> emptyObj(thread, NewJSObject(thread, factory, globalEnv).GetTaggedValue());
JSHandle<PromiseIteratorRecord> promiseIter = factory->NewPromiseIteratorRecord(emptyObj, emptyObj);
DUMP_FOR_HANDLE(promiseIter)
break;
}
case JSType::MICRO_JOB_QUEUE: {
CHECK_DUMP_FILEDS(Record::SIZE, MicroJobQueue::SIZE, 2)
JSHandle<MicroJobQueue> microJob = factory->NewMicroJobQueue();
DUMP_FOR_HANDLE(microJob)
break;
}
case JSType::PENDING_JOB: {
CHECK_DUMP_FILEDS(Record::SIZE, PendingJob::SIZE, 2)
JSHandle<JSHClass> pendingClass(thread,
JSHClass::Cast(globalConst->GetPendingJobClass().GetTaggedObject()));
JSHandle<TaggedObject> pendingJob(thread, factory->NewDynObject(pendingClass));
DUMP_FOR_HANDLE(pendingJob)
break;
}
case JSType::FUNCTION_EXTRA_INFO: {
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), JSFunctionExtraInfo::SIZE, 2)
JSHandle<JSHClass> funcExtraClass(thread,
JSHClass::Cast(globalConst->GetFunctionExtraInfoClass().GetTaggedObject()));
JSHandle<TaggedObject> funcInfo(thread, factory->NewDynObject(funcExtraClass));
DUMP_FOR_HANDLE(funcInfo)
break;
}
case JSType::COMPLETION_RECORD: {
CHECK_DUMP_FILEDS(Record::SIZE, CompletionRecord::SIZE, 2)
JSHandle<CompletionRecord> comRecord = factory->NewCompletionRecord(0, globalEnv->GetEmptyArray());
DUMP_FOR_HANDLE(comRecord)
break;
}
case JSType::MACHINE_CODE_OBJECT: {
CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), MachineCode::DATA_OFFSET, 1)
JSHandle<MachineCode> machineCode = factory->NewMachineCodeObject(16, nullptr);
DUMP_FOR_HANDLE(machineCode)
break;
}
case JSType::ECMA_MODULE: {
CHECK_DUMP_FILEDS(ECMAObject::SIZE, EcmaModule::SIZE, 1)
JSHandle<EcmaModule> ecmaModule = factory->NewEmptyEcmaModule();
DUMP_FOR_HANDLE(ecmaModule)
break;
}
default:
LOG_ECMA_MEM(ERROR) << "JSType " << static_cast<int>(type) << " cannot be dumped.";
UNREACHABLE();
break;
}
}
#undef NEW_OBJECT_AND_DUMP
#undef DUMP_FOR_HANDLE
}
} // namespace panda::test

View File

@ -122,6 +122,7 @@ public:
ACCESSORS(TransitionHClass, TRANSITION_HCLASS_OFFSET, SIZE)
DECL_VISIT_OBJECT(HANDLER_INFO_OFFSET, SIZE)
DECL_DUMP()
};
class PrototypeHandler : public TaggedObject {
@ -146,6 +147,7 @@ public:
ACCESSORS(Holder, HOLDER_OFFSET, SIZE)
DECL_VISIT_OBJECT(HANDLER_INFO_OFFSET, SIZE)
DECL_DUMP()
};
} // namespace panda::ecmascript
#endif // ECMASCRIPT_IC_IC_HANDLER_H

View File

@ -42,6 +42,7 @@ public:
ACCESSORS(Value, VALUE_OFFSET, SIZE);
DECL_VISIT_OBJECT(VALUE_OFFSET, SIZE)
DECL_DUMP()
};
} // namespace ecmascript
} // namespace panda

View File

@ -35,6 +35,7 @@ public:
static constexpr size_t HAS_CHANGED_OFFSET = TaggedObjectSize();
SET_GET_PRIMITIVE_FIELD(HasChanged, bool, HAS_CHANGED_OFFSET, SIZE);
DECL_DUMP()
};
class ProtoChangeDetails : public TaggedObject {
@ -51,6 +52,7 @@ public:
ACCESSORS(RegisterIndex, REGISTER_INDEX_OFFSET, SIZE);
DECL_VISIT_OBJECT(CHANGE_LISTENER_OFFSET, SIZE)
DECL_DUMP()
};
class ChangeListener : public WeakVector {

View File

@ -269,8 +269,8 @@ JSTaggedValue FastRuntimeStub::AddPropertyByName(JSThread *thread, JSTaggedValue
// change to dictionary and add one.
JSHandle<NameDictionary> dict(JSObject::TransitionToDictionary(thread, objHandle));
attr.SetDictionaryOrder(PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES);
auto result = JSTaggedValue(NameDictionary::PutIfAbsent(thread, dict, keyHandle, valueHandle, attr));
objHandle->SetProperties(thread, result);
NameDictionary *newDict = NameDictionary::PutIfAbsent(thread, dict, keyHandle, valueHandle, attr);
objHandle->SetProperties(thread, JSTaggedValue(newDict));
// index is not essential when fastMode is false;
return JSTaggedValue::Undefined();
}
@ -286,8 +286,8 @@ JSTaggedValue FastRuntimeStub::AddPropertyByName(JSThread *thread, JSTaggedValue
array->Set(thread, outProps, valueHandle.GetTaggedValue());
} else {
JSHandle<NameDictionary> dictHandle(array);
auto result = JSTaggedValue(NameDictionary::PutIfAbsent(thread, dictHandle, keyHandle, valueHandle, attr));
objHandle->SetProperties(thread, result);
NameDictionary *newDict = NameDictionary::PutIfAbsent(thread, dictHandle, keyHandle, valueHandle, attr);
objHandle->SetProperties(thread, JSTaggedValue(newDict));
}
return JSTaggedValue::Undefined();
}
@ -880,9 +880,9 @@ bool FastRuntimeStub::SetPropertyByName(JSThread *thread, JSTaggedValue receiver
if (receiver.IsJSGlobalObject()) {
[[maybe_unused]] EcmaHandleScope handleScope(thread);
JSHandle<GlobalDictionary> dict_handle(thread, properties);
JSHandle<GlobalDictionary> dictHandle(thread, properties);
// globalobj have no internal accessor
GlobalDictionary::InvalidatePropertyBox(thread, dict_handle, indexOrEntry, attr);
GlobalDictionary::InvalidatePropertyBox(thread, dictHandle, indexOrEntry, attr);
return true;
}
@ -961,7 +961,7 @@ bool FastRuntimeStub::SetGlobalOwnProperty(JSThread *thread, JSTaggedValue recei
JSHandle<JSTaggedValue> keyHandle(thread, key);
JSHandle<JSTaggedValue> valHandle(thread, value);
JSHandle<JSObject> objHandle(thread, obj);
JSHandle<GlobalDictionary> dict_handle(thread, GlobalDictionary::Create(thread));
JSHandle<GlobalDictionary> dictHandle(thread, GlobalDictionary::Create(thread));
// Add PropertyBox to global dictionary
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
@ -970,9 +970,9 @@ bool FastRuntimeStub::SetGlobalOwnProperty(JSThread *thread, JSTaggedValue recei
PropertyBoxType boxType = valHandle->IsUndefined() ? PropertyBoxType::UNDEFINED : PropertyBoxType::CONSTANT;
attr.SetBoxType(boxType);
objHandle->SetProperties(
thread, JSTaggedValue(GlobalDictionary::PutIfAbsent(thread, dict_handle, keyHandle,
JSHandle<JSTaggedValue>(boxHandle), attr)));
GlobalDictionary *properties =
GlobalDictionary::PutIfAbsent(thread, dictHandle, keyHandle, JSHandle<JSTaggedValue>(boxHandle), attr);
objHandle->SetProperties(thread, JSTaggedValue(properties));
return true;
}
@ -983,8 +983,8 @@ bool FastRuntimeStub::SetGlobalOwnProperty(JSThread *thread, JSTaggedValue recei
if (!attr.IsAccessor()) {
if (attr.IsWritable()) {
// globalobj have no internal accessor
JSHandle<GlobalDictionary> dict_handle(thread, dict);
GlobalDictionary::InvalidatePropertyBox(thread, dict_handle, entry, attr);
JSHandle<GlobalDictionary> dictHandle(thread, dict);
GlobalDictionary::InvalidatePropertyBox(thread, dictHandle, entry, attr);
return true;
}
}
@ -1011,7 +1011,7 @@ bool FastRuntimeStub::SetGlobalOwnProperty(JSThread *thread, JSTaggedValue recei
JSHandle<JSTaggedValue> keyHandle(thread, key);
JSHandle<JSTaggedValue> valHandle(thread, value);
JSHandle<JSObject> objHandle(thread, obj);
JSHandle<GlobalDictionary> dict_handle(thread, dict);
JSHandle<GlobalDictionary> dictHandle(thread, dict);
// Add PropertyBox to global dictionary
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
@ -1020,9 +1020,9 @@ bool FastRuntimeStub::SetGlobalOwnProperty(JSThread *thread, JSTaggedValue recei
PropertyBoxType boxType = valHandle->IsUndefined() ? PropertyBoxType::UNDEFINED : PropertyBoxType::CONSTANT;
attr.SetBoxType(boxType);
objHandle->SetProperties(thread, JSTaggedValue(GlobalDictionary::PutIfAbsent(
thread, dict_handle, keyHandle,
JSHandle<JSTaggedValue>(boxHandle), attr)));
GlobalDictionary *properties =
GlobalDictionary::PutIfAbsent(thread, dictHandle, keyHandle, JSHandle<JSTaggedValue>(boxHandle), attr);
objHandle->SetProperties(thread, JSTaggedValue(properties));
return true;
}

View File

@ -1439,8 +1439,9 @@ JSTaggedValue SlowRuntimeStub::StGlobalRecord(JSThread *thread, JSTaggedValue pr
PropertyBoxType boxType = valueHandle->IsUndefined() ? PropertyBoxType::UNDEFINED : PropertyBoxType::CONSTANT;
attributes.SetBoxType(boxType);
dict->PutIfAbsent(thread, dictHandle, propHandle, JSHandle<JSTaggedValue>(box), attributes);
dict = GlobalDictionary::PutIfAbsent(thread, dictHandle, propHandle, JSHandle<JSTaggedValue>(box), attributes);
RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread);
env->SetGlobalRecord(thread, JSTaggedValue(dict));
return JSTaggedValue::True();
}

View File

@ -27,8 +27,8 @@
#include "utils/expected.h"
namespace panda::ecmascript::job {
void MicroJobQueue::EnqueueJob(JSThread *thread, QueueType queueType, const JSHandle<JSFunction> &job,
const JSHandle<TaggedArray> &argv)
void MicroJobQueue::EnqueueJob(JSThread *thread, JSHandle<MicroJobQueue> jobQueue, QueueType queueType,
const JSHandle<JSFunction> &job, const JSHandle<TaggedArray> &argv)
{
// 1. Assert: Type(queueName) is String and its value is the name of a Job Queue recognized by this implementation.
// 2. Assert: job is the name of a Job.
@ -39,24 +39,22 @@ void MicroJobQueue::EnqueueJob(JSThread *thread, QueueType queueType, const JSHa
[[maybe_unused]] EcmaHandleScope handleScope(thread);
JSHandle<PendingJob> pendingJob(factory->NewPendingJob(job, argv));
if (queueType == QueueType::QUEUE_PROMISE) {
JSHandle<TaggedQueue> promiseQueue(thread, GetPromiseJobQueue());
JSHandle<TaggedQueue> promiseQueue(thread, jobQueue->GetPromiseJobQueue());
LOG_ECMA(DEBUG) << "promiseQueue start length: " << promiseQueue->Size();
JSHandle<TaggedQueue> newPromiseQueue(
thread, TaggedQueue::Push(thread, promiseQueue, JSHandle<JSTaggedValue>::Cast(pendingJob)));
SetPromiseJobQueue(thread, newPromiseQueue.GetTaggedValue());
TaggedQueue *newPromiseQueue = TaggedQueue::Push(thread, promiseQueue, JSHandle<JSTaggedValue>(pendingJob));
jobQueue->SetPromiseJobQueue(thread, JSTaggedValue(newPromiseQueue));
LOG_ECMA(DEBUG) << "promiseQueue end length: " << newPromiseQueue->Size();
} else if (queueType == QueueType::QUEUE_SCRIPT) {
JSHandle<TaggedQueue> scriptQueue(thread, GetScriptJobQueue());
JSHandle<TaggedQueue> newScriptQueue(
thread, TaggedQueue::Push(thread, scriptQueue, JSHandle<JSTaggedValue>::Cast(pendingJob)));
SetScriptJobQueue(thread, newScriptQueue.GetTaggedValue());
JSHandle<TaggedQueue> scriptQueue(thread, jobQueue->GetScriptJobQueue());
TaggedQueue *newScriptQueue = TaggedQueue::Push(thread, scriptQueue, JSHandle<JSTaggedValue>(pendingJob));
jobQueue->SetScriptJobQueue(thread, JSTaggedValue(newScriptQueue));
}
}
void MicroJobQueue::ExecutePendingJob(JSThread *thread)
void MicroJobQueue::ExecutePendingJob(JSThread *thread, JSHandle<MicroJobQueue> jobQueue)
{
[[maybe_unused]] EcmaHandleScope handleScope(thread);
JSHandle<TaggedQueue> promiseQueue(thread, GetPromiseJobQueue());
JSMutableHandle<TaggedQueue> promiseQueue(thread, jobQueue->GetPromiseJobQueue());
JSMutableHandle<PendingJob> pendingJob(thread, JSTaggedValue::Undefined());
while (!promiseQueue->Empty()) {
LOG_ECMA(DEBUG) << "promiseQueue start length: " << promiseQueue->Size();
@ -66,10 +64,10 @@ void MicroJobQueue::ExecutePendingJob(JSThread *thread)
if (thread->HasPendingException()) {
return;
}
promiseQueue = JSHandle<TaggedQueue>(thread, GetPromiseJobQueue());
promiseQueue.Update(jobQueue->GetPromiseJobQueue());
}
JSHandle<TaggedQueue> scriptQueue(thread, GetScriptJobQueue());
JSHandle<TaggedQueue> scriptQueue(thread, jobQueue->GetScriptJobQueue());
while (!scriptQueue->Empty()) {
pendingJob.Update(scriptQueue->Pop(thread));
PendingJob::ExecutePendingJob(pendingJob, thread);

View File

@ -40,9 +40,9 @@ public:
return static_cast<MicroJobQueue *>(object);
}
void EnqueueJob(JSThread *thread, QueueType queueType, const JSHandle<JSFunction> &job,
const JSHandle<TaggedArray> &argv);
void ExecutePendingJob(JSThread *thread);
static void EnqueueJob(JSThread *thread, JSHandle<MicroJobQueue> jobQueue, QueueType queueType,
const JSHandle<JSFunction> &job, const JSHandle<TaggedArray> &argv);
static void ExecutePendingJob(JSThread *thread, JSHandle<MicroJobQueue> jobQueue);
static constexpr size_t PROMISE_JOB_QUEUE_OFFSET = Record::SIZE;
ACCESSORS(PromiseJobQueue, PROMISE_JOB_QUEUE_OFFSET, SCRIPT_JOB_QUEUE_OFFSET);

View File

@ -190,8 +190,8 @@ void JSArray::SetCapacity(JSThread *thread, const JSHandle<JSObject> &array, uin
uint32_t attr = dictHandle->GetAttributes(entry).GetValue();
PropertyAttributes propAttr(attr);
if (propAttr.IsConfigurable()) {
NumberDictionary *dictionary = NumberDictionary::Remove(thread, dictHandle, entry);
array->SetElements(thread, JSTaggedValue(dictionary));
NumberDictionary *newDict = NumberDictionary::Remove(thread, dictHandle, entry);
array->SetElements(thread, JSTaggedValue(newDict));
if (i == 0) {
newNumOfElements = i;
break;

View File

@ -54,6 +54,7 @@ public:
ACCESSORS(BoundCompare, BOUND_COMPARE_OFFSET, SIZE)
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, ICU_FIELD_OFFSET, SIZE)
DECL_DUMP()
icu::Collator *GetIcuCollator() const
{

View File

@ -107,6 +107,7 @@ public:
ACCESSORS(BoundFormat, BOUND_FORMAT_OFFSET, SIZE)
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LOCALE_OFFSET, SIZE)
DECL_DUMP()
icu::Locale *GetIcuLocale() const;
void SetIcuLocale(JSThread *thread, const icu::Locale &icuLocale, const DeleteEntryPoint &callback);

View File

@ -197,7 +197,8 @@ void JSForInIterator::SlowGetAllEnumKeys(JSThread *thread, const JSHandle<JSForI
for (array_size_t i = 0; i < len; i++) {
value.Update(arr->Get(i));
if (value->IsString()) {
remaining.Update(JSTaggedValue(TaggedQueue::Push(thread, remaining, value)));
TaggedQueue *newQueue = TaggedQueue::Push(thread, remaining, value);
remaining.Update(JSTaggedValue(newQueue));
}
}
it->SetRemainingKeys(thread, remaining);
@ -244,9 +245,9 @@ std::pair<JSTaggedValue, bool> JSForInIterator::NextInternal(JSThread *thread, c
PropertyDescriptor desc(thread);
bool has = JSTaggedValue::GetOwnProperty(thread, object, key, desc);
if (has) {
auto queue = JSTaggedValue(TaggedQueue::Push(thread, visited, key));
visited.Update(queue);
it->SetVisitedKeys(thread, queue);
auto newQueue = JSTaggedValue(TaggedQueue::Push(thread, visited, key));
visited.Update(newQueue);
it->SetVisitedKeys(thread, newQueue);
if (desc.IsEnumerable()) {
return std::make_pair(key.GetTaggedValue(), false);
}

View File

@ -52,6 +52,7 @@ public:
ACCESSORS(RemainingKeys, REMAINING_KEYS_OFFSET, SIZE)
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, OBJECT_OFFSET, SIZE)
DECL_DUMP()
};
} // namespace panda::ecmascript

View File

@ -431,6 +431,7 @@ public:
ACCESSORS(Collator, COLLATOR_OFFSET, SIZE);
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSFunction, NUMBER_FORMAT_OFFSET, SIZE)
DECL_DUMP()
};
} // namespace panda::ecmascript

View File

@ -36,6 +36,7 @@ public:
ACCESSORS(Data, DATA_OFFSET, SIZE);
DECL_VISIT_OBJECT(CALL_BACK_OFFSET, SIZE)
DECL_DUMP()
};
} // namespace panda::ecmascript
#endif

View File

@ -46,6 +46,7 @@ public:
ACCESSORS(LexicalEnv, GENERATOR_LEXICALENV_OFFSET, SIZE)
DECL_VISIT_OBJECT(GENERATOR_REGS_ARRAY_OFFSET, SIZE)
DECL_DUMP()
};
class JSGeneratorObject : public JSObject {
@ -84,6 +85,7 @@ public:
}
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, GENERATOR_STATE_OFFSET, SIZE)
DECL_DUMP()
};
class JSAsyncFuncObject : public JSGeneratorObject {
@ -98,6 +100,7 @@ public:
ACCESSORS(Promise, GENERATOR_PROMISE_OFFSET, SIZE);
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSGeneratorObject, GENERATOR_PROMISE_OFFSET, SIZE)
DECL_DUMP()
};
} // namespace ecmascript
} // namespace panda

View File

@ -38,6 +38,7 @@ void JSHClass::AddTransitions(const JSThread *thread, const JSHandle<JSHClass> &
child->SetParent(thread, parent.GetTaggedValue());
return;
}
JSMutableHandle<TransitionsDictionary> dict(thread, JSTaggedValue::Undefined());
if (transitions.IsJSHClass()) {
auto cachedHClass = JSHClass::Cast(transitions.GetTaggedObject());
int last = cachedHClass->GetPropertiesNumber() - 1;
@ -45,11 +46,11 @@ void JSHClass::AddTransitions(const JSThread *thread, const JSHandle<JSHClass> &
auto attr = JSHandle<JSTaggedValue>(thread, JSTaggedValue(layoutInfo->GetAttr(last).GetPropertyMetaData()));
auto lastKey = JSHandle<JSTaggedValue>(thread, layoutInfo->GetKey(last));
auto lastHClass = JSHandle<JSTaggedValue>(thread, cachedHClass);
auto dict = JSHandle<TransitionsDictionary>(thread, TransitionsDictionary::Create(thread));
dict.Update(JSTaggedValue(TransitionsDictionary::Create(thread)));
transitions = JSTaggedValue(TransitionsDictionary::PutIfAbsent(thread, dict, lastKey, lastHClass, attr));
}
auto attr = JSHandle<JSTaggedValue>(thread, JSTaggedValue(attributes.GetPropertyMetaData()));
JSHandle<TransitionsDictionary> dict(thread, transitions);
dict.Update(transitions);
transitions =
JSTaggedValue(TransitionsDictionary::PutIfAbsent(thread, dict, key, JSHandle<JSTaggedValue>(child), attr));
parent->SetTransitions(thread, transitions);
@ -68,6 +69,7 @@ void JSHClass::AddProtoTransitions(const JSThread *thread, const JSHandle<JSHCla
const JSHandle<JSTaggedValue> &proto)
{
JSTaggedValue transitions = parent->GetTransitions();
JSMutableHandle<TransitionsDictionary> dict(thread, JSTaggedValue::Undefined());
if (transitions.IsNull()) {
transitions = JSTaggedValue(TransitionsDictionary::Create(thread));
} else if (transitions.IsJSHClass()) {
@ -77,11 +79,11 @@ void JSHClass::AddProtoTransitions(const JSThread *thread, const JSHandle<JSHCla
auto attr = JSHandle<JSTaggedValue>(thread, JSTaggedValue(layoutInfo->GetAttr(last).GetPropertyMetaData()));
auto lastKey = JSHandle<JSTaggedValue>(thread, layoutInfo->GetKey(last));
auto lastHClass = JSHandle<JSTaggedValue>(thread, cachedHClass);
auto dict = JSHandle<TransitionsDictionary>(thread, TransitionsDictionary::Create(thread));
dict.Update(JSTaggedValue(TransitionsDictionary::Create(thread)));
transitions = JSTaggedValue(TransitionsDictionary::PutIfAbsent(thread, dict, lastKey, lastHClass, attr));
}
JSHandle<TransitionsDictionary> dict(thread, transitions);
dict.Update(transitions);
transitions =
JSTaggedValue(TransitionsDictionary::PutIfAbsent(thread, dict, key, JSHandle<JSTaggedValue>(child), proto));
parent->SetTransitions(thread, transitions);

View File

@ -32,6 +32,7 @@ public:
ACCESSORS(FallbackSymbol, FALLBACK_SYMBOL, SIZE)
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, FALLBACK_SYMBOL, SIZE)
DECL_DUMP()
};
} // namespace panda::ecmascript

View File

@ -159,6 +159,7 @@ public:
ACCESSORS(IcuField, ICU_FIELD_OFFSET, SIZE)
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, ICU_FIELD_OFFSET, SIZE)
DECL_DUMP()
icu::Locale *GetIcuLocale() const
{

View File

@ -28,8 +28,8 @@ void JSMap::Set(JSThread *thread, const JSHandle<JSMap> &map, const JSHandle<JST
}
JSHandle<LinkedHashMap> mapHandle(thread, LinkedHashMap::Cast(map->GetLinkedMap().GetTaggedObject()));
auto result = LinkedHashMap::Set(thread, mapHandle, key, value);
map->SetLinkedMap(thread, result);
JSTaggedValue newMap = LinkedHashMap::Set(thread, mapHandle, key, value);
map->SetLinkedMap(thread, newMap);
}
bool JSMap::Delete(const JSThread *thread, const JSHandle<JSMap> &map, const JSHandle<JSTaggedValue> &key)
@ -41,8 +41,8 @@ bool JSMap::Delete(const JSThread *thread, const JSHandle<JSMap> &map, const JSH
}
mapHandle->RemoveEntry(thread, entry);
auto result = LinkedHashMap::Shrink(thread, mapHandle);
map->SetLinkedMap(thread, result);
JSTaggedValue newMap = LinkedHashMap::Shrink(thread, mapHandle);
map->SetLinkedMap(thread, newMap);
return true;
}

View File

@ -83,6 +83,7 @@ public:
ACCESSORS(IcuField, BOUND_FORMAT_OFFSET, SIZE)
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LOCALE_OFFSET, SIZE)
DECL_DUMP()
icu::number::LocalizedNumberFormatter *GetIcuCallTarget() const
{

View File

@ -127,7 +127,8 @@ JSHandle<NameDictionary> JSObject::TransitionToDictionary(const JSThread *thread
attr.SetBoxType(PropertyBoxType::UNDEFINED);
valueHandle.Update(value);
keyHandle.Update(key);
dict.Update(JSTaggedValue(NameDictionary::PutIfAbsent(thread, dict, keyHandle, valueHandle, attr)));
NameDictionary *newDict = NameDictionary::PutIfAbsent(thread, dict, keyHandle, valueHandle, attr);
dict.Update(JSTaggedValue(newDict));
}
receiver->SetProperties(thread, dict);
@ -152,7 +153,8 @@ void JSObject::ElementsToDictionary(const JSThread *thread, JSHandle<JSObject> o
}
key.Update(JSTaggedValue(i));
valueHandle.Update(value);
dict.Update(JSTaggedValue(NumberDictionary::PutIfAbsent(thread, dict, key, valueHandle, attr)));
NumberDictionary *newDict = NumberDictionary::PutIfAbsent(thread, dict, key, valueHandle, attr);
dict.Update(JSTaggedValue(newDict));
}
obj->SetElements(thread, dict);
@ -193,9 +195,9 @@ bool JSObject::AddElementInternal(JSThread *thread, const JSHandle<JSObject> &re
if (isDictionary) {
ASSERT(elements->IsDictionaryMode());
JSHandle<JSTaggedValue> keyHandle(thread, JSTaggedValue(static_cast<int32_t>(index)));
NumberDictionary *dict =
NumberDictionary *newDict =
NumberDictionary::Put(thread, JSHandle<NumberDictionary>(thread, elements), keyHandle, value, attr);
receiver->SetElements(thread, JSTaggedValue(dict));
receiver->SetElements(thread, JSTaggedValue(newDict));
return true;
}
@ -205,8 +207,8 @@ bool JSObject::AddElementInternal(JSThread *thread, const JSHandle<JSObject> &re
JSObject::ElementsToDictionary(thread, receiver);
JSHandle<JSTaggedValue> keyHandle(thread, JSTaggedValue(static_cast<int32_t>(index)));
JSHandle<NumberDictionary> dict(thread, receiver->GetElements());
auto key = JSTaggedValue(NumberDictionary::Put(thread, dict, keyHandle, value, attr));
receiver->SetElements(thread, key);
NumberDictionary *newKey = NumberDictionary::Put(thread, dict, keyHandle, value, attr);
receiver->SetElements(thread, JSTaggedValue(newKey));
return true;
}
elements = *JSObject::GrowElementsCapacity(thread, receiver, index + 1);
@ -223,8 +225,8 @@ void JSObject::DeletePropertyInternal(JSThread *thread, const JSHandle<JSObject>
if (obj->IsJSGlobalObject()) {
JSHandle<GlobalDictionary> dictHandle(thread, obj->GetProperties());
GlobalDictionary *dict = GlobalDictionary::Remove(thread, dictHandle, index);
obj->SetProperties(thread, JSTaggedValue(dict));
GlobalDictionary *newDict = GlobalDictionary::Remove(thread, dictHandle, index);
obj->SetProperties(thread, JSTaggedValue(newDict));
return;
}
@ -232,14 +234,14 @@ void JSObject::DeletePropertyInternal(JSThread *thread, const JSHandle<JSObject>
JSHandle<NameDictionary> dictHandle(TransitionToDictionary(thread, obj));
int entry = dictHandle->FindEntry(key.GetTaggedValue());
ASSERT(entry != -1);
NameDictionary *dict = NameDictionary::Remove(thread, dictHandle, entry);
obj->SetProperties(thread, JSTaggedValue(dict));
NameDictionary *newDict = NameDictionary::Remove(thread, dictHandle, entry);
obj->SetProperties(thread, JSTaggedValue(newDict));
return;
}
JSHandle<NameDictionary> dictHandle(array);
NameDictionary *dict = NameDictionary::Remove(thread, dictHandle, index);
obj->SetProperties(thread, JSTaggedValue(dict));
NameDictionary *newDict = NameDictionary::Remove(thread, dictHandle, index);
obj->SetProperties(thread, JSTaggedValue(newDict));
}
void JSObject::GetAllKeys(const JSThread *thread, const JSHandle<JSObject> &obj, int offset,

View File

@ -591,7 +591,7 @@ public:
ACCESSORS(Properties, PROPERTIES_OFFSET, ELEMENTS_OFFSET);
ACCESSORS(Elements, ELEMENTS_OFFSET, SIZE);
DECL_VISIT_OBJECT_FOR_JS_OBJECT(ECMAObject, PROPERTIES_OFFSET, SIZE)
DECL_DUMP()

View File

@ -50,6 +50,7 @@ public:
ACCESSORS(IcuNF, ICU_NUMBER_FORMAT_OFFSET, SIZE)
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LOCALE_OFFSET, SIZE)
DECL_DUMP()
icu::number::LocalizedNumberFormatter *GetIcuNumberFormatter() const;

View File

@ -178,7 +178,7 @@ JSTaggedValue JSPromise::TriggerPromiseReactions(JSThread *thread, const JSHandl
JSHandle<TaggedArray> arguments = factory->NewTaggedArray(2); // 2 means the length of new array
arguments->Set(thread, 0, reaction);
arguments->Set(thread, 1, argument);
job->EnqueueJob(thread, job::QueueType::QUEUE_PROMISE, promiseReactionsJob, arguments);
job::MicroJobQueue::EnqueueJob(thread, job, job::QueueType::QUEUE_PROMISE, promiseReactionsJob, arguments);
}
// 2. Return undefined.
return globalConst->GetUndefined();

View File

@ -29,6 +29,9 @@ public:
static constexpr size_t VALUE_OFFSET = JSObject::SIZE;
ACCESSORS(Value, VALUE_OFFSET, GLOBAL_ENV_OFFSET)
ACCESSORS(GlobalEnv, GLOBAL_ENV_OFFSET, SIZE)
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, VALUE_OFFSET, SIZE)
DECL_DUMP()
};
} // namespace panda::ecmascript

View File

@ -55,6 +55,7 @@ public:
ACCESSORS(IcuField, ICU_FIELD_OFFSET, SIZE)
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, LOCALE_OFFSET, SIZE)
DECL_DUMP()
// 14.1.1 InitializeRelativeTimeFormat ( relativeTimeFormat, locales, options )
static JSHandle<JSRelativeTimeFormat> InitializeRelativeTimeFormat(

View File

@ -28,8 +28,8 @@ void JSSet::Add(JSThread *thread, const JSHandle<JSSet> &set, const JSHandle<JST
}
JSHandle<LinkedHashSet> setHandle(thread, LinkedHashSet::Cast(set->GetLinkedSet().GetTaggedObject()));
auto table = LinkedHashSet::Add(thread, setHandle, value);
set->SetLinkedSet(thread, table);
JSTaggedValue newSet = LinkedHashSet::Add(thread, setHandle, value);
set->SetLinkedSet(thread, newSet);
}
bool JSSet::Delete(const JSThread *thread, const JSHandle<JSSet> &set, const JSHandle<JSTaggedValue> &value)
@ -40,8 +40,8 @@ bool JSSet::Delete(const JSThread *thread, const JSHandle<JSSet> &set, const JSH
return false;
}
setHandle->RemoveEntry(thread, entry);
auto table = LinkedHashSet::Shrink(thread, setHandle);
set->SetLinkedSet(thread, table);
JSTaggedValue newSet = LinkedHashSet::Shrink(thread, setHandle);
set->SetLinkedSet(thread, newSet);
return true;
}

View File

@ -38,6 +38,7 @@ public:
ACCESSORS(StringIteratorNextIndex, STRING_ITERATOR_NEXT_INDEX_OFFSET, SIZE)
DECL_VISIT_OBJECT_FOR_JS_OBJECT(JSObject, ITERATED_STRING_OFFSET, SIZE)
DECL_DUMP()
};
} // namespace ecmascript
} // namespace panda

View File

@ -332,7 +332,8 @@ public:
void DumpTaggedValue(JSThread *thread, std::ostream &os) const DUMP_API_ATTR;
void Dump(JSThread *thread, std::ostream &os) const DUMP_API_ATTR;
void Dump(JSThread *thread) const DUMP_API_ATTR;
void DumpForSnapshot(JSThread *thread, std::vector<std::pair<CString, JSTaggedValue>> &vec) const;
void DumpForSnapshot(JSThread *thread, std::vector<std::pair<CString, JSTaggedValue>> &vec,
bool isVmMode = true) const;
static void DumpVal(JSThread *thread, JSTaggedType val) DUMP_API_ATTR;
private:

View File

@ -86,6 +86,9 @@ void JSThread::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1)
if (!exception_.IsHole()) {
v0(Root::ROOT_VM, ObjectSlot(ToUintPtr(&exception_)));
}
if (!stubCode_.IsHole()) {
v0(Root::ROOT_VM, ObjectSlot(ToUintPtr(&stubCode_)));
}
// visit global Constant
globalConst_.VisitRangeSlot(v1);
// visit stack roots

View File

@ -204,6 +204,14 @@ public:
void IterateWeakEcmaGlobalStorage(const WeakRootVisitor &visitor);
uintptr_t* GetLastOptCallRuntimePc() const
{
return lastOptCallRuntimePc_;
}
void SetLastOptCallRuntimePc(uintptr_t* pc)
{
lastOptCallRuntimePc_ = pc;
}
private:
NO_COPY_SEMANTIC(JSThread);
NO_MOVE_SEMANTIC(JSThread);
@ -238,6 +246,7 @@ private:
bool stableArrayElementsGuardians_ {true};
GlobalEnvConstants globalConst_; // Place-Holder
InternalCallParams *internalCallParams_ {nullptr};
uintptr_t *lastOptCallRuntimePc_ {nullptr};
friend class EcmaHandleScope;
friend class GlobalHandleCollection;

View File

@ -30,8 +30,8 @@ void JSWeakMap::Set(JSThread *thread, const JSHandle<JSWeakMap> &map, const JSHa
}
JSHandle<LinkedHashMap> mapHandle(thread, LinkedHashMap::Cast(map->GetLinkedMap().GetTaggedObject()));
auto result = LinkedHashMap::SetWeakRef(thread, mapHandle, key, value);
map->SetLinkedMap(thread, result);
JSTaggedValue newMap = LinkedHashMap::SetWeakRef(thread, mapHandle, key, value);
map->SetLinkedMap(thread, newMap);
}
bool JSWeakMap::Delete(JSThread *thread, const JSHandle<JSWeakMap> &map, const JSHandle<JSTaggedValue> &key)
@ -43,8 +43,8 @@ bool JSWeakMap::Delete(JSThread *thread, const JSHandle<JSWeakMap> &map, const J
}
mapHandle->RemoveEntry(thread, entry);
auto result = LinkedHashMap::Shrink(thread, mapHandle);
map->SetLinkedMap(thread, result);
JSTaggedValue newMap = LinkedHashMap::Shrink(thread, mapHandle);
map->SetLinkedMap(thread, newMap);
return true;
}
@ -70,8 +70,8 @@ void JSWeakSet::Add(JSThread *thread, const JSHandle<JSWeakSet> &weakSet, const
}
JSHandle<LinkedHashSet> weakSetHandle(thread, LinkedHashSet::Cast(weakSet->GetLinkedSet().GetTaggedObject()));
auto result = LinkedHashSet::AddWeakRef(thread, weakSetHandle, value);
weakSet->SetLinkedSet(thread, result);
JSTaggedValue newSet = LinkedHashSet::AddWeakRef(thread, weakSetHandle, value);
weakSet->SetLinkedSet(thread, newSet);
}
bool JSWeakSet::Delete(JSThread *thread, const JSHandle<JSWeakSet> &weakSet, const JSHandle<JSTaggedValue> &value)
@ -82,8 +82,8 @@ bool JSWeakSet::Delete(JSThread *thread, const JSHandle<JSWeakSet> &weakSet, con
return false;
}
weakSetHandle->RemoveEntry(thread, entry);
auto result = LinkedHashSet::Shrink(thread, weakSetHandle);
weakSet->SetLinkedSet(thread, result);
JSTaggedValue newSet = LinkedHashSet::Shrink(thread, weakSetHandle);
weakSet->SetLinkedSet(thread, newSet);
return true;
}

View File

@ -142,10 +142,10 @@ void FreeListAllocator::Free(uintptr_t begin, uintptr_t end, bool isAdd)
{
ASSERT(heap_ != nullptr);
size_t size = end - begin;
FreeObject::FillFreeObject(heap_->GetEcmaVM(), begin, size);
if (UNLIKELY(size < FreeObject::SIZE_OFFSET)) {
return;
}
FreeObject::FillFreeObject(heap_->GetEcmaVM(), begin, size);
freeList_->Free(begin, size, isAdd);
}

View File

@ -30,6 +30,7 @@
#include "ecmascript/js_array_iterator.h"
#include "ecmascript/js_arraybuffer.h"
#include "ecmascript/js_async_function.h"
#include "ecmascript/js_collator.h"
#include "ecmascript/js_dataview.h"
#include "ecmascript/js_date.h"
#include "ecmascript/js_date_time_format.h"
@ -43,8 +44,10 @@
#include "ecmascript/js_map_iterator.h"
#include "ecmascript/js_number_format.h"
#include "ecmascript/js_object-inl.h"
#include "ecmascript/js_plural_rules.h"
#include "ecmascript/js_primitive_ref.h"
#include "ecmascript/js_promise.h"
#include "ecmascript/js_realm.h"
#include "ecmascript/js_regexp.h"
#include "ecmascript/js_relative_time_format.h"
#include "ecmascript/js_set.h"
@ -53,6 +56,7 @@
#include "ecmascript/js_typed_array.h"
#include "ecmascript/js_weak_container.h"
#include "ecmascript/mem/heap_roots.h"
#include "ecmascript/mem/machine_code.h"
#include "ecmascript/mem/mem.h"
namespace panda::ecmascript {
@ -196,6 +200,7 @@ void HeapRootManager::MarkObjectBody(TaggedObject *object, JSHClass *klass, cons
break;
case JSType::TAGGED_ARRAY:
case JSType::TAGGED_DICTIONARY:
case JSType::TEMPLATE_MAP:
TaggedArray::Cast(object)->VisitRangeSlot(visitor);
break;
case JSType::GLOBAL_ENV:
@ -225,9 +230,6 @@ void HeapRootManager::MarkObjectBody(TaggedObject *object, JSHClass *klass, cons
case JSType::PROTOTYPE_INFO:
ProtoChangeDetails::Cast(object)->VisitRangeSlot(visitor);
break;
case JSType::TEMPLATE_MAP:
UNREACHABLE();
break;
case JSType::PROMISE_CAPABILITY:
PromiseCapability::Cast(object)->VisitRangeSlot(visitor);
break;
@ -282,6 +284,18 @@ void HeapRootManager::MarkObjectBody(TaggedObject *object, JSHClass *klass, cons
case JSType::JS_INTL_BOUND_FUNCTION:
JSIntlBoundFunction::Cast(object)->VisitRangeSlot(visitor);
break;
case JSType::JS_REALM:
JSRealm::Cast(object)->VisitRangeSlot(visitor);
break;
case JSType::JS_COLLATOR:
JSCollator::Cast(object)->VisitRangeSlot(visitor);
break;
case JSType::JS_PLURAL_RULES:
JSPluralRules::Cast(object)->VisitRangeSlot(visitor);
break;
case JSType::MACHINE_CODE_OBJECT:
MachineCode::Cast(object)->VisitRangeSlot(visitor);
break;
default:
UNREACHABLE();
}

View File

@ -36,6 +36,8 @@ public:
ACCESSORS(InstructionSizeInBytes, INS_SIZE_OFFSET, DATA_OFFSET);
static constexpr size_t SIZE = DATA_OFFSET;
DECL_DUMP()
uintptr_t GetDataOffsetAddress(void)
{
return reinterpret_cast<uintptr_t>(this) + DATA_OFFSET;
@ -53,10 +55,19 @@ public:
return;
}
}
void VisitRangeSlot(const EcmaObjectRangeVisitor &v)
{
// left blank deliberately,only need to visit TaggedObject type object.
}
void VisitObjects([[maybe_unused]] const EcmaObjectRangeVisitor &visitor) const
{
// left blank deliberately,only need to visit TaggedObject type object.
}
size_t GetMachineCodeObjectSize(void)
{
return sizeof(MachineCode) + this->GetInstructionSizeInBytes().GetInt();
return SIZE + this->GetInstructionSizeInBytes().GetInt();
}
};
} // namespace ecmascript

View File

@ -2106,7 +2106,7 @@ uintptr_t ObjectFactory::NewSpaceBySnapShotAllocator(size_t size)
JSHandle<MachineCode> ObjectFactory::NewMachineCodeObject(size_t length, const uint8_t *data)
{
NewObjectHook();
TaggedObject *obj = heapHelper_.AllocateMachineCodeSpaceObject(machineCodeClass_, length + sizeof(MachineCode));
TaggedObject *obj = heapHelper_.AllocateMachineCodeSpaceObject(machineCodeClass_, length + MachineCode::SIZE);
MachineCode *code = MachineCode::Cast(obj);
code->SetInstructionSizeInBytes(thread_, JSTaggedValue(static_cast<int>(length)));
if (data != nullptr) {

View File

@ -104,7 +104,6 @@ using base::ErrorType;
using DeleteEntryPoint = void (*)(void *, void *);
enum class RemoveSlots { YES, NO };
class ObjectFactory {
public:
explicit ObjectFactory(JSThread *thread, Heap *heap);
@ -358,6 +357,11 @@ public:
JSHandle<EcmaString> NewFromString(EcmaString *str);
JSHandle<EcmaString> ConcatFromString(const JSHandle<EcmaString> &prefix, const JSHandle<EcmaString> &suffix);
// used for creating Function
JSHandle<JSObject> NewJSObject(const JSHandle<JSHClass> &jshclass);
// used for creating jshclass in Builtins, Function, Class_Linker
JSHandle<JSHClass> NewEcmaDynClass(uint32_t size, JSType type, const JSHandle<JSTaggedValue> &prototype);
private:
friend class GlobalEnv;
friend class GlobalEnvConstants;
@ -419,11 +423,6 @@ private:
JSHandle<JSHClass> NewEcmaDynClass(uint32_t size, JSType type);
// used for creating jshclass in GlobalEnv, EcmaVM
JSHandle<JSHClass> NewEcmaDynClass(JSHClass *hclass, uint32_t size, JSType type);
// used for creating jshclass in Builtins, Function, Class_Linker
JSHandle<JSHClass> NewEcmaDynClass(uint32_t size, JSType type, const JSHandle<JSTaggedValue> &prototype);
// used for creating Function
JSHandle<JSObject> NewJSObject(const JSHandle<JSHClass> &jshclass);
// used to create nonmovable js_object
JSHandle<JSObject> NewNonMovableJSObject(const JSHandle<JSHClass> &jshclass);

View File

@ -568,8 +568,8 @@ void ObjectOperator::DeleteElementInHolder() const
JSObject::ElementsToDictionary(thread_, JSHandle<JSObject>(holder_));
} else {
JSHandle<NumberDictionary> dictHandle(thread_, elements);
NumberDictionary *dict = NumberDictionary::Remove(thread_, dictHandle, GetIndex());
obj->SetElements(thread_, JSTaggedValue(dict));
NumberDictionary *newDict = NumberDictionary::Remove(thread_, dictHandle, GetIndex());
obj->SetElements(thread_, JSTaggedValue(newDict));
}
}
@ -661,9 +661,9 @@ void ObjectOperator::AddPropertyInternal(const JSHandle<JSTaggedValue> &value)
PropertyBoxType cellType = value->IsUndefined() ? PropertyBoxType::UNDEFINED : PropertyBoxType::CONSTANT;
attr.SetBoxType(cellType);
JSTaggedValue properties(
GlobalDictionary::PutIfAbsent(thread_, dict, key_, JSHandle<JSTaggedValue>(cellHandle), attr));
obj->SetProperties(thread_, properties);
GlobalDictionary *properties =
GlobalDictionary::PutIfAbsent(thread_, dict, key_, JSHandle<JSTaggedValue>(cellHandle), attr);
obj->SetProperties(thread_, JSTaggedValue(properties));
// index and fastMode is not essential for global obj;
SetFound(0, cellHandle.GetTaggedValue(), attr.GetValue(), true);
return;
@ -704,8 +704,8 @@ void ObjectOperator::AddPropertyInternal(const JSHandle<JSTaggedValue> &value)
// change to dictionary and add one.
JSHandle<NameDictionary> dict(JSObject::TransitionToDictionary(thread_, obj));
attr.SetDictionaryOrder(PropertyAttributes::MAX_CAPACITY_OF_PROPERTIES);
auto result = JSTaggedValue(NameDictionary::PutIfAbsent(thread_, dict, key_, value, attr));
obj->SetProperties(thread_, result);
NameDictionary *newDict = NameDictionary::PutIfAbsent(thread_, dict, key_, value, attr);
obj->SetProperties(thread_, JSTaggedValue(newDict));
// index is not essential when fastMode is false;
SetFound(0, value.GetTaggedValue(), attr.GetValue(), false);
return;
@ -724,8 +724,8 @@ void ObjectOperator::AddPropertyInternal(const JSHandle<JSTaggedValue> &value)
}
JSHandle<NameDictionary> dictHandle(array);
auto result = JSTaggedValue(NameDictionary::PutIfAbsent(thread_, dictHandle, key_, value, attr));
obj->SetProperties(thread_, result);
NameDictionary *newDict = NameDictionary::PutIfAbsent(thread_, dictHandle, key_, value, attr);
obj->SetProperties(thread_, JSTaggedValue(newDict));
SetFound(0, value.GetTaggedValue(), attr.GetValue(), false);
}

View File

@ -28,10 +28,11 @@ namespace panda::ecmascript {
bool RuntimeTrampolines::AddElementInternal(uint64_t argThread, uint64_t argReceiver, uint32_t argIndex,
uint64_t argValue, uint32_t argAttr)
{
JSTaggedType *fp = nullptr;
GET_CURRETN_FP(fp);
uintptr_t *curFp = nullptr;
auto thread = reinterpret_cast<JSThread *>(argThread);
CallRuntimeTrampolinesScope scope(thread, fp);
GET_CURRETN_FP(curFp);
uintptr_t *prevFp = GET_PREV_FP(curFp);
CallRuntimeTrampolinesScope scope(thread, prevFp, curFp);
[[maybe_unused]] EcmaHandleScope handleScope(thread);
JSHandle<JSObject> receiver(thread, reinterpret_cast<TaggedObject *>(argReceiver));
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argValue)));
@ -42,11 +43,11 @@ bool RuntimeTrampolines::AddElementInternal(uint64_t argThread, uint64_t argRece
bool RuntimeTrampolines::CallSetter(uint64_t argThread, uint64_t argSetter, uint64_t argReceiver, uint64_t argValue,
bool argMayThrow)
{
JSTaggedType *fp = nullptr;
GET_CURRETN_FP(fp);
uintptr_t *curFp = nullptr;
auto thread = reinterpret_cast<JSThread *>(argThread);
CallRuntimeTrampolinesScope scope(thread, fp);
[[maybe_unused]] EcmaHandleScope handleScope(thread);
GET_CURRETN_FP(curFp);
uintptr_t * prevFp = GET_PREV_FP(curFp);
CallRuntimeTrampolinesScope scope(thread, prevFp, curFp);
JSHandle<JSTaggedValue> receiver(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argReceiver)));
JSHandle<JSTaggedValue> value(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argValue)));
auto setter = AccessorData::Cast((reinterpret_cast<panda::ObjectHeader *>(argSetter)));
@ -55,10 +56,11 @@ bool RuntimeTrampolines::CallSetter(uint64_t argThread, uint64_t argSetter, uint
void RuntimeTrampolines::ThrowTypeError(uint64_t argThread, int argMessageStringId)
{
JSTaggedType *fp = nullptr;
GET_CURRETN_FP(fp);
uintptr_t *curFp = nullptr;
auto thread = reinterpret_cast<JSThread *>(argThread);
CallRuntimeTrampolinesScope scope(thread, fp);
GET_CURRETN_FP(curFp);
uintptr_t *prevFp = GET_PREV_FP(curFp);
CallRuntimeTrampolinesScope scope(thread, prevFp, curFp);
[[maybe_unused]] EcmaHandleScope handleScope(thread);
std::string message = MessageString::GetMessageString(argMessageStringId);
ObjectFactory *factory = JSThread::Cast(thread)->GetEcmaVM()->GetFactory();
@ -69,10 +71,11 @@ void RuntimeTrampolines::ThrowTypeError(uint64_t argThread, int argMessageString
bool RuntimeTrampolines::JSProxySetProperty(uint64_t argThread, uint64_t argProxy, uint64_t argKey, uint64_t argValue,
uint64_t argReceiver, bool argMayThrow)
{
JSTaggedType *fp = nullptr;
GET_CURRETN_FP(fp);
uintptr_t *curFp = nullptr;
auto thread = reinterpret_cast<JSThread *>(argThread);
CallRuntimeTrampolinesScope scope(thread, fp);
GET_CURRETN_FP(curFp);
uintptr_t *prevFp = GET_PREV_FP(curFp);
CallRuntimeTrampolinesScope scope(thread, prevFp, curFp);
[[maybe_unused]] EcmaHandleScope handleScope(thread);
JSHandle<JSProxy> proxy(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argProxy)));
JSHandle<JSTaggedValue> index(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argKey)));
@ -90,10 +93,11 @@ uint32_t RuntimeTrampolines::GetHash32(uint64_t key, uint64_t len)
uint64_t RuntimeTrampolines::CallGetter(uint64_t argThread, uint64_t argGetter, uint64_t argReceiver)
{
JSTaggedType *fp = nullptr;
GET_CURRETN_FP(fp);
uintptr_t *curFp = nullptr;
auto thread = reinterpret_cast<JSThread *>(argThread);
CallRuntimeTrampolinesScope scope(thread, fp);
GET_CURRETN_FP(curFp);
uintptr_t *prevFp = GET_PREV_FP(curFp);
CallRuntimeTrampolinesScope scope(thread, prevFp, curFp);
auto accessor = AccessorData::Cast(reinterpret_cast<TaggedObject *>(argGetter));
JSHandle<JSTaggedValue> objHandle(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argReceiver)));
return JSObject::CallGetter(thread, accessor, objHandle).GetRawData();
@ -101,10 +105,11 @@ uint64_t RuntimeTrampolines::CallGetter(uint64_t argThread, uint64_t argGetter,
uint64_t RuntimeTrampolines::AccessorGetter(uint64_t argThread, uint64_t argGetter, uint64_t argReceiver)
{
JSTaggedType *fp = nullptr;
GET_CURRETN_FP(fp);
uintptr_t *curFp = nullptr;
auto thread = reinterpret_cast<JSThread *>(argThread);
CallRuntimeTrampolinesScope scope(thread, fp);
GET_CURRETN_FP(curFp);
uintptr_t *prevFp = GET_PREV_FP(curFp);
CallRuntimeTrampolinesScope scope(thread, prevFp, curFp);
auto accessor = AccessorData::Cast(reinterpret_cast<TaggedObject *>(argGetter));
JSHandle<JSObject> objHandle(thread, JSTaggedValue(reinterpret_cast<TaggedObject *>(argReceiver)));
return accessor->CallInternalGet(thread, objHandle).GetRawData();
@ -139,4 +144,9 @@ uint64_t RuntimeTrampolines::Execute(uint64_t argThread, uint64_t argFunc,
return EcmaInterpreter::Execute(thread, params).GetRawData();
}
double RuntimeTrampolines::FloatMod(double left, double right)
{
return std::fmod(left, right);
}
} // namespace panda::ecmascript

View File

@ -49,35 +49,44 @@ public:
static int32_t FindElementWithCache(uint64_t argThread, uint64_t hClass, uint64_t key, int32_t num);
static uint32_t StringGetHashCode(uint64_t ecmaString);
static uint64_t Execute(uint64_t argThread, uint64_t argFunc, uint64_t thisArg, uint32_t argc, uint64_t argArgv);
static double FloatMod(double left, double right);
};
class CallRuntimeTrampolinesScope {
public:
CallRuntimeTrampolinesScope(JSThread *thread, JSTaggedType *newFp)
:oldRbp_(const_cast<JSTaggedType *>(thread->GetCurrentSPFrame())),
CallRuntimeTrampolinesScope(JSThread *thread, uintptr_t *newFp, uintptr_t *pc)
:lastFp_(nullptr),
thread_(thread)
{
thread_->SetCurrentSPFrame(newFp);
lastOptCallRuntimePc_ = thread->GetLastOptCallRuntimePc();
thread->SetLastOptCallRuntimePc(pc);
JSTaggedType *cursp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
lastFp_ = static_cast<uintptr_t *>(static_cast<void *>(cursp));
JSTaggedType *newSp = static_cast<JSTaggedType *>(static_cast<void *>(newFp));
thread_->SetCurrentSPFrame(newSp);
// print newfp and type for debug
std::cout << "CallRuntimeTrampolinesScope newFp: " << newFp << " oldRbp_ : " << oldRbp_
<< " thread_->fp:" << thread_->GetCurrentSPFrame() <<std::endl;
std::cout << "CallRuntimeTrampolinesScope newFp: " << newFp << " lastFp_ : " << lastFp_
<< std::endl;
FrameType type = *(reinterpret_cast<FrameType*>(
reinterpret_cast<long long>(newFp) + FrameConst::kFrameType));
std::cout << "type = " << as_integer(type) << std::endl;
std::cout << __FUNCTION__ << " type = " << as_integer(type) << std::endl;
}
~CallRuntimeTrampolinesScope()
{
// print oldfp and type for debug
std::cout << "~CallRuntimeTrampolinesScope oldRbp_: " << oldRbp_ <<
std::cout << "~CallRuntimeTrampolinesScope lastFp_: " << lastFp_ <<
" thread_->fp:" << thread_->GetCurrentSPFrame() << std::endl;
FrameType type = *(reinterpret_cast<FrameType*>(
reinterpret_cast<long long>(oldRbp_) + FrameConst::kFrameType));
std::cout << "type = " << as_integer(type) << std::endl;
thread_->SetCurrentSPFrame(oldRbp_);
reinterpret_cast<long long>(lastFp_) + FrameConst::kFrameType));
std::cout << __FUNCTION__ << "type = " << as_integer(type) << std::endl;
JSTaggedType *oldSp = static_cast<JSTaggedType *>(static_cast<void *>(lastFp_));
thread_->SetCurrentSPFrame(oldSp);
thread_->SetLastOptCallRuntimePc(lastOptCallRuntimePc_);
}
private:
JSTaggedType *oldRbp_;
uintptr_t *lastFp_;
JSThread *thread_;
uintptr_t *lastOptCallRuntimePc_;
};
} // namespace panda::ecmascript
#endif

View File

@ -179,6 +179,33 @@ host_unittest_action("GlueRegsTest") {
}
}
host_unittest_action("JsArrayIteratorTest") {
module_out_path = module_output_path
sources = [
# test file
"js_array_iterator_test.cpp",
]
configs = [
"//ark/js_runtime:ecma_test_config",
"//ark/js_runtime:ark_jsruntime_public_config", # should add before
# arkruntime_public_config
"//ark/js_runtime:ark_jsruntime_common_config",
"$ark_root/runtime:arkruntime_public_config",
]
deps = [
"$ark_root/libpandabase:libarkbase",
"//ark/js_runtime:libark_jsruntime_test",
sdk_libc_secshared_dep,
]
if (!is_standard_system) {
deps += [ "$ark_root/runtime:libarkruntime" ]
}
}
host_unittest_action("JsArrayTest") {
module_out_path = module_output_path
@ -206,6 +233,33 @@ host_unittest_action("JsArrayTest") {
}
}
host_unittest_action("JsDataViewTest") {
module_out_path = module_output_path
sources = [
# test file
"js_dataview_test.cpp",
]
configs = [
"//ark/js_runtime:ecma_test_config",
"//ark/js_runtime:ark_jsruntime_public_config", # should add before
# arkruntime_public_config
"//ark/js_runtime:ark_jsruntime_common_config",
"$ark_root/runtime:arkruntime_public_config",
]
deps = [
"$ark_root/libpandabase:libarkbase",
"//ark/js_runtime:libark_jsruntime_test",
sdk_libc_secshared_dep,
]
if (!is_standard_system) {
deps += [ "$ark_root/runtime:libarkruntime" ]
}
}
host_unittest_action("JsDateTest") {
module_out_path = module_output_path
@ -922,7 +976,9 @@ group("unittest") {
":GlueRegsTest",
":HugeObjectTest",
":JsArgumentsTest",
":JsArrayIteratorTest",
":JsArrayTest",
":JsDataViewTest",
":JsDateTest",
":JsForinIteratorTest",
":JsFunctionTest",
@ -963,7 +1019,9 @@ group("host_unittest") {
":GlueRegsTestAction",
":HugeObjectTestAction",
":JsArgumentsTestAction",
":JsArrayIteratorTestAction",
":JsArrayTestAction",
":JsDataViewTestAction",
":JsDateTestAction",
":JsForinIteratorTestAction",
":JsFunctionTestAction",

View File

@ -29,7 +29,7 @@ public:
GTEST_LOG_(INFO) << "SetUpTestCase";
}
static void TesrDownTestCase()
static void TearDownTestCase()
{
GTEST_LOG_(INFO) << "TearDownCase";
}

View File

@ -26,7 +26,7 @@ public:
GTEST_LOG_(INFO) << "SetUpTestCase";
}
static void TesrDownTestCase()
static void TearDownTestCase()
{
GTEST_LOG_(INFO) << "TearDownCase";
}

View File

@ -0,0 +1,178 @@
/*
* 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 "ecmascript/global_env.h"
#include "ecmascript/js_array_iterator.h"
#include "ecmascript/js_array.h"
#include "ecmascript/object_factory.h"
#include "ecmascript/tests/test_helper.h"
using namespace panda::ecmascript;
namespace panda::test {
class JSArrayIteratorTest : public testing::Test {
public:
static void SetUpTestCase()
{
GTEST_LOG_(INFO) << "SetUpTestCase";
}
static void TearDownTestCase()
{
GTEST_LOG_(INFO) << "TearDownCase";
}
void SetUp() override
{
TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
}
void TearDown() override
{
TestHelper::DestroyEcmaVMWithScope(instance, scope);
}
PandaVM *instance {nullptr};
ecmascript::EcmaHandleScope *scope {nullptr};
JSThread *thread {nullptr};
};
/*
* Feature: JSArrayIterator
* Function: SetIteratedArray
* SubFunction: GetIteratedArray
* FunctionPoints: Set Iterated Array
* CaseDescription: Call the "SetIteratedArray" function, check whether the result returned through "GetIteratedArray"
* function from the JSArrayIterator is within expectations.
*/
HWTEST_F_L0(JSArrayIteratorTest, SetIteratedArray)
{
EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
ObjectFactory *factory = ecmaVMPtr->GetFactory();
uint32_t arrayFrom1[10] = {0, 6, 8, 99, 200, 1, -1, -199, 33, 100};
uint32_t arrayFrom2[10] = {1111, 3211, 737, 0, 1267, 174, 2763, 832, 11, 93};
int numArrayFrom1 = sizeof(arrayFrom1)/sizeof(arrayFrom1[0]);
int numArrayFrom2 = sizeof(arrayFrom2)/sizeof(arrayFrom2[0]);
JSHandle<TaggedArray> handleTaggedArrayFrom1(factory->NewTaggedArray(numArrayFrom1));
JSHandle<TaggedArray> handleTaggedArrayFrom2(factory->NewTaggedArray(numArrayFrom2));
for (int i = 0; i < numArrayFrom1; i++) {
handleTaggedArrayFrom1->Set(thread, i, JSTaggedValue(arrayFrom1[i]));
}
for (int i = 0; i < numArrayFrom2; i++) {
handleTaggedArrayFrom2->Set(thread, i, JSTaggedValue(arrayFrom2[i]));
}
JSHandle<JSObject> handleJSObjectTaggedArrayFrom1(JSArray::CreateArrayFromList(thread, handleTaggedArrayFrom1));
JSHandle<JSObject> handleJSObjectTaggedArrayFrom2(JSArray::CreateArrayFromList(thread, handleTaggedArrayFrom2));
// Call "SetIteratedArray" function through "NewJSArrayIterator" function of "object_factory.cpp".
JSHandle<JSArrayIterator> handleJSArrayIter = factory->NewJSArrayIterator(handleJSObjectTaggedArrayFrom1,
IterationKind::KEY);
JSHandle<JSArray> handleJSArrayTo1(thread, JSArray::Cast(handleJSArrayIter->GetIteratedArray().GetTaggedObject()));
EXPECT_EQ(handleJSArrayTo1->GetArrayLength(), numArrayFrom1);
for (int i = 0; i < numArrayFrom1; i++) {
EXPECT_EQ(JSArray::FastGetPropertyByValue(thread, JSHandle<JSTaggedValue>(handleJSArrayTo1), i)->GetNumber(),
arrayFrom1[i]);
}
// Call "SetIteratedArray" function in this HWTEST_F_L0.
handleJSArrayIter->SetIteratedArray(thread, handleJSObjectTaggedArrayFrom2);
JSHandle<JSArray> handleJSArrayTo2(thread, JSArray::Cast(handleJSArrayIter->GetIteratedArray().GetTaggedObject()));
EXPECT_EQ(handleJSArrayTo2->GetArrayLength(), numArrayFrom2);
for (int i = 0; i < numArrayFrom2; i++) {
EXPECT_EQ(JSArray::FastGetPropertyByValue(thread, JSHandle<JSTaggedValue>(handleJSArrayTo2), i)->GetNumber(),
arrayFrom2[i]);
}
}
/*
* Feature: JSArrayIterator
* Function: SetNextIndex
* SubFunction: GetNextIndex
* FunctionPoints: Set Next Index
* CaseDescription: Call the "SetNextIndex" function, check whether the result returned through "GetNextIndex" function
* from the JSArrayIterator is within expectations.
*/
HWTEST_F_L0(JSArrayIteratorTest, SetNextIndex)
{
EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
ObjectFactory *factory = ecmaVMPtr->GetFactory();
uint32_t array[10] = {0, 6, 8, 99, 200, 1, -1, -199, 33, 100};
int numArray = sizeof(array)/sizeof(array[0]);
JSHandle<TaggedArray> handleTaggedArray(factory->NewTaggedArray(numArray));
for (int i = 0; i < numArray; i++) {
handleTaggedArray->Set(thread, i, JSTaggedValue(array[i]));
}
JSHandle<JSObject> handleJSObjectTaggedArray(JSArray::CreateArrayFromList(thread, handleTaggedArray));
// Call "SetNextIndex" function through "NewJSArrayIterator" function of "object_factory.cpp".
JSHandle<JSArrayIterator> handleJSArrayIter = factory->NewJSArrayIterator(handleJSObjectTaggedArray,
IterationKind::KEY);
EXPECT_EQ(handleJSArrayIter->GetNextIndex().GetNumber(), 0);
int testQuantity = 100;
for (int i = 1; i <= testQuantity; i++) {
JSHandle<JSTaggedValue> handleTagValNextIndex(thread, JSTaggedValue(i));
// Call "SetNextIndex" function in this HWTEST_F_L0.
handleJSArrayIter->SetNextIndex(thread, handleTagValNextIndex);
EXPECT_EQ(handleJSArrayIter->GetNextIndex().GetNumber(), i);
}
}
/*
* Feature: JSArrayIterator
* Function: SetIterationKind
* SubFunction: GetIterationKind
* FunctionPoints: Set Iteration Kind
* CaseDescription: Call the "SetIterationKind" function, check whether the result returned through "GetIterationKind"
* function from the JSArrayIterator is within expectations.
*/
HWTEST_F_L0(JSArrayIteratorTest, SetIterationKind)
{
EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
ObjectFactory *factory = ecmaVMPtr->GetFactory();
uint32_t array[10] = {0, 6, 8, 99, 200, 1, -1, -199, 33, 100};
int numArray = sizeof(array)/sizeof(array[0]);
JSHandle<TaggedArray> handleTaggedArray(factory->NewTaggedArray(numArray));
for (int i = 0; i < numArray; i++) {
handleTaggedArray->Set(thread, i, JSTaggedValue(array[i]));
}
JSHandle<JSTaggedValue> handleTagVal0(thread, JSTaggedValue(0));
JSHandle<JSTaggedValue> handleTagVal1(thread, JSTaggedValue(1));
JSHandle<JSTaggedValue> handleTagVal2(thread, JSTaggedValue(2));
JSHandle<JSObject> handleJSObjectTaggedArray(JSArray::CreateArrayFromList(thread, handleTaggedArray));
// Call "SetIterationKind" function through "NewJSArrayIterator" function of "object_factory.cpp".
JSHandle<JSArrayIterator> handleJSArrayIter = factory->NewJSArrayIterator(handleJSObjectTaggedArray,
IterationKind::KEY);
EXPECT_EQ(handleJSArrayIter->GetIterationKind().GetNumber(), 0);
handleJSArrayIter = factory->NewJSArrayIterator(handleJSObjectTaggedArray, IterationKind::VALUE);
EXPECT_EQ(handleJSArrayIter->GetIterationKind().GetNumber(), 1);
handleJSArrayIter = factory->NewJSArrayIterator(handleJSObjectTaggedArray, IterationKind::KEY_AND_VALUE);
EXPECT_EQ(handleJSArrayIter->GetIterationKind().GetNumber(), 2);
// Call "SetIterationKind" function in this HWTEST_F_L0.
handleJSArrayIter->SetIterationKind(thread, handleTagVal0);
EXPECT_EQ(handleJSArrayIter->GetIterationKind().GetNumber(), 0);
handleJSArrayIter->SetIterationKind(thread, handleTagVal1);
EXPECT_EQ(handleJSArrayIter->GetIterationKind().GetNumber(), 1);
handleJSArrayIter->SetIterationKind(thread, handleTagVal2);
EXPECT_EQ(handleJSArrayIter->GetIterationKind().GetNumber(), 2);
}
} // namespace panda::ecmascript

View File

@ -0,0 +1,214 @@
/*
* 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 "ecmascript/global_env.h"
#include "ecmascript/js_arraybuffer.h"
#include "ecmascript/js_dataview.h"
#include "ecmascript/object_factory.h"
#include "ecmascript/tests/test_helper.h"
using namespace panda::ecmascript;
namespace panda::test {
class JSDataViewTest : public testing::Test {
public:
static void SetUpTestCase()
{
GTEST_LOG_(INFO) << "SetUpTestCase";
}
static void TearDownTestCase()
{
GTEST_LOG_(INFO) << "TearDownCase";
}
void SetUp() override
{
TestHelper::CreateEcmaVMWithScope(instance, thread, scope);
}
void TearDown() override
{
TestHelper::DestroyEcmaVMWithScope(instance, scope);
}
PandaVM *instance {nullptr};
ecmascript::EcmaHandleScope *scope {nullptr};
JSThread *thread {nullptr};
};
/*
* Feature: JSDataView
* Function: GetElementSize
* SubFunction: N/A
* FunctionPoints: Get ElementSize
* CaseDescription: Check whether the returned value through "GetElementSize" function is within expectations.
*/
HWTEST_F_L0(JSDataViewTest, GetElementSize)
{
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::INT8), 1);
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::UINT8), 1);
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::UINT8_CLAMPED), 1);
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::INT16), 2);
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::UINT16), 2);
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::INT32), 4);
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::UINT32), 4);
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::FLOAT32), 4);
EXPECT_EQ(JSDataView::GetElementSize(DataViewType::FLOAT64), 8);
}
/*
* Feature: JSDataView
* Function: SetDataView
* SubFunction: GetDataView
* FunctionPoints: Set DataView
* CaseDescription: Check whether the returned value through "GetDataView" function is within expectations after
* calling "SetDataView" function.
*/
HWTEST_F_L0(JSDataViewTest, SetDataView)
{
EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
ObjectFactory *factory = ecmaVMPtr->GetFactory();
JSHandle<GlobalEnv> handleGlobalEnv = ecmaVMPtr->GetGlobalEnv();
int32_t lengthDataArrayBuf = 8;
int32_t offsetDataView = 4;
int32_t lengthDataView = 4;
JSHandle<JSFunction> handleFuncArrayBuf(handleGlobalEnv->GetArrayBufferFunction());
JSHandle<JSTaggedValue> handleTagValFuncArrayBuf(handleFuncArrayBuf);
JSHandle<JSArrayBuffer> handleArrayBuf(
factory->NewJSObjectByConstructor(handleFuncArrayBuf, handleTagValFuncArrayBuf));
handleArrayBuf->SetArrayBufferByteLength(thread, JSTaggedValue(lengthDataArrayBuf));
// Call "SetDataView" function through "NewJSDataView" function of "object_factory.cpp"
JSHandle<JSDataView> handleDataView = factory->NewJSDataView(handleArrayBuf, offsetDataView,
lengthDataView);
EXPECT_TRUE(handleDataView->GetDataView().IsTrue());
// Call "SetDataView" function in this HWTEST_F_L0.
handleDataView->SetDataView(thread, JSTaggedValue::False());
EXPECT_TRUE(handleDataView->GetDataView().IsFalse());
handleDataView->SetDataView(thread, JSTaggedValue::True());
EXPECT_TRUE(handleDataView->GetDataView().IsTrue());
}
/*
* Feature: JSDataView
* Function: SetViewedArrayBuffer
* SubFunction: GetViewedArrayBuffer
* FunctionPoints: Set ViewedArrayBuffer
* CaseDescription: Check whether the returned value through "GetViewedArrayBuffer" function is within expectations
* after calling "SetViewedArrayBuffer" function.
*/
HWTEST_F_L0(JSDataViewTest, SetViewedArrayBuffer)
{
EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
ObjectFactory *factory = ecmaVMPtr->GetFactory();
JSHandle<JSFunction> handleFuncArrayBuf(ecmaVMPtr->GetGlobalEnv()->GetArrayBufferFunction());
JSHandle<JSTaggedValue> handleTagValFuncArrayBuf(handleFuncArrayBuf);
int32_t lengthDataArrayBuf1 = 8;
int32_t lengthDataArrayBuf2 = 16;
int32_t offsetDataView = 4;
int32_t lengthDataView = 4;
JSHandle<JSArrayBuffer> handleArrayBuf1(
factory->NewJSObjectByConstructor(handleFuncArrayBuf, handleTagValFuncArrayBuf));
JSHandle<JSArrayBuffer> handleArrayBuf2(
factory->NewJSObjectByConstructor(handleFuncArrayBuf, handleTagValFuncArrayBuf));
handleArrayBuf1->SetArrayBufferByteLength(thread, JSTaggedValue(lengthDataArrayBuf1));
handleArrayBuf2->SetArrayBufferByteLength(thread, JSTaggedValue(lengthDataArrayBuf2));
// Call "SetViewedArrayBuffer" function through "NewJSDataView" function of "object_factory.cpp"
JSHandle<JSDataView> handleDataView = factory->NewJSDataView(handleArrayBuf1, offsetDataView,
lengthDataView);
JSHandle<JSTaggedValue> handleTagValDataViewFrom1(thread, handleArrayBuf1.GetTaggedValue());
JSHandle<JSTaggedValue> handleTagValDataViewTo1(thread, handleDataView->GetViewedArrayBuffer());
EXPECT_TRUE(JSTaggedValue::Equal(thread, handleTagValDataViewFrom1, handleTagValDataViewTo1));
// Call "SetViewedArrayBuffer" function in this HWTEST_F_L0.
handleDataView->SetViewedArrayBuffer(thread, handleArrayBuf2.GetTaggedValue());
JSHandle<JSTaggedValue> handleTagValDataViewFrom2(thread, handleArrayBuf2.GetTaggedValue());
JSHandle<JSTaggedValue> handleTagValDataViewTo2(thread, handleDataView->GetViewedArrayBuffer());
EXPECT_TRUE(JSTaggedValue::Equal(thread, handleTagValDataViewFrom2, handleTagValDataViewTo2));
EXPECT_FALSE(JSTaggedValue::Equal(thread, handleTagValDataViewFrom1, handleTagValDataViewFrom2));
}
/*
* Feature: JSDataView
* Function: SetByteLength
* SubFunction: GetByteLength
* FunctionPoints: Set ByteLength
* CaseDescription: Check whether the returned value through "GetByteLength" function is within expectations after
* calling "SetByteLength" function.
*/
HWTEST_F_L0(JSDataViewTest, SetByteLength)
{
EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
ObjectFactory *factory = ecmaVMPtr->GetFactory();
JSHandle<JSFunction> handleFuncArrayBuf(ecmaVMPtr->GetGlobalEnv()->GetArrayBufferFunction());
JSHandle<JSTaggedValue> handleTagValFuncArrayBuf(handleFuncArrayBuf);
int32_t lengthDataArrayBuf = 8;
int32_t offsetDataView = 4;
int32_t lengthDataView1 = 4;
int32_t lengthDataView2 = 2;
JSHandle<JSTaggedValue> handleTagValLengthDataView2(thread, JSTaggedValue(lengthDataView2));
JSHandle<JSArrayBuffer> handleArrayBuf(
factory->NewJSObjectByConstructor(handleFuncArrayBuf, handleTagValFuncArrayBuf));
handleArrayBuf->SetArrayBufferByteLength(thread, JSTaggedValue(lengthDataArrayBuf));
// Call "SetByteLength" function through "NewJSDataView" function of "object_factory.cpp"
JSHandle<JSDataView> handleDataView = factory->NewJSDataView(handleArrayBuf, offsetDataView,
lengthDataView1);
EXPECT_EQ(handleDataView->GetByteLength().GetNumber(), lengthDataView1);
// Call "SetByteLength" function in this HWTEST_F_L0.
handleDataView->SetByteLength(thread, handleTagValLengthDataView2);
EXPECT_EQ(handleDataView->GetByteLength().GetNumber(), lengthDataView2);
}
/*
* Feature: JSDataView
* Function: SetByteOffset
* SubFunction: GetByteOffset
* FunctionPoints: Set ByteOffset
* CaseDescription: Check whether the returned value through "GetByteOffset" function is within expectations after
* calling "SetByteOffset" function.
*/
HWTEST_F_L0(JSDataViewTest, SetByteOffset)
{
EcmaVM *ecmaVMPtr = thread->GetEcmaVM();
ObjectFactory *factory = ecmaVMPtr->GetFactory();
JSHandle<JSFunction> handleFuncArrayBuf1(ecmaVMPtr->GetGlobalEnv()->GetArrayBufferFunction());
JSHandle<JSTaggedValue> handleTagValFuncArrayBuf1(handleFuncArrayBuf1);
int32_t lengthDataArrayBuf = 8;
int32_t offsetDataView1 = 4;
int32_t offsetDataView2 = 6;
int32_t lengthDataView = 2;
JSHandle<JSTaggedValue> handleTagValOffsetDataView2(thread, JSTaggedValue(offsetDataView2));
JSHandle<JSArrayBuffer> handleArrayBuf(
factory->NewJSObjectByConstructor(handleFuncArrayBuf1, handleTagValFuncArrayBuf1));
handleArrayBuf->SetArrayBufferByteLength(thread, JSTaggedValue(lengthDataArrayBuf));
// Call "SetByteOffset" function through "NewJSDataView" function of "object_factory.cpp"
JSHandle<JSDataView> handleDataView = factory->NewJSDataView(handleArrayBuf, offsetDataView1,
lengthDataView);
EXPECT_EQ(handleDataView->GetByteOffset().GetNumber(), offsetDataView1);
// Call "SetByteOffset" function in this HWTEST_F_L0.
handleDataView->SetByteOffset(thread, handleTagValOffsetDataView2);
EXPECT_EQ(handleDataView->GetByteOffset().GetNumber(), offsetDataView2);
}
} // namespace panda::ecmascript

View File

@ -78,7 +78,7 @@ HWTEST_F_L0(NameDictionaryTest, addKeyAndValue)
int numOfElement = 64;
JSHandle<NameDictionary> dictJShandle(thread, NameDictionary::Create(thread, numOfElement));
EXPECT_TRUE(*dictJShandle != nullptr);
JSHandle<NameDictionary> dictHandle(dictJShandle);
JSMutableHandle<NameDictionary> dictHandle(dictJShandle);
JSHandle<JSTaggedValue> objFun = GetGlobalEnv(thread)->GetObjectFunction();
// create key and values
@ -103,7 +103,8 @@ HWTEST_F_L0(NameDictionaryTest, addKeyAndValue)
PropertyAttributes metaData2;
// test insert()
JSHandle<NameDictionary> dict(thread, NameDictionary::PutIfAbsent(thread, dictHandle, key1, value1, metaData1));
NameDictionary *dict = NameDictionary::PutIfAbsent(thread, dictHandle, key1, value1, metaData1);
dictHandle.Update(JSTaggedValue(dict));
EXPECT_EQ(dict->EntriesCount(), 1);
// test find() and lookup()
@ -111,10 +112,10 @@ HWTEST_F_L0(NameDictionaryTest, addKeyAndValue)
EXPECT_EQ(key1.GetTaggedValue(), JSTaggedValue(dict->GetKey(entry1).GetRawData()));
EXPECT_EQ(value1.GetTaggedValue(), JSTaggedValue(dict->GetValue(entry1).GetRawData()));
JSHandle<NameDictionary> dict2(thread, dict->PutIfAbsent(thread, dictHandle, key2, value2, metaData2));
JSHandle<NameDictionary> dict2(thread, NameDictionary::PutIfAbsent(thread, dictHandle, key2, value2, metaData2));
EXPECT_EQ(dict2->EntriesCount(), 2);
// test remove()
dict->Remove(thread, dictHandle, entry1);
dict = NameDictionary::Remove(thread, dictHandle, entry1);
EXPECT_EQ(-1, dict->FindEntry(key1.GetTaggedValue()));
EXPECT_EQ(dict->EntriesCount(), 1);
}
@ -172,7 +173,8 @@ HWTEST_F_L0(NameDictionaryTest, ShrinkCapacity)
PropertyAttributes metaData;
// test insert()
dictHandle.Update(JSTaggedValue(NameDictionary::PutIfAbsent(thread, dictHandle, key, value, metaData)));
NameDictionary *newDict = NameDictionary::PutIfAbsent(thread, dictHandle, key, value, metaData);
dictHandle.Update(JSTaggedValue(newDict));
}
keyArray[5] = '2';
@ -183,7 +185,8 @@ HWTEST_F_L0(NameDictionaryTest, ShrinkCapacity)
int entry = dictHandle->FindEntry(arrayHandle.GetTaggedValue());
EXPECT_NE(entry, -1);
dictHandle.Update(JSTaggedValue(NameDictionary::Remove(thread, dictHandle, entry)));
NameDictionary *newDict1 = NameDictionary::Remove(thread, dictHandle, entry);
dictHandle.Update(JSTaggedValue(newDict1));
EXPECT_EQ(dictHandle->EntriesCount(), 9);
EXPECT_EQ(dictHandle->Size(), 16);
}

View File

@ -47,8 +47,8 @@ source_set("libark_ecma_debugger_static") {
deps = [
"$ark_root/libpandabase:libarkbase",
"$ark_root/libpandafile:libarkfile",
"$ark_root/runtime:arkruntime_header_deps",
]
deps += arkruntime_header_gen_deps
cflags_cc = [ "-fvisibility=hidden" ]
}
@ -84,8 +84,8 @@ source_set("libark_ecma_debugger_test_static") {
deps = [
"$ark_root/libpandabase:libarkbase",
"$ark_root/libpandafile:libarkfile",
"$ark_root/runtime:arkruntime_header_deps",
]
deps += arkruntime_header_gen_deps
}
ohos_shared_library("libark_ecma_debugger_test") {

View File

@ -19,10 +19,6 @@
namespace panda::tooling::ecmascript {
void JSPtHooks::Breakpoint([[maybe_unused]] PtThread thread, const PtLocation &location)
{
if (thread.GetId() != ManagedThread::NON_INITIALIZED_THREAD_ID) {
// Skip none-js thread
return;
}
LOG(DEBUG, DEBUGGER) << "JSPtHooks: Breakpoint => " << location.GetMethodId() << ": "
<< location.GetBytecodeOffset();
@ -38,13 +34,9 @@ void JSPtHooks::Paused(PauseReason reason)
backend_->NotifyPaused({}, reason);
}
void JSPtHooks::Exception(PtThread thread, [[maybe_unused]] const PtLocation &location,
void JSPtHooks::Exception([[maybe_unused]] PtThread thread, [[maybe_unused]] const PtLocation &location,
[[maybe_unused]] PtObject exceptionObject, [[maybe_unused]] const PtLocation &catchLocation)
{
if (thread.GetId() != ManagedThread::NON_INITIALIZED_THREAD_ID) {
// Skip none-js thread
return;
}
LOG(DEBUG, DEBUGGER) << "JSPtHooks: Exception";
[[maybe_unused]] LocalScope scope(backend_->ecmaVm_);
@ -58,12 +50,8 @@ void JSPtHooks::Exception(PtThread thread, [[maybe_unused]] const PtLocation &lo
}
}
void JSPtHooks::SingleStep(PtThread thread, const PtLocation &location)
void JSPtHooks::SingleStep([[maybe_unused]] PtThread thread, const PtLocation &location)
{
if (thread.GetId() != ManagedThread::NON_INITIALIZED_THREAD_ID) {
// Skip none-js thread
return;
}
LOG(DEBUG, DEBUGGER) << "JSPtHooks: SingleStep => " << location.GetBytecodeOffset();
[[maybe_unused]] LocalScope scope(backend_->ecmaVm_);

View File

@ -73,8 +73,7 @@ void JSDebugger::BytecodePcChanged(ManagedThread *thread, Method *method, uint32
HandleBreakpoint(JSThread::Cast(thread), JSMethod::Cast(method), bcOffset);
}
bool JSDebugger::HandleBreakpoint([[maybe_unused]] const JSThread *thread, const JSMethod *method,
uint32_t bcOffset)
bool JSDebugger::HandleBreakpoint(const JSThread *thread, const JSMethod *method, uint32_t bcOffset)
{
if (!FindBreakpoint(method, bcOffset)) {
return false;
@ -83,7 +82,7 @@ bool JSDebugger::HandleBreakpoint([[maybe_unused]] const JSThread *thread, const
auto *pf = method->GetPandaFile();
PtLocation location {pf->GetFilename().c_str(), method->GetFileId(), bcOffset};
if (hooks_ != nullptr) {
hooks_->Breakpoint(PtThread(ManagedThread::NON_INITIALIZED_THREAD_ID), location);
hooks_->Breakpoint(PtThread(thread->GetId()), location);
}
return true;
@ -99,7 +98,7 @@ void JSDebugger::HandleExceptionThrowEvent(const JSThread *thread, const JSMetho
PtLocation throwLocation {pf->GetFilename().c_str(), method->GetFileId(), bcOffset};
if (hooks_ != nullptr) {
hooks_->Exception(PtThread(ManagedThread::NON_INITIALIZED_THREAD_ID), throwLocation, PtObject(), throwLocation);
hooks_->Exception(PtThread(thread->GetId()), throwLocation, PtObject(), throwLocation);
}
}

View File

@ -49,7 +49,7 @@ JSTaggedValue WeakVector::Get(array_size_t index) const
void WeakVector::Set(const JSThread *thread, array_size_t index, JSTaggedValue value)
{
ASSERT(index < GetCapacity());
return TaggedArray::Set(thread, VectorToArrayIndex(index), value);
TaggedArray::Set(thread, VectorToArrayIndex(index), value);
}
void WeakVector::SetEnd(const JSThread *thread, array_size_t end)

View File

@ -21,14 +21,6 @@ asan_lib_path = "/usr/lib/llvm-10/lib/clang/10.0.0/lib/linux"
sdk_libc_secshared_dep = "//utils/native/base:utilsecurec"
sdk_libc_secshared_config = "//utils/native/base:utils_config"
# Add for header file dependence, should dependent this when include
# header file of runtime, but not dependent libarkruntime
arkruntime_header_gen_deps = [
"$ark_root/runtime:arkruntime_gen_intrinsics_intrinsics_h",
"$ark_root/runtime:libarkruntime_options_gen_h",
"$ark_root/verification/gen:verification_verifier_messages_h",
]
# Generate file for a template and YAML data provided.
#
# Mandatory arguments:

View File

@ -35,21 +35,20 @@ def parse_args():
return args
def copy_xml(args):
"""copy resource xml to test direction."""
def copy_res(args):
"""copy resources to test direction."""
src_xml_file = os.path.join(args.src_path, args.src_xml)
dst_xml_file = os.path.join(args.dst_path, args.src_xml)
if not os.path.isfile(src_xml_file):
print(args.src_xml + " not exist.")
return
if not os.path.exists(args.dst_path):
os.makedirs(args.dst_path)
if os.path.exists(args.dst_path):
shutil.rmtree(args.dst_path)
shutil.copyfile(src_xml_file, dst_xml_file)
shutil.copytree(args.src_path, args.dst_path)
if __name__ == '__main__':
input_args = parse_args()
copy_xml(input_args)
copy_res(input_args)