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;