diff --git a/README.md b/README.md index 99fc3c478191561e49881bf1067da31c7c9e361e..f9ba018a5a762f705effa0b9ac403c06702956fa 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ For more infomation, see: [ARK Runtime Subsystem](https://gitee.com/openharmony/ ## Build ``` -./build.sh --product-name Hi3516DV300 --build-target ark\_js\_runtime +./build.sh --product-name Hi3516DV300 --build-target ark_js_runtime ``` ### Available APIs @@ -66,9 +66,9 @@ For details about how to generate JS bytecodes, see [Using the Toolchain](docs/ To run bytecodes: ``` -cd out/release -LD\_LIBRARY\_PATH=clang\_x64/ark/ark\_js\_runtime:clang\_x64/ark/ark:clang\_x64/global/i18n:../../prebuilts/clang/ohos/linux-x86\_64/llvm/lib/ -./clang\_x64/ark/ark\_js\_runtime/ark\_js\_vm helloworld.abc +$ cd out/release +$ export LD_LIBRARY_PATH=clang_x64/ark/ark_js_runtime:clang_x64/ark/ark:clang_x64/global/i18n:../../prebuilts/clang/ohos/linux-x86_64/llvm/lib/ +$ ./clang_x64/ark/ark_js_runtime/ark_js_vm helloworld.abc ``` For more infomation, please see: [ARK-Runtime-Usage-Guide](https://gitee.com/openharmony/ark_js_runtime/blob/master/docs/ARK-Runtime-Usage-Guide.md). diff --git a/README_zh.md b/README_zh.md index d7adae57ad981a1cb639d9666c14f950b526a1bc..952dce67e1393ec9b688c15538cf37a0872e2618 100644 --- a/README_zh.md +++ b/README_zh.md @@ -53,7 +53,7 @@ ## 编译构建 ``` -./build.sh --product-name Hi3516DV300 --build-target ark\_js\_runtime +$ ./build.sh --product-name Hi3516DV300 --build-target ark_js_runtime ``` ### 接口说明 @@ -66,11 +66,9 @@ JS生成字节码参考[工具链使用](docs/using-the-toolchain-zh.md) 字节码执行: ``` -cd out/release - -LD\_LIBRARY\_PATH=clang\_x64/ark/ark\_js\_runtime:clang\_x64/ark/ark:clang\_x64/global/i18n:../../prebuilts/clang/ohos/linux-x86\_64/llvm/lib/ - -./clang\_x64/ark/ark\_js\_runtime/ark\_js\_vm helloworld.abc +$ cd out/release +$ export LD_LIBRARY_PATH=clang_x64/ark/ark_js_runtime:clang_x64/ark/ark:clang_x64/global/i18n:../../prebuilts/clang/ohos/linux-x86_64/llvm/lib/ +$ ./clang_x64/ark/ark_js_runtime/ark_js_vm helloworld.abc ``` 更多使用说明请参考:[方舟运行时使用指南](https://gitee.com/openharmony/ark_js_runtime/blob/master/docs/ARK-Runtime-Usage-Guide-zh.md) diff --git a/ecmascript/ecma_isa.yaml b/ecmascript/ecma_isa.yaml index 3a59436ab3b7b3ce20cf8fa6358a7efb6f6fb073..26a06b0b2fc03230b739a2ec86ffa15d701d3960 100644 --- a/ecmascript/ecma_isa.yaml +++ b/ecmascript/ecma_isa.yaml @@ -577,3 +577,12 @@ groups: prefix: ecma format: [pref_op_id_32] properties: [string_id] + - sig: ecma.stownbyvaluewithnameset v1:in:top, v2:in:top + acc: in:top + prefix: ecma + format: [pref_op_v1_8_v2_8] + - sig: ecma.stownbynamewithnameset string_id, v:in:top + acc: in:top + prefix: ecma + format: [pref_op_id_32_v_8] + properties: [string_id] diff --git a/ecmascript/interpreter/interpreter-inl.h b/ecmascript/interpreter/interpreter-inl.h index 99efe62c898a8b9f80112c357b8041fd98da66a2..f70d136fca7c8a04709d7f98edd2fdebac469d66 100644 --- a/ecmascript/interpreter/interpreter-inl.h +++ b/ecmascript/interpreter/interpreter-inl.h @@ -2303,9 +2303,6 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool value = GET_ACC(); if (!res.IsHole()) { INTERPRETER_RETURN_IF_ABRUPT(res); - if (value.IsJSFunction()) { - JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetTaggedObject()), propKey); - } RESTORE_ACC(); DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); } @@ -2745,6 +2742,73 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool DISPATCH(BytecodeInstruction::Format::PREF_ID32); } + HANDLE_OPCODE(HANDLE_STOWNBYVALUEWITHNAMESET_PREF_V8_V8) { + uint32_t v0 = READ_INST_8_1(); + uint32_t v1 = READ_INST_8_2(); + LOG_INST() << "intrinsics::stownbyvaluewithnameset" + << " v" << v0 << " v" << v1; + JSTaggedValue receiver = GET_VREG_VALUE(v0); + if (receiver.IsHeapObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) { + SAVE_ACC(); + JSTaggedValue propKey = GET_VREG_VALUE(v1); + JSTaggedValue value = GET_ACC(); + // fast path + JSTaggedValue res = FastRuntimeStub::SetPropertyByValue(thread, receiver, propKey, value); + + // SetPropertyByValue maybe gc need update the value + RESTORE_ACC(); + propKey = GET_VREG_VALUE(v1); + value = GET_ACC(); + if (!res.IsHole()) { + INTERPRETER_RETURN_IF_ABRUPT(res); + JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetTaggedObject()), propKey); + RESTORE_ACC(); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); + } + } + + // slow path + SAVE_ACC(); + receiver = GET_VREG_VALUE(v0); // Maybe moved by GC + auto propKey = GET_VREG_VALUE(v1); // Maybe moved by GC + auto value = GET_ACC(); // Maybe moved by GC + JSTaggedValue res = SlowRuntimeStub::StOwnByValueWithNameSet(thread, receiver, propKey, value); + RESTORE_ACC(); + INTERPRETER_RETURN_IF_ABRUPT(res); + DISPATCH(BytecodeInstruction::Format::PREF_V8_V8); + } + HANDLE_OPCODE(HANDLE_STOWNBYNAMEWITHNAMESET_PREF_ID32_V8) { + uint32_t stringId = READ_INST_32_1(); + uint32_t v0 = READ_INST_8_5(); + LOG_INST() << "intrinsics::stownbynamewithnameset " + << "v" << v0 << " stringId:" << stringId; + + JSTaggedValue receiver = GET_VREG_VALUE(v0); + if (receiver.IsJSObject() && !receiver.IsClassConstructor() && !receiver.IsClassPrototype()) { + JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); + JSTaggedValue value = GET_ACC(); + // fast path + SAVE_ACC(); + JSTaggedValue res = FastRuntimeStub::SetPropertyByName(thread, receiver, propKey, value); + if (!res.IsHole()) { + INTERPRETER_RETURN_IF_ABRUPT(res); + JSFunction::SetFunctionNameNoPrefix(thread, JSFunction::Cast(value.GetTaggedObject()), propKey); + RESTORE_ACC(); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); + } + RESTORE_ACC(); + } + + SAVE_ACC(); + receiver = GET_VREG_VALUE(v0); // Maybe moved by GC + auto propKey = constpool->GetObjectFromCache(stringId); // Maybe moved by GC + auto value = GET_ACC(); // Maybe moved by GC + JSTaggedValue res = SlowRuntimeStub::StOwnByNameWithNameSet(thread, receiver, propKey, value); + RESTORE_ACC(); + INTERPRETER_RETURN_IF_ABRUPT(res); + DISPATCH(BytecodeInstruction::Format::PREF_ID32_V8); + } + HANDLE_OPCODE(HANDLE_LDGLOBALVAR_PREF_ID32) { uint32_t stringId = READ_INST_32_1(); JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); diff --git a/ecmascript/interpreter/interpreter.h b/ecmascript/interpreter/interpreter.h index 62964b5a7da72604bcc56228f5b9b2e7ada53de2..cb988f370138aae771da0c4d057671abfa2a8989 100644 --- a/ecmascript/interpreter/interpreter.h +++ b/ecmascript/interpreter/interpreter.h @@ -214,6 +214,8 @@ enum EcmaOpcode { STCONSTTOGLOBALRECORD_PREF_ID32, STLETTOGLOBALRECORD_PREF_ID32, STCLASSTOGLOBALRECORD_PREF_ID32, + STOWNBYVALUEWITHNAMESET_PREF_V8_V8, + STOWNBYNAMEWITHNAMESET_PREF_ID32_V8, MOV_DYN_V8_V8, MOV_DYN_V16_V16, LDA_STR_ID32, diff --git a/ecmascript/interpreter/slow_runtime_stub.cpp b/ecmascript/interpreter/slow_runtime_stub.cpp index 5874bcd6cb94543c838b29b4afb366a02a4967a6..2c08c94165340c862ecee1a520f9a4b10a8dc32f 100644 --- a/ecmascript/interpreter/slow_runtime_stub.cpp +++ b/ecmascript/interpreter/slow_runtime_stub.cpp @@ -740,6 +740,32 @@ JSTaggedValue SlowRuntimeStub::StOwnByName(JSThread *thread, JSTaggedValue obj, return JSTaggedValue::True(); } +JSTaggedValue SlowRuntimeStub::StOwnByNameWithNameSet(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, + JSTaggedValue value) +{ + INTERPRETER_TRACE(thread, StOwnByNameDyn); + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + JSHandle objHandle(thread, obj); + JSHandle propHandle(thread, prop); + JSHandle valueHandle(thread, value); + ASSERT(propHandle->IsStringOrSymbol()); + + JSHandle propKey = JSTaggedValue::ToPropertyKey(thread, propHandle); + + // property in class is non-enumerable + bool enumerable = !(objHandle->IsClassPrototype() || objHandle->IsClassConstructor()); + + PropertyDescriptor desc(thread, valueHandle, true, enumerable, true); + bool ret = JSTaggedValue::DefineOwnProperty(thread, objHandle, propHandle, desc); + if (!ret) { + return ThrowTypeError(thread, "SetOwnByNameWithNameSet failed"); + } + JSFunctionBase::SetFunctionName(thread, JSHandle::Cast(valueHandle), propKey, + JSHandle(thread, JSTaggedValue::Undefined())); + return JSTaggedValue::True(); +} + JSTaggedValue SlowRuntimeStub::StOwnByIndex(JSThread *thread, JSTaggedValue obj, uint32_t idx, JSTaggedValue value) { INTERPRETER_TRACE(thread, StOwnByIdDyn); @@ -763,6 +789,7 @@ JSTaggedValue SlowRuntimeStub::StOwnByIndex(JSThread *thread, JSTaggedValue obj, JSTaggedValue SlowRuntimeStub::StOwnByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, JSTaggedValue value) { [[maybe_unused]] EcmaHandleScope handleScope(thread); + INTERPRETER_TRACE(thread, StOwnByValueDyn); const GlobalEnvConstants *globalConst = thread->GlobalConstants(); JSHandle objHandle(thread, obj); @@ -783,6 +810,33 @@ JSTaggedValue SlowRuntimeStub::StOwnByValue(JSThread *thread, JSTaggedValue obj, if (!ret) { return ThrowTypeError(thread, "StOwnByValue failed"); } + return JSTaggedValue::True(); +} + +JSTaggedValue SlowRuntimeStub::StOwnByValueWithNameSet(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, + JSTaggedValue value) +{ + [[maybe_unused]] EcmaHandleScope handleScope(thread); + INTERPRETER_TRACE(thread, StOwnByValueDyn); + const GlobalEnvConstants *globalConst = thread->GlobalConstants(); + JSHandle objHandle(thread, obj); + JSHandle keyHandle(thread, key); + JSHandle valueHandle(thread, value); + + if (objHandle->IsClassConstructor() && + JSTaggedValue::SameValue(keyHandle, globalConst->GetHandledPrototypeString())) { + return ThrowTypeError(thread, "In a class, static property named 'prototype' throw a TypeError"); + } + + // property in class is non-enumerable + bool enumerable = !(objHandle->IsClassPrototype() || objHandle->IsClassConstructor()); + + PropertyDescriptor desc(thread, valueHandle, true, enumerable, true); + JSMutableHandle propKey(JSTaggedValue::ToPropertyKey(thread, keyHandle)); + bool ret = JSTaggedValue::DefineOwnProperty(thread, objHandle, propKey, desc); + if (!ret) { + return ThrowTypeError(thread, "StOwnByValueWithNameSet failed"); + } if (valueHandle->IsJSFunction()) { if (propKey->IsNumber()) { propKey.Update(base::NumberHelper::NumberToString(thread, propKey.GetTaggedValue()).GetTaggedValue()); diff --git a/ecmascript/interpreter/slow_runtime_stub.h b/ecmascript/interpreter/slow_runtime_stub.h index 5523c60564e922c08ed50a2d90c3bb170215671e..afa120f0ce5363cf0377931671767a785f508afd 100644 --- a/ecmascript/interpreter/slow_runtime_stub.h +++ b/ecmascript/interpreter/slow_runtime_stub.h @@ -79,8 +79,12 @@ public: static void ThrowDeleteSuperProperty(JSThread *thread); static JSTaggedValue StOwnByName(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, JSTaggedValue value); + static JSTaggedValue StOwnByNameWithNameSet(JSThread *thread, JSTaggedValue obj, JSTaggedValue prop, + JSTaggedValue value); static JSTaggedValue StOwnByIndex(JSThread *thread, JSTaggedValue obj, uint32_t idx, JSTaggedValue value); static JSTaggedValue StOwnByValue(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, JSTaggedValue value); + static JSTaggedValue StOwnByValueWithNameSet(JSThread *thread, JSTaggedValue obj, JSTaggedValue key, + JSTaggedValue value); static JSTaggedValue CreateEmptyArray(JSThread *thread, ObjectFactory *factory, JSHandle globalEnv); static JSTaggedValue CreateEmptyObject(JSThread *thread, ObjectFactory *factory, JSHandle globalEnv); static JSTaggedValue CreateObjectWithBuffer(JSThread *thread, ObjectFactory *factory, JSObject *literal); diff --git a/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl b/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl index bb5386e842a7b1828d9389d546d363f3dfcfdbdd..5aaacdc93266af639b912df0b1ad5162fc3a554f 100644 --- a/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl +++ b/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl @@ -144,6 +144,8 @@ &&DEBUG_HANDLE_STCONSTTOGLOBALRECORD_PREF_ID32, &&DEBUG_HANDLE_STLETTOGLOBALRECORD_PREF_ID32, &&DEBUG_HANDLE_STCLASSTOGLOBALRECORD_PREF_ID32, + &&DEBUG_HANDLE_STOWNBYVALUEWITHNAMESET_PREF_V8_V8, + &&DEBUG_HANDLE_STOWNBYNAMEWITHNAMESET_PREF_ID32_V8, &&DEBUG_HANDLE_MOV_DYN_V8_V8, &&DEBUG_HANDLE_MOV_DYN_V16_V16, &&DEBUG_HANDLE_LDA_STR_ID32, @@ -266,6 +268,4 @@ &&DEBUG_HANDLE_OVERFLOW, &&DEBUG_HANDLE_OVERFLOW, &&DEBUG_HANDLE_OVERFLOW, - &&DEBUG_HANDLE_OVERFLOW, - &&DEBUG_HANDLE_OVERFLOW, - &&DEBUG_HANDLE_OVERFLOW, + &&DEBUG_HANDLE_OVERFLOW, \ No newline at end of file diff --git a/ecmascript/interpreter/templates/debugger_instruction_handler.inl b/ecmascript/interpreter/templates/debugger_instruction_handler.inl index 60d3cac4a82b366bd14e74e1ef0b85a7bf6e0a19..e578e5cfebc0112b1cc23d32b2a883ac7b3c05a8 100644 --- a/ecmascript/interpreter/templates/debugger_instruction_handler.inl +++ b/ecmascript/interpreter/templates/debugger_instruction_handler.inl @@ -668,6 +668,16 @@ NOTIFY_DEBUGGER_EVENT(); REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STCLASSTOGLOBALRECORD_PREF_ID32); } + HANDLE_OPCODE(DEBUG_HANDLE_STOWNBYVALUEWITHNAMESET_PREF_V8_V8) + { + NOTIFY_DEBUGGER_EVENT(); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOWNBYVALUEWITHNAMESET_PREF_V8_V8); + } + HANDLE_OPCODE(DEBUG_HANDLE_STOWNBYNAMEWITHNAMESET_PREF_ID32_V8) + { + NOTIFY_DEBUGGER_EVENT(); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STOWNBYNAMEWITHNAMESET_PREF_ID32_V8); + } HANDLE_OPCODE(DEBUG_HANDLE_MOV_DYN_V8_V8) { NOTIFY_DEBUGGER_EVENT(); diff --git a/ecmascript/interpreter/templates/instruction_dispatch.inl b/ecmascript/interpreter/templates/instruction_dispatch.inl index a9599b0c7a085d7ba8a7a26e8808d2bf800d9b1a..2462b523597738826ddbf06720d5c4543b814e4c 100644 --- a/ecmascript/interpreter/templates/instruction_dispatch.inl +++ b/ecmascript/interpreter/templates/instruction_dispatch.inl @@ -144,6 +144,8 @@ &&HANDLE_STCONSTTOGLOBALRECORD_PREF_ID32, &&HANDLE_STLETTOGLOBALRECORD_PREF_ID32, &&HANDLE_STCLASSTOGLOBALRECORD_PREF_ID32, + &&HANDLE_STOWNBYVALUEWITHNAMESET_PREF_V8_V8, + &&HANDLE_STOWNBYNAMEWITHNAMESET_PREF_ID32_V8, &&HANDLE_MOV_DYN_V8_V8, &&HANDLE_MOV_DYN_V16_V16, &&HANDLE_LDA_STR_ID32, @@ -267,5 +269,4 @@ &&HANDLE_OVERFLOW, &&HANDLE_OVERFLOW, &&HANDLE_OVERFLOW, - &&HANDLE_OVERFLOW, - &&HANDLE_OVERFLOW, + diff --git a/ecmascript/object_factory.cpp b/ecmascript/object_factory.cpp index 7282588009227f3e99881e2fcce43a598c034e9d..c44e7fe41a3f8dea465014d5414905810041c38c 100644 --- a/ecmascript/object_factory.cpp +++ b/ecmascript/object_factory.cpp @@ -290,6 +290,7 @@ JSHandle ObjectFactory::NewJSObject(const JSHandle &jshclass NewObjectHook(); JSHandle obj(thread_, JSObject::Cast(NewDynObject(jshclass, JSHClass::DEFAULT_CAPACITY_OF_IN_OBJECTS))); JSHandle emptyArray = EmptyArray(); + Barriers::SetDynPrimitive(*obj, ECMAObject::HASH_OFFSET, JSTaggedValue(0).GetRawData()); obj->SetElements(thread_, emptyArray, SKIP_BARRIER); obj->SetProperties(thread_, emptyArray, SKIP_BARRIER); return obj;