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..c777e42923 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); + RESTORE_ACC(); } else { + // 2. find from global object + FastRuntimeStub::GetGlobalOwnProperty(globalObj, propKey, &found); + if (!found) { + auto result = SlowRuntimeStub::ThrowReferenceError(thread, propKey, " is not defined"); + INTERPRETER_RETURN_IF_ABRUPT(result); + } 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..7b41340d62 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" @@ -273,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); @@ -492,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) { @@ -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,59 @@ 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 +1401,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..25b48dfddd 100644 --- a/test/moduletest/BUILD.gn +++ b/test/moduletest/BUILD.gn @@ -21,6 +21,7 @@ group("ark_js_moduletest") { "fortest:fortest_test(${host_toolchain})", "generator:generator_test(${host_toolchain})", "getunmappedargs:getunmappedargs_test(${host_toolchain})", + "globalrecord:globalrecord_test(${host_toolchain})", "helloworld:helloworld_test(${host_toolchain})", "lexicalenv:lexicalenv_test(${host_toolchain})", diff --git a/test/moduletest/globalrecord/BUILD.gn b/test/moduletest/globalrecord/BUILD.gn new file mode 100755 index 0000000000..8b2201e7c3 --- /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..0081051128 --- /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);