/* * 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/accessor_data.h" #include "ecmascript/class_info_extractor.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/property_box.h" #include "ecmascript/ic/proto_change_details.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_arraylist.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 { class EcmaDumpTest : 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}; }; #ifndef NDEBUG HWTEST_F_L0(EcmaDumpTest, Dump) { JSTaggedValue value1(100); value1.D(); JSTaggedValue value2(100.0); JSTaggedValue::DV(value2.GetRawData()); JSTaggedValue::Undefined().D(); JSHandle env = thread->GetEcmaVM()->GetGlobalEnv(); env.Dump(); JSHandle objFunc(env->GetObjectFunction()); objFunc.Dump(); } #endif // #ifndef NDEBUG static JSHandle NewJSMap(JSThread *thread, ObjectFactory *factory, JSHandle proto) { JSHandle mapClass = factory->NewEcmaDynClass(JSMap::SIZE, JSType::JS_MAP, proto); JSHandle jsMap = JSHandle::Cast(factory->NewJSObject(mapClass)); JSHandle linkedMap(LinkedHashMap::Create(thread)); jsMap->SetLinkedMap(thread, linkedMap); return jsMap; } static JSHandle NewJSSet(JSThread *thread, ObjectFactory *factory, JSHandle proto) { JSHandle setClass = factory->NewEcmaDynClass(JSSet::SIZE, JSType::JS_SET, proto); JSHandle jsSet = JSHandle::Cast(factory->NewJSObject(setClass)); JSHandle linkedSet(LinkedHashSet::Create(thread)); jsSet->SetLinkedSet(thread, linkedSet); return jsSet; } static JSHandle NewJSObject(JSThread *thread, ObjectFactory *factory, JSHandle globalEnv) { JSFunction *jsFunc = globalEnv->GetObjectFunction().GetObject(); JSHandle jsFunc1(thread, jsFunc); JSHandle jsObj = factory->NewJSObjectByConstructor(JSHandle(jsFunc1), jsFunc1); return jsObj; } HWTEST_F_L0(EcmaDumpTest, HeapProfileDump) { [[maybe_unused]] ecmascript::EcmaHandleScope scope(thread); auto factory = thread->GetEcmaVM()->GetFactory(); auto globalEnv = thread->GetEcmaVM()->GetGlobalEnv(); auto globalConst = const_cast(thread->GlobalConstants()); JSHandle proto = globalEnv->GetFunctionPrototype(); std::vector> snapshotVector; #define DUMP_FOR_HANDLE(dumpHandle) \ dumpHandle.GetTaggedValue().D(); \ dumpHandle.GetTaggedValue().DumpForSnapshot(thread, snapshotVector); #define NEW_OBJECT_AND_DUMP(ClassName, TypeName) \ JSHandle class##ClassName = \ factory->NewEcmaDynClass(ClassName::SIZE, JSType::TypeName, proto); \ JSHandle object##ClassName = factory->NewJSObject(class##ClassName); \ object##ClassName.GetTaggedValue().D(); \ object##ClassName.GetTaggedValue().DumpForSnapshot(thread, snapshotVector); for (JSType type = JSType::JS_OBJECT; type <= JSType::JS_TYPE_LAST; type = JSType(static_cast(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 jsObj = NewJSObject(thread, factory, globalEnv); DUMP_FOR_HANDLE(jsObj) break; } case JSType::JS_REALM: { CHECK_DUMP_FILEDS(JSObject::SIZE, JSRealm::SIZE, 2) JSHandle 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 jsFunc = globalEnv->GetFunctionFunction(); DUMP_FOR_HANDLE(jsFunc) break; } case JSType::JS_PROXY_REVOC_FUNCTION: { CHECK_DUMP_FILEDS(JSFunction::SIZE, JSProxyRevocFunction::SIZE, 1) JSHandle proxyRevocClass = JSHandle::Cast(globalEnv->GetProxyRevocFunctionClass()); JSHandle proxyRevocFunc = factory->NewJSObject(proxyRevocClass); DUMP_FOR_HANDLE(proxyRevocFunc) break; } case JSType::JS_PROMISE_REACTIONS_FUNCTION: { CHECK_DUMP_FILEDS(JSFunction::SIZE, JSPromiseReactionsFunction::SIZE, 2) JSHandle promiseReactClass = JSHandle::Cast(globalEnv->GetPromiseReactionFunctionClass()); JSHandle promiseReactFunc = factory->NewJSObject(promiseReactClass); DUMP_FOR_HANDLE(promiseReactFunc) break; } case JSType::JS_PROMISE_EXECUTOR_FUNCTION: { CHECK_DUMP_FILEDS(JSFunction::SIZE, JSPromiseExecutorFunction::SIZE, 1) JSHandle promiseExeClass = JSHandle::Cast(globalEnv->GetPromiseExecutorFunctionClass()); JSHandle 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 promiseAllClass = JSHandle::Cast(globalEnv->GetPromiseAllResolveElementFunctionClass()); JSHandle 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 intlBoundFunc = factory->NewJSIntlBoundFunction(); DUMP_FOR_HANDLE(intlBoundFunc) break; } case JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION: { CHECK_DUMP_FILEDS(JSFunction::SIZE, JSAsyncAwaitStatusFunction::SIZE, 1) JSHandle 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 = NewJSSet(thread, factory, proto); DUMP_FOR_HANDLE(jsSet) break; } case JSType::JS_MAP: { CHECK_DUMP_FILEDS(JSObject::SIZE, JSMap::SIZE, 1) JSHandle jsMap = NewJSMap(thread, factory, proto); DUMP_FOR_HANDLE(jsMap) break; } case JSType::JS_WEAK_MAP: { CHECK_DUMP_FILEDS(JSObject::SIZE, JSWeakMap::SIZE, 1) JSHandle weakMapClass = factory->NewEcmaDynClass(JSWeakMap::SIZE, JSType::JS_WEAK_MAP, proto); JSHandle jsWeakMap = JSHandle::Cast(factory->NewJSObject(weakMapClass)); JSHandle weakLinkedMap(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 weakSetClass = factory->NewEcmaDynClass(JSWeakSet::SIZE, JSType::JS_WEAK_SET, proto); JSHandle jsWeakSet = JSHandle::Cast(factory->NewJSObject(weakSetClass)); JSHandle weakLinkedSet(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 dateClass = factory->NewEcmaDynClass(JSDate::SIZE, JSType::JS_DATE, proto); JSHandle date = JSHandle::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 array(thread, factory->NewJSArray().GetTaggedValue()); JSHandle forInIter = factory->NewJSForinIterator(array); DUMP_FOR_HANDLE(forInIter) break; } case JSType::JS_MAP_ITERATOR: { CHECK_DUMP_FILEDS(JSObject::SIZE, JSMapIterator::SIZE, 3) JSHandle 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 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 arrayIter = factory->NewJSArrayIterator(JSHandle::Cast(factory->NewJSArray()), IterationKind::KEY); DUMP_FOR_HANDLE(arrayIter) break; } case JSType::JS_STRING_ITERATOR: { CHECK_DUMP_FILEDS(JSObject::SIZE, JSStringIterator::SIZE, 2) JSHandle 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 asyncFuncObject = factory->NewJSAsyncFuncObject(); DUMP_FOR_HANDLE(asyncFuncObject) break; } case JSType::JS_ARRAY: { CHECK_DUMP_FILEDS(JSObject::SIZE, JSArray::SIZE, 1) JSHandle 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 globalObject = globalEnv->GetJSGlobalObject(); DUMP_FOR_HANDLE(globalObject) break; } case JSType::JS_PROXY: { CHECK_DUMP_FILEDS(ECMAObject::SIZE, JSProxy::SIZE, 3) JSHandle emptyObj(thread, NewJSObject(thread, factory, globalEnv).GetTaggedValue()); JSHandle proxy = factory->NewJSProxy(emptyObj, emptyObj); DUMP_FOR_HANDLE(proxy) break; } case JSType::HCLASS: { CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), JSHClass::SIZE, 9) JSHandle 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 = factory->NewTaggedArray(4); DUMP_FOR_HANDLE(taggedArray) break; } case JSType::TAGGED_DICTIONARY: { JSHandle 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 accessor = factory->NewAccessorData(); DUMP_FOR_HANDLE(accessor) break; } case JSType::SYMBOL: { CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), JSSymbol::SIZE, 3) JSHandle symbol = factory->NewJSSymbol(); DUMP_FOR_HANDLE(symbol) break; } case JSType::JS_GENERATOR_CONTEXT: { CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), GeneratorContext::SIZE, 7) JSHandle genContext = factory->NewGeneratorContext(); DUMP_FOR_HANDLE(genContext) break; } case JSType::PROTOTYPE_HANDLER: { CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), PrototypeHandler::SIZE, 3) JSHandle protoHandler = factory->NewPrototypeHandler(); DUMP_FOR_HANDLE(protoHandler) break; } case JSType::TRANSITION_HANDLER: { CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), TransitionHandler::SIZE, 2) JSHandle transitionHandler = factory->NewTransitionHandler(); DUMP_FOR_HANDLE(transitionHandler) break; } case JSType::PROPERTY_BOX: { CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), PropertyBox::SIZE, 1) JSHandle PropertyBox = factory->NewPropertyBox(globalEnv->GetEmptyArray()); DUMP_FOR_HANDLE(PropertyBox) break; } case JSType::PROTO_CHANGE_MARKER: { CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), ProtoChangeMarker::SIZE, 1) JSHandle protoMaker = factory->NewProtoChangeMarker(); DUMP_FOR_HANDLE(protoMaker) break; } case JSType::PROTOTYPE_INFO: { CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), ProtoChangeDetails::SIZE, 2) JSHandle protoDetails = factory->NewProtoChangeDetails(); DUMP_FOR_HANDLE(protoDetails) break; } case JSType::TEMPLATE_MAP: { JSHandle templateMap = globalEnv->GetTemplateMap(); DUMP_FOR_HANDLE(templateMap) break; } case JSType::PROGRAM: { CHECK_DUMP_FILEDS(ECMAObject::SIZE, Program::SIZE, 5) JSHandle 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 promiseCapa = factory->NewPromiseCapability(); DUMP_FOR_HANDLE(promiseCapa) break; } case JSType::PROMISE_RECORD: { CHECK_DUMP_FILEDS(Record::SIZE, PromiseRecord::SIZE, 1) JSHandle promiseRecord = factory->NewPromiseRecord(); DUMP_FOR_HANDLE(promiseRecord) break; } case JSType::RESOLVING_FUNCTIONS_RECORD: { CHECK_DUMP_FILEDS(Record::SIZE, ResolvingFunctionsRecord::SIZE, 2) JSHandle ResolvingFunc = factory->NewResolvingFunctionsRecord(); DUMP_FOR_HANDLE(ResolvingFunc) break; } case JSType::PROMISE_REACTIONS: { CHECK_DUMP_FILEDS(Record::SIZE, PromiseReaction::SIZE, 3) JSHandle promiseReact = factory->NewPromiseReaction(); DUMP_FOR_HANDLE(promiseReact) break; } case JSType::PROMISE_ITERATOR_RECORD: { CHECK_DUMP_FILEDS(Record::SIZE, PromiseIteratorRecord::SIZE, 2) JSHandle emptyObj(thread, NewJSObject(thread, factory, globalEnv).GetTaggedValue()); JSHandle promiseIter = factory->NewPromiseIteratorRecord(emptyObj, emptyObj); DUMP_FOR_HANDLE(promiseIter) break; } case JSType::MICRO_JOB_QUEUE: { CHECK_DUMP_FILEDS(Record::SIZE, ecmascript::job::MicroJobQueue::SIZE, 2) JSHandle microJob = factory->NewMicroJobQueue(); DUMP_FOR_HANDLE(microJob) break; } case JSType::PENDING_JOB: { CHECK_DUMP_FILEDS(Record::SIZE, ecmascript::job::PendingJob::SIZE, 2) JSHandle pendingClass(thread, JSHClass::Cast(globalConst->GetPendingJobClass().GetTaggedObject())); JSHandle pendingJob(thread, factory->NewDynObject(pendingClass)); DUMP_FOR_HANDLE(pendingJob) break; } case JSType::FUNCTION_EXTRA_INFO: { CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), JSFunctionExtraInfo::SIZE, 2) JSHandle funcExtraClass(thread, JSHClass::Cast(globalConst->GetFunctionExtraInfoClass().GetTaggedObject())); JSHandle funcInfo(thread, factory->NewDynObject(funcExtraClass)); DUMP_FOR_HANDLE(funcInfo) break; } case JSType::COMPLETION_RECORD: { CHECK_DUMP_FILEDS(Record::SIZE, CompletionRecord::SIZE, 2) JSHandle 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 = factory->NewMachineCodeObject(16, nullptr); DUMP_FOR_HANDLE(machineCode) break; } case JSType::ECMA_MODULE: { CHECK_DUMP_FILEDS(ECMAObject::SIZE, EcmaModule::SIZE, 1) JSHandle ecmaModule = factory->NewEmptyEcmaModule(); DUMP_FOR_HANDLE(ecmaModule) break; } case JSType::CLASS_INFO_EXTRACTOR: { CHECK_DUMP_FILEDS(TaggedObject::TaggedObjectSize(), ClassInfoExtractor::SIZE, 10) JSHandle classInfoExtractor = factory->NewClassInfoExtractor(nullptr); DUMP_FOR_HANDLE(classInfoExtractor) break; } case JSType::JS_QUEUE: case JSType::JS_ARRAY_LIST: { CHECK_DUMP_FILEDS(JSObject::SIZE, JSArrayList::SIZE, 1) // unused break; } default: LOG_ECMA_MEM(ERROR) << "JSType " << static_cast(type) << " cannot be dumped."; UNREACHABLE(); break; } } #undef NEW_OBJECT_AND_DUMP #undef DUMP_FOR_HANDLE } } // namespace panda::test