1 /* 2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_H 17 #define ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_H 18 19 #include "ecmascript/base/number_helper.h" 20 #include "ecmascript/compiler/assembler/assembler.h" 21 #include "ecmascript/compiler/builtins/builtins_call_signature.h" 22 #include "ecmascript/compiler/call_signature.h" 23 #include "ecmascript/compiler/circuit.h" 24 #include "ecmascript/compiler/gate.h" 25 #include "ecmascript/compiler/gate_accessor.h" 26 #include "ecmascript/compiler/lcr_gate_meta_data.h" 27 #include "ecmascript/compiler/share_gate_meta_data.h" 28 #include "ecmascript/compiler/variable_type.h" 29 #include "ecmascript/global_env_constants.h" 30 #include "ecmascript/js_tagged_value.h" 31 #include "ecmascript/jspandafile/constpool_value.h" 32 33 namespace panda::ecmascript::kungfu { 34 using namespace panda::ecmascript; 35 #define DEFVALUE(varname, cirBuilder, type, val) \ 36 Variable varname(cirBuilder, type, cirBuilder->NextVariableId(), val) 37 38 class BuiltinsTypedArrayStubBuilder; 39 class BuiltinsStringStubBuilder; 40 class CompilationConfig; 41 class Environment; 42 class Label; 43 class NTypeBytecodeLowering; 44 class SlowPathLowering; 45 class StubBuilder; 46 class TypedBytecodeLowering; 47 class PGOHCRLowering; 48 class NTypeHCRLowering; 49 class TSHCRLowering; 50 class Variable; 51 class NativeInlineLowering; 52 class TypedHCRLowering; 53 class TypedNativeInlineLowering; 54 class StringBuilderOptimizer; 55 class PostSchedule; 56 class TSHCROptPass; 57 class BuiltinLowering; 58 59 #define BINARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(V) \ 60 V(Int16Add, Add, MachineType::I16) \ 61 V(Int32Add, Add, MachineType::I32) \ 62 V(Int64Add, Add, MachineType::I64) \ 63 V(DoubleAdd, Add, MachineType::F64) \ 64 V(PtrAdd, Add, MachineType::ARCH) \ 65 V(DoubleExp, Exp, MachineType::F64) \ 66 V(Int16Sub, Sub, MachineType::I16) \ 67 V(Int32Sub, Sub, MachineType::I32) \ 68 V(Int64Sub, Sub, MachineType::I64) \ 69 V(DoubleSub, Sub, MachineType::F64) \ 70 V(PtrSub, Sub, MachineType::ARCH) \ 71 V(Int32Mul, Mul, MachineType::I32) \ 72 V(Int64Mul, Mul, MachineType::I64) \ 73 V(DoubleMul, Mul, MachineType::F64) \ 74 V(PtrMul, Mul, MachineType::ARCH) \ 75 V(Int32Div, Sdiv, MachineType::I32) \ 76 V(Int64Div, Sdiv, MachineType::I64) \ 77 V(DoubleDiv, Fdiv, MachineType::F64) \ 78 V(Int32Mod, Smod, MachineType::I32) \ 79 V(DoubleMod, Smod, MachineType::F64) \ 80 V(BitAnd, And, MachineType::I1) \ 81 V(Int8And, And, MachineType::I8) \ 82 V(Int8Xor, Xor, MachineType::I8) \ 83 V(Int16And, And, MachineType::I16) \ 84 V(Int32And, And, MachineType::I32) \ 85 V(Int64And, And, MachineType::I64) \ 86 V(BitOr, Or, MachineType::I1) \ 87 V(Int16Or, Or, MachineType::I16) \ 88 V(Int32Or, Or, MachineType::I32) \ 89 V(Int64Or, Or, MachineType::I64) \ 90 V(Int32Xor, Xor, MachineType::I32) \ 91 V(Int64Xor, Xor, MachineType::I64) \ 92 V(Int16LSL, Lsl, MachineType::I16) \ 93 V(Int32LSL, Lsl, MachineType::I32) \ 94 V(Int64LSL, Lsl, MachineType::I64) \ 95 V(Int8LSR, Lsr, MachineType::I8) \ 96 V(Int16LSR, Lsr, MachineType::I16) \ 97 V(Int32LSR, Lsr, MachineType::I32) \ 98 V(Int64LSR, Lsr, MachineType::I64) \ 99 V(Int32ASR, Asr, MachineType::I32) \ 100 V(Int64ASR, Asr, MachineType::I64) \ 101 V(Int32Min, Min, MachineType::I32) \ 102 V(DoubleMin, Min, MachineType::F64) \ 103 V(Int32Max, Max, MachineType::I32) \ 104 V(DoubleMax, Max, MachineType::F64) 105 106 #define UNARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(V) \ 107 V(BoolNot, Rev, MachineType::I1) \ 108 V(Int32Not, Rev, MachineType::I32) \ 109 V(Int64Not, Rev, MachineType::I64) \ 110 V(CastDoubleToInt64, Bitcast, MachineType::I64) \ 111 V(CastInt64ToFloat64, Bitcast, MachineType::F64) \ 112 V(CastInt32ToFloat32, Bitcast, MachineType::F32) \ 113 V(CastFloat32ToInt32, Bitcast, MachineType::I32) \ 114 V(SExtInt32ToInt64, Sext, MachineType::I64) \ 115 V(SExtInt1ToInt64, Sext, MachineType::I64) \ 116 V(SExtInt1ToInt32, Sext, MachineType::I32) \ 117 V(ZExtInt8ToInt16, Zext, MachineType::I16) \ 118 V(ZExtInt32ToInt64, Zext, MachineType::I64) \ 119 V(ZExtInt1ToInt64, Zext, MachineType::I64) \ 120 V(ZExtInt1ToInt32, Zext, MachineType::I32) \ 121 V(ZExtInt8ToInt32, Zext, MachineType::I32) \ 122 V(ZExtInt8ToInt64, Zext, MachineType::I64) \ 123 V(ZExtInt8ToPtr, Zext, MachineType::ARCH) \ 124 V(ZExtInt16ToPtr, Zext, MachineType::ARCH) \ 125 V(ZExtInt32ToPtr, Zext, MachineType::ARCH) \ 126 V(SExtInt32ToPtr, Sext, MachineType::ARCH) \ 127 V(ZExtInt16ToInt32, Zext, MachineType::I32) \ 128 V(ZExtInt16ToInt64, Zext, MachineType::I64) \ 129 V(DoubleTrunc, DoubleTrunc, MachineType::F64) \ 130 V(TruncInt16ToInt8, Trunc, MachineType::I8) \ 131 V(TruncInt64ToInt32, Trunc, MachineType::I32) \ 132 V(TruncPtrToInt32, Trunc, MachineType::I32) \ 133 V(TruncInt64ToInt1, Trunc, MachineType::I1) \ 134 V(TruncInt64ToInt16, Trunc, MachineType::I16) \ 135 V(TruncInt32ToInt1, Trunc, MachineType::I1) \ 136 V(TruncInt32ToInt8, Trunc, MachineType::I8) \ 137 V(TruncInt32ToInt16, Trunc, MachineType::I16) \ 138 V(TruncFloatToInt64, TruncFloatToInt64, MachineType::I64) \ 139 V(TruncFloatToInt32, TruncFloatToInt32, MachineType::I32) \ 140 V(ExtFloat32ToDouble, Fext, MachineType::F64) \ 141 V(TruncDoubleToFloat32, Ftrunc, MachineType::F32) \ 142 V(ChangeInt32ToFloat64, SignedIntToFloat, MachineType::F64) \ 143 V(ChangeInt32ToFloat32, SignedIntToFloat, MachineType::F32) \ 144 V(ChangeUInt32ToFloat64, UnsignedIntToFloat, MachineType::F64) \ 145 V(ChangeFloat64ToInt32, FloatToSignedInt, MachineType::I32) \ 146 V(ChangeTaggedPointerToInt64, TaggedToInt64, MachineType::I64) \ 147 V(SExtInt16ToInt64, Sext, MachineType::I64) \ 148 V(SExtInt16ToInt32, Sext, MachineType::I32) \ 149 V(SExtInt8ToInt32, Sext, MachineType::I32) \ 150 V(SExtInt8ToInt64, Sext, MachineType::I64) \ 151 V(Abs, Abs, MachineType::I32) \ 152 V(FAbs, Abs, MachineType::F64) \ 153 V(CountLeadingZeroes32, Clz32, MachineType::I32) \ 154 V(DoubleCeil, Ceil, MachineType::F64) \ 155 V(DoubleFloor, Floor, MachineType::F64) \ 156 V(Int64Rev, BitRev, MachineType::I64) \ 157 V(Int32Rev, BitRev, MachineType::I32) \ 158 V(Int16Rev, BitRev, MachineType::I16) \ 159 V(Int8Rev, BitRev, MachineType::I8) 160 161 #define BINARY_CMP_METHOD_LIST_WITHOUT_BITWIDTH(V) \ 162 V(DoubleLessThan, Fcmp, static_cast<BitField>(FCmpCondition::OLT)) \ 163 V(DoubleLessThanOrEqual, Fcmp, static_cast<BitField>(FCmpCondition::OLE)) \ 164 V(DoubleGreaterThan, Fcmp, static_cast<BitField>(FCmpCondition::OGT)) \ 165 V(DoubleGreaterThanOrEqual, Fcmp, static_cast<BitField>(FCmpCondition::OGE)) \ 166 V(DoubleEqual, Fcmp, static_cast<BitField>(FCmpCondition::OEQ)) \ 167 V(DoubleNotEqual, Fcmp, static_cast<BitField>(FCmpCondition::ONE)) \ 168 V(Int8GreaterThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::SGE)) \ 169 V(Int32LessThan, Icmp, static_cast<BitField>(ICmpCondition::SLT)) \ 170 V(Int32LessThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::SLE)) \ 171 V(Int32GreaterThan, Icmp, static_cast<BitField>(ICmpCondition::SGT)) \ 172 V(Int32GreaterThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::SGE)) \ 173 V(Int32UnsignedLessThan, Icmp, static_cast<BitField>(ICmpCondition::ULT)) \ 174 V(Int32UnsignedLessThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::ULE)) \ 175 V(Int32UnsignedGreaterThan, Icmp, static_cast<BitField>(ICmpCondition::UGT)) \ 176 V(Int32UnsignedGreaterThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::UGE)) \ 177 V(Int64LessThan, Icmp, static_cast<BitField>(ICmpCondition::SLT)) \ 178 V(Int64LessThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::SLE)) \ 179 V(Int64GreaterThan, Icmp, static_cast<BitField>(ICmpCondition::SGT)) \ 180 V(Int64GreaterThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::SGE)) \ 181 V(Int64UnsignedLessThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::ULE)) \ 182 V(Int64UnsignedGreaterThan, Icmp, static_cast<BitField>(ICmpCondition::UGT)) \ 183 V(Int64UnsignedGreaterThanOrEqual, Icmp, static_cast<BitField>(ICmpCondition::UGE)) 184 185 class CircuitBuilder { 186 public: CircuitBuilder(Circuit * circuit)187 explicit CircuitBuilder(Circuit *circuit) : circuit_(circuit), acc_(circuit) {} CircuitBuilder(Circuit * circuit,CompilationConfig * cmpCfg)188 CircuitBuilder(Circuit *circuit, CompilationConfig *cmpCfg) 189 : circuit_(circuit), acc_(circuit), cmpCfg_(cmpCfg) 190 { 191 } 192 ~CircuitBuilder() = default; 193 NO_MOVE_SEMANTIC(CircuitBuilder); 194 NO_COPY_SEMANTIC(CircuitBuilder); 195 196 enum JudgeMethodType { 197 HAS_AOT, 198 HAS_AOT_FASTCALL, 199 HAS_AOT_NOTFASTCALL, 200 }; 201 202 // **************************** Share IR ***************************** 203 GateRef Arguments(size_t index); 204 GateRef DefaultCase(GateRef switchBranch); 205 GateRef DependRelay(GateRef state, GateRef depend); 206 void DeoptCheck(GateRef condition, GateRef frameState, DeoptType type); 207 GateRef GetElementsArray(GateRef object); 208 GateRef GetLengthOfTaggedArray(GateRef array); 209 GateRef GetLengthOfJSTypedArray(GateRef array); 210 GateRef GetDataOfTaggedArray(GateRef array); 211 GateRef GetLengthOfJSArray(GateRef array); 212 GateRef IsTypedArray(GateRef array); 213 GateRef IsSharedTypedArray(GateRef array); 214 GateRef GetSuperConstructor(GateRef ctor); 215 GateRef Merge(const std::vector<GateRef> &inList); 216 GateRef Selector(OpCode opcode, MachineType machineType, GateRef control, const std::vector<GateRef> &values, 217 int valueCounts, VariableType type = VariableType::VOID()); 218 GateRef Selector(OpCode opcode, GateRef control, const std::vector<GateRef> &values, 219 int valueCounts, VariableType type = VariableType::VOID()); 220 GateRef Nop(); 221 GateRef Return(GateRef state, GateRef depend, GateRef value); 222 GateRef ReturnVoid(GateRef state, GateRef depend); 223 GateRef Goto(GateRef state); 224 GateRef LoopBegin(GateRef state); 225 GateRef LoopEnd(GateRef state); 226 GateRef LoopExit(GateRef state); 227 GateRef LoopExitDepend(GateRef state, GateRef depend); 228 GateRef LoopExitValue(GateRef state, GateRef value); 229 GateRef IfTrue(GateRef ifBranch); 230 GateRef IfFalse(GateRef ifBranch); 231 GateRef IsJsCOWArray(GateRef obj); 232 GateRef IsCOWArray(GateRef objectType); 233 GateRef IsTaggedArray(GateRef object); 234 GateRef CheckJSType(GateRef object, JSType jsType); 235 GateRef IsMutantTaggedArray(GateRef objectType); 236 GateRef SwitchCase(GateRef switchBranch, int64_t value); 237 GateRef Int8(int8_t val); 238 GateRef Int16(int16_t val); 239 GateRef Int32(int32_t value); 240 GateRef Int64(int64_t value); 241 GateRef IntPtr(int64_t val); 242 GateRef StringPtr(std::string_view str); 243 GateRef StringPtr(const std::string &str); 244 GateRef Boolean(bool value); 245 GateRef Double(double value); 246 GateRef UndefineConstant(); 247 GateRef HoleConstant(); 248 GateRef SpecialHoleConstant(); 249 GateRef NullPtrConstant(); 250 GateRef NullConstant(); 251 GateRef TaggedValueConstant(JSTaggedValue taggedValue); 252 GateRef ExceptionConstant(); 253 void ClearConstantCache(GateRef gate); 254 GateRef NanValue(); 255 GateRef RelocatableData(uint64_t val); 256 257 #define BRANCH(condition, trueLabel, falseLabel) \ 258 { \ 259 std::ostringstream os; \ 260 os << __func__ << ": " << #trueLabel << "- " << #falseLabel; \ 261 Branch(condition, trueLabel, falseLabel, 1, 1, os.str().c_str()); \ 262 } 263 264 #define BRANCH_CIR(condition, trueLabel, falseLabel) \ 265 { \ 266 std::ostringstream os; \ 267 os << __func__ << ": " << #trueLabel << "- " << #falseLabel; \ 268 builder_.Branch(condition, trueLabel, falseLabel, 1, 1, os.str().c_str()); \ 269 } 270 271 #define BRANCH_LIKELY(condition, trueLabel, falseLabel) \ 272 { \ 273 std::ostringstream os; \ 274 os << __func__ << ": " << #trueLabel << "(likely)- " << #falseLabel; \ 275 Branch(condition, trueLabel, falseLabel, \ 276 BranchWeight::DEOPT_WEIGHT, BranchWeight::ONE_WEIGHT, os.str().c_str()); \ 277 } 278 279 #define BRANCH_CIR_LIKELY(condition, trueLabel, falseLabel) \ 280 { \ 281 std::ostringstream os; \ 282 os << __func__ << ": " << #trueLabel << "(likely)- " << #falseLabel; \ 283 builder_.Branch(condition, trueLabel, falseLabel, \ 284 BranchWeight::DEOPT_WEIGHT, BranchWeight::ONE_WEIGHT, os.str().c_str()); \ 285 } 286 287 #define BRANCH_UNLIKELY(condition, trueLabel, falseLabel) \ 288 { \ 289 std::ostringstream os; \ 290 os << __func__ << ": " << #trueLabel << "(unlikely)- " << #falseLabel; \ 291 Branch(condition, trueLabel, falseLabel, \ 292 BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, os.str().c_str()); \ 293 } 294 295 #define BRANCH_CIR_UNLIKELY(condition, trueLabel, falseLabel) \ 296 { \ 297 std::ostringstream os; \ 298 os << __func__ << ": " << #trueLabel << "(unlikely)- " << #falseLabel; \ 299 builder_.Branch(condition, trueLabel, falseLabel, \ 300 BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, os.str().c_str()); \ 301 } 302 303 #define BRANCH_NO_WEIGHT(condition, trueLabel, falseLabel) \ 304 { \ 305 std::ostringstream os; \ 306 os << __func__ << ": " << #trueLabel << "(no weight)- " << #falseLabel; \ 307 Branch(condition, trueLabel, falseLabel, \ 308 BranchWeight::ZERO_WEIGHT, BranchWeight::ZERO_WEIGHT, os.str().c_str()); \ 309 } 310 311 GateRef Branch(GateRef state, GateRef condition, uint32_t leftWeight = 1, uint32_t rightWeight = 1, 312 const char* comment = nullptr); // 1: default branch weight 313 GateRef SwitchBranch(GateRef state, GateRef index, int caseCounts); 314 void AppendFrameArgs(std::vector<GateRef> &args, GateRef hirGate); 315 inline GateRef True(); 316 inline GateRef False(); 317 inline GateRef Undefined(); 318 inline GateRef Hole(); 319 320 GateRef ElementsKindIsInt(GateRef kind); 321 GateRef ElementsKindIsIntOrHoleInt(GateRef kind); 322 GateRef ElementsKindIsNumber(GateRef kind); 323 GateRef ElementsKindIsNumOrHoleNum(GateRef kind); 324 GateRef ElementsKindIsString(GateRef kind); 325 GateRef ElementsKindIsStringOrHoleString(GateRef kind); 326 GateRef ElementsKindIsHeapKind(GateRef kind); 327 GateRef ElementsKindHasHole(GateRef kind); 328 329 GateRef LoadBuiltinObject(size_t offset); 330 331 // Get 332 GateRef GetConstPoolFromFunction(GateRef jsFunc); 333 GateRef GetUnsharedConstpoolFromGlue(GateRef glue, GateRef constpool); 334 GateRef GetUnsharedConstpoolIndex(GateRef constpool); 335 GateRef GetUnsharedConstpool(GateRef arrayAddr, GateRef index); 336 GateRef GetUnsharedConstpoolArrayLen(GateRef glue); 337 GateRef GetCodeAddr(GateRef jsFunc); 338 GateRef GetBaselineCodeAddr(GateRef baselineCode); 339 GateRef GetObjectByIndexFromConstPool(GateRef glue, GateRef hirGate, GateRef frameState, GateRef index, 340 ConstPoolType type); 341 GateRef GetObjectFromConstPool(GateRef glue, GateRef hirGate, GateRef shardConstPool, GateRef unsharedConstPool, 342 GateRef module, GateRef index, ConstPoolType type); 343 GateRef GetFunctionLexicalEnv(GateRef function); 344 GateRef GetGlobalEnv(); 345 GateRef GetGlobalEnvObj(GateRef env, size_t index); 346 GateRef GetGlobalEnvObjHClass(GateRef env, size_t index); 347 GateRef GetGlobalConstantValue(ConstantIndex index); 348 GateRef GetGlobalEnvValue(VariableType type, GateRef env, size_t index); 349 GateRef GetGlobalObject(GateRef glue); 350 GateRef GetMethodFromFunction(GateRef function); 351 GateRef GetModuleFromFunction(GateRef function); 352 GateRef GetSendableEnvFromModule(GateRef module); 353 GateRef GetHomeObjectFromFunction(GateRef function); 354 GateRef GetHClassGateFromIndex(GateRef gate, int32_t index); 355 GateRef GetProfileTypeInfo(GateRef function); 356 inline GateRef GetExpectedNumOfArgs(GateRef method); 357 inline GateRef GetGlobalConstantOffset(ConstantIndex index); // shareir 358 GateRef GetEmptyArray(GateRef glue); 359 GateRef GetPrototypeFromHClass(GateRef hClass); 360 GateRef GetEnumCacheFromHClass(GateRef hClass); 361 GateRef GetProtoChangeMarkerFromHClass(GateRef hClass); 362 GateRef GetLengthFromForInIterator(GateRef iter); 363 GateRef GetIndexFromForInIterator(GateRef iter); 364 GateRef GetKeysFromForInIterator(GateRef iter); 365 GateRef GetObjectFromForInIterator(GateRef iter); 366 GateRef GetCachedHclassFromForInIterator(GateRef iter); 367 void SetLengthOfForInIterator(GateRef glue, GateRef iter, GateRef length); 368 void SetIndexOfForInIterator(GateRef glue, GateRef iter, GateRef index); 369 void SetKeysOfForInIterator(GateRef glue, GateRef iter, GateRef keys); 370 void SetObjectOfForInIterator(GateRef glue, GateRef iter, GateRef object); 371 void SetCachedHclassOfForInIterator(GateRef glue, GateRef iter, GateRef hclass); 372 void IncreaseIteratorIndex(GateRef glue, GateRef iter, GateRef index); 373 void IncreaseArrayIteratorIndex(GateRef glue, GateRef iter, GateRef index); 374 void SetNextIndexOfArrayIterator(GateRef glue, GateRef iter, GateRef nextIndex); 375 void SetIteratedArrayOfArrayIterator(GateRef glue, GateRef iter, GateRef iteratedArray); 376 void SetBitFieldOfArrayIterator(GateRef glue, GateRef iter, GateRef kind); 377 GateRef GetArrayIterationKind(GateRef iter); 378 GateRef GetHasChanged(GateRef object); 379 GateRef GetAccessorHasChanged(GateRef object); 380 GateRef GetNotFoundHasChanged(GateRef object); 381 GateRef HasDeleteProperty(GateRef hClass); 382 GateRef IsOnHeap(GateRef hClass); 383 GateRef IsEcmaObject(GateRef obj); 384 385 // Set 386 void SetLengthToFunction(GateRef glue, GateRef function, GateRef value); 387 void SetLexicalEnvToFunction(GateRef glue, GateRef function, GateRef value); 388 void SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value); 389 void SetModuleToFunction(GateRef glue, GateRef function, GateRef value); 390 void SetSendableEnvToModule(GateRef glue, GateRef module, GateRef value); 391 void SetRawProfileTypeInfoToFunction(GateRef glue, GateRef function, GateRef value); 392 void UpdateProfileTypeInfoCellToFunction(GateRef glue, GateRef function, 393 GateRef profileTypeInfo, GateRef slotId); 394 void UpdateProfileTypeInfoCellType(GateRef glue, GateRef profileTypeInfoCell); 395 396 GateRef FunctionIsResolved(GateRef function); 397 GateRef HasPendingException(GateRef glue); // shareir 398 GateRef IsUtf8String(GateRef string); 399 GateRef IsUtf16String(GateRef string); 400 GateRef IsInternString(GateRef string); 401 GateRef LoadObjectFromConstPool(GateRef constPool, GateRef index); 402 GateRef IsAccessorInternal(GateRef accessor); 403 404 // label related 405 void NewEnvironment(GateRef hir); 406 void DeleteCurrentEnvironment(); 407 inline int NextVariableId(); 408 inline void HandleException(GateRef result, Label *success, Label *exception, Label *exit); 409 inline void HandleException(GateRef result, Label *success, Label *fail, Label *exit, GateRef exceptionVal); 410 inline void SubCfgEntry(Label *entry); 411 inline void SubCfgExit(); 412 inline GateRef Return(GateRef value); 413 inline GateRef Return(); 414 inline void Bind(Label *label); 415 inline void Bind(Label *label, bool justSlowPath); 416 void Jump(Label *label); 417 void Branch(GateRef condition, Label *trueLabel, Label *falseLabel, 418 uint32_t trueWeight = 1, uint32_t falseWeight = 1, const char* comment = nullptr); 419 void Switch(GateRef index, Label *defaultLabel, 420 const int64_t *keysValue, Label *keysLabel, int numberOfKeys); 421 void Switch(GateRef index, Label *defaultLabel, 422 const int64_t *keysValue, Label * const *keysLabel, int numberOfKeys); 423 void LoopBegin(Label *loopHead); 424 void LoopEnd(Label *loopHead); 425 void LoopExit(const std::vector<Variable*> &vars, size_t diff = 1); 426 inline Label *GetCurrentLabel() const; 427 inline GateRef GetState() const; 428 inline GateRef GetDepend() const; 429 inline StateDepend GetStateDepend() const; 430 GetCircuit()431 Circuit *GetCircuit() const 432 { 433 return circuit_; 434 } 435 SetEnvironment(Environment * env)436 void SetEnvironment(Environment *env) 437 { 438 env_ = env; 439 } GetCurrentEnvironment()440 Environment *GetCurrentEnvironment() const 441 { 442 return env_; 443 } SetCompilationConfig(CompilationConfig * cmpCfg)444 void SetCompilationConfig(CompilationConfig *cmpCfg) 445 { 446 cmpCfg_ = cmpCfg; 447 } GetCompilationConfig()448 CompilationConfig *GetCompilationConfig() const 449 { 450 return cmpCfg_; 451 } 452 453 // **************************** High IR ****************************** 454 GateRef CreateArray(ElementsKind kind, uint32_t arraySize, GateRef elementsLength, RegionSpaceFlag flag); 455 GateRef CreateArrayWithBuffer(ElementsKind kind, ArrayMetaDataAccessor::Mode mode, GateRef cpId, 456 GateRef constPoolIndex, RegionSpaceFlag flag); 457 GateRef CreateArguments(ElementsKind kind, CreateArgumentsAccessor::Mode mode, GateRef restIdx); 458 GateRef Construct(GateRef hirGate, std::vector<GateRef> args); 459 GateRef CallNew(GateRef hirGate, std::vector<GateRef> args, bool needPushArgv = false); 460 GateRef CallInternal(GateRef hirGate, std::vector<GateRef> args, uint64_t pcOffset); 461 GateRef TypedCallNative(GateRef hirGate, GateRef thisObj, GateRef funcId); 462 GateRef IsBase(GateRef ctor); 463 GateRef IsDerived(GateRef ctor); 464 GateRef ToLength(GateRef receiver); 465 GateRef StoreModuleVar(GateRef jsFunc, GateRef index, GateRef value); 466 GateRef LdLocalModuleVar(GateRef jsFunc, GateRef index); 467 GateRef BuiltinConstructor(BuiltinsStubCSigns::ID id, GateRef gate); 468 469 inline GateRef GetMethodId(GateRef func); 470 inline GateRef GetBuiltinsId(GateRef func); 471 inline GateRef IsAOTLiteralInfo(GateRef x); 472 GateRef GetKeyFromLexivalEnv(GateRef lexicalEnv, GateRef levelIndex, GateRef slotIndex); 473 GateRef GetParentEnv(GateRef object); 474 GateRef GetSendableParentEnv(GateRef object); 475 GateRef GetPropertiesFromLexicalEnv(GateRef object, GateRef index); 476 GateRef GetPropertiesFromSendableEnv(GateRef object, GateRef index); 477 GateRef Float32ArrayConstructor(GateRef hirGate, std::vector<GateRef> args); 478 479 // call operation 480 GateRef CallPrivateGetter(GateRef hirGate, GateRef receiver, GateRef accessor, const char* comment = nullptr); 481 GateRef CallPrivateSetter( 482 GateRef hirGate, GateRef receiver, GateRef accessor, GateRef value, const char* comment = nullptr); 483 GateRef CallGetter(GateRef hirGate, GateRef receiver, GateRef holder, 484 GateRef propertyLookupResult, const char* comment = nullptr); 485 GateRef CallSetter(GateRef hirGate, GateRef receiver, GateRef holder, GateRef propertyLookupResult, 486 GateRef value, const char* comment = nullptr); 487 GateRef CallBCHandler(GateRef glue, GateRef target, const std::vector<GateRef> &args, 488 const char* comment = nullptr); 489 GateRef CallBCDebugger(GateRef glue, GateRef target, const std::vector<GateRef> &args, 490 const char* comment = nullptr); 491 GateRef CallBuiltin(GateRef glue, GateRef target, const std::vector<GateRef> &args, 492 GateRef hir = Circuit::NullGate(), 493 const char* comment = nullptr); 494 GateRef CallBuiltinWithArgv(GateRef glue, GateRef target, const std::vector<GateRef> &args, 495 const char* comment = nullptr); 496 GateRef CallRuntimeVarargs(GateRef glue, int index, GateRef argc, GateRef argv, const char* comment = nullptr); 497 GateRef CallRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args, GateRef hirGate, 498 const char* comment = nullptr); 499 GateRef CallNGCRuntime(GateRef glue, GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel); 500 501 GateRef CallNGCRuntime(GateRef glue, int index, GateRef depend, const std::vector<GateRef> &args, 502 GateRef hirGate, const char* comment = nullptr); 503 GateRef FastCallOptimized(GateRef glue, GateRef code, GateRef depend, const std::vector<GateRef> &args, 504 GateRef hirGate); 505 GateRef CallOptimized(GateRef glue, GateRef code, GateRef depend, const std::vector<GateRef> &args, 506 GateRef hirGate); 507 GateRef CallStub(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args, 508 const char* comment = nullptr); 509 GateRef CallCommonStub(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args, 510 const char *comment = nullptr); 511 GateRef CallBuiltinRuntime(GateRef glue, GateRef depend, const std::vector<GateRef> &args, bool isNew = false); 512 GateRef CallBuiltinRuntimeWithNewTarget(GateRef glue, GateRef depend, const std::vector<GateRef> &args); 513 GateRef Call(const CallSignature* cs, GateRef glue, GateRef target, GateRef depend, 514 const std::vector<GateRef> &args, GateRef hirGate, const char* comment = nullptr); 515 GateRef NoLabelCallRuntime(GateRef glue, GateRef depend, size_t index, std::vector<GateRef> &args, GateRef hirGate); 516 517 void StartCallTimer(GateRef glue, GateRef gate, const std::vector<GateRef> &args, bool useLabel); 518 void EndCallTimer(GateRef glue, GateRef gate, const std::vector<GateRef> &args, bool useLabel); 519 GateRef GetCallBuiltinId(GateRef method); 520 521 // FastCall 522 inline GateRef CanFastCall(GateRef jsFunc); 523 524 // Js world 525 inline GateRef GetObjectType(GateRef hClass); 526 inline GateRef HasConstructor(GateRef object); 527 inline GateRef IsSpecial(GateRef x, JSTaggedType type); 528 inline GateRef IsJSFunction(GateRef obj); 529 inline GateRef IsDictionaryMode(GateRef object); 530 inline GateRef IsJsType(GateRef object, JSType type); 531 inline GateRef IsStableElements(GateRef hClass); 532 inline GateRef IsStableArguments(GateRef hClass); 533 inline GateRef IsStableArray(GateRef hClass); 534 inline GateRef IsDictionaryElement(GateRef hClass); 535 inline GateRef IsJSArrayPrototypeModified(GateRef hClass); 536 inline GateRef IsClassConstructor(GateRef object); 537 inline GateRef IsClassConstructorWithBitField(GateRef bitfield); 538 inline GateRef IsConstructor(GateRef object); 539 inline GateRef IsClassPrototype(GateRef object); 540 inline GateRef IsClassPrototypeWithBitField(GateRef object); 541 inline GateRef IsExtensible(GateRef object); 542 inline GateRef IsJSObject(GateRef obj); 543 inline GateRef IsCallable(GateRef obj); 544 inline GateRef IsCallableFromBitField(GateRef bitfield); 545 inline GateRef AlreadyDeopt(GateRef method); 546 inline GateRef AlreadyDeoptFromExtraLiteralInfo(GateRef callfield); 547 inline GateRef IsPrototypeHClass(GateRef hclass); 548 inline GateRef IsJsProxy(GateRef obj); 549 GateRef IsJSHClass(GateRef obj); 550 inline void StoreHClass(GateRef glue, GateRef object, GateRef hClass); 551 inline void StoreHClassWithoutBarrier(GateRef glue, GateRef object, GateRef hClass); 552 inline void StorePrototype(GateRef glue, GateRef hclass, GateRef prototype); 553 void SetExtensibleToBitfield(GateRef glue, GateRef obj, bool isExtensible); 554 555 // WeakRef 556 inline GateRef CreateWeakRef(GateRef x); 557 inline GateRef LoadObjectFromWeakRef(GateRef x); 558 559 // hClass 560 inline GateRef GetElementsKindByHClass(GateRef hClass); 561 inline GateRef GetObjectSizeFromHClass(GateRef hClass); 562 inline GateRef HasConstructorByHClass(GateRef hClass); 563 inline GateRef IsDictionaryModeByHClass(GateRef hClass); 564 inline GateRef LoadHClass(GateRef object); 565 inline GateRef LoadHClassByConstOffset(GateRef object); 566 inline GateRef LoadPrototype(GateRef hclass); 567 inline GateRef LoadPrototypeHClass(GateRef object); 568 inline GateRef LoadPrototypeOfPrototypeHClass(GateRef object); 569 void SetPropertyInlinedProps(GateRef glue, GateRef obj, GateRef hClass, 570 GateRef value, GateRef attrOffset, VariableType type); 571 572 // Others 573 GateRef OrdinaryHasInstance(GateRef obj, GateRef target); 574 GateRef MigrateArrayWithKind(GateRef receiver, GateRef oldElementsKind, GateRef newElementsKind); 575 576 // **************************** Middle IR **************************** 577 GateRef EcmaObjectCheck(GateRef gate); 578 GateRef HeapObjectCheck(GateRef gate, GateRef frameState); 579 GateRef MathHClassConsistencyCheck(GateRef receiver); 580 GateRef HeapObjectIsEcmaObjectCheck(GateRef gate, GateRef frameState); 581 GateRef ProtoChangeMarkerCheck(GateRef gate, GateRef frameState = Gate::InvalidGateRef); 582 GateRef StableArrayCheck(GateRef gate, ElementsKind kind, ArrayMetaDataAccessor::Mode mode); 583 GateRef ElementsKindCheck(GateRef receiver, ElementsKind kind, ArrayMetaDataAccessor::Mode mode); 584 GateRef COWArrayCheck(GateRef gate); 585 GateRef EcmaStringCheck(GateRef gate); 586 GateRef InternStringCheck(GateRef gate); 587 GateRef EcmaMapCheck(GateRef gate); 588 GateRef FlattenTreeStringCheck(GateRef gate); 589 GateRef HClassStableArrayCheck(GateRef gate, GateRef frameState, ArrayMetaDataAccessor accessor); 590 GateRef ArrayGuardianCheck(GateRef frameState); 591 GateRef TypedArrayCheck(GateRef gate, ParamType paramType, TypedArrayMetaDataAccessor::Mode mode, 592 OnHeapMode onHeap = OnHeapMode::NONE); 593 GateRef LoadTypedArrayLength(GateRef gate, ParamType paramType, OnHeapMode onHeap = OnHeapMode::NONE); 594 GateRef RangeGuard(GateRef gate, uint32_t left, uint32_t right); 595 GateRef BuiltinPrototypeHClassCheck(GateRef gate, BuiltinTypeId type, ElementsKind kind, 596 bool isPrototypeOfPrototype); 597 GateRef OrdinaryHasInstanceCheck(GateRef target, GateRef jsFunc, std::vector<GateRef> &expectedHCIndexes); 598 GateRef IndexCheck(GateRef gate, GateRef index); 599 GateRef ObjectTypeCheck(bool isHeapObject, GateRef gate, GateRef hclassIndex, 600 GateRef frameState = Gate::InvalidGateRef); 601 GateRef TryPrimitiveTypeCheck(GateType type, GateRef gate); 602 GateRef CallTargetCheck(GateRef gate, GateRef function, GateRef id, const char* comment = nullptr); 603 GateRef CallTargetCheck(GateRef gate, GateRef function, GateRef id, std::vector<GateRef> params, 604 const char* comment = nullptr); 605 template<TypedCallTargetCheckOp Op> 606 GateRef JSCallTargetTypeCheck(GateRef func, GateRef methodIndex, GateRef gate); 607 template<TypedCallTargetCheckOp Op> 608 inline GateRef JSNoGCCallThisTargetTypeCheck(GateRef func, GateRef methodId, GateRef gate); 609 GateRef CallTargetIsCompiledCheck(GateRef func, GateRef gate); 610 GateRef TypeOfCheck(GateRef gate, ParamType paramType); 611 GateRef TypedTypeOf(ParamType paramType); 612 GateRef TypedCallOperator(GateRef hirGate, MachineType type, const std::vector<GateRef>& inList, bool isSideEffect); 613 inline GateRef TypedCallBuiltin(GateRef hirGate, const std::vector<GateRef> &args, 614 BuiltinsStubCSigns::ID id, bool isSideEffect); 615 GateRef TypeConvert(MachineType type, ParamType typeFrom, GateType typeTo, const std::vector<GateRef>& inList); 616 GateRef Int32CheckRightIsZero(GateRef right); 617 GateRef RemainderIsNegativeZero(GateRef left, GateRef right); 618 GateRef Float64CheckRightIsZero(GateRef right); 619 GateRef ValueCheckNegOverflow(GateRef value); 620 GateRef OverflowCheck(GateRef value); 621 GateRef LexVarIsHoleCheck(GateRef value); 622 GateRef IsUndefinedOrHoleCheck(GateRef value); 623 GateRef IsNotUndefinedOrHoleCheck(GateRef value); 624 GateRef IsDataViewCheck(GateRef obj); 625 GateRef IsCallableCheck(GateRef func, GateRef frameState = Circuit::NullGate()); 626 GateRef Int32UnsignedUpperBoundCheck(GateRef value, GateRef upperBound); 627 GateRef Int32DivWithCheck(GateRef left, GateRef right); 628 GateType GetGateTypeOfValueType(ValueType type); 629 GateRef InsertStableArrayCheck(GateRef array, ArrayMetaDataAccessor accessor); 630 GateRef InsertLoadArrayLength(GateRef array, GateRef length, bool isTypedArray); 631 GateRef InsertTypedArrayCheck(GateRef array, TypedArrayMetaDataAccessor accessor); 632 GateRef ArrayConstructorCheck(GateRef gate); 633 GateRef Float32ArrayConstructorCheck(GateRef gate); 634 GateRef ObjectConstructorCheck(GateRef gate); 635 GateRef BooleanConstructorCheck(GateRef gate); 636 GateRef InsertTypedBinaryop(GateRef left, GateRef right, TypedBinOp op); 637 GateRef InsertRangeCheckPredicate(GateRef left, TypedBinOp cond, GateRef right); 638 GateRef TypedConditionJump(MachineType type, TypedJumpOp jumpOp, uint32_t weight, ParamType paramType, 639 const std::vector<GateRef>& inList); 640 GateRef TypedNewAllocateThis(GateRef ctor, GateRef hclass, GateRef size, GateRef frameState); 641 GateRef TypedSuperAllocateThis(GateRef superCtor, GateRef newTarget, GateRef frameState); 642 template<TypedBinOp Op> 643 inline GateRef TypedBinaryOp(GateRef x, GateRef y, ParamType paramType); 644 template<TypedUnOp Op> 645 inline GateRef TypedUnaryOp(GateRef x, ParamType paramType); 646 template<TypedJumpOp Op> 647 inline GateRef TypedConditionJump(GateRef x, ParamType paramType, uint32_t weight); 648 GateRef Convert(GateRef gate, ValueType src, ValueType dst); 649 GateRef ConvertBoolToTaggedBoolean(GateRef gate); 650 GateRef ConvertTaggedBooleanToBool(GateRef gate); 651 GateRef ConvertInt32ToBool(GateRef gate); 652 GateRef ConvertFloat64ToBool(GateRef gate); 653 GateRef ConvertInt32ToTaggedInt(GateRef gate); 654 GateRef ConvertFloat64ToTaggedDouble(GateRef gate); 655 GateRef ConvertFloat64ToInt32(GateRef gate); 656 GateRef ConvertInt32ToFloat64(GateRef gate); 657 GateRef ConvertBoolToInt32(GateRef gate, ConvertSupport support); 658 GateRef ConvertBoolToFloat64(GateRef gate, ConvertSupport support); 659 GateRef ConvertUInt32ToBool(GateRef gate); 660 GateRef ConvertUInt32ToTaggedNumber(GateRef gate); 661 GateRef ConvertUInt32ToFloat64(GateRef gate); 662 GateRef ConvertCharToEcmaString(GateRef gate); 663 GateRef ConvertCharToInt32(GateRef gate); 664 GateRef ConvertCharToDouble(GateRef gate); 665 GateRef CheckAndConvert( 666 GateRef gate, ValueType src, ValueType dst, ConvertSupport support = ConvertSupport::ENABLE); 667 GateRef ConvertHoleAsUndefined(GateRef receiver); 668 GateRef ConvertSpecialHoleIntToTagged(GateRef gate); 669 GateRef ConvertSpecialHoleDoubleToTagged(GateRef gate); 670 GateRef CheckSpecialHoleAndConvertToTaggedInt(GateRef receiver); 671 GateRef CheckSpecialHoleAndConvertToTaggedDouble(GateRef receiver); 672 GateRef CheckUInt32AndConvertToInt32(GateRef gate); 673 GateRef CheckTaggedIntAndConvertToInt32(GateRef gate); 674 GateRef CheckTaggedDoubleAndConvertToInt32(GateRef gate); 675 GateRef CheckTaggedNumberAndConvertToInt32(GateRef gate); 676 GateRef CheckTaggedIntAndConvertToFloat64(GateRef gate); 677 GateRef CheckTaggedDoubleAndConvertToFloat64(GateRef gate); 678 GateRef CheckTaggedNumberAndConvertToFloat64(GateRef gate); 679 GateRef CheckTaggedNumberAndConvertToBool(GateRef gate); 680 GateRef CheckTaggedBooleanAndConvertToBool(GateRef gate); 681 GateRef CheckNullAndConvertToInt32(GateRef gate); 682 GateRef CheckTaggedBooleanAndConvertToInt32(GateRef gate); 683 GateRef CheckHoleIntAndConvertToTaggedInt(GateRef gate); 684 GateRef CheckHoleDoubleAndConvertToTaggedDouble(GateRef gate); 685 GateRef CheckNullAndConvertToFloat64(GateRef gate); 686 GateRef CheckTaggedBooleanAndConvertToFloat64(GateRef gate); 687 GateRef CheckUndefinedAndConvertToFloat64(GateRef gate); 688 GateRef CheckUndefinedAndConvertToBool(GateRef gate); 689 GateRef CheckNullAndConvertToBool(GateRef gate); 690 GateRef CheckUndefinedAndConvertToInt32(GateRef gate); 691 GateRef CheckHoleIntAndConvertToInt32(GateRef gate); 692 GateRef CheckHoleDoubleAndConvertToInt32(GateRef gate); 693 GateRef CheckHoleIntAndConvertToFloat64(GateRef gate); 694 GateRef CheckHoleDoubleAndConvertToFloat64(GateRef gate); 695 GateRef CheckFloat64ConvertToInt32Legally(GateRef gate); 696 GateRef StartAllocate(); 697 GateRef FinishAllocate(GateRef value); 698 699 inline GateRef PrimitiveToNumber(GateRef x, ParamType paramType); 700 inline GateRef GetValueFromTaggedArray(GateRef array, GateRef index); 701 inline GateRef GetValueFromTaggedArray(VariableType valType, GateRef array, GateRef index); 702 inline GateRef GetValueFromJSArrayWithElementsKind(VariableType type, GateRef array, GateRef index); 703 template<TypedLoadOp Op> 704 GateRef LoadElement(GateRef receiver, GateRef index, OnHeapMode onHeap = OnHeapMode::NONE); 705 GateRef LoadProperty(GateRef receiver, GateRef propertyLookupResult, bool isFunction); 706 GateRef LoadArrayLength(GateRef gate, ElementsKind kind, ArrayMetaDataAccessor::Mode mode); 707 inline GateRef LoadFromTaggedArray(GateRef array, size_t index); 708 GateRef LoadStringLength(GateRef string); 709 GateRef LoadMapSize(GateRef string); 710 GateRef LoadConstOffset(VariableType type, GateRef receiver, size_t offset, 711 MemoryAttribute mAttr = MemoryAttribute::Default()); 712 GateRef LoadHClassFromConstpool(GateRef constpool, size_t index); 713 GateRef TypedCall(GateRef hirGate, std::vector<GateRef> args, bool isNoGC); 714 GateRef TypedFastCall(GateRef hirGate, std::vector<GateRef> args, bool isNoGC); 715 inline void SetValueToTaggedArray(VariableType valType, GateRef glue, GateRef array, GateRef index, GateRef val); 716 GateRef StoreConstOffset(VariableType type, GateRef receiver, size_t offset, GateRef value, 717 MemoryAttribute mAttr = MemoryAttribute::Default()); 718 inline GateRef StoreToTaggedArray(GateRef array, size_t index, GateRef value); 719 GateRef StringEqual(GateRef x, GateRef y); 720 GateRef StringAdd(GateRef x, GateRef y, uint32_t stringStatus = 0); 721 template<TypedStoreOp Op> 722 GateRef StoreElement(GateRef receiver, GateRef index, GateRef value, OnHeapMode onHeap = OnHeapMode::NONE); 723 GateRef StoreMemory(MemoryType Op, VariableType type, GateRef receiver, GateRef index, GateRef value); 724 GateRef StoreProperty(GateRef receiver, GateRef propertyLookupResult, GateRef value, uint32_t receiverHClassIndex); 725 inline GateRef JudgeAotAndFastCall(GateRef jsFunc, JudgeMethodType type); 726 GateRef ComputeTaggedArraySize(GateRef length); 727 GateRef HeapAlloc(GateRef glue, GateRef size, GateType type, RegionSpaceFlag flag); 728 GateRef TaggedIsHeapObjectOp(GateRef value); 729 GateRef IsSpecificObjectType(GateRef obj, JSType type); 730 GateRef IsMarkerCellValid(GateRef cell); 731 GateRef IsMarkerCellValidOp(GateRef cell); 732 GateRef MonoLoadPropertyOnProto(GateRef receiver, GateRef plrGate, GateRef jsFunc, size_t hclassIndex); 733 GateRef MonoCallGetterOnProto(GateRef gate, GateRef receiver, GateRef plrGate, GateRef jsFunc, size_t hclassIndex); 734 GateRef MonoStorePropertyLookUpProto(GateRef receiver, GateRef plrGate, GateRef jsFunc, size_t hclassIndex, 735 GateRef value); 736 GateRef MonoStoreProperty(GateRef receiver, GateRef plrGate, GateRef jsFunc, size_t hclassIndex, 737 GateRef value, GateRef keyIndex, GateRef isProto, GateRef frameState); 738 GateRef TypedCreateObjWithBuffer(std::vector<GateRef> &valueIn); 739 template<TypedLoadOp Op> 740 GateRef ConvertJSArrayHoleAsUndefined(GateRef receiver); 741 GateRef BuildBigIntAsIntN(const GateMetaData* op, std::vector<GateRef> &&args); 742 GateRef NewJSPrimitiveRef(GateRef glue, size_t index, GateRef obj); 743 GateRef ToObject(GateRef glue, GateRef obj); 744 GateRef GetPrototype(GateRef glue, GateRef object); 745 746 GateRef GetGlobalConstantValue(VariableType type, GateRef glue, ConstantIndex index); 747 GateRef TransProtoWithoutLayout(GateRef glue, GateRef hClass, GateRef proto); 748 GateRef OrdinaryNewJSObjectCreate(GateRef glue, GateRef proto); 749 750 // bit operation 751 inline GateRef TaggedIsInt(GateRef x); 752 inline GateRef TaggedIsDouble(GateRef x); 753 inline GateRef TaggedIsObject(GateRef x); 754 inline GateRef TaggedIsNumber(GateRef x); 755 inline GateRef TaggedIsNumeric(GateRef x); 756 inline GateRef TaggedIsNotHole(GateRef x); 757 inline GateRef TaggedIsHole(GateRef x); 758 inline GateRef TaggedIsNullPtr(GateRef x); 759 inline GateRef TaggedIsUndefined(GateRef x); 760 inline GateRef TaggedIsException(GateRef x); 761 inline GateRef TaggedIsSpecial(GateRef x); 762 inline GateRef TaggedIsHeapObject(GateRef x); 763 inline GateRef TaggedIsArrayIterator(GateRef obj); 764 inline GateRef TaggedIsAsyncGeneratorObject(GateRef x); 765 inline GateRef TaggedIsJSGlobalObject(GateRef x); 766 inline GateRef TaggedIsGeneratorObject(GateRef x); 767 inline GateRef TaggedIsJSArray(GateRef x); 768 inline GateRef TaggedIsPropertyBox(GateRef x); 769 inline GateRef TaggedIsWeak(GateRef x); 770 inline GateRef TaggedIsPrototypeHandler(GateRef x); 771 inline GateRef TaggedIsTransitionHandler(GateRef x); 772 inline GateRef TaggedIsStoreAOTHandler(GateRef x); 773 inline GateRef TaggedIsTransWithProtoHandler(GateRef x); 774 inline GateRef TaggedIsUndefinedOrNull(GateRef x); 775 inline GateRef TaggedIsUndefinedOrNullOrHole(GateRef x); 776 inline GateRef TaggedIsNotUndefinedAndNullAndHole(GateRef x); 777 inline GateRef TaggedIsNotUndefinedAndNull(GateRef x); 778 inline GateRef TaggedIsUndefinedOrHole(GateRef x); 779 inline GateRef TaggedIsTrue(GateRef x); 780 inline GateRef TaggedIsFalse(GateRef x); 781 inline GateRef TaggedIsNull(GateRef x); 782 inline GateRef TaggedIsNotNull(GateRef x); 783 inline GateRef TaggedIsBoolean(GateRef x); 784 inline GateRef TaggedIsNativePointer(GateRef x); 785 inline GateRef TaggedIsBigInt(GateRef obj); 786 inline GateRef TaggedIsString(GateRef obj); 787 inline GateRef TaggedIsStringIterator(GateRef obj); 788 inline GateRef TaggedIsSharedObj(GateRef obj); 789 inline GateRef TaggedIsStableArray(GateRef glue, GateRef obj); 790 inline GateRef TaggedIsStringOrSymbol(GateRef obj); 791 inline GateRef TaggedIsSymbol(GateRef obj); 792 inline GateRef TaggedIsProtoChangeMarker(GateRef obj); 793 inline GateRef TaggedObjectIsJSMap(GateRef obj); 794 inline GateRef TaggedObjectIsJSSet(GateRef obj); 795 inline GateRef TaggedObjectIsJSDate(GateRef obj); 796 inline GateRef TaggedObjectIsTypedArray(GateRef obj); 797 inline GateRef TaggedObjectIsJSArray(GateRef obj); 798 inline GateRef TaggedIsBoundFunction(GateRef obj); 799 inline GateRef TaggedGetInt(GateRef x); 800 inline GateRef TaggedObjectIsString(GateRef obj); 801 inline GateRef TaggedObjectIsShared(GateRef obj); 802 inline GateRef TaggedObjectIsEcmaObject(GateRef obj); 803 inline GateRef TaggedObjectIsByteArray(GateRef obj); 804 inline GateRef TaggedObjectIsMap(GateRef obj); 805 inline GateRef TaggedObjectIsDataView(GateRef obj); 806 inline GateRef IsSpecialHole(GateRef x); 807 inline GateRef IsNotSpecialHole(GateRef x); 808 inline GateRef TaggedTrue(); 809 inline GateRef TaggedFalse(); 810 811 // String 812 inline GateRef BothAreString(GateRef x, GateRef y); 813 inline GateRef IsTreeString(GateRef obj); 814 inline GateRef IsSlicedString(GateRef obj); 815 inline GateRef IsSpecialSlicedString(GateRef obj); 816 inline GateRef IsLineString(GateRef obj); 817 inline GateRef IsConstantString(GateRef obj); 818 inline GateRef TreeStringIsFlat(GateRef string); 819 inline GateRef GetFirstFromTreeString(GateRef string); 820 inline GateRef GetSecondFromTreeString(GateRef string); 821 inline GateRef ComputeSizeUtf8(GateRef length); 822 inline GateRef ComputeSizeUtf16(GateRef length); 823 inline GateRef AlignUp(GateRef x, GateRef alignment); 824 GateRef NumberToString(GateRef number); 825 GateRef TaggedPointerToInt64(GateRef x); 826 GateRef GetLengthFromString(GateRef value); 827 GateRef Rotl(GateRef word, uint32_t shift); 828 GateRef CalcHashcodeForInt(GateRef value); 829 GateRef GetHashcodeFromString(GateRef glue, GateRef value, GateRef hir = Circuit::NullGate()); 830 GateRef TryGetHashcodeFromString(GateRef string); 831 GateRef IsIntegerString(GateRef string); 832 GateRef IsLiteralString(GateRef string); 833 GateRef CanBeConcat(GateRef leftString, GateRef rightString, GateRef isValidOpt); 834 GateRef CanBackStore(GateRef rightString, GateRef isValidOpt); 835 GateRef GetRawHashFromString(GateRef value); 836 GateRef GetStringDataFromLineOrConstantString(GateRef str); 837 void CopyUtf8AsUtf16(GateRef glue, GateRef dst, GateRef src, GateRef sourceLength); 838 void CopyChars(GateRef glue, GateRef dst, GateRef source, GateRef sourceLength, 839 GateRef charSize, VariableType type); 840 void SetRawHashcode(GateRef glue, GateRef str, GateRef rawHashcode, GateRef isInteger); 841 GateRef StringFromSingleCharCode(GateRef gate); 842 GateRef StringCharCodeAt(GateRef thisValue, GateRef posTag); 843 GateRef StringSubstring(std::vector<GateRef>& args); 844 GateRef StringSubStr(GateRef thisValue, GateRef intStart, GateRef lengthTag); 845 GateRef StringSlice(std::vector<GateRef>& args); 846 GateRef NumberIsNaN(GateRef gate); 847 GateRef NumberParseFloat(GateRef gate, GateRef frameState); 848 GateRef NumberParseInt(GateRef gate, GateRef radix); 849 GateRef NumberIsFinite(GateRef gate); 850 GateRef NumberIsInteger(GateRef gate); 851 GateRef NumberIsSafeInteger(GateRef gate); 852 GateRef ArrayBufferIsView(GateRef gate); 853 GateRef DataViewGet( 854 GateRef thisobj, GateRef index, GateRef dataViewCallID, GateRef isLittleEndian, GateRef frameState); 855 GateRef DataViewSet(GateRef thisobj, 856 GateRef index, 857 GateRef value, 858 GateRef dataViewCallID, 859 GateRef isLittleEndian, 860 GateRef frameState); 861 GateRef ArrayIncludesIndexOf( 862 GateRef elements, GateRef target, GateRef fromIndex, GateRef len, GateRef CallID, GateRef ArrayKind); 863 GateRef ArrayIteratorBuiltin(GateRef thisArray, GateRef callID); 864 GateRef ArrayForEach(GateRef thisValue, GateRef callBackFn, GateRef usingThis, uint32_t pcOffset); 865 GateRef ArraySort(GateRef thisValue, GateRef callBackFn); 866 GateRef ArrayFilter( 867 GateRef thisValue, GateRef callBackFn, GateRef usingThis, GateRef frameState, uint32_t pcOffset); 868 GateRef ArrayMap(GateRef thisValue, GateRef callBackFn, GateRef usingThis, GateRef frameState, uint32_t pcOffset); 869 GateRef ArraySome(GateRef thisValue, GateRef callBackFn, GateRef usingThis, uint32_t pcOffset); 870 GateRef ArrayFindOrFindIndex( 871 GateRef thisValue, GateRef callBackFn, GateRef usingThis, GateRef callIDRef, uint32_t pcOffset); 872 GateRef ArrayEvery(GateRef thisValue, GateRef callBackFn, GateRef usingThis, uint32_t pcOffset); 873 GateRef ArrayPop(GateRef thisValue, GateRef frameState); 874 GateRef ArrayPush(GateRef thisValue, GateRef value); 875 GateRef ArraySlice(GateRef thisValue, GateRef startIndex, GateRef endIndex, GateRef frameState); 876 GateRef ToNumber(GateRef gate, GateRef value, GateRef glue); 877 GateRef StringToNumber(GateRef gate, GateRef value, GateRef radix, GateRef glue); 878 GateRef IsASCIICharacter(GateRef gate); 879 880 // for in 881 GateRef GetEnumCacheKind(GateRef glue, GateRef enumCache); 882 GateRef IsEnumCacheValid(GateRef receiver, GateRef cachedHclass, GateRef kind); 883 GateRef NeedCheckProperty(GateRef receiver); 884 885 // ElementsKind Array 886 GateRef MigrateFromRawValueToHeapValues(GateRef object, GateRef needCOW, GateRef isIntKind); 887 GateRef MigrateFromHeapValueToRawValue(GateRef object, GateRef needCOW, GateRef isIntKind); 888 GateRef MigrateFromHoleIntToHoleNumber(GateRef object); 889 GateRef MigrateFromHoleNumberToHoleInt(GateRef object); 890 891 // **************************** Low IR ******************************* 892 inline GateRef Equal(GateRef x, GateRef y, const char* comment = nullptr); 893 inline GateRef NotEqual(GateRef x, GateRef y, const char* comment = nullptr); 894 inline GateRef IntPtrAdd(GateRef x, GateRef y); 895 inline GateRef IntPtrSub(GateRef x, GateRef y); 896 inline GateRef IntPtrMul(GateRef x, GateRef y); 897 inline GateRef IntPtrDiv(GateRef x, GateRef y); 898 inline GateRef IntPtrOr(GateRef x, GateRef y); 899 inline GateRef IntPtrLSL(GateRef x, GateRef y); 900 inline GateRef IntPtrLSR(GateRef x, GateRef y); 901 inline GateRef Int64NotEqual(GateRef x, GateRef y); 902 inline GateRef Int32NotEqual(GateRef x, GateRef y); 903 inline GateRef Int64Equal(GateRef x, GateRef y); 904 inline GateRef Int8Equal(GateRef x, GateRef y); 905 inline GateRef Int32Equal(GateRef x, GateRef y); 906 inline GateRef IntPtrLessThan(GateRef x, GateRef y); 907 inline GateRef IntPtrLessThanOrEqual(GateRef x, GateRef y); 908 inline GateRef IntPtrGreaterThan(GateRef x, GateRef y); 909 inline GateRef IntPtrGreaterThanOrEqual(GateRef x, GateRef y); 910 inline GateRef IntPtrAnd(GateRef x, GateRef y); 911 inline GateRef IntPtrNot(GateRef x); 912 inline GateRef IntPtrEqual(GateRef x, GateRef y); 913 GateRef DoubleTrunc(GateRef gate, GateRef value, const char* comment = nullptr); 914 GateRef AddWithOverflow(GateRef left, GateRef right); 915 GateRef SubWithOverflow(GateRef left, GateRef right); 916 GateRef MulWithOverflow(GateRef left, GateRef right); 917 GateRef ExtractValue(MachineType mt, GateRef pointer, GateRef index); 918 GateRef Sqrt(GateRef param); 919 MachineType GetMachineTypeOfValueType(ValueType type); 920 GateRef Alloca(size_t size); 921 GateRef ReadSp(); 922 GateRef BinaryArithmetic(const GateMetaData* meta, MachineType machineType, GateRef left, 923 GateRef right, GateType gateType = GateType::Empty(), const char* comment = nullptr); 924 GateRef BinaryCmp(const GateMetaData* meta, GateRef left, GateRef right, const char* comment = nullptr); 925 GateRef Load(VariableType type, GateRef base, GateRef offset, MemoryAttribute mAttr = MemoryAttribute::Default()); 926 GateRef Load(VariableType type, GateRef base, GateRef offset, GateRef depend, 927 MemoryAttribute mAttr = MemoryAttribute::Default()); 928 GateRef Load(VariableType type, GateRef addr, MemoryAttribute mAttr = MemoryAttribute::Default()); 929 void Store(VariableType type, GateRef glue, GateRef base, GateRef offset, GateRef value, 930 MemoryAttribute mAttr = MemoryAttribute::Default()); 931 void StoreWithoutBarrier(VariableType type, GateRef addr, GateRef value, 932 MemoryAttribute mAttr = MemoryAttribute::Default()); 933 GateRef ThreeInt64Min(GateRef first, GateRef second, GateRef third); 934 935 // cast operation 936 inline GateRef Int16ToBigEndianInt16(GateRef x); 937 inline GateRef Int32ToBigEndianInt32(GateRef x); 938 inline GateRef Int64ToBigEndianInt64(GateRef x); 939 inline GateRef GetInt64OfTInt(GateRef x); 940 inline GateRef GetInt32OfTInt(GateRef x); 941 inline GateRef GetInt32OfTNumber(GateRef x); 942 inline GateRef TaggedCastToIntPtr(GateRef x); 943 inline GateRef GetDoubleOfTInt(GateRef x); 944 inline GateRef GetDoubleOfTDouble(GateRef x); 945 inline GateRef GetBooleanOfTBoolean(GateRef x); 946 GateRef GetDoubleOfTNumber(GateRef x); 947 GateRef TruncDoubleToInt(GateRef glue, GateRef x, size_t typeBits); 948 GateRef DoubleToIntOverflowCheck(GateRef x, size_t typeBits); 949 GateRef SaturateTruncDoubleToInt32(GateRef glue, GateRef x); 950 GateRef DoubleCheckINFInRangeInt32(GateRef x); 951 GateRef DoubleInRangeInt32(GateRef x); 952 inline GateRef Int32ToTaggedPtr(GateRef x); 953 inline GateRef Int64ToTaggedPtr(GateRef x); 954 inline GateRef Int32ToTaggedInt(GateRef x); 955 inline GateRef ToTaggedInt(GateRef x); 956 inline GateRef ToTaggedIntPtr(GateRef x); 957 inline GateRef DoubleToTaggedDoublePtr(GateRef x); 958 inline GateRef DoubleIsImpureNaN(GateRef x); 959 inline GateRef BooleanToTaggedBooleanPtr(GateRef x); 960 inline GateRef BooleanToInt32(GateRef x); 961 inline GateRef BooleanToFloat64(GateRef x); 962 inline GateRef Float32ToTaggedDoublePtr(GateRef x); 963 inline GateRef TaggedDoublePtrToFloat32(GateRef x); 964 inline GateRef TaggedIntPtrToFloat32(GateRef x); 965 inline GateRef DoubleToTaggedDouble(GateRef x); 966 inline GateRef DoubleToTagged(GateRef x); 967 inline GateRef DoubleIsNAN(GateRef x); 968 inline GateRef DoubleIsINF(GateRef x); 969 inline GateRef DoubleIsNanOrInf(GateRef x); 970 GateRef DoubleIsWithinInt32(GateRef x); 971 static MachineType GetMachineTypeFromVariableType(VariableType type); 972 GateRef FastToBoolean(GateRef value); 973 974 // Opcode with control and depend inputs from label and value inputs args 975 GateRef BuildControlDependOp(const GateMetaData* op, std::vector<GateRef> args, 976 std::vector<GateRef> frameStates = {}); 977 template<OpCode Op, MachineType Type> 978 inline GateRef BinaryOp(GateRef x, GateRef y); 979 template<OpCode Op, MachineType Type> 980 inline GateRef BinaryOpWithOverflow(GateRef x, GateRef y); 981 982 GateRef BuildTypedArrayIterator(GateRef gate, const GateMetaData* op); 983 GateRef IsStableArrayLengthWriteable(GateRef array); 984 985 #define ARITHMETIC_BINARY_OP_WITH_BITWIDTH(NAME, OPCODEID, MACHINETYPEID) \ 986 inline GateRef NAME(GateRef x, GateRef y, GateType type = GateType::Empty(), const char* comment = nullptr) \ 987 { \ 988 return BinaryArithmetic(circuit_->OPCODEID(), MACHINETYPEID, x, y, type, comment); \ 989 } 990 991 BINARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(ARITHMETIC_BINARY_OP_WITH_BITWIDTH) 992 #undef ARITHMETIC_BINARY_OP_WITH_BITWIDTH 993 994 #define ARITHMETIC_UNARY_OP_WITH_BITWIDTH(NAME, OPCODEID, MACHINETYPEID) \ 995 inline GateRef NAME(GateRef x, const char* comment = nullptr) \ 996 { \ 997 return circuit_->NewGate(circuit_->OPCODEID(), MACHINETYPEID, { x }, GateType::NJSValue(), comment); \ 998 } 999 1000 UNARY_ARITHMETIC_METHOD_LIST_WITH_BITWIDTH(ARITHMETIC_UNARY_OP_WITH_BITWIDTH) 1001 #undef ARITHMETIC_UNARY_OP_WITH_BITWIDTH 1002 1003 #define CMP_BINARY_OP_WITHOUT_BITWIDTH(NAME, OPCODEID, CONDITION) \ 1004 inline GateRef NAME(GateRef x, GateRef y, const char* comment = nullptr) \ 1005 { \ 1006 return BinaryCmp(circuit_->OPCODEID(static_cast<uint64_t>(CONDITION)), x, y, comment); \ 1007 } 1008 1009 BINARY_CMP_METHOD_LIST_WITHOUT_BITWIDTH(CMP_BINARY_OP_WITHOUT_BITWIDTH) 1010 #undef CMP_BINARY_OP_WITHOUT_BITWIDTH 1011 1012 private: 1013 1014 std::vector<GateRef> ConcatParams(const std::vector<std::vector<GateRef>>& params); 1015 static constexpr uint32_t GATE_TWO_VALUESIN = 2; 1016 1017 inline void SetDepend(GateRef depend); 1018 inline void SetState(GateRef state); 1019 1020 template <class LabelPtrGetter> 1021 void SwitchGeneric(GateRef index, Label *defaultLabel, Span<const int64_t> keysValue, 1022 LabelPtrGetter getIthLabelFn); 1023 1024 #define ARITHMETIC_UNARY_OP_WITH_BITWIDTH(NAME, OPCODEID, MACHINETYPEID) \ 1025 inline GateRef NAME(GateRef x, const char* comment = nullptr) \ 1026 { \ 1027 return circuit_->NewGate(circuit_->OPCODEID(), MACHINETYPEID, { x }, GateType::NJSValue(), comment); \ 1028 } 1029 1030 #undef ARITHMETIC_UNARY_OP_WITH_BITWIDTH 1031 1032 Circuit *circuit_ {nullptr}; 1033 GateAccessor acc_; 1034 Environment *env_ {nullptr}; 1035 CompilationConfig *cmpCfg_ {nullptr}; 1036 friend StubBuilder; 1037 friend BuiltinsStringStubBuilder; 1038 friend BuiltinsTypedArrayStubBuilder; 1039 friend TypedBytecodeLowering; 1040 friend NTypeBytecodeLowering; 1041 friend PGOHCRLowering; 1042 friend TSHCRLowering; 1043 friend NTypeHCRLowering; 1044 friend SlowPathLowering; 1045 friend NativeInlineLowering; 1046 friend TypedHCRLowering; 1047 friend TypedNativeInlineLowering; 1048 friend PostSchedule; 1049 friend TSHCROptPass; 1050 friend BuiltinLowering; 1051 }; 1052 1053 class LogicAndBuilder { 1054 public: 1055 inline LogicAndBuilder(Environment *env); 1056 inline ~LogicAndBuilder(); 1057 NO_MOVE_SEMANTIC(LogicAndBuilder); 1058 NO_COPY_SEMANTIC(LogicAndBuilder); 1059 1060 inline LogicAndBuilder &And(GateRef check); 1061 1062 inline GateRef Done(); 1063 private: 1064 Environment *env_ {nullptr}; 1065 CircuitBuilder *builder_ {nullptr}; 1066 Label *subentry_ {nullptr}; 1067 Variable *result_ {nullptr}; 1068 Label *exit_ {nullptr}; 1069 std::vector<Label*> labels_; 1070 }; 1071 1072 class LogicOrBuilder { 1073 public: 1074 inline LogicOrBuilder(Environment *env); 1075 inline ~LogicOrBuilder(); 1076 NO_MOVE_SEMANTIC(LogicOrBuilder); 1077 NO_COPY_SEMANTIC(LogicOrBuilder); 1078 1079 inline LogicOrBuilder &Or(GateRef check); 1080 1081 inline GateRef Done(); 1082 private: 1083 Environment *env_ {nullptr}; 1084 CircuitBuilder *builder_ {nullptr}; 1085 Label *subentry_ {nullptr}; 1086 Variable *result_ {nullptr}; 1087 Label *exit_ {nullptr}; 1088 std::vector<Label*> labels_; 1089 }; 1090 } // namespace panda::ecmascript::kungfu 1091 1092 #endif // ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_H 1093