diff --git a/ecmascript/compiler/bytecodes.cpp b/ecmascript/compiler/bytecodes.cpp index c5a45fabc845a16529938d31dbd4b5a6b28ed52b..6891b3e9a517d1789966b0aea4d8e079ffb00a4a 100644 --- a/ecmascript/compiler/bytecodes.cpp +++ b/ecmascript/compiler/bytecodes.cpp @@ -120,6 +120,12 @@ void BytecodeMetaData::InitReadEnvFlag(EcmaOpcode &opcode, uint32_t &flags) case EcmaOpcode::CALLRUNTIME_CREATEPRIVATEPROPERTY_PREF_IMM16_ID16: case EcmaOpcode::CALLRUNTIME_DEFINEPRIVATEPROPERTY_PREF_IMM8_IMM16_IMM16_V8: case EcmaOpcode::CALLRUNTIME_LDSENDABLECLASS_PREF_IMM16: + case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM8_ID16: + case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM16_ID16: + case EcmaOpcode::CREATEEMPTYARRAY_IMM16: + case EcmaOpcode::CREATEEMPTYARRAY_IMM8: + case EcmaOpcode::LDGLOBALVAR_IMM16_ID16: + case EcmaOpcode::STGLOBALVAR_IMM16_ID16: flags |= BytecodeFlags::READ_ENV; break; default: @@ -1458,12 +1464,23 @@ void BytecodeInfo::InitBytecodeInfo(BytecodeCircuitBuilder *builder, } case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM8_ID16: { uint16_t imm = READ_INST_16_1(); + uint16_t slotId = READ_INST_8_0(); info.inputs.emplace_back(ConstDataId(ConstDataIDType::ArrayLiteralIDType, imm)); + info.inputs.emplace_back(VirtualRegister(builder->GetEnvVregIdx())); + info.inputs.emplace_back(ICSlotId(slotId)); break; } case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM16_ID16: { uint16_t imm = READ_INST_16_2(); + uint16_t slotId = READ_INST_16_0(); info.inputs.emplace_back(ConstDataId(ConstDataIDType::ArrayLiteralIDType, imm)); + info.inputs.emplace_back(VirtualRegister(builder->GetEnvVregIdx())); + info.inputs.emplace_back(ICSlotId(slotId)); + break; + } + case EcmaOpcode::CREATEEMPTYARRAY_IMM8: + case EcmaOpcode::CREATEEMPTYARRAY_IMM16: { + info.inputs.emplace_back(VirtualRegister(builder->GetEnvVregIdx())); break; } case EcmaOpcode::GETMODULENAMESPACE_IMM8: { @@ -1871,6 +1888,7 @@ void BytecodeInfo::InitBytecodeInfo(BytecodeCircuitBuilder *builder, uint16_t stringId = READ_INST_16_2(); info.inputs.emplace_back(ICSlotId(slotId)); info.inputs.emplace_back(ConstDataId(ConstDataIDType::StringIDType, stringId)); + info.inputs.emplace_back(VirtualRegister(builder->GetEnvVregIdx())); break; } case EcmaOpcode::LDOBJBYNAME_IMM8_ID16: { @@ -1934,6 +1952,7 @@ void BytecodeInfo::InitBytecodeInfo(BytecodeCircuitBuilder *builder, uint32_t stringId = READ_INST_16_2(); info.inputs.emplace_back(ICSlotId(slotId)); info.inputs.emplace_back(ConstDataId(ConstDataIDType::StringIDType, stringId)); + info.inputs.emplace_back(VirtualRegister(builder->GetEnvVregIdx())); break; } case EcmaOpcode::CREATEGENERATOROBJ_V8: { @@ -2168,8 +2187,6 @@ void BytecodeInfo::InitBytecodeInfo(BytecodeCircuitBuilder *builder, case EcmaOpcode::THROW_PREF_NONE: case EcmaOpcode::GETPROPITERATOR: case EcmaOpcode::GETRESUMEMODE: - case EcmaOpcode::CREATEEMPTYARRAY_IMM8: - case EcmaOpcode::CREATEEMPTYARRAY_IMM16: case EcmaOpcode::CREATEEMPTYOBJECT: case EcmaOpcode::DEBUGGER: case EcmaOpcode::ISTRUE: diff --git a/ecmascript/compiler/call_signature.cpp b/ecmascript/compiler/call_signature.cpp index 9bcb1b73338261121425159aade97fb85b70997a..ec62f6f85ee9f579533469775758eeccab13951b 100644 --- a/ecmascript/compiler/call_signature.cpp +++ b/ecmascript/compiler/call_signature.cpp @@ -580,15 +580,17 @@ DEF_CALL_SIGNATURE(TryStGlobalByName) DEF_CALL_SIGNATURE(LdGlobalVar) { + constexpr size_t PARAM_COUNT = 5; // 4 : 4 input parameters - CallSignature signature("LdGlobalVar", 0, 4, ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY()); + CallSignature signature("LdGlobalVar", 0, PARAM_COUNT, ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY()); *callSign = signature; // 4 : 4 input parameters - std::array params = { - VariableType::NATIVE_POINTER(), // glue - VariableType::INT64(), // key - VariableType::JS_ANY(), // jsFunc - VariableType::INT32(), // slot id + std::array params = { + VariableType::NATIVE_POINTER(), // glue + VariableType::INT64(), // key + VariableType::JS_ANY(), // currentEnv + VariableType::JS_ANY(), // jsFunc + VariableType::INT32(), // slot id }; callSign->SetParameters(params.data()); callSign->SetCallConv(CallSignature::CallConv::CCallConv); @@ -596,16 +598,17 @@ DEF_CALL_SIGNATURE(LdGlobalVar) DEF_CALL_SIGNATURE(StGlobalVar) { - // 5 : 5 input parameters - CallSignature signature("StGlobalVar", 0, 5, ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY()); + // 6 : 6 input parameters + constexpr size_t PARAM_COUNT = 6; + CallSignature signature("StGlobalVar", 0, PARAM_COUNT, ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY()); *callSign = signature; - // 5 : 5 input parameters - std::array params = { - VariableType::NATIVE_POINTER(), // glue - VariableType::INT64(), // string id - VariableType::JS_ANY(), // value - VariableType::JS_ANY(), // jsFunc - VariableType::INT32(), // slot id + std::array params = { + VariableType::NATIVE_POINTER(), // glue + VariableType::INT64(), // string id + VariableType::JS_ANY(), // value + VariableType::JS_ANY(), // currentEnv + VariableType::JS_ANY(), // jsFunc + VariableType::INT32(), // slot id }; callSign->SetParameters(params.data()); callSign->SetCallConv(CallSignature::CallConv::CCallConv); @@ -967,16 +970,12 @@ DEF_CALL_SIGNATURE(ConstructorCheck) DEF_CALL_SIGNATURE(CreateEmptyArray) { // 5 : 5 input parameters - CallSignature signature("CreateEmptyArray", 0, 5, - ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY()); + CallSignature signature("CreateEmptyArray", 0, 2, ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY()); *callSign = signature; // 5 : 5 input parameters - std::array params = { + std::array params = { VariableType::NATIVE_POINTER(), // glue - VariableType::JS_ANY(), // jsFunc - VariableType::JS_ANY(), // pc - VariableType::INT32(), // profileTypeInfo - VariableType::INT32(), // slotId + VariableType::JS_ANY(), // currentEnv }; callSign->SetParameters(params.data()); callSign->SetCallConv(CallSignature::CallConv::CCallConv); @@ -984,17 +983,15 @@ DEF_CALL_SIGNATURE(CreateEmptyArray) DEF_CALL_SIGNATURE(CreateArrayWithBuffer) { - // 6 : 6 input parameters - CallSignature signature("CreateArrayWithBuffer", 0, 6, - ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY()); + constexpr size_t PARAM_COUNT = 5; + CallSignature signature("CreateArrayWithBuffer", 0, PARAM_COUNT, ArgumentsOrder::DEFAULT_ORDER, + VariableType::JS_ANY()); *callSign = signature; - // 6 : 6 input parameters - std::array params = { + std::array params = { VariableType::NATIVE_POINTER(), // glue VariableType::INT32(), // index VariableType::JS_ANY(), // jsFunc - VariableType::JS_ANY(), // pc - VariableType::INT32(), // profileTypeInfo + VariableType::JS_ANY(), // currentEnv VariableType::INT32(), // slotId }; callSign->SetParameters(params.data()); diff --git a/ecmascript/compiler/circuit_builder.cpp b/ecmascript/compiler/circuit_builder.cpp index 1baf37f3020a997e39bf25469d0e65b4e01bdd13..3dc9b74bc247c2cd18ecaa66b785e9c7223f0e36 100644 --- a/ecmascript/compiler/circuit_builder.cpp +++ b/ecmascript/compiler/circuit_builder.cpp @@ -567,6 +567,27 @@ GateRef CircuitBuilder::GetGlobalEnv(GateRef glue) return Load(VariableType::JS_ANY(), glue, glue, globalEnvOffset); } +GateRef CircuitBuilder::GetGlobalEnvByCurrentEnv(GateRef glue, GateRef currentEnv) +{ + Label entry(env_); + SubCfgEntry(&entry); + Label fromGlue(env_); + Label exit(env_); + DEFVALUE(globalEnv, env_, VariableType::JS_ANY(), UndefineConstant()); + + globalEnv = GetValueFromTaggedArray(glue, currentEnv, Int32(BaseEnv::GLOBAL_ENV_INDEX)); + BRANCH(TaggedIsHole(*globalEnv), &fromGlue, &exit); + Bind(&fromGlue); + { + globalEnv = GetGlobalEnv(glue); + Jump(&exit); + } + Bind(&exit); + GateRef ret = *globalEnv; + SubCfgExit(); + return ret; +} + GateRef CircuitBuilder::GetGlobalObject(GateRef glue, GateRef globalEnv) { return GetGlobalEnvValue(VariableType::JS_ANY(), glue, globalEnv, GlobalEnv::JS_GLOBAL_OBJECT_INDEX); diff --git a/ecmascript/compiler/circuit_builder.h b/ecmascript/compiler/circuit_builder.h index 473c08e46defea5590be344fe94206fbbe5a44f1..7a375df6405b410c972875840d87e53ad101b602 100644 --- a/ecmascript/compiler/circuit_builder.h +++ b/ecmascript/compiler/circuit_builder.h @@ -348,6 +348,7 @@ public: GateRef GetGlobalConstantValue(ConstantIndex index); GateRef GetGlobalEnvValue(VariableType type, GateRef glue, GateRef env, size_t index); GateRef GetGlobalEnv(GateRef glue); + GateRef GetGlobalEnvByCurrentEnv(GateRef glue, GateRef currentEnv); GateRef GetGlobalObject(GateRef glue, GateRef globalEnv); GateRef GetMethodFromFunction(GateRef glue, GateRef function); GateRef GetModuleFromFunction(GateRef glue, GateRef function); @@ -455,9 +456,10 @@ public: } // **************************** High IR ****************************** - GateRef CreateArray(ElementsKind kind, uint32_t arraySize, GateRef elementsLength, RegionSpaceFlag flag); + GateRef CreateArray(ElementsKind kind, uint32_t arraySize, GateRef elementsLength, GateRef currentEnv, + RegionSpaceFlag flag); GateRef CreateArrayWithBuffer(ElementsKind kind, ArrayMetaDataAccessor::Mode mode, GateRef cpId, - GateRef constPoolIndex, RegionSpaceFlag flag); + GateRef constPoolIndex, GateRef currentEnv, RegionSpaceFlag flag); GateRef CreateArguments(ElementsKind kind, CreateArgumentsAccessor::Mode mode, GateRef restIdx); GateRef Construct(GateRef hirGate, std::vector args); GateRef CallNew(GateRef hirGate, std::vector args, bool needPushArgv = false); diff --git a/ecmascript/compiler/common_stubs.cpp b/ecmascript/compiler/common_stubs.cpp index 469c7032c88954d2a0920357a570e1f9895d8b62..5a7e36c579c10592f704cb2e058ac9973c2de617 100644 --- a/ecmascript/compiler/common_stubs.cpp +++ b/ecmascript/compiler/common_stubs.cpp @@ -907,12 +907,13 @@ void LdGlobalVarStubBuilder::GenerateCircuit() { GateRef glue = PtrArgument(0); GateRef id = Int64Argument(1); - GateRef jsFunc = TaggedArgument(2); // 2 : 3th para - GateRef slotId = Int32Argument(3); // 3 : 4th para + GateRef currentEnv = TaggedArgument(2); // 2 : 3rd para + GateRef jsFunc = TaggedArgument(3); // 3 : 4th para + GateRef slotId = Int32Argument(4); // 4 : 5th para AccessObjectStubBuilder builder(this, jsFunc); StringIdInfo info(0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID); GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc); - GateRef globalEnv = builder.GetGlobalEnv(glue); + GateRef globalEnv = builder.GetCurrentGlobalEnv(glue, currentEnv); Return(builder.LoadGlobalVar(glue, globalEnv, id, info, profileTypeInfo, slotId, ProfileOperation())); } @@ -921,12 +922,13 @@ void StGlobalVarStubBuilder::GenerateCircuit() GateRef glue = PtrArgument(0); GateRef id = Int64Argument(1); GateRef value = TaggedArgument(2); // 2 : 3rd para - GateRef jsFunc = TaggedArgument(3); // 3 : 4th para - GateRef slotId = Int32Argument(4); // 4: 5th para + GateRef currentEnv = TaggedArgument(3); // 3 : 4th para + GateRef jsFunc = TaggedArgument(4); // 4 : 5th para + GateRef slotId = Int32Argument(5); // 5: 6th para AccessObjectStubBuilder builder(this, jsFunc); StringIdInfo info(0, 0, StringIdInfo::Offset::INVALID, StringIdInfo::Length::INVALID); GateRef profileTypeInfo = UpdateProfileTypeInfo(glue, jsFunc); - GateRef globalEnv = builder.GetGlobalEnv(glue); + GateRef globalEnv = builder.GetCurrentGlobalEnv(glue, currentEnv); Return(builder.StoreGlobalVar(glue, globalEnv, id, info, value, profileTypeInfo, slotId)); } @@ -1158,7 +1160,8 @@ void ConstructorCheckStubBuilder::GenerateCircuit() void CreateEmptyArrayStubBuilder::GenerateCircuit() { GateRef glue = PtrArgument(0); - NewObjectStubBuilder newBuilder(this, GetGlobalEnv(glue)); + GateRef currentEnv = TaggedArgument(1); // 1 : 2nd para + NewObjectStubBuilder newBuilder(this, GetCurrentGlobalEnv(glue, currentEnv)); Return(newBuilder.CreateEmptyArray(glue)); } @@ -1167,8 +1170,10 @@ void CreateArrayWithBufferStubBuilder::GenerateCircuit() GateRef glue = PtrArgument(0); GateRef index = Int32Argument(1); GateRef jsFunc = TaggedArgument(2); // 2 : 3rd para - GateRef slotId = Int32Argument(5); // 5 : 6th para - NewObjectStubBuilder newBuilder(this, GetGlobalEnv(glue)); + GateRef currentEnv = TaggedArgument(3); // 3 : 4th para + GateRef slotId = Int32Argument(4); // 4 : 5th para + GateRef globalEnv = GetCurrentGlobalEnv(glue, currentEnv); + NewObjectStubBuilder newBuilder(this, globalEnv); Return(newBuilder.CreateArrayWithBuffer( glue, index, jsFunc, { IntPtr(0), 0, true }, Undefined(), slotId, ProfileOperation())); } diff --git a/ecmascript/compiler/hcr_circuit_builder.cpp b/ecmascript/compiler/hcr_circuit_builder.cpp index 2bdef20f9f1c13f9117dc4f1b759c77f7e7d307e..8a02cd2cda395ecdb1f331ebe642b9d9dafa0edd 100644 --- a/ecmascript/compiler/hcr_circuit_builder.cpp +++ b/ecmascript/compiler/hcr_circuit_builder.cpp @@ -529,33 +529,32 @@ GateRef CircuitBuilder::CallNew(GateRef hirGate, std::vector args, return callGate; } -GateRef CircuitBuilder::CreateArray(ElementsKind kind, uint32_t arraySize, - GateRef elementsLength, RegionSpaceFlag flag) +GateRef CircuitBuilder::CreateArray(ElementsKind kind, uint32_t arraySize, GateRef elementsLength, GateRef currentEnv, + RegionSpaceFlag flag) { auto currentLabel = env_->GetCurrentLabel(); auto currentControl = currentLabel->GetControl(); auto currentDepend = currentLabel->GetDepend(); ArrayMetaDataAccessor accessor(kind, ArrayMetaDataAccessor::Mode::CREATE, arraySize, flag); - GateRef newGate = GetCircuit()->NewGate(circuit_->CreateArray(accessor.ToValue()), MachineType::I64, - { currentControl, currentDepend, elementsLength }, - GateType::TaggedValue()); + GateRef newGate = + GetCircuit()->NewGate(circuit_->CreateArray(accessor.ToValue()), MachineType::I64, + {currentControl, currentDepend, elementsLength, currentEnv}, GateType::TaggedValue()); currentLabel->SetControl(newGate); currentLabel->SetDepend(newGate); return newGate; } GateRef CircuitBuilder::CreateArrayWithBuffer(ElementsKind kind, ArrayMetaDataAccessor::Mode mode, GateRef cpId, - GateRef constPoolIndex, RegionSpaceFlag flag) + GateRef constPoolIndex, GateRef currentEnv, RegionSpaceFlag flag) { auto currentLabel = env_->GetCurrentLabel(); auto currentControl = currentLabel->GetControl(); auto currentDepend = currentLabel->GetDepend(); auto frameState = acc_.FindNearestFrameState(currentDepend); ArrayMetaDataAccessor accessor(kind, mode, 0, flag); - GateRef newGate = GetCircuit()->NewGate(circuit_->CreateArrayWithBuffer(accessor.ToValue()), - MachineType::I64, - { currentControl, currentDepend, cpId, constPoolIndex, frameState }, - GateType::NJSValue()); + GateRef newGate = GetCircuit()->NewGate( + circuit_->CreateArrayWithBuffer(accessor.ToValue()), MachineType::I64, + {currentControl, currentDepend, cpId, constPoolIndex, currentEnv, frameState}, GateType::NJSValue()); currentLabel->SetControl(newGate); currentLabel->SetDepend(newGate); return newGate; diff --git a/ecmascript/compiler/hcr_opcodes.h b/ecmascript/compiler/hcr_opcodes.h index f9415cb37516dda414978107908c9128d1687933..4884db938e5344d5422c78304f42013b5ed862c2 100644 --- a/ecmascript/compiler/hcr_opcodes.h +++ b/ecmascript/compiler/hcr_opcodes.h @@ -57,8 +57,8 @@ namespace panda::ecmascript::kungfu { V(CallGetter, CALL_GETTER, GateFlags::HAS_FRAME_STATE, 1, 1, 3) \ V(CallSetter, CALL_SETTER, GateFlags::HAS_FRAME_STATE, 1, 1, 4) \ V(MonoCallGetterOnProto, MONO_CALL_GETTER_ON_PROTO, GateFlags::HAS_FRAME_STATE, 1, 1, 4) \ - V(CreateArray, CREATE_ARRAY, GateFlags::NONE_FLAG, 1, 1, 1) \ - V(CreateArrayWithBuffer, CREATE_ARRAY_WITH_BUFFER, GateFlags::CHECKABLE, 1, 1, 2) \ + V(CreateArray, CREATE_ARRAY, GateFlags::NONE_FLAG, 1, 1, 2) \ + V(CreateArrayWithBuffer, CREATE_ARRAY_WITH_BUFFER, GateFlags::CHECKABLE, 1, 1, 3) \ V(CreateArguments, CREATE_ARGUMENTS, GateFlags::HAS_FRAME_STATE, 1, 1, 1) #define HCR_GATE_META_DATA_LIST_WITH_VALUE(V) \ diff --git a/ecmascript/compiler/ntype_bytecode_lowering.cpp b/ecmascript/compiler/ntype_bytecode_lowering.cpp index 0990394dff880f4b4468cc96895aacc096fd8dd1..f99f6bee6810f7ca31c6ff3af6709fed151c525d 100644 --- a/ecmascript/compiler/ntype_bytecode_lowering.cpp +++ b/ecmascript/compiler/ntype_bytecode_lowering.cpp @@ -202,15 +202,17 @@ void NTypeBytecodeLowering::LowerNTypedCreateEmptyArray(GateRef gate) ElementsKind kind = acc_.TryGetElementsKind(gate); uint32_t length = acc_.TryGetArrayElementsLength(gate); RegionSpaceFlag flag = acc_.TryGetRegionSpaceFlag(gate); - GateRef array = builder_.CreateArray(kind, 0, builder_.Int64(length), flag); + GateRef currentEnv = acc_.GetValueIn(gate, 0); // 0: currentEnv + GateRef array = builder_.CreateArray(kind, 0, builder_.Int64(length), currentEnv, flag); acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), array); } void NTypeBytecodeLowering::LowerNTypedCreateArrayWithBuffer(GateRef gate) { - // 1: number of value inputs - ASSERT(acc_.GetNumValueIn(gate) == 1); + // 3: number of value inputs, index, currentEnv, slotId + ASSERT(acc_.GetNumValueIn(gate) == 3); GateRef index = acc_.GetValueIn(gate, 0); + GateRef currentEnv = acc_.GetValueIn(gate, 1); auto methodOffset = acc_.TryGetMethodOffset(gate); uint32_t cpId = ptManager_->GetConstantPoolIDByMethodOffset(methodOffset); @@ -225,8 +227,7 @@ void NTypeBytecodeLowering::LowerNTypedCreateArrayWithBuffer(GateRef gate) RegionSpaceFlag flag = acc_.TryGetRegionSpaceFlag(gate); GateRef cpIdGr = builder_.Int32(cpId); GateRef array = - builder_.CreateArrayWithBuffer(kind, ArrayMetaDataAccessor::Mode::CREATE, - cpIdGr, index, flag); + builder_.CreateArrayWithBuffer(kind, ArrayMetaDataAccessor::Mode::CREATE, cpIdGr, index, currentEnv, flag); acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), array); } diff --git a/ecmascript/compiler/ntype_hcr_lowering.cpp b/ecmascript/compiler/ntype_hcr_lowering.cpp index ca51979388cad218e8acbbe6c89cc2a7bd607d8f..83e2688a2df1e95641eaf47fd766360810aaf1d2 100644 --- a/ecmascript/compiler/ntype_hcr_lowering.cpp +++ b/ecmascript/compiler/ntype_hcr_lowering.cpp @@ -62,9 +62,10 @@ void NTypeHCRLowering::LowerCreateEmptyArray(GateRef gate, GateRef glue) GateRef length = builder_.Int32(0); GateRef elements = Circuit::NullGate(); GateRef value = acc_.GetValueIn(gate, 0); + GateRef currentEnv = acc_.GetValueIn(gate, 1); auto hintLength = static_cast(acc_.GetConstantValue(value)); elements = builder_.GetGlobalConstantValue(ConstantIndex::EMPTY_ARRAY_OBJECT_INDEX); - auto array = NewJSArrayLiteral(glue, gate, elements, length, hintLength); + auto array = NewJSArrayLiteral(glue, gate, elements, length, currentEnv, hintLength); acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), array); } @@ -73,8 +74,9 @@ void NTypeHCRLowering::LowerCreateArrayWithOwn(GateRef gate, GateRef glue) uint32_t elementsLength = acc_.GetArraySize(gate); GateRef length = builder_.IntPtr(elementsLength); GateRef elements = CreateElementsWithLength(gate, glue, elementsLength); + GateRef currentEnv = acc_.GetValueIn(gate, 1); - auto array = NewJSArrayLiteral(glue, gate, elements, length); + auto array = NewJSArrayLiteral(glue, gate, elements, length, currentEnv); acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), array); } @@ -82,9 +84,10 @@ void NTypeHCRLowering::LowerCreateArrayWithBuffer(GateRef gate, GateRef glue) { Environment env(gate, circuit_, &builder_); // 2: number of value inputs - ASSERT(acc_.GetNumValueIn(gate) == 2); + ASSERT(acc_.GetNumValueIn(gate) == 3); GateRef cpId = acc_.GetValueIn(gate, 0); GateRef index = acc_.GetValueIn(gate, 1); + GateRef currentEnv = acc_.GetValueIn(gate, 2); uint32_t constPoolIndex = static_cast(acc_.GetConstantValue(index)); ArgumentAccessor argAcc(circuit_); GateRef frameState = GetFrameState(gate); @@ -127,7 +130,7 @@ void NTypeHCRLowering::LowerCreateArrayWithBuffer(GateRef gate, GateRef glue) length = builder_.IntPtr(literialLength); } - auto array = NewJSArrayLiteral(glue, gate, elements, length); + auto array = NewJSArrayLiteral(glue, gate, elements, length, currentEnv); acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), array); } @@ -209,7 +212,7 @@ GateRef NTypeHCRLowering::CreateElementsWithLength(GateRef gate, GateRef glue, s } GateRef NTypeHCRLowering::NewJSArrayLiteral(GateRef glue, GateRef gate, GateRef elements, GateRef length, - uint32_t hintLength) + GateRef currentEnv, uint32_t hintLength) { ElementsKind kind = acc_.GetArrayMetaDataAccessor(gate).GetElementsKind(); RegionSpaceFlag flag = RegionSpaceFlag::IN_YOUNG_SPACE; @@ -219,7 +222,7 @@ GateRef NTypeHCRLowering::NewJSArrayLiteral(GateRef glue, GateRef gate, GateRef GateRef hclass = Circuit::NullGate(); // At define point, we use initial array class without IsPrototype set. auto hclassIndex = compilationEnv_->GetArrayHClassIndex(kind, false); - GateRef globalEnv = builder_.GetGlobalEnv(glue); + GateRef globalEnv = builder_.GetGlobalEnvByCurrentEnv(glue, currentEnv); hclass = builder_.GetGlobalEnvValue(VariableType::JS_POINTER(), glue, globalEnv, static_cast(hclassIndex)); JSHandle arrayFunc(compilationEnv_->GetGlobalEnv()->GetArrayFunction()); diff --git a/ecmascript/compiler/ntype_hcr_lowering.h b/ecmascript/compiler/ntype_hcr_lowering.h index dd164a6e3b8657dd53885b536633b83b9a855d78..e03e655214a8d68d97d39c72fb6a2ac52dadbcf9 100644 --- a/ecmascript/compiler/ntype_hcr_lowering.h +++ b/ecmascript/compiler/ntype_hcr_lowering.h @@ -54,8 +54,8 @@ private: GateRef LoadFromConstPool(GateRef glue, GateRef unsharedConstPool, size_t index, size_t valVecType); GateRef NewActualArgv(GateRef gate, GateRef glue); - GateRef NewJSArrayLiteral( - GateRef glue, GateRef gate, GateRef elements, GateRef length, uint32_t hintLength = 0); + GateRef NewJSArrayLiteral(GateRef glue, GateRef gate, GateRef elements, GateRef length, GateRef currentEnv, + uint32_t hintLength = 0); GateRef NewTaggedArray(size_t length, GateRef glue); GateRef CreateElementsWithLength(GateRef gate, GateRef glue, size_t arrayLength); GateRef LowerCallRuntime(GateRef glue, GateRef hirGate, int index, const std::vector &args, diff --git a/ecmascript/compiler/slowpath_lowering.cpp b/ecmascript/compiler/slowpath_lowering.cpp index 8de6466e63711986db439df3b55e45d5348fa188..b8e4ca14f0d603a9d27f98735a251c2631f7d26e 100644 --- a/ecmascript/compiler/slowpath_lowering.cpp +++ b/ecmascript/compiler/slowpath_lowering.cpp @@ -1001,11 +1001,12 @@ void SlowPathLowering::LowerTryLdGlobalByName(GateRef gate) void SlowPathLowering::LowerStGlobalVar(GateRef gate) { - // 3: number of value inputs - ASSERT(acc_.GetNumValueIn(gate) == 3); + // 4: number of value inputs + ASSERT(acc_.GetNumValueIn(gate) == 4); GateRef id = acc_.GetValueIn(gate, 1); // 1: the second parameter GateRef value = acc_.GetValueIn(gate, 2); // 2: the 2nd para is value - LowerCallStubWithIC(gate, CommonStubCSigns::StGlobalVar, { id, value }); + GateRef currentEnv = acc_.GetValueIn(gate, 3); // 3: the 3rd para is current env + LowerCallStubWithIC(gate, CommonStubCSigns::StGlobalVar, {id, value, currentEnv}); } void SlowPathLowering::LowerGetIterator(GateRef gate) @@ -1594,7 +1595,9 @@ void SlowPathLowering::LowerFastStrictEqual(GateRef gate) void SlowPathLowering::LowerCreateEmptyArray(GateRef gate) { - GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::CreateEmptyArray, { glue_ }); + // 0: means currentEnv index + GateRef currentEnv = acc_.GetValueIn(gate, 0); + GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::CreateEmptyArray, {glue_, currentEnv}); GateRef newRes = LowerUpdateArrayHClassAtDefine(gate, result); ReplaceHirWithValue(gate, newRes); } @@ -1608,8 +1611,12 @@ void SlowPathLowering::LowerCreateEmptyObject(GateRef gate) void SlowPathLowering::LowerCreateArrayWithBuffer(GateRef gate) { GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC); + // 0,1,2 means index, currentEnv, slotID GateRef index = builder_.TruncInt64ToInt32(acc_.GetValueIn(gate, 0)); - GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::CreateArrayWithBuffer, { glue_, index, jsFunc }); + GateRef currentEnv = acc_.GetValueIn(gate, 1); + GateRef slotID = builder_.ZExtInt16ToInt32(acc_.GetValueIn(gate, 2)); + GateRef result = builder_.CallStub(glue_, gate, CommonStubCSigns::CreateArrayWithBuffer, + {glue_, index, jsFunc, currentEnv, slotID}); // when elementsKind switch on, we should not update arrayHClass here. GateRef newRes = LowerUpdateArrayHClassAtDefine(gate, result); ReplaceHirWithValue(gate, newRes); @@ -2480,10 +2487,11 @@ void SlowPathLowering::LowerStOwnByNameWithNameSet(GateRef gate) void SlowPathLowering::LowerLdGlobalVar(GateRef gate) { - // 2: number of value inputs - ASSERT(acc_.GetNumValueIn(gate) == 2); + // 3: number of value inputs: slotID stringId currentEnv + ASSERT(acc_.GetNumValueIn(gate) == 3); GateRef stringId = acc_.GetValueIn(gate, 1); // 1: the second parameter - LowerCallStubWithIC(gate, CommonStubCSigns::LdGlobalVar, { stringId }); + GateRef currentEnv = acc_.GetValueIn(gate, 2); // 2: the third parameter + LowerCallStubWithIC(gate, CommonStubCSigns::LdGlobalVar, {stringId, currentEnv}); } bool SlowPathLowering::enableMegaIC(GateRef gate)