From 04e7b5b65cd8ce3846ec76b8663d36027e34a12a Mon Sep 17 00:00:00 2001 From: lifansheng Date: Fri, 10 Sep 2021 16:34:37 +0800 Subject: [PATCH 1/7] Add GlobalRcord Signed-off-by: lifansheng --- ecmascript/ecma_isa.yaml | 15 ++++ ecmascript/ecma_vm.cpp | 2 + ecmascript/global_env.h | 3 +- ecmascript/ic/ic_runtime.cpp | 11 ++- ecmascript/interpreter/interpreter-inl.h | 72 ++++++++++++++++-- ecmascript/interpreter/interpreter.h | 3 + ecmascript/interpreter/slow_runtime_stub.cpp | 76 ++++++++++++++++++- ecmascript/interpreter/slow_runtime_stub.h | 4 + .../debugger_instruction_dispatch.inl | 6 +- .../debugger_instruction_handler.inl | 15 ++++ .../templates/instruction_dispatch.inl | 6 +- ecmascript/property_attributes.h | 12 ++- test/moduletest/BUILD.gn | 1 + test/moduletest/globalrecord/BUILD.gn | 18 +++++ test/moduletest/globalrecord/expect_out.txt | 18 +++++ test/moduletest/globalrecord/globalrecord.js | 34 +++++++++ 16 files changed, 276 insertions(+), 20 deletions(-) create mode 100755 test/moduletest/globalrecord/BUILD.gn create mode 100755 test/moduletest/globalrecord/expect_out.txt create mode 100755 test/moduletest/globalrecord/globalrecord.js diff --git a/ecmascript/ecma_isa.yaml b/ecmascript/ecma_isa.yaml index 56ca07bf86..3a59436ab3 100644 --- a/ecmascript/ecma_isa.yaml +++ b/ecmascript/ecma_isa.yaml @@ -562,3 +562,18 @@ groups: acc: inout:top prefix: ecma format: [pref_op_none] + - sig: ecma.stconsttoglobalrecord string_id + acc: in:top + prefix: ecma + format: [pref_op_id_32] + properties: [string_id] + - sig: ecma.stlettoglobalrecord string_id + acc: in:top + prefix: ecma + format: [pref_op_id_32] + properties: [string_id] + - sig: ecma.stclasstoglobalrecord string_id + acc: in:top + prefix: ecma + format: [pref_op_id_32] + properties: [string_id] diff --git a/ecmascript/ecma_vm.cpp b/ecmascript/ecma_vm.cpp index 2fde7aa0d3..31bb8274e6 100644 --- a/ecmascript/ecma_vm.cpp +++ b/ecmascript/ecma_vm.cpp @@ -33,6 +33,7 @@ #include "ecmascript/js_invoker.h" #include "ecmascript/js_thread.h" #include "ecmascript/mem/heap.h" +#include "ecmascript/tagged_dictionary.h" #include "ecmascript/object_factory.h" #include "ecmascript/regexp/regexp_parser_cache.h" #include "ecmascript/runtime_call_id.h" @@ -152,6 +153,7 @@ bool EcmaVM::Initialize() globalEnv->SetEmptyArray(thread_, factory_->NewEmptyArray()); globalEnv->SetEmptyLayoutInfo(thread_, factory_->CreateLayoutInfo(0)); globalEnv->SetRegisterSymbols(thread_, JSTaggedValue(SymbolTable::Create(thread_))); + globalEnv->SetGlobalRecord(thread_, JSTaggedValue(NameDictionary::Create(thread_))); JSTaggedValue emptyStr = thread_->GlobalConstants()->GetEmptyString(); stringTable_->InternEmptyString(EcmaString::Cast(emptyStr.GetTaggedObject())); globalEnv->SetEmptyTaggedQueue(thread_, factory_->NewTaggedQueue(0)); diff --git a/ecmascript/global_env.h b/ecmascript/global_env.h index 3d9c225b67..a2d4ce9fc7 100644 --- a/ecmascript/global_env.h +++ b/ecmascript/global_env.h @@ -137,7 +137,8 @@ class JSThread; V(JSTaggedValue, JSIntlBoundFunctionClass, JS_INTL_BOUND_FUNCTION_CLASS) \ V(JSTaggedValue, NumberFormatLocales, NUMBER_FORMAT_LOCALES_INDEX) \ V(JSTaggedValue, DateTimeFormatLocales, DATE_TIMEFORMAT_LOCALES_INDEX) \ - V(JSTaggedValue, JSNativeObjectClass, JS_NATIVE_OBJECT_CLASS) + V(JSTaggedValue, JSNativeObjectClass, JS_NATIVE_OBJECT_CLASS) \ + V(JSTaggedValue, GlobalRecord, GLOBAL_RECORD) class GlobalEnv : public TaggedObject { public: diff --git a/ecmascript/ic/ic_runtime.cpp b/ecmascript/ic/ic_runtime.cpp index 2c3b96859a..55227c0d20 100644 --- a/ecmascript/ic/ic_runtime.cpp +++ b/ecmascript/ic/ic_runtime.cpp @@ -25,7 +25,7 @@ #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/js_typed_array.h" #include "ecmascript/object_factory-inl.h" - +#include "ecmascript/tagged_dictionary.h" namespace panda::ecmascript { #define TRACE_IC 0 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) @@ -134,12 +134,17 @@ void ICRuntime::TraceIC([[maybe_unused]] JSHandle receiver, JSTaggedValue LoadICRuntime::LoadMiss(JSHandle receiver, JSHandle key) { if (receiver->IsTypedArray() || !receiver->IsJSObject()) { - return JSTaggedValue::GetProperty(GetThread(), receiver, key).GetValue().GetTaggedValue(); + return JSTaggedValue::GetProperty(thread_, receiver, key).GetValue().GetTaggedValue(); } ObjectOperator op(GetThread(), receiver, key); auto result = JSHandle(thread_, JSObject::GetProperty(GetThread(), &op)); if (!op.IsFound() && GetICKind() == ICKind::NamedGlobalLoadIC) { - return SlowRuntimeStub::ThrowReferenceError(GetThread(), key.GetTaggedValue(), " is not defined"); + bool found = false; + JSTaggedValue res = SlowRuntimeStub::LdGlobalRecord(thread_, key.GetTaggedValue(), &found); + if (!found) { + return SlowRuntimeStub::ThrowReferenceError(GetThread(), key.GetTaggedValue(), " is not definded"); + } + return res; } RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(GetThread()); // ic-switch diff --git a/ecmascript/interpreter/interpreter-inl.h b/ecmascript/interpreter/interpreter-inl.h index e0200af998..b1319bc682 100644 --- a/ecmascript/interpreter/interpreter-inl.h +++ b/ecmascript/interpreter/interpreter-inl.h @@ -2631,14 +2631,20 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool #endif bool found = false; - JSTaggedValue result = FastRuntimeStub::GetGlobalOwnProperty(globalObj, prop, &found); + // order: 1. global record 2. global object + JSTaggedValue result = SlowRuntimeStub::LdGlobalRecord(thread, prop, &found); if (found) { SET_ACC(result); } else { - // slow path + JSTaggedValue globalResult = FastRuntimeStub::GetGlobalOwnProperty(globalObj, prop, &found); + if (found) { + SET_ACC(globalResult); + } else { + // slow path JSTaggedValue res = SlowRuntimeStub::TryLdGlobalByName(thread, globalObj, prop); INTERPRETER_RETURN_IF_ABRUPT(res); SET_ACC(res); + } } DISPATCH(BytecodeInstruction::Format::PREF_ID32); @@ -2666,12 +2672,21 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool #endif bool found = false; - FastRuntimeStub::GetGlobalOwnProperty(globalObj, propKey, &found); - if (!found) { - // slow path will throw exception - JSTaggedValue res = SlowRuntimeStub::TryStGlobalByName(thread, propKey); + SlowRuntimeStub::LdGlobalRecord(thread, propKey, &found); + // 1. find from global record + if (found) { + JSTaggedValue value = GET_ACC(); + SAVE_ACC(); + JSTaggedValue res = SlowRuntimeStub::TryUpdateGlobalRecord(thread, propKey, value); INTERPRETER_RETURN_IF_ABRUPT(res); - } else { + RESTORE_ACC(); + } + else { + // 2. find from global object + FastRuntimeStub::GetGlobalOwnProperty(globalObj, propKey, &found); + if (!found) { + SlowRuntimeStub::ThrowReferenceError(thread, propKey, " is not defined"); + } JSTaggedValue value = GET_ACC(); SAVE_ACC(); JSTaggedValue res = SlowRuntimeStub::StGlobalVar(thread, propKey, value); @@ -2680,6 +2695,49 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool } DISPATCH(BytecodeInstruction::Format::PREF_ID32); } + + HANDLE_OPCODE(HANDLE_STCONSTTOGLOBALRECORD_PREF_ID32) { + uint32_t stringId = READ_INST_32_1(); + JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); + LOG_INST() << "intrinsics::stconsttoglobalrecord" + << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())); + + JSTaggedValue value = GET_ACC(); + SAVE_ACC(); + JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value, true); + INTERPRETER_RETURN_IF_ABRUPT(res); + RESTORE_ACC(); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); + } + + HANDLE_OPCODE(HANDLE_STLETTOGLOBALRECORD_PREF_ID32) { + uint32_t stringId = READ_INST_32_1(); + JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); + LOG_INST() << "intrinsics::stlettoglobalrecord" + << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())); + + JSTaggedValue value = GET_ACC(); + SAVE_ACC(); + JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value, false); + INTERPRETER_RETURN_IF_ABRUPT(res); + RESTORE_ACC(); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); + } + + HANDLE_OPCODE(HANDLE_STCLASSTOGLOBALRECORD_PREF_ID32) { + uint32_t stringId = READ_INST_32_1(); + JSTaggedValue propKey = constpool->GetObjectFromCache(stringId); + LOG_INST() << "intrinsics::stclasstoglobalrecord" + << " stringId:" << stringId << ", " << ConvertToString(EcmaString::Cast(propKey.GetTaggedObject())); + + JSTaggedValue value = GET_ACC(); + SAVE_ACC(); + JSTaggedValue res = SlowRuntimeStub::StGlobalRecord(thread, propKey, value, false); + INTERPRETER_RETURN_IF_ABRUPT(res); + RESTORE_ACC(); + DISPATCH(BytecodeInstruction::Format::PREF_ID32); + } + 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 ab6ecb8f6d..62964b5a7d 100644 --- a/ecmascript/interpreter/interpreter.h +++ b/ecmascript/interpreter/interpreter.h @@ -211,6 +211,9 @@ enum EcmaOpcode { CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8, ISTRUE_PREF, ISFALSE_PREF, + STCONSTTOGLOBALRECORD_PREF_ID32, + STLETTOGLOBALRECORD_PREF_ID32, + STCLASSTOGLOBALRECORD_PREF_ID32, 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 405dd0c092..97c4d02430 100644 --- a/ecmascript/interpreter/slow_runtime_stub.cpp +++ b/ecmascript/interpreter/slow_runtime_stub.cpp @@ -37,6 +37,7 @@ #include "ecmascript/js_proxy.h" #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/js_thread.h" +#include "ecmascript/tagged_dictionary.h" #include "ecmascript/runtime_call_id.h" #include "ecmascript/template_string.h" #include "ecmascript/vmstat/runtime_stat.h" @@ -1283,10 +1284,18 @@ JSTaggedValue SlowRuntimeStub::TryLdGlobalByName(JSThread *thread, JSTaggedValue JSHandle obj(thread, global.GetTaggedObject()->GetClass()->GetPrototype()); JSHandle propHandle(thread, prop); OperationResult res = JSTaggedValue::GetProperty(thread, obj, propHandle); - if (!res.GetPropertyMetaData().IsFound()) { + if (res.GetPropertyMetaData().IsFound()) { + return res.GetValue().GetTaggedValue(); + } + + EcmaVM *vm = thread->GetEcmaVM(); + JSHandle env = vm->GetGlobalEnv(); + NameDictionary *dict = NameDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject()); + int entry = dict->FindEntry(propHandle.GetTaggedValue()); + if (entry == -1) { return ThrowReferenceError(thread, prop, " is not defined"); } - return res.GetValue().GetTaggedValue(); + return dict->GetValue(entry); } JSTaggedValue SlowRuntimeStub::TryStGlobalByName(JSThread *thread, JSTaggedValue prop) @@ -1319,6 +1328,62 @@ JSTaggedValue SlowRuntimeStub::StGlobalVar(JSThread *thread, JSTaggedValue prop, return JSTaggedValue::True(); } +JSTaggedValue SlowRuntimeStub::TryUpdateGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value) +{ + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + EcmaVM *vm = thread->GetEcmaVM(); + JSHandle env = vm->GetGlobalEnv(); + NameDictionary *dict = NameDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject()); + int entry = dict->FindEntry(prop); + + if (dict->GetAttributes(entry).IsConstProps()) { + return ThrowSyntaxError(thread, " const can not be modified"); + } + dict->UpdateValue(thread, entry, value); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return JSTaggedValue::True(); +} + +JSTaggedValue SlowRuntimeStub::LdGlobalRecord(JSThread *thread, JSTaggedValue key, bool *found) { + + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + EcmaVM *vm = thread->GetEcmaVM(); + JSHandle env = vm->GetGlobalEnv(); + NameDictionary *dict = NameDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject()); + + int entry = dict->FindEntry(key); + if (entry != -1) { + *found = true; + return dict->GetValue(entry); + } + return JSTaggedValue::Undefined(); + +} + +JSTaggedValue SlowRuntimeStub::StGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value, bool isConst) +{ + [[maybe_unused]] EcmaHandleScope handleScope(thread); + + EcmaVM *vm = thread->GetEcmaVM(); + JSHandle env = vm->GetGlobalEnv(); + NameDictionary *dict = NameDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject()); + + int entry = dict->FindEntry(prop); + if (entry != -1) { + return ThrowReferenceError(thread, prop, " is not defined"); + } + PropertyAttributes attributes; + attributes.SetIsConstProps(isConst); + JSHandle propHandle(thread, prop); + JSHandle valueHandle(thread, value); + JSHandle dictHandle(thread, dict); + dict->PutIfAbsent(thread, dictHandle, propHandle, valueHandle, attributes); + RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); + return JSTaggedValue::True(); +} + JSTaggedValue SlowRuntimeStub::ThrowReferenceError(JSThread *thread, JSTaggedValue prop, const char *desc) { [[maybe_unused]] EcmaHandleScope handleScope(thread); @@ -1339,6 +1404,13 @@ JSTaggedValue SlowRuntimeStub::ThrowTypeError(JSThread *thread, const char *mess THROW_TYPE_ERROR_AND_RETURN(thread, message, JSTaggedValue::Exception()); } +JSTaggedValue SlowRuntimeStub::ThrowSyntaxError(JSThread *thread, const char *message) +{ + [[maybe_unused]] EcmaHandleScope handleScope(thread); + ASSERT_NO_ABRUPT_COMPLETION(thread); + THROW_SYNTAX_ERROR_AND_RETURN(thread, message, JSTaggedValue::Exception()); +} + JSTaggedValue SlowRuntimeStub::StArraySpread(JSThread *thread, JSTaggedValue dst, JSTaggedValue index, JSTaggedValue src) { diff --git a/ecmascript/interpreter/slow_runtime_stub.h b/ecmascript/interpreter/slow_runtime_stub.h index 32b5704db3..5523c60564 100644 --- a/ecmascript/interpreter/slow_runtime_stub.h +++ b/ecmascript/interpreter/slow_runtime_stub.h @@ -121,6 +121,9 @@ public: static JSTaggedValue TryStGlobalByName(JSThread *thread, JSTaggedValue prop); static JSTaggedValue LdGlobalVar(JSThread *thread, JSTaggedValue global, JSTaggedValue prop); static JSTaggedValue StGlobalVar(JSThread *thread, JSTaggedValue prop, JSTaggedValue value); + static JSTaggedValue StGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value, bool isConst); + static JSTaggedValue LdGlobalRecord(JSThread *thread, JSTaggedValue key, bool *found); + static JSTaggedValue TryUpdateGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value); static JSTaggedValue StArraySpread(JSThread *thread, JSTaggedValue dst, JSTaggedValue index, JSTaggedValue src); static JSTaggedValue DefineGeneratorFunc(JSThread *thread, JSFunction *func); @@ -145,6 +148,7 @@ public: private: static JSTaggedValue ThrowTypeError(JSThread *thread, const char *message); + static JSTaggedValue ThrowSyntaxError(JSThread *thread, const char *message); static JSTaggedValue GetCallSpreadArgs(JSThread *thread, JSTaggedValue array); }; } // namespace panda::ecmascript diff --git a/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl b/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl index c9111ef78f..bb5386e842 100644 --- a/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl +++ b/ecmascript/interpreter/templates/debugger_instruction_dispatch.inl @@ -141,6 +141,9 @@ &&DEBUG_HANDLE_CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8, &&DEBUG_HANDLE_ISTRUE_PREF, &&DEBUG_HANDLE_ISFALSE_PREF, + &&DEBUG_HANDLE_STCONSTTOGLOBALRECORD_PREF_ID32, + &&DEBUG_HANDLE_STLETTOGLOBALRECORD_PREF_ID32, + &&DEBUG_HANDLE_STCLASSTOGLOBALRECORD_PREF_ID32, &&DEBUG_HANDLE_MOV_DYN_V8_V8, &&DEBUG_HANDLE_MOV_DYN_V16_V16, &&DEBUG_HANDLE_LDA_STR_ID32, @@ -266,6 +269,3 @@ &&DEBUG_HANDLE_OVERFLOW, &&DEBUG_HANDLE_OVERFLOW, &&DEBUG_HANDLE_OVERFLOW, - &&DEBUG_HANDLE_OVERFLOW, - &&DEBUG_HANDLE_OVERFLOW, - &&DEBUG_HANDLE_OVERFLOW, diff --git a/ecmascript/interpreter/templates/debugger_instruction_handler.inl b/ecmascript/interpreter/templates/debugger_instruction_handler.inl index 1c03309f21..60d3cac4a8 100644 --- a/ecmascript/interpreter/templates/debugger_instruction_handler.inl +++ b/ecmascript/interpreter/templates/debugger_instruction_handler.inl @@ -653,6 +653,21 @@ NOTIFY_DEBUGGER_EVENT(); REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::ISFALSE_PREF); } + HANDLE_OPCODE(DEBUG_HANDLE_STCONSTTOGLOBALRECORD_PREF_ID32) + { + NOTIFY_DEBUGGER_EVENT(); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STCONSTTOGLOBALRECORD_PREF_ID32); + } + HANDLE_OPCODE(DEBUG_HANDLE_STLETTOGLOBALRECORD_PREF_ID32) + { + NOTIFY_DEBUGGER_EVENT(); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STLETTOGLOBALRECORD_PREF_ID32); + } + HANDLE_OPCODE(DEBUG_HANDLE_STCLASSTOGLOBALRECORD_PREF_ID32) + { + NOTIFY_DEBUGGER_EVENT(); + REAL_GOTO_DISPATCH_OPCODE(EcmaOpcode::STCLASSTOGLOBALRECORD_PREF_ID32); + } 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 dfdfb40bae..a9599b0c7a 100644 --- a/ecmascript/interpreter/templates/instruction_dispatch.inl +++ b/ecmascript/interpreter/templates/instruction_dispatch.inl @@ -141,6 +141,9 @@ &&HANDLE_CREATEREGEXPWITHLITERAL_PREF_ID32_IMM8, &&HANDLE_ISTRUE_PREF, &&HANDLE_ISFALSE_PREF, + &&HANDLE_STCONSTTOGLOBALRECORD_PREF_ID32, + &&HANDLE_STLETTOGLOBALRECORD_PREF_ID32, + &&HANDLE_STCLASSTOGLOBALRECORD_PREF_ID32, &&HANDLE_MOV_DYN_V8_V8, &&HANDLE_MOV_DYN_V16_V16, &&HANDLE_LDA_STR_ID32, @@ -266,6 +269,3 @@ &&HANDLE_OVERFLOW, &&HANDLE_OVERFLOW, &&HANDLE_OVERFLOW, - &&HANDLE_OVERFLOW, - &&HANDLE_OVERFLOW, - &&HANDLE_OVERFLOW, diff --git a/ecmascript/property_attributes.h b/ecmascript/property_attributes.h index b7d07eb1b2..ef272fb6cb 100644 --- a/ecmascript/property_attributes.h +++ b/ecmascript/property_attributes.h @@ -76,7 +76,7 @@ public: static constexpr uint32_t NORMAL_ATTR_BITS = 18; using NormalAttrField = BitField; using SortedIndexField = OffsetField::NextField; // 28 - + using IsConstPropsField = SortedIndexField::NextFlag; // 29 // dictionary mode, include global using PropertyBoxTypeField = PropertyMetaDataField::NextField; // 2: 2 bits, 5-6 using DictionaryOrderField = PropertyBoxTypeField::NextField; // 26 @@ -217,6 +217,16 @@ public: return IsInlinedPropsField::Get(value_); } + inline void SetIsConstProps(bool flag) + { + IsConstPropsField::Set(flag, &value_); + } + + inline bool IsConstProps() const + { + return IsConstPropsField::Get(value_); + } + inline void SetRepresentation(Representation representation) { RepresentationField::Set(representation, &value_); diff --git a/test/moduletest/BUILD.gn b/test/moduletest/BUILD.gn index d93fd0a18e..d49939ec85 100644 --- a/test/moduletest/BUILD.gn +++ b/test/moduletest/BUILD.gn @@ -22,6 +22,7 @@ group("ark_js_moduletest") { "generator:generator_test(${host_toolchain})", "getunmappedargs:getunmappedargs_test(${host_toolchain})", "helloworld:helloworld_test(${host_toolchain})", + "globalrecord:globalrecord_test(${host_toolchain})", "lexicalenv:lexicalenv_test(${host_toolchain})", # "module:module_test(${host_toolchain})", diff --git a/test/moduletest/globalrecord/BUILD.gn b/test/moduletest/globalrecord/BUILD.gn new file mode 100755 index 0000000000..c43d7f3e2e --- /dev/null +++ b/test/moduletest/globalrecord/BUILD.gn @@ -0,0 +1,18 @@ +# 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. + +import("//ark/js_runtime/test/test_helper.gni") + +host_moduletest_action("globalrecord") { + deps = [] +} diff --git a/test/moduletest/globalrecord/expect_out.txt b/test/moduletest/globalrecord/expect_out.txt new file mode 100755 index 0000000000..01dbe2fefe --- /dev/null +++ b/test/moduletest/globalrecord/expect_out.txt @@ -0,0 +1,18 @@ +# 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. + +Not support function toString() due to Runtime can not obtain Source Code yet. +extends String +a +aa +b diff --git a/test/moduletest/globalrecord/globalrecord.js b/test/moduletest/globalrecord/globalrecord.js new file mode 100755 index 0000000000..b43c94dd3a --- /dev/null +++ b/test/moduletest/globalrecord/globalrecord.js @@ -0,0 +1,34 @@ +/* + * 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. + */ + +"use strict" + +class View{} +let a = "a"; +const b = "b"; + +print(View); + +class myString extends String{} +var view = new myString("extends String"); +print(View); + +print(a); +a = "a" +print(a); + +print(b); +b = "bb" +print(b); -- Gitee From 3ddc13c94b4babeb02f8029a3882270e22874a4b Mon Sep 17 00:00:00 2001 From: lifansheng Date: Fri, 10 Sep 2021 16:47:04 +0800 Subject: [PATCH 2/7] modify globalrecordjs Signed-off-by: lifansheng --- test/moduletest/globalrecord/globalrecord.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/moduletest/globalrecord/globalrecord.js b/test/moduletest/globalrecord/globalrecord.js index b43c94dd3a..0081051128 100755 --- a/test/moduletest/globalrecord/globalrecord.js +++ b/test/moduletest/globalrecord/globalrecord.js @@ -23,7 +23,7 @@ print(View); class myString extends String{} var view = new myString("extends String"); -print(View); +print(view); print(a); a = "a" -- Gitee From d8e4e7774f412cd3ae8e406123ef942e65656070 Mon Sep 17 00:00:00 2001 From: lifansheng Date: Fri, 10 Sep 2021 17:29:24 +0800 Subject: [PATCH 3/7] modify gn Signed-off-by: lifansheng --- test/moduletest/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/moduletest/BUILD.gn b/test/moduletest/BUILD.gn index d49939ec85..25b48dfddd 100644 --- a/test/moduletest/BUILD.gn +++ b/test/moduletest/BUILD.gn @@ -21,8 +21,8 @@ group("ark_js_moduletest") { "fortest:fortest_test(${host_toolchain})", "generator:generator_test(${host_toolchain})", "getunmappedargs:getunmappedargs_test(${host_toolchain})", - "helloworld:helloworld_test(${host_toolchain})", "globalrecord:globalrecord_test(${host_toolchain})", + "helloworld:helloworld_test(${host_toolchain})", "lexicalenv:lexicalenv_test(${host_toolchain})", # "module:module_test(${host_toolchain})", -- Gitee From 05714d074f08ff4c2ab8bc45709c129433101ce3 Mon Sep 17 00:00:00 2001 From: lifansheng Date: Fri, 10 Sep 2021 17:33:01 +0800 Subject: [PATCH 4/7] Add GlobalRecort and modify gn Signed-off-by: lifansheng --- ecmascript/interpreter/interpreter-inl.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ecmascript/interpreter/interpreter-inl.h b/ecmascript/interpreter/interpreter-inl.h index b1319bc682..155bb11d83 100644 --- a/ecmascript/interpreter/interpreter-inl.h +++ b/ecmascript/interpreter/interpreter-inl.h @@ -2685,7 +2685,8 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool // 2. find from global object FastRuntimeStub::GetGlobalOwnProperty(globalObj, propKey, &found); if (!found) { - SlowRuntimeStub::ThrowReferenceError(thread, propKey, " is not defined"); + auto result = SlowRuntimeStub::ThrowReferenceError(thread, propKey, " is not defined"); + INTERPRETER_RETURN_IF_ABRUPT(result); } JSTaggedValue value = GET_ACC(); SAVE_ACC(); -- Gitee From 07432439471d0ff72b0b7f28e2d6437be4d4e850 Mon Sep 17 00:00:00 2001 From: lifansheng Date: Sat, 11 Sep 2021 09:54:43 +0800 Subject: [PATCH 5/7] modify codecheck Signed-off-by: lifansheng --- ecmascript/interpreter/interpreter-inl.h | 3 +-- ecmascript/interpreter/slow_runtime_stub.cpp | 13 +++++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/ecmascript/interpreter/interpreter-inl.h b/ecmascript/interpreter/interpreter-inl.h index 155bb11d83..c777e42923 100644 --- a/ecmascript/interpreter/interpreter-inl.h +++ b/ecmascript/interpreter/interpreter-inl.h @@ -2680,8 +2680,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool JSTaggedValue res = SlowRuntimeStub::TryUpdateGlobalRecord(thread, propKey, value); INTERPRETER_RETURN_IF_ABRUPT(res); RESTORE_ACC(); - } - else { + } else { // 2. find from global object FastRuntimeStub::GetGlobalOwnProperty(globalObj, propKey, &found); if (!found) { diff --git a/ecmascript/interpreter/slow_runtime_stub.cpp b/ecmascript/interpreter/slow_runtime_stub.cpp index 97c4d02430..507722f3ee 100644 --- a/ecmascript/interpreter/slow_runtime_stub.cpp +++ b/ecmascript/interpreter/slow_runtime_stub.cpp @@ -274,8 +274,8 @@ JSTaggedValue SlowRuntimeStub::Div2Dyn(JSThread *thread, JSTaggedValue left, JST if (dLeft == 0 || std::isnan(dLeft)) { return JSTaggedValue(base::NAN_VALUE); } - bool positive = ((bit_cast(dRight) & base::DOUBLE_SIGN_MASK) == - (bit_cast(dLeft) & base::DOUBLE_SIGN_MASK)); + bool positive = (((bit_cast(dRight)) & base::DOUBLE_SIGN_MASK) == + ((bit_cast(dLeft)) & base::DOUBLE_SIGN_MASK)); return JSTaggedValue(positive ? base::POSITIVE_INFINITY : -base::POSITIVE_INFINITY); } return JSTaggedValue(dLeft / dRight); @@ -493,7 +493,7 @@ JSTaggedValue SlowRuntimeStub::ExpDyn(JSThread *thread, JSTaggedValue base, JSTa return JSTaggedValue(base::NAN_VALUE); } - if ((doubleBase == 0 && (bit_cast(doubleBase) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK) && + if (((doubleBase == 0) && (bit_cast(doubleBase) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK) && std::isfinite(doubleExponent) && base::NumberHelper::TruncateDouble(doubleExponent) == doubleExponent && base::NumberHelper::TruncateDouble(doubleExponent / 2) + base::HALF == (doubleExponent / 2)) { // 2: half if (doubleExponent > 0) { @@ -1336,7 +1336,6 @@ JSTaggedValue SlowRuntimeStub::TryUpdateGlobalRecord(JSThread *thread, JSTaggedV JSHandle env = vm->GetGlobalEnv(); NameDictionary *dict = NameDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject()); int entry = dict->FindEntry(prop); - if (dict->GetAttributes(entry).IsConstProps()) { return ThrowSyntaxError(thread, " const can not be modified"); } @@ -1345,21 +1344,19 @@ JSTaggedValue SlowRuntimeStub::TryUpdateGlobalRecord(JSThread *thread, JSTaggedV return JSTaggedValue::True(); } -JSTaggedValue SlowRuntimeStub::LdGlobalRecord(JSThread *thread, JSTaggedValue key, bool *found) { - +JSTaggedValue SlowRuntimeStub::LdGlobalRecord(JSThread *thread, JSTaggedValue key, bool *found) +{ [[maybe_unused]] EcmaHandleScope handleScope(thread); EcmaVM *vm = thread->GetEcmaVM(); JSHandle env = vm->GetGlobalEnv(); NameDictionary *dict = NameDictionary::Cast(env->GetGlobalRecord()->GetTaggedObject()); - int entry = dict->FindEntry(key); if (entry != -1) { *found = true; return dict->GetValue(entry); } return JSTaggedValue::Undefined(); - } JSTaggedValue SlowRuntimeStub::StGlobalRecord(JSThread *thread, JSTaggedValue prop, JSTaggedValue value, bool isConst) -- Gitee From fe913b8f2b77322e18cf49121eccc0c727fda4a9 Mon Sep 17 00:00:00 2001 From: lifansheng Date: Sat, 11 Sep 2021 10:14:20 +0800 Subject: [PATCH 6/7] modify gn Signed-off-by: lifansheng --- test/moduletest/globalrecord/BUILD.gn | 34 +++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/test/moduletest/globalrecord/BUILD.gn b/test/moduletest/globalrecord/BUILD.gn index c43d7f3e2e..8b2201e7c3 100755 --- a/test/moduletest/globalrecord/BUILD.gn +++ b/test/moduletest/globalrecord/BUILD.gn @@ -1,18 +1,18 @@ -# 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 +# 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. - -import("//ark/js_runtime/test/test_helper.gni") - -host_moduletest_action("globalrecord") { - deps = [] -} + +import("//ark/js_runtime/test/test_helper.gni") + +host_moduletest_action("globalrecord") { + deps = [] +} -- Gitee From 120daa2a1f6bfd52b4d7a63e0b4eff38c42a3fb3 Mon Sep 17 00:00:00 2001 From: lifansheng Date: Sat, 11 Sep 2021 10:47:56 +0800 Subject: [PATCH 7/7] modify codecheck Signed-off-by: lifansheng --- ecmascript/interpreter/slow_runtime_stub.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ecmascript/interpreter/slow_runtime_stub.cpp b/ecmascript/interpreter/slow_runtime_stub.cpp index 507722f3ee..7b41340d62 100644 --- a/ecmascript/interpreter/slow_runtime_stub.cpp +++ b/ecmascript/interpreter/slow_runtime_stub.cpp @@ -493,7 +493,7 @@ JSTaggedValue SlowRuntimeStub::ExpDyn(JSThread *thread, JSTaggedValue base, JSTa return JSTaggedValue(base::NAN_VALUE); } - if (((doubleBase == 0) && (bit_cast(doubleBase) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK) && + if (((doubleBase == 0) && ((bit_cast(doubleBase)) & base::DOUBLE_SIGN_MASK) == base::DOUBLE_SIGN_MASK) && std::isfinite(doubleExponent) && base::NumberHelper::TruncateDouble(doubleExponent) == doubleExponent && base::NumberHelper::TruncateDouble(doubleExponent / 2) + base::HALF == (doubleExponent / 2)) { // 2: half if (doubleExponent > 0) { -- Gitee