45 operation_typer_(
broker, zone()),
46 tick_counter_(tick_counter) {
66 if (node->op()->ValueOutputCount() == 0)
return NoChange();
71 switch (node->opcode()) {
72#define DECLARE_UNARY_CASE(x, ...) \
73 case IrOpcode::k##x: \
74 return Type##x(Operand(node, 0));
81#undef DECLARE_UNARY_CASE
82#define DECLARE_BINARY_CASE(x, ...) \
83 case IrOpcode::k##x: \
84 return Type##x(Operand(node, 0), Operand(node, 1));
91#undef DECLARE_BINARY_CASE
92#define DECLARE_OTHER_CASE(x, ...) \
93 case IrOpcode::k##x: \
103#undef DECLARE_OTHER_CASE
104#define DECLARE_IMPOSSIBLE_CASE(x, ...) case IrOpcode::k##x:
269#undef DECLARE_IMPOSSIBLE_CASE
284#define DECLARE_METHOD(x, ...) inline Type Type##x(Node* node);
294#define DECLARE_METHOD(x, ...) inline Type Type##x(Type input);
357#define DECLARE_METHOD(Name) \
358 static Type Name(Type type, Typer* t) { \
359 return t->operation_typer_.Name(type); \
367#define DECLARE_METHOD(Name) \
368 static Type Name(Type lhs, Type rhs, Typer* t) { \
369 return t->operation_typer_.Name(lhs, rhs); \
377#define DECLARE_METHOD(Name, ...) \
378 inline Type Type##Name(Type left, Type right) { \
379 return TypeBinaryOp(left, right, Name##Typer); \
383#define DECLARE_METHOD(Name, ...) \
384 inline Type Type##Name(Type left, Type right) { \
385 return TypeBinaryOp(left, right, Name); \
393#define DECLARE_METHOD(Name, ...) \
394 inline Type Type##Name(Type input) { return TypeUnaryOp(input, Name); }
421#define DECLARE_METHOD(x, ...) static Type x##Typer(Type, Type, Typer*);
441 if (node->opcode() == IrOpcode::kPhi ||
442 node->opcode() == IrOpcode::kInductionVariablePhi) {
449 std::ostringstream ostream;
450 node->Print(ostream);
451 FATAL(
"UpdateType error for node %s", ostream.str().c_str());
472 if (induction_vars !=
nullptr) {
475 Visitor visitor(
this, induction_vars);
477 graph_reducer.AddReducer(&visitor);
478 for (Node*
const root : roots) graph_reducer.ReduceNode(root);
479 graph_reducer.ReduceGraph();
481 if (induction_vars !=
nullptr) {
484 InductionVariable* induction_var = entry.second;
485 if (induction_var->phi()->opcode() == IrOpcode::kInductionVariablePhi) {
486 CHECK(visitor.InductionVariablePhiTypeIsPrefixedPoint(induction_var));
495 if (node->op()->ValueOutputCount() > 0) {
519 return TypeUnaryOp(input, f);
529 return TypeBinaryOp(left, right, f);
534 : f(left, right, typer_);
539 lhs = ToNumeric(lhs, t);
540 rhs = ToNumeric(rhs, t);
543 bool lhs_is_number = lhs.
Is(Type::Number());
544 bool rhs_is_number = rhs.
Is(Type::Number());
545 if (lhs_is_number && rhs_is_number) {
546 return f(lhs, rhs, t);
551 return Type::Number();
553 if (lhs.
Is(Type::BigInt())) {
554 return Type::BigInt();
556 return Type::Numeric();
562 if ((outcome & kComparisonUndefined) != 0)
result |= kComparisonUndefined;
563 if ((outcome & kComparisonTrue) != 0)
result |= kComparisonFalse;
564 if ((outcome & kComparisonFalse) != 0)
result |= kComparisonTrue;
570 if ((outcome & kComparisonFalse) != 0 ||
571 (outcome & kComparisonUndefined) != 0) {
572 return (outcome & kComparisonTrue) != 0 ? Type::Boolean()
573 : t->singleton_false_;
576 return t->singleton_true_;
580 type = ToNumeric(type, t);
581 if (type.Is(Type::Number())) {
582 return NumberBitwiseXor(type, t->cache_->kSingletonMinusOne, t);
584 if (type.Is(Type::BigInt())) {
585 return Type::BigInt();
587 return Type::Numeric();
591 type = ToNumeric(type, t);
592 if (type.Is(Type::Number())) {
593 return NumberSubtract(type, t->cache_->kSingletonOne, t);
595 if (type.Is(Type::BigInt())) {
596 return Type::BigInt();
598 return Type::Numeric();
602 type = ToNumeric(type, t);
603 if (type.Is(Type::Number())) {
604 return NumberAdd(type, t->cache_->kSingletonOne, t);
606 if (type.Is(Type::BigInt())) {
607 return Type::BigInt();
609 return Type::Numeric();
613 type = ToNumeric(type, t);
614 if (type.Is(Type::Number())) {
615 return NumberMultiply(type, t->cache_->kSingletonMinusOne, t);
617 if (type.Is(Type::BigInt())) {
618 return Type::BigInt();
620 return Type::Numeric();
626 if (type.Is(Type::Primitive()) && !type.Maybe(Type::Receiver())) {
629 return Type::Primitive();
633 return t->operation_typer()->ToBoolean(type);
640 if (type.Is(t->cache_->kInteger))
return type;
641 if (type.Is(t->cache_->kIntegerOrMinusZeroOrNaN)) {
643 t->cache_->kSingletonZero, t->zone());
645 return t->cache_->kInteger;
651 type = ToInteger(type, t);
652 if (type.IsNone())
return type;
653 double min = type.Min();
654 double max = type.Max();
661 if (min <= 0.0) min = 0.0;
669 type = ToPrimitive(type, t);
670 if (type.Is(Type::Name()))
return type;
671 if (type.Maybe(Type::Symbol()))
return Type::Name();
677 return t->operation_typer_.ToNumber(type);
682 return t->operation_typer_.ToNumberConvertBigInt(type);
687 return t->operation_typer_.ToBigInt(type);
692 return t->operation_typer_.ToBigIntConvertNumber(type);
697 return t->operation_typer_.ToNumeric(type);
703 if (type.Is(Type::Receiver()))
return type;
704 if (type.Is(Type::Primitive()))
return Type::StringWrapperOrOtherObject();
705 if (!type.Maybe(Type::OtherUndetectable())) {
706 return Type::DetectableReceiver();
708 return Type::Receiver();
714 type = ToPrimitive(type, t);
715 if (type.Is(Type::String()))
return type;
716 return Type::String();
723 CHECK(!type.IsNone());
724 if (type.Is(Type::TypedArray()))
return t->singleton_true_;
725 if (!type.Maybe(Type::TypedArray()) && !type.Maybe(Type::OtherObject())) {
726 return t->singleton_false_;
728 return Type::Boolean();
732 CHECK(!type.IsNone());
733 if (type.Is(Type::BigInt()))
return t->singleton_true_;
734 if (!type.Maybe(Type::BigInt()))
return t->singleton_false_;
735 return Type::Boolean();
739 CHECK(!type.IsNone());
740 if (type.Is(Type::Callable()))
return t->singleton_true_;
741 if (!type.Maybe(Type::Callable()))
return t->singleton_false_;
742 return Type::Boolean();
747 CHECK(!type.IsNone());
748 if (type.IsHeapConstant() &&
749 type.AsHeapConstant()->Ref().map(t->broker()).is_constructor()) {
750 return t->singleton_true_;
752 if (!type.Maybe(Type::Callable()))
return t->singleton_false_;
753 return Type::Boolean();
757 CHECK(!type.IsNone());
758 if (type.Is(Type::DetectableCallable()))
return t->singleton_true_;
759 if (!type.Maybe(Type::DetectableCallable()))
return t->singleton_false_;
760 return Type::Boolean();
764 CHECK(!type.IsNone());
765 if (type.Is(Type::MinusZero()))
return t->singleton_true_;
766 if (!type.Maybe(Type::MinusZero()))
return t->singleton_false_;
767 return Type::Boolean();
771 CHECK(!type.IsNone());
772 if (type.Is(Type::MinusZero()))
return t->singleton_true_;
773 if (!type.Maybe(Type::MinusZero()))
return t->singleton_false_;
774 return Type::Boolean();
778 CHECK(!type.IsNone());
779 if (type.Is(Type::NaN()))
return t->singleton_true_;
780 if (!type.Maybe(Type::NaN()))
return t->singleton_false_;
781 return Type::Boolean();
785 CHECK(!type.IsNone());
786 if (type.Is(Type::NaN()))
return t->singleton_true_;
787 if (!type.Maybe(Type::NaN()))
return t->singleton_false_;
788 return Type::Boolean();
792 CHECK(!type.IsNone());
793 if (type.Is(Type::NonCallable()))
return t->singleton_true_;
794 if (!type.Maybe(Type::NonCallable()))
return t->singleton_false_;
795 return Type::Boolean();
799 CHECK(!type.IsNone());
800 if (type.Is(Type::Number()))
return t->singleton_true_;
801 if (!type.Maybe(Type::Number()))
return t->singleton_false_;
802 return Type::Boolean();
806 CHECK(!type.IsNone());
807 if (type.Is(Type::Receiver()))
return t->singleton_true_;
808 if (!type.Maybe(Type::Receiver()))
return t->singleton_false_;
809 return Type::Boolean();
814 return Type::Boolean();
818 CHECK(!type.IsNone());
819 if (type.Is(Type::String()))
return t->singleton_true_;
820 if (!type.Maybe(Type::String()))
return t->singleton_false_;
821 return Type::Boolean();
825 CHECK(!type.IsNone());
826 if (type.Is(Type::Symbol()))
return t->singleton_true_;
827 if (!type.Maybe(Type::Symbol()))
return t->singleton_false_;
828 return Type::Boolean();
832 CHECK(!type.IsNone());
833 if (type.Is(Type::Undetectable()))
return t->singleton_true_;
834 if (!type.Maybe(Type::Undetectable()))
return t->singleton_false_;
835 return Type::Boolean();
842Type Typer::Visitor::TypeStart(
Node* node) {
return Type::Internal(); }
844Type Typer::Visitor::TypeIfException(
Node* node) {
return Type::NonInternal(); }
848Type Typer::Visitor::TypeParameter(Node* node) {
849 StartNode
start{node->InputAt(0)};
852 return Type::Function();
853 }
else if (index == 0) {
855 return Type::Receiver();
860 }
else if (index ==
start.NewTargetParameterIndex()) {
862 return Type::Receiver();
864 return Type::Union(Type::Receiver(), Type::Undefined(), typer_->
zone());
866 }
else if (index ==
start.ArgCountParameterIndex()) {
868 }
else if (index ==
start.ContextParameterIndex()) {
869 return Type::OtherInternal();
871 return Type::NonInternal();
874Type Typer::Visitor::TypeOsrValue(Node* node) {
876 return Type::OtherInternal();
882Type Typer::Visitor::TypeRetain(Node* node) {
UNREACHABLE(); }
884Type Typer::Visitor::TypeInt32Constant(Node* node) {
return Type::Machine(); }
886Type Typer::Visitor::TypeInt64Constant(Node* node) {
return Type::Machine(); }
888Type Typer::Visitor::TypeTaggedIndexConstant(Node* node) {
UNREACHABLE(); }
890Type Typer::Visitor::TypeRelocatableInt32Constant(Node* node) {
UNREACHABLE(); }
892Type Typer::Visitor::TypeRelocatableInt64Constant(Node* node) {
UNREACHABLE(); }
894Type Typer::Visitor::TypeFloat32Constant(Node* node) {
UNREACHABLE(); }
896Type Typer::Visitor::TypeFloat64Constant(Node* node) {
UNREACHABLE(); }
898Type Typer::Visitor::TypeNumberConstant(Node* node) {
903Type Typer::Visitor::TypeHeapConstant(Node* node) {
907Type Typer::Visitor::TypeCompressedHeapConstant(Node* node) {
UNREACHABLE(); }
909Type Typer::Visitor::TypeTrustedHeapConstant(Node* node) {
913Type Typer::Visitor::TypeExternalConstant(Node* node) {
914 return Type::ExternalPointer();
917Type Typer::Visitor::TypePointerConstant(Node* node) {
918 return Type::ExternalPointer();
921Type Typer::Visitor::TypeSelect(Node* node) {
925Type Typer::Visitor::TypePhi(Node* node) {
926 int arity = node->op()->ValueInputCount();
927 Type type = Operand(node, 0);
928 for (
int i = 1;
i < arity; ++
i) {
934Type Typer::Visitor::TypeEnterMachineGraph(Node* node) {
935 return Type::Machine();
938Type Typer::Visitor::TypeExitMachineGraph(Node* node) {
942Type Typer::Visitor::TypeInductionVariablePhi(Node* node) {
947 Type initial_type = Operand(node, 0);
948 Type increment_type = Operand(node, 2);
957 if (initial_type.IsNone() ||
969 for (
int i = 0;
i < arity; ++
i) {
977 InductionVariable* induction_var = res->second;
983 double increment_min;
984 double increment_max;
986 increment_min = increment_type.Min();
987 increment_max = increment_type.Max();
990 increment_min = -increment_type.Max();
991 increment_max = -increment_type.Min();
994 if (increment_min >= 0) {
996 min = initial_type.Min();
997 for (
auto bound : induction_var->upper_bounds()) {
998 Type bound_type = TypeOrNone(bound.bound);
1002 if (bound_type.IsNone()) {
1003 max = initial_type.Max();
1006 double bound_max = bound_type.Max();
1010 max = std::min(max, bound_max + increment_max);
1013 max = std::max(max, initial_type.Max());
1014 }
else if (increment_max <= 0) {
1016 max = initial_type.Max();
1017 for (
auto bound : induction_var->lower_bounds()) {
1018 Type bound_type = TypeOrNone(bound.bound);
1022 if (bound_type.IsNone()) {
1023 min = initial_type.Min();
1026 double bound_min = bound_type.Min();
1030 min = std::max(min, bound_min + increment_min);
1033 min = std::min(min, initial_type.Min());
1043 StdoutStream{} << std::setprecision(10) <<
"Loop ("
1045 <<
") variable bounds in "
1046 << (arithmetic_type ==
1050 <<
" for phi " << node->id() <<
": (" << min <<
", " << max
1059 Node* node = induction_var->
phi();
1060 DCHECK_EQ(node->opcode(), IrOpcode::kInductionVariablePhi);
1069 Type bound_type = TypeOrNone(bound.bound);
1071 if (!bound_type.
IsNone()) {
1080 Type bound_type = TypeOrNone(bound.bound);
1082 if (!bound_type.
IsNone()) {
1090 if (arith_type.
IsNone()) {
1097 switch (arith_input->
opcode()) {
1098 case IrOpcode::kSpeculativeToNumber:
1101 case IrOpcode::kJSToNumber:
1104 case IrOpcode::kJSToNumberConvertBigInt:
1113 switch (arith->
opcode()) {
1115 case IrOpcode::k##x: \
1116 type = Type##x(type, increment_type); \
1121 CASE(NumberSubtract)
1122 CASE(SpeculativeNumberAdd)
1123 CASE(SpeculativeNumberSubtract)
1124 CASE(SpeculativeAdditiveSafeIntegerAdd)
1125 CASE(SpeculativeAdditiveSafeIntegerSubtract)
1126 CASE(SpeculativeSmallIntegerAdd)
1127 CASE(SpeculativeSmallIntegerSubtract)
1144Type Typer::Visitor::TypeLoopExitValue(Node* node) {
return Operand(node, 0); }
1146Type Typer::Visitor::TypeLoopExitEffect(Node* node) {
UNREACHABLE(); }
1148Type Typer::Visitor::TypeEnsureWritableFastElements(Node* node) {
1149 return Operand(node, 1);
1152Type Typer::Visitor::TypeMaybeGrowFastElements(Node* node) {
1153 return Operand(node, 1);
1156Type Typer::Visitor::TypeTransitionElementsKind(Node* node) {
UNREACHABLE(); }
1158Type Typer::Visitor::TypeTransitionElementsKindOrCheckMap(Node* node) {
1162Type Typer::Visitor::TypeCheckpoint(Node* node) {
UNREACHABLE(); }
1164Type Typer::Visitor::TypeBeginRegion(Node* node) {
UNREACHABLE(); }
1166Type Typer::Visitor::TypeFinishRegion(Node* node) {
return Operand(node, 0); }
1168Type Typer::Visitor::TypeFrameState(Node* node) {
1170 return Type::Internal();
1173Type Typer::Visitor::TypeStateValues(Node* node) {
return Type::Internal(); }
1175Type Typer::Visitor::TypeTypedStateValues(Node* node) {
1176 return Type::Internal();
1179Type Typer::Visitor::TypeObjectId(Node* node) {
UNREACHABLE(); }
1181Type Typer::Visitor::TypeArgumentsElementsState(Node* node) {
1182 return Type::Internal();
1185Type Typer::Visitor::TypeArgumentsLengthState(Node* node) {
1186 return Type::Internal();
1189Type Typer::Visitor::TypeObjectState(Node* node) {
return Type::Internal(); }
1191Type Typer::Visitor::TypeTypedObjectState(Node* node) {
1192 return Type::Internal();
1195Type Typer::Visitor::TypeCall(Node* node) {
return Type::Any(); }
1197Type Typer::Visitor::TypeFastApiCall(Node* node) {
1200 const CFunctionInfo* c_signature = op_params.c_function().signature;
1201 CTypeInfo return_type = c_signature->ReturnInfo();
1203 switch (return_type.GetType()) {
1205 return Type::Boolean();
1208 return Type::Number();
1210 return Type::Signed32();
1212 if (c_signature->GetInt64Representation() ==
1214 return Type::SignedBigInt64();
1216 DCHECK_EQ(c_signature->GetInt64Representation(),
1218 return Type::Number();
1220 return Type::String();
1222 return Type::Unsigned32();
1224 if (c_signature->GetInt64Representation() ==
1226 return Type::UnsignedBigInt64();
1228 DCHECK_EQ(c_signature->GetInt64Representation(),
1230 return Type::Number();
1244#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
1245Type Typer::Visitor::TypeGetContinuationPreservedEmbedderData(Node* node) {
1249Type Typer::Visitor::TypeSetContinuationPreservedEmbedderData(Node* node) {
1254#if V8_ENABLE_WEBASSEMBLY
1255Type Typer::Visitor::TypeJSWasmCall(Node* node) {
1256 const JSWasmCallParameters& op_params = JSWasmCallParametersOf(node->op());
1257 const wasm::CanonicalSig* wasm_signature = op_params.signature();
1258 if (wasm_signature->return_count() > 0) {
1259 return JSWasmCallNode::TypeForWasmReturnType(wasm_signature->GetReturn());
1265Type Typer::Visitor::TypeProjection(Node* node) {
1266 Type
const type = Operand(node, 0);
1269 if (type.IsTuple() && index < type.AsTuple()->Arity()) {
1270 return type.AsTuple()->Element(index);
1275Type Typer::Visitor::TypeMapGuard(Node* node) {
UNREACHABLE(); }
1277Type Typer::Visitor::TypeTypeGuard(Node* node) {
1278 Type
const type = Operand(node, 0);
1282Type Typer::Visitor::TypeDead(Node* node) {
return Type::None(); }
1283Type Typer::Visitor::TypeDeadValue(Node* node) {
return Type::None(); }
1284Type Typer::Visitor::TypeUnreachable(Node* node) {
return Type::None(); }
1286Type Typer::Visitor::TypePlug(Node* node) {
UNREACHABLE(); }
1287Type Typer::Visitor::TypeStaticAssert(Node* node) {
UNREACHABLE(); }
1288Type Typer::Visitor::TypeSLVerifierHint(Node* node) {
UNREACHABLE(); }
1292Type Typer::Visitor::JSEqualTyper(Type lhs, Type rhs,
Typer* t) {
1293 if (lhs.IsNone() || rhs.IsNone())
return Type::None();
1294 if (lhs.Is(Type::NaN()) || rhs.Is(Type::NaN()))
return t->singleton_false_;
1295 if (lhs.Is(Type::NullOrUndefined()) && rhs.Is(Type::NullOrUndefined())) {
1296 return t->singleton_true_;
1298 if (lhs.Is(Type::Number()) && rhs.Is(Type::Number()) &&
1299 (lhs.Max() < rhs.Min() || lhs.Min() > rhs.Max())) {
1300 return t->singleton_false_;
1302 if (lhs.IsSingleton() && rhs.Is(lhs)) {
1306 return t->singleton_true_;
1308 return Type::Boolean();
1311Type Typer::Visitor::JSStrictEqualTyper(Type lhs, Type rhs,
Typer* t) {
1312 return t->operation_typer()->StrictEqual(lhs, rhs);
1322 lhs = ToPrimitive(lhs, t);
1323 rhs = ToPrimitive(rhs, t);
1324 if (lhs.
Maybe(Type::String()) && rhs.
Maybe(Type::String())) {
1328 lhs = ToNumeric(lhs, t);
1329 rhs = ToNumeric(rhs, t);
1330 if (lhs.
Is(Type::Number()) && rhs.
Is(Type::Number())) {
1331 return NumberCompareTyper(lhs, rhs, t);
1347 if (lhs.
Is(Type::NaN()) || rhs.
Is(Type::NaN()))
return kComparisonUndefined;
1352 result = kComparisonFalse;
1353 }
else if (lhs.
Min() >= rhs.
Max()) {
1354 result = kComparisonFalse;
1355 }
else if (lhs.
Max() < rhs.
Min()) {
1356 result = kComparisonTrue;
1363 if (lhs.
Maybe(Type::NaN()) || rhs.
Maybe(Type::NaN())) {
1364 result |= kComparisonUndefined;
1370 return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
1374 return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
1378 return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
1381Type Typer::Visitor::JSGreaterThanOrEqualTyper(Type lhs, Type rhs,
Typer* t) {
1382 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
1387Type Typer::Visitor::JSBitwiseOrTyper(Type lhs, Type rhs,
Typer* t) {
1388 return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseOr);
1391Type Typer::Visitor::JSBitwiseAndTyper(Type lhs, Type rhs,
Typer* t) {
1392 return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseAnd);
1395Type Typer::Visitor::JSBitwiseXorTyper(Type lhs, Type rhs,
Typer* t) {
1396 return BinaryNumberOpTyper(lhs, rhs, t, NumberBitwiseXor);
1399Type Typer::Visitor::JSShiftLeftTyper(Type lhs, Type rhs,
Typer* t) {
1400 return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftLeft);
1403Type Typer::Visitor::JSShiftRightTyper(Type lhs, Type rhs,
Typer* t) {
1404 return BinaryNumberOpTyper(lhs, rhs, t, NumberShiftRight);
1407Type Typer::Visitor::JSShiftRightLogicalTyper(Type lhs, Type rhs,
Typer* t) {
1413Type Typer::Visitor::JSAddTyper(Type lhs, Type rhs,
Typer* t) {
1414 lhs = ToPrimitive(lhs, t);
1415 rhs = ToPrimitive(rhs, t);
1416 if (lhs.Maybe(Type::String()) || rhs.Maybe(Type::String())) {
1417 if (lhs.Is(Type::String()) || rhs.Is(Type::String())) {
1418 return Type::String();
1420 return Type::NumericOrString();
1424 return BinaryNumberOpTyper(lhs, rhs, t, NumberAdd);
1427Type Typer::Visitor::JSSubtractTyper(Type lhs, Type rhs,
Typer* t) {
1428 return BinaryNumberOpTyper(lhs, rhs, t, NumberSubtract);
1431Type Typer::Visitor::JSMultiplyTyper(Type lhs, Type rhs,
Typer* t) {
1432 return BinaryNumberOpTyper(lhs, rhs, t, NumberMultiply);
1435Type Typer::Visitor::JSDivideTyper(Type lhs, Type rhs,
Typer* t) {
1436 return BinaryNumberOpTyper(lhs, rhs, t, NumberDivide);
1439Type Typer::Visitor::JSModulusTyper(Type lhs, Type rhs,
Typer* t) {
1440 return BinaryNumberOpTyper(lhs, rhs, t, NumberModulus);
1443Type Typer::Visitor::JSExponentiateTyper(Type lhs, Type rhs,
Typer* t) {
1445 return Type::Numeric();
1450#define DEFINE_METHOD(Name) \
1451 Type Typer::Visitor::TypeJS##Name(Type input) { \
1452 return TypeUnaryOp(input, Name); \
1469Type Typer::Visitor::TypeTypeOf(Node* node) {
1470 return Type::InternalizedString();
1475Type Typer::Visitor::TypeToBoolean(Node* node) {
1476 return TypeUnaryOp(node, ToBoolean);
1481Type Typer::Visitor::TypeJSCreate(Node* node) {
return Type::Object(); }
1483Type Typer::Visitor::TypeJSCreateArguments(Node* node) {
1486 return Type::Array();
1489 return Type::OtherObject();
1494Type Typer::Visitor::TypeJSCreateArray(Node* node) {
return Type::Array(); }
1496Type Typer::Visitor::TypeJSCreateArrayIterator(Node* node) {
1497 return Type::OtherObject();
1500Type Typer::Visitor::TypeJSCreateAsyncFunctionObject(Node* node) {
1501 return Type::OtherObject();
1504Type Typer::Visitor::TypeJSCreateCollectionIterator(Node* node) {
1505 return Type::OtherObject();
1508Type Typer::Visitor::TypeJSCreateBoundFunction(Node* node) {
1509 return Type::BoundFunction();
1512Type Typer::Visitor::TypeJSCreateGeneratorObject(Node* node) {
1513 return Type::OtherObject();
1516Type Typer::Visitor::TypeJSCreateClosure(Node* node) {
1517 SharedFunctionInfoRef shared =
1518 JSCreateClosureNode{node}.Parameters().shared_info();
1520 return Type::ClassConstructor();
1522 return Type::CallableFunction();
1526Type Typer::Visitor::TypeJSCreateIterResultObject(Node* node) {
1527 return Type::OtherObject();
1530Type Typer::Visitor::TypeJSCreateStringIterator(Node* node) {
1531 return Type::OtherObject();
1534Type Typer::Visitor::TypeJSCreateKeyValueArray(Node* node) {
1535 return Type::Array();
1538Type Typer::Visitor::TypeJSCreateObject(Node* node) {
1539 return Type::OtherObject();
1542Type Typer::Visitor::TypeJSCreateStringWrapper(Node* node) {
1543 return Type::StringWrapper();
1546Type Typer::Visitor::TypeJSCreatePromise(Node* node) {
1547 return Type::OtherObject();
1550Type Typer::Visitor::TypeJSCreateTypedArray(Node* node) {
1551 return Type::TypedArray();
1554Type Typer::Visitor::TypeJSCreateLiteralArray(Node* node) {
1555 return Type::Array();
1558Type Typer::Visitor::TypeJSCreateEmptyLiteralArray(Node* node) {
1559 return Type::Array();
1562Type Typer::Visitor::TypeJSCreateArrayFromIterable(Node* node) {
1563 return Type::Array();
1566Type Typer::Visitor::TypeJSCreateLiteralObject(Node* node) {
1567 return Type::OtherObject();
1570Type Typer::Visitor::TypeJSCreateEmptyLiteralObject(Node* node) {
1571 return Type::OtherObject();
1574Type Typer::Visitor::TypeJSCloneObject(Node* node) {
1575 return Type::OtherObject();
1578Type Typer::Visitor::TypeJSCreateLiteralRegExp(Node* node) {
1579 return Type::OtherObject();
1582Type Typer::Visitor::TypeJSGetTemplateObject(Node* node) {
1583 return Type::Array();
1586Type Typer::Visitor::TypeJSLoadProperty(Node* node) {
return Type::Any(); }
1588Type Typer::Visitor::TypeJSLoadNamed(Node* node) {
1594 JSLoadNamedNode
n(node);
1595 NamedAccess
const& p = n.Parameters();
1596 DCHECK(!p.name().object()->IsPrivateBrand());
1598 return Type::NonInternal();
1601Type Typer::Visitor::TypeJSLoadNamedFromSuper(Node* node) {
1602 return Type::NonInternal();
1605Type Typer::Visitor::TypeJSLoadGlobal(Node* node) {
1606 return Type::NonInternal();
1609Type Typer::Visitor::TypeJSParseInt(Type input) {
return Type::Number(); }
1611Type Typer::Visitor::TypeJSRegExpTest(Node* node) {
return Type::Boolean(); }
1619 static const double kWeakenMinLimits[] = {0.0,
1639 -562949953421312.0};
1640 static const double kWeakenMaxLimits[] = {0.0,
1665 if (!previous_type.
Maybe(integer)) {
1666 return current_type;
1674 if (!IsWeakened(node->id())) {
1680 if (current.IsInvalid() ||
previous.IsInvalid()) {
1681 return current_type;
1684 SetWeakened(node->id());
1687 double current_min = current_integer.
Min();
1688 double new_min = current_min;
1691 if (current_min != previous_integer.
Min()) {
1693 for (
double const min : kWeakenMinLimits) {
1694 if (min <= current_min) {
1701 double current_max = current_integer.
Max();
1702 double new_max = current_max;
1705 if (current_max != previous_integer.
Max()) {
1707 for (
double const max : kWeakenMaxLimits) {
1708 if (max >= current_max) {
1724Type Typer::Visitor::TypeJSSetNamedProperty(Node* node) {
UNREACHABLE(); }
1726Type Typer::Visitor::TypeJSStoreGlobal(Node* node) {
UNREACHABLE(); }
1728Type Typer::Visitor::TypeJSDefineNamedOwnProperty(Node* node) {
UNREACHABLE(); }
1730Type Typer::Visitor::TypeJSDefineKeyedOwnPropertyInLiteral(Node* node) {
1734Type Typer::Visitor::TypeJSStoreInArrayLiteral(Node* node) {
UNREACHABLE(); }
1736Type Typer::Visitor::TypeJSDeleteProperty(Node* node) {
1737 return Type::Boolean();
1740Type Typer::Visitor::TypeJSHasProperty(Node* node) {
return Type::Boolean(); }
1744Type Typer::Visitor::JSHasInPrototypeChainTyper(Type lhs, Type rhs,
Typer* t) {
1745 return Type::Boolean();
1748Type Typer::Visitor::JSInstanceOfTyper(Type lhs, Type rhs,
Typer* t) {
1749 return Type::Boolean();
1752Type Typer::Visitor::JSOrdinaryHasInstanceTyper(Type lhs, Type rhs,
Typer* t) {
1753 return Type::Boolean();
1756Type Typer::Visitor::TypeJSGetSuperConstructor(Node* node) {
1757 return Type::NonInternal();
1760Type Typer::Visitor::TypeJSFindNonDefaultConstructorOrConstruct(Node* node) {
1765Type Typer::Visitor::TypeJSHasContextExtension(Node* node) {
1766 return Type::Boolean();
1769Type Typer::Visitor::TypeJSLoadContext(Node* node) {
1771 switch (access.index()) {
1774 return Type::OtherInternal();
1780Type Typer::Visitor::TypeJSLoadScriptContext(Node* node) {
1782 switch (access.index()) {
1786 return Type::OtherInternal();
1792Type Typer::Visitor::TypeJSStoreContext(Node* node) {
UNREACHABLE(); }
1794Type Typer::Visitor::TypeJSStoreScriptContext(Node* node) {
UNREACHABLE(); }
1796Type Typer::Visitor::TypeJSCreateFunctionContext(Node* node) {
1797 return Type::OtherInternal();
1800Type Typer::Visitor::TypeJSCreateCatchContext(Node* node) {
1801 return Type::OtherInternal();
1804Type Typer::Visitor::TypeJSCreateWithContext(Node* node) {
1805 return Type::OtherInternal();
1808Type Typer::Visitor::TypeJSCreateBlockContext(Node* node) {
1809 return Type::OtherInternal();
1814Type Typer::Visitor::TypeJSConstructForwardVarargs(Node* node) {
1815 return Type::Receiver();
1818Type Typer::Visitor::TypeJSConstructForwardAllArgs(Node* node) {
1819 return Type::Receiver();
1822Type Typer::Visitor::TypeJSConstruct(Node* node) {
return Type::Receiver(); }
1824Type Typer::Visitor::TypeJSConstructWithArrayLike(Node* node) {
1825 return Type::Receiver();
1828Type Typer::Visitor::TypeJSConstructWithSpread(Node* node) {
1829 return Type::Receiver();
1832Type Typer::Visitor::TypeJSObjectIsArray(Node* node) {
return Type::Boolean(); }
1834Type Typer::Visitor::TypeDateNow(Node* node) {
return Type::Number(); }
1836Type Typer::Visitor::TypeDoubleArrayMin(Node* node) {
return Type::Number(); }
1838Type Typer::Visitor::TypeDoubleArrayMax(Node* node) {
return Type::Number(); }
1840Type Typer::Visitor::TypeUnsigned32Divide(Node* node) {
1841 Type lhs = Operand(node, 0);
1847 return Type::NonInternal();
1850 if (!function.shared(t->broker()).HasBuiltinId()) {
1851 return Type::NonInternal();
1853 switch (function.shared(t->broker()).builtin_id()) {
1854 case Builtin::kMathRandom:
1855 return Type::PlainNumber();
1856 case Builtin::kMathFloor:
1857 case Builtin::kMathCeil:
1858 case Builtin::kMathRound:
1859 case Builtin::kMathTrunc:
1860 return t->cache_->kIntegerOrMinusZeroOrNaN;
1862 case Builtin::kMathAbs:
1863 case Builtin::kMathExp:
1864 return Type::Union(Type::PlainNumber(), Type::NaN(), t->zone());
1865 case Builtin::kMathAcos:
1866 case Builtin::kMathAcosh:
1867 case Builtin::kMathAsin:
1868 case Builtin::kMathAsinh:
1869 case Builtin::kMathAtan:
1870 case Builtin::kMathAtanh:
1871 case Builtin::kMathCbrt:
1872 case Builtin::kMathCos:
1873 case Builtin::kMathExpm1:
1874 case Builtin::kMathFround:
1875 case Builtin::kMathLog:
1876 case Builtin::kMathLog1p:
1877 case Builtin::kMathLog10:
1878 case Builtin::kMathLog2:
1879 case Builtin::kMathSin:
1880 case Builtin::kMathSqrt:
1881 case Builtin::kMathTan:
1882 return Type::Number();
1883 case Builtin::kMathSign:
1884 return t->cache_->kMinusOneToOneOrMinusZeroOrNaN;
1886 case Builtin::kMathAtan2:
1887 case Builtin::kMathPow:
1888 case Builtin::kMathMax:
1889 case Builtin::kMathMin:
1890 case Builtin::kMathHypot:
1891 return Type::Number();
1892 case Builtin::kMathImul:
1893 return Type::Signed32();
1894 case Builtin::kMathClz32:
1895 return t->cache_->kZeroToThirtyTwo;
1897 case Builtin::kDateNow:
1898 return t->cache_->kTimeValueType;
1899 case Builtin::kDatePrototypeGetDate:
1900 return t->cache_->kJSDateDayType;
1901 case Builtin::kDatePrototypeGetDay:
1902 return t->cache_->kJSDateWeekdayType;
1903 case Builtin::kDatePrototypeGetFullYear:
1904 return t->cache_->kJSDateYearType;
1905 case Builtin::kDatePrototypeGetHours:
1906 return t->cache_->kJSDateHourType;
1907 case Builtin::kDatePrototypeGetMilliseconds:
1910 case Builtin::kDatePrototypeGetMinutes:
1911 return t->cache_->kJSDateMinuteType;
1912 case Builtin::kDatePrototypeGetMonth:
1913 return t->cache_->kJSDateMonthType;
1914 case Builtin::kDatePrototypeGetSeconds:
1915 return t->cache_->kJSDateSecondType;
1916 case Builtin::kDatePrototypeGetTime:
1917 return t->cache_->kJSDateValueType;
1920 case Builtin::kSymbolConstructor:
1921 return Type::Symbol();
1922 case Builtin::kSymbolPrototypeToString:
1923 return Type::String();
1924 case Builtin::kSymbolPrototypeValueOf:
1925 return Type::Symbol();
1928 case Builtin::kBigIntConstructor:
1929 return Type::BigInt();
1932 case Builtin::kNumberConstructor:
1933 return Type::Number();
1934 case Builtin::kNumberIsFinite:
1935 case Builtin::kNumberIsInteger:
1936 case Builtin::kNumberIsNaN:
1937 case Builtin::kNumberIsSafeInteger:
1938 return Type::Boolean();
1939 case Builtin::kNumberParseFloat:
1940 return Type::Number();
1941 case Builtin::kNumberParseInt:
1942 return t->cache_->kIntegerOrMinusZeroOrNaN;
1943 case Builtin::kNumberToString:
1944 return Type::String();
1947 case Builtin::kStringConstructor:
1948 return Type::String();
1949 case Builtin::kStringPrototypeCharCodeAt:
1952 case Builtin::kStringCharAt:
1953 return Type::String();
1954 case Builtin::kStringPrototypeCodePointAt:
1956 Type::Undefined(), t->zone());
1957 case Builtin::kStringPrototypeConcat:
1958 case Builtin::kStringFromCharCode:
1959 case Builtin::kStringFromCodePoint:
1960 return Type::String();
1961 case Builtin::kStringPrototypeIndexOf:
1962 case Builtin::kStringPrototypeLastIndexOf:
1964 case Builtin::kStringPrototypeEndsWith:
1965 case Builtin::kStringPrototypeIncludes:
1966 return Type::Boolean();
1967 case Builtin::kStringRaw:
1968 case Builtin::kStringRepeat:
1969 case Builtin::kStringPrototypeSlice:
1970 return Type::String();
1971 case Builtin::kStringPrototypeStartsWith:
1972 return Type::Boolean();
1973 case Builtin::kStringPrototypeSubstr:
1974 case Builtin::kStringSubstring:
1975 case Builtin::kStringPrototypeToString:
1976#ifdef V8_INTL_SUPPORT
1977 case Builtin::kStringPrototypeToLowerCaseIntl:
1978 case Builtin::kStringPrototypeToUpperCaseIntl:
1980 case Builtin::kStringPrototypeToLowerCase:
1981 case Builtin::kStringPrototypeToUpperCase:
1983 case Builtin::kStringPrototypeTrim:
1984 case Builtin::kStringPrototypeTrimEnd:
1985 case Builtin::kStringPrototypeTrimStart:
1986 case Builtin::kStringPrototypeValueOf:
1987 return Type::String();
1989 case Builtin::kStringPrototypeIterator:
1990 case Builtin::kStringIteratorPrototypeNext:
1991 return Type::OtherObject();
1993 case Builtin::kArrayPrototypeEntries:
1994 case Builtin::kArrayPrototypeKeys:
1995 case Builtin::kArrayPrototypeValues:
1996 case Builtin::kTypedArrayPrototypeEntries:
1997 case Builtin::kTypedArrayPrototypeKeys:
1998 case Builtin::kTypedArrayPrototypeValues:
1999 case Builtin::kArrayIteratorPrototypeNext:
2000 case Builtin::kMapIteratorPrototypeNext:
2001 case Builtin::kSetIteratorPrototypeNext:
2002 return Type::OtherObject();
2003 case Builtin::kTypedArrayPrototypeToStringTag:
2004 return Type::Union(Type::InternalizedString(), Type::Undefined(),
2008 case Builtin::kArrayIsArray:
2009 return Type::Boolean();
2010 case Builtin::kArrayConcat:
2011 return Type::Receiver();
2012 case Builtin::kArrayEvery:
2013 return Type::Boolean();
2014 case Builtin::kArrayPrototypeFill:
2015 case Builtin::kArrayFilter:
2016 return Type::Receiver();
2017 case Builtin::kArrayPrototypeFindIndex:
2019 case Builtin::kArrayForEach:
2020 return Type::Undefined();
2021 case Builtin::kArrayIncludes:
2022 return Type::Boolean();
2023 case Builtin::kArrayIndexOf:
2025 case Builtin::kArrayPrototypeJoin:
2026 return Type::String();
2027 case Builtin::kArrayPrototypeLastIndexOf:
2029 case Builtin::kArrayMap:
2030 return Type::Receiver();
2031 case Builtin::kArrayPush:
2032 return t->cache_->kPositiveSafeInteger;
2033 case Builtin::kArrayPrototypeReverse:
2034 case Builtin::kArrayPrototypeSlice:
2035 return Type::Receiver();
2036 case Builtin::kArraySome:
2037 return Type::Boolean();
2038 case Builtin::kArrayPrototypeSplice:
2039 return Type::Receiver();
2040 case Builtin::kArrayUnshift:
2041 return t->cache_->kPositiveSafeInteger;
2044 case Builtin::kArrayBufferIsView:
2045 return Type::Boolean();
2048 case Builtin::kObjectAssign:
2049 return Type::Receiver();
2050 case Builtin::kObjectCreate:
2051 return Type::OtherObject();
2052 case Builtin::kObjectIs:
2053 case Builtin::kObjectHasOwn:
2054 case Builtin::kObjectPrototypeHasOwnProperty:
2055 case Builtin::kObjectPrototypeIsPrototypeOf:
2056 return Type::Boolean();
2057 case Builtin::kObjectToString:
2058 return Type::String();
2060 case Builtin::kPromiseAll:
2061 return Type::Receiver();
2062 case Builtin::kPromisePrototypeThen:
2063 return Type::Receiver();
2064 case Builtin::kPromiseRace:
2065 return Type::Receiver();
2066 case Builtin::kPromiseReject:
2067 return Type::Receiver();
2068 case Builtin::kPromiseResolveTrampoline:
2069 return Type::Receiver();
2072 case Builtin::kRegExpPrototypeCompile:
2073 return Type::OtherObject();
2074 case Builtin::kRegExpPrototypeExec:
2075 return Type::Union(Type::Array(), Type::Null(), t->zone());
2076 case Builtin::kRegExpPrototypeTest:
2077 return Type::Boolean();
2078 case Builtin::kRegExpPrototypeToString:
2079 return Type::String();
2082 case Builtin::kFunctionPrototypeBind:
2083 return Type::BoundFunction();
2084 case Builtin::kFunctionPrototypeHasInstance:
2085 return Type::Boolean();
2088 case Builtin::kGlobalDecodeURI:
2089 case Builtin::kGlobalDecodeURIComponent:
2090 case Builtin::kGlobalEncodeURI:
2091 case Builtin::kGlobalEncodeURIComponent:
2092 case Builtin::kGlobalEscape:
2093 case Builtin::kGlobalUnescape:
2094 return Type::String();
2095 case Builtin::kGlobalIsFinite:
2096 case Builtin::kGlobalIsNaN:
2097 return Type::Boolean();
2100 case Builtin::kMapPrototypeClear:
2101 case Builtin::kMapPrototypeForEach:
2102 return Type::Undefined();
2103 case Builtin::kMapPrototypeDelete:
2104 case Builtin::kMapPrototypeHas:
2105 return Type::Boolean();
2106 case Builtin::kMapPrototypeEntries:
2107 case Builtin::kMapPrototypeKeys:
2108 case Builtin::kMapPrototypeSet:
2109 case Builtin::kMapPrototypeValues:
2110 return Type::OtherObject();
2113 case Builtin::kSetPrototypeAdd:
2114 case Builtin::kSetPrototypeEntries:
2115 case Builtin::kSetPrototypeValues:
2116 return Type::OtherObject();
2117 case Builtin::kSetPrototypeClear:
2118 case Builtin::kSetPrototypeForEach:
2119 return Type::Undefined();
2120 case Builtin::kSetPrototypeDelete:
2121 case Builtin::kSetPrototypeHas:
2122 return Type::Boolean();
2125 case Builtin::kWeakMapPrototypeDelete:
2126 case Builtin::kWeakMapPrototypeHas:
2127 return Type::Boolean();
2128 case Builtin::kWeakMapPrototypeSet:
2129 return Type::OtherObject();
2132 case Builtin::kWeakSetPrototypeAdd:
2133 return Type::OtherObject();
2134 case Builtin::kWeakSetPrototypeDelete:
2135 case Builtin::kWeakSetPrototypeHas:
2136 return Type::Boolean();
2138 return Type::NonInternal();
2142Type Typer::Visitor::TypeJSCallForwardVarargs(
Node* node) {
2143 return TypeUnaryOp(node, JSCallTyper);
2146Type Typer::Visitor::TypeJSCall(
Node* node) {
2149 return TypeUnaryOp(node, JSCallTyper);
2152Type Typer::Visitor::TypeJSCallWithArrayLike(Node* node) {
2153 return TypeUnaryOp(node, JSCallTyper);
2156Type Typer::Visitor::TypeJSCallWithSpread(Node* node) {
2157 return TypeUnaryOp(node, JSCallTyper);
2160Type Typer::Visitor::TypeJSCallRuntime(Node* node) {
2162 case Runtime::kInlineCreateIterResultObject:
2163 return Type::OtherObject();
2164 case Runtime::kHasInPrototypeChain:
2165 return Type::Boolean();
2175Type Typer::Visitor::TypeJSForInEnumerate(Node* node) {
2176 return Type::OtherInternal();
2179Type Typer::Visitor::TypeJSForInNext(Node* node) {
2183Type Typer::Visitor::TypeJSForInPrepare(Node* node) {
2185 Type
const cache_type =
2187 Type
const cache_array = Type::OtherInternal();
2192Type Typer::Visitor::TypeJSLoadMessage(Node* node) {
return Type::Any(); }
2194Type Typer::Visitor::TypeJSStoreMessage(Node* node) {
UNREACHABLE(); }
2196Type Typer::Visitor::TypeJSLoadModule(Node* node) {
return Type::Any(); }
2198Type Typer::Visitor::TypeJSStoreModule(Node* node) {
UNREACHABLE(); }
2200Type Typer::Visitor::TypeJSGetImportMeta(Node* node) {
return Type::Any(); }
2202Type Typer::Visitor::TypeJSGeneratorStore(Node* node) {
UNREACHABLE(); }
2204Type Typer::Visitor::TypeJSGeneratorRestoreContinuation(Node* node) {
2208Type Typer::Visitor::TypeJSGeneratorRestoreContext(Node* node) {
2212Type Typer::Visitor::TypeJSGeneratorRestoreRegister(Node* node) {
2216Type Typer::Visitor::TypeJSGeneratorRestoreInputOrDebugPos(Node* node) {
2220Type Typer::Visitor::TypeJSStackCheck(Node* node) {
return Type::Any(); }
2222Type Typer::Visitor::TypeJSDebugger(Node* node) {
return Type::Any(); }
2224Type Typer::Visitor::TypeJSAsyncFunctionEnter(Node* node) {
2225 return Type::OtherObject();
2228Type Typer::Visitor::TypeJSAsyncFunctionReject(Node* node) {
2229 return Type::OtherObject();
2232Type Typer::Visitor::TypeJSAsyncFunctionResolve(Node* node) {
2233 return Type::OtherObject();
2236Type Typer::Visitor::TypeJSFulfillPromise(Node* node) {
2237 return Type::Undefined();
2240Type Typer::Visitor::TypeJSPerformPromiseThen(Node* node) {
2241 return Type::Receiver();
2244Type Typer::Visitor::TypeJSPromiseResolve(Node* node) {
2245 return Type::Receiver();
2248Type Typer::Visitor::TypeJSRejectPromise(Node* node) {
2249 return Type::Undefined();
2252Type Typer::Visitor::TypeJSResolvePromise(Node* node) {
2253 return Type::Undefined();
2258Type Typer::Visitor::TypeBooleanNot(Node* node) {
return Type::Boolean(); }
2267 return FalsifyUndefined(
2273 return FalsifyUndefined(
2282 return Type::Boolean();
2285Type Typer::Visitor::TypeNumberEqual(
Node* node) {
2286 return TypeBinaryOp(node, NumberEqualTyper);
2289Type Typer::Visitor::TypeNumberLessThan(
Node* node) {
2290 return TypeBinaryOp(node, NumberLessThanTyper);
2293Type Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
2294 return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
2297Type Typer::Visitor::TypeSpeculativeNumberEqual(Node* node) {
2298 return TypeBinaryOp(node, NumberEqualTyper);
2301Type Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) {
2302 return TypeBinaryOp(node, NumberLessThanTyper);
2305Type Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
2306 return TypeBinaryOp(node, NumberLessThanOrEqualTyper);
2309#define BIGINT_COMPARISON_BINOP(Name) \
2310 Type Typer::Visitor::Type##Name(Node* node) { \
2311 return TypeBinaryOp(node, BigIntCompareTyper); \
2319#undef BIGINT_COMPARISON_BINOP
2321Type Typer::Visitor::TypeStringConcat(Node* node) {
return Type::String(); }
2323Type Typer::Visitor::TypeStringToNumber(Node* node) {
2324 return TypeUnaryOp(node,
ToNumber);
2327Type Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
2328 return TypeUnaryOp(node,
ToNumber);
2331Type Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) {
2332 return Type::Integral32();
2335Type Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
2336 return Type::Number();
2342 return t->singleton_true_;
2344 return Type::Boolean();
2347Type Typer::Visitor::TypeReferenceEqual(
Node* node) {
2348 return TypeBinaryOp(node, ReferenceEqualTyper);
2353 return t->operation_typer()->SameValue(lhs, rhs);
2358 return t->operation_typer()->SameValueNumbersOnly(lhs, rhs);
2361Type Typer::Visitor::TypeSameValue(
Node* node) {
2362 return TypeBinaryOp(node, SameValueTyper);
2365Type Typer::Visitor::TypeSameValueNumbersOnly(
Node* node) {
2366 return TypeBinaryOp(node, SameValueNumbersOnlyTyper);
2369Type Typer::Visitor::TypeNumberSameValue(Node* node) {
UNREACHABLE(); }
2371Type Typer::Visitor::TypeStringEqual(Node* node) {
return Type::Boolean(); }
2373Type Typer::Visitor::TypeStringLessThan(Node* node) {
return Type::Boolean(); }
2375Type Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
2376 return Type::Boolean();
2380 return Type::String();
2384 return Type::String();
2387Type Typer::Visitor::TypeStringToLowerCaseIntl(
Node* node) {
2388 return Type::String();
2391Type Typer::Visitor::TypeStringToUpperCaseIntl(
Node* node) {
2392 return Type::String();
2395Type Typer::Visitor::TypeStringCharCodeAt(Node* node) {
2399Type Typer::Visitor::TypeStringCodePointAt(Node* node) {
2403Type Typer::Visitor::TypeStringFromSingleCharCode(Node* node) {
2404 return TypeUnaryOp(node, StringFromSingleCharCodeTyper);
2407Type Typer::Visitor::TypeStringFromSingleCodePoint(Node* node) {
2408 return TypeUnaryOp(node, StringFromSingleCodePointTyper);
2411Type Typer::Visitor::TypeStringFromCodePointAt(Node* node) {
2412 return Type::String();
2415Type Typer::Visitor::TypeStringIndexOf(Node* node) {
2419Type Typer::Visitor::TypeStringLength(Node* node) {
2423Type Typer::Visitor::TypeStringWrapperLength(Node* node) {
2427Type Typer::Visitor::TypeStringSubstring(Node* node) {
return Type::String(); }
2429Type Typer::Visitor::TypeCheckBounds(Node* node) {
2434Type Typer::Visitor::TypeCheckHeapObject(Node* node) {
2435 Type type = Operand(node, 0);
2439Type Typer::Visitor::TypeCheckIf(Node* node) {
UNREACHABLE(); }
2441Type Typer::Visitor::TypeCheckInternalizedString(Node* node) {
2442 Type arg = Operand(node, 0);
2446Type Typer::Visitor::TypeCheckMaps(Node* node) {
UNREACHABLE(); }
2448Type Typer::Visitor::TypeCompareMaps(Node* node) {
return Type::Boolean(); }
2450Type Typer::Visitor::TypeCheckNumber(Node* node) {
2454Type Typer::Visitor::TypeCheckNumberFitsInt32(Node* node) {
2458Type Typer::Visitor::TypeCheckReceiver(Node* node) {
2459 Type arg = Operand(node, 0);
2463Type Typer::Visitor::TypeCheckReceiverOrNullOrUndefined(Node* node) {
2464 Type arg = Operand(node, 0);
2468Type Typer::Visitor::TypeCheckSmi(Node* node) {
2469 Type arg = Operand(node, 0);
2473Type Typer::Visitor::TypeCheckString(Node* node) {
2474 Type arg = Operand(node, 0);
2478Type Typer::Visitor::TypeCheckStringOrStringWrapper(Node* node) {
2479 Type arg = Operand(node, 0);
2483Type Typer::Visitor::TypeCheckSymbol(Node* node) {
2484 Type arg = Operand(node, 0);
2488Type Typer::Visitor::TypeCheckFloat64Hole(Node* node) {
2492Type Typer::Visitor::TypeChangeFloat64HoleToTagged(Node* node) {
2496Type Typer::Visitor::TypeCheckNotTaggedHole(Node* node) {
2497 Type type = Operand(node, 0);
2502Type Typer::Visitor::TypeCheckClosure(Node* node) {
2504 OptionalSharedFunctionInfoRef shared = cell.shared_function_info(
broker());
2505 if (!shared.has_value())
return Type::Function();
2508 return Type::ClassConstructor();
2510 return Type::CallableFunction();
2514Type Typer::Visitor::TypeConvertReceiver(Node* node) {
2515 Type arg = Operand(node, 0);
2519Type Typer::Visitor::TypeConvertTaggedHoleToUndefined(Node* node) {
2520 Type type = Operand(node, 0);
2524Type Typer::Visitor::TypeCheckEqualsInternalizedString(Node* node) {
2528Type Typer::Visitor::TypeCheckEqualsSymbol(Node* node) {
UNREACHABLE(); }
2530Type Typer::Visitor::TypeAllocate(Node* node) {
2534Type Typer::Visitor::TypeAllocateRaw(Node* node) {
UNREACHABLE(); }
2536Type Typer::Visitor::TypeLoadFieldByIndex(Node* node) {
2537 return Type::NonInternal();
2540Type Typer::Visitor::TypeLoadField(Node* node) {
2544Type Typer::Visitor::TypeLoadMessage(Node* node) {
return Type::Any(); }
2546Type Typer::Visitor::TypeLoadElement(Node* node) {
2550Type Typer::Visitor::TypeLoadStackArgument(Node* node) {
2551 return Type::NonInternal();
2554Type Typer::Visitor::TypeLoadFromObject(Node* node) {
UNREACHABLE(); }
2555Type Typer::Visitor::TypeLoadImmutableFromObject(Node* node) {
UNREACHABLE(); }
2557Type Typer::Visitor::TypeLoadTypedElement(Node* node) {
2559#define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2560 case kExternal##ElemType##Array: \
2561 return typer_->cache_->k##ElemType;
2563#undef TYPED_ARRAY_CASE
2568Type Typer::Visitor::TypeLoadDataViewElement(Node* node) {
2570#define TYPED_ARRAY_CASE(ElemType, type, TYPE, ctype) \
2571 case kExternal##ElemType##Array: \
2572 return typer_->cache_->k##ElemType;
2574#undef TYPED_ARRAY_CASE
2579Type Typer::Visitor::TypeStoreField(Node* node) {
UNREACHABLE(); }
2581Type Typer::Visitor::TypeStoreMessage(Node* node) {
UNREACHABLE(); }
2583Type Typer::Visitor::TypeStoreElement(Node* node) {
UNREACHABLE(); }
2585Type Typer::Visitor::TypeStoreToObject(Node* node) {
UNREACHABLE(); }
2586Type Typer::Visitor::TypeInitializeImmutableInObject(Node* node) {
2590Type Typer::Visitor::TypeTransitionAndStoreElement(Node* node) {
2594Type Typer::Visitor::TypeTransitionAndStoreNumberElement(Node* node) {
2598Type Typer::Visitor::TypeTransitionAndStoreNonNumberElement(Node* node) {
2602Type Typer::Visitor::TypeStoreSignedSmallElement(Node* node) {
UNREACHABLE(); }
2604Type Typer::Visitor::TypeStoreTypedElement(Node* node) {
UNREACHABLE(); }
2606Type Typer::Visitor::TypeStoreDataViewElement(Node* node) {
UNREACHABLE(); }
2608Type Typer::Visitor::TypeObjectIsArrayBufferView(Node* node) {
2609 return TypeUnaryOp(node, ObjectIsArrayBufferView);
2612Type Typer::Visitor::TypeObjectIsBigInt(Node* node) {
2613 return TypeUnaryOp(node, ObjectIsBigInt);
2616Type Typer::Visitor::TypeObjectIsCallable(Node* node) {
2617 return TypeUnaryOp(node, ObjectIsCallable);
2620Type Typer::Visitor::TypeObjectIsConstructor(Node* node) {
2621 return TypeUnaryOp(node, ObjectIsConstructor);
2624Type Typer::Visitor::TypeObjectIsDetectableCallable(Node* node) {
2625 return TypeUnaryOp(node, ObjectIsDetectableCallable);
2628Type Typer::Visitor::TypeObjectIsMinusZero(Node* node) {
2629 return TypeUnaryOp(node, ObjectIsMinusZero);
2632Type Typer::Visitor::TypeNumberIsMinusZero(Node* node) {
2633 return TypeUnaryOp(node, NumberIsMinusZero);
2636Type Typer::Visitor::TypeNumberIsFloat64Hole(Node* node) {
2637 return Type::Boolean();
2640Type Typer::Visitor::TypeNumberIsFinite(Node* node) {
return Type::Boolean(); }
2642Type Typer::Visitor::TypeObjectIsFiniteNumber(Node* node) {
2643 return Type::Boolean();
2646Type Typer::Visitor::TypeNumberIsInteger(Node* node) {
UNREACHABLE(); }
2648Type Typer::Visitor::TypeObjectIsSafeInteger(Node* node) {
2649 return Type::Boolean();
2652Type Typer::Visitor::TypeNumberIsSafeInteger(Node* node) {
UNREACHABLE(); }
2654Type Typer::Visitor::TypeObjectIsInteger(Node* node) {
return Type::Boolean(); }
2656Type Typer::Visitor::TypeObjectIsNaN(Node* node) {
2657 return TypeUnaryOp(node, ObjectIsNaN);
2660Type Typer::Visitor::TypeNumberIsNaN(Node* node) {
2661 return TypeUnaryOp(node, NumberIsNaN);
2664Type Typer::Visitor::TypeObjectIsNonCallable(Node* node) {
2665 return TypeUnaryOp(node, ObjectIsNonCallable);
2668Type Typer::Visitor::TypeObjectIsNumber(Node* node) {
2669 return TypeUnaryOp(node, ObjectIsNumber);
2672Type Typer::Visitor::TypeObjectIsReceiver(Node* node) {
2673 return TypeUnaryOp(node, ObjectIsReceiver);
2676Type Typer::Visitor::TypeObjectIsSmi(Node* node) {
2677 return TypeUnaryOp(node, ObjectIsSmi);
2680Type Typer::Visitor::TypeObjectIsString(Node* node) {
2681 return TypeUnaryOp(node, ObjectIsString);
2684Type Typer::Visitor::TypeObjectIsSymbol(Node* node) {
2685 return TypeUnaryOp(node, ObjectIsSymbol);
2688Type Typer::Visitor::TypeObjectIsUndetectable(Node* node) {
2689 return TypeUnaryOp(node, ObjectIsUndetectable);
2692Type Typer::Visitor::TypeArgumentsLength(Node* node) {
2696Type Typer::Visitor::TypeRestLength(Node* node) {
2700Type Typer::Visitor::TypeTypedArrayLength(Node* node) {
2704Type Typer::Visitor::TypeNewDoubleElements(Node* node) {
2705 return Type::OtherInternal();
2708Type Typer::Visitor::TypeNewSmiOrObjectElements(Node* node) {
2709 return Type::OtherInternal();
2712Type Typer::Visitor::TypeNewArgumentsElements(Node* node) {
2713 return Type::OtherInternal();
2716Type Typer::Visitor::TypeNewConsString(Node* node) {
return Type::String(); }
2718Type Typer::Visitor::TypeFindOrderedHashMapEntry(Node* node) {
2722Type Typer::Visitor::TypeFindOrderedHashMapEntryForInt32Key(Node* node) {
2726Type Typer::Visitor::TypeFindOrderedHashSetEntry(Node* node) {
2730Type Typer::Visitor::TypeRuntimeAbort(Node* node) {
UNREACHABLE(); }
2732Type Typer::Visitor::TypeAssertType(Node* node) {
UNREACHABLE(); }
2734Type Typer::Visitor::TypeVerifyType(Node* node) {
UNREACHABLE(); }
2736Type Typer::Visitor::TypeCheckTurboshaftTypeOf(Node* node) {
2737 return TypeOrNone(node->InputAt(0));
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype)
#define Assert(condition)
@ CONTEXT_SIDE_TABLE_PROPERTY_INDEX
static constexpr int kMaxLength
static const uint32_t kMaxLength
static const base::uc32 kMaxCodePoint
const ZoneVector< Bound > & lower_bounds()
const ZoneVector< Bound > & upper_bounds()
static constexpr int kJSCallClosureParamIndex
static const int kOsrContextSpillSlotIndex
void ChangeToInductionVariablePhis()
void ChangeToPhisAndInsertGuards()
const ZoneMap< int, InductionVariable * > & induction_variables()
static Type GetType(const Node *node)
static bool IsTyped(const Node *node)
static bool AllValueInputsAreTyped(Node *node)
static Node * GetValueInput(Node *node, int index)
static void SetType(Node *node, Type type)
static Node * GetControlInput(Node *node, int index=0)
constexpr IrOpcode::Value opcode() const
const Operator * op() const
Node * InputAt(int index) const
Type TypeTypeGuard(const Operator *sigma_op, Type input)
Type CheckFloat64Hole(Type type)
Type CheckNumber(Type type)
Type ToNumberConvertBigInt(Type type)
Type ConvertTaggedHoleToUndefined(Type type)
Type singleton_false() const
Type singleton_true() const
Type CheckBounds(Type index, Type length)
Type CheckNumberFitsInt32(Type type)
static Reduction Changed(Node *node)
static Reduction NoChange()
void AddDecorator(GraphDecorator *decorator)
void RemoveDecorator(GraphDecorator *decorator)
Type const kStringLengthType
Type const kArgumentsLengthType
Type const kJSTypedArrayLengthType
Type const kFixedArrayLengthType
static TypeCache const * Get()
Type const kSingletonZero
static Type UnsignedSmall()
static Type Union(Type type1, Type type2, Zone *zone)
bool Maybe(Type that) const
bool IsHeapConstant() const
const HeapConstantType * AsHeapConstant() const
static Type Constant(JSHeapBroker *broker, Handle< i::Object > value, Zone *zone)
static Type SignedSmall()
static Type Tuple(Type first, Type second, Type third, Zone *zone)
static Type Intersect(Type type1, Type type2, Zone *zone)
static Type Range(double min, double max, Zone *zone)
void Decorate(Node *node) final
Type TypeUnaryOp(Node *node, UnaryTyperFun)
static Type ToInteger(Type, Typer *)
static Type JSCallTyper(Type, Typer *)
static ComparisonOutcome JSCompareTyper(Type, Type, Typer *)
Type TypeOrNone(Node *node)
Type TypeNode(Node *node)
Type Weaken(Node *node, Type current_type, Type previous_type)
static Type ObjectIsNumber(Type, Typer *)
static Type SameValueTyper(Type, Type, Typer *)
static Type StringFromSingleCharCodeTyper(Type, Typer *)
LoopVariableOptimizer * induction_vars_
static Type ToBigIntConvertNumber(Type, Typer *)
bool InductionVariablePhiTypeIsPrefixedPoint(InductionVariable *induction_var)
static ComparisonOutcome NumberCompareTyper(Type, Type, Typer *)
static Type ObjectIsBigInt(Type, Typer *)
static Type Decrement(Type, Typer *)
static Type ObjectIsNonCallable(Type, Typer *)
static Type ObjectIsCallable(Type, Typer *)
static Type NumberLessThanTyper(Type, Type, Typer *)
static Type ObjectIsString(Type, Typer *)
ZoneSet< NodeId > weakened_nodes_
static Type StringFromSingleCodePointTyper(Type, Typer *)
Type TypeBinaryOp(Node *node, BinaryTyperFun)
void SetWeakened(NodeId node_id)
static Type BinaryNumberOpTyper(Type lhs, Type rhs, Typer *t, BinaryTyperFun f)
bool IsWeakened(NodeId node_id)
static Type NumberLessThanOrEqualTyper(Type, Type, Typer *)
static Type ReferenceEqualTyper(Type, Type, Typer *)
static Type NumberIsMinusZero(Type, Typer *)
static Type Negate(Type, Typer *)
Reduction UpdateType(Node *node, Type current)
static Type ToNumeric(Type, Typer *)
static Type ToObject(Type, Typer *)
Visitor(Typer *typer, LoopVariableOptimizer *induction_vars)
static Type ObjectIsUndetectable(Type, Typer *)
const char * reducer_name() const override
static Type NumberEqualTyper(Type, Type, Typer *)
static Type BigIntCompareTyper(Type, Type, Typer *)
static Type BitwiseNot(Type, Typer *)
static Type ObjectIsMinusZero(Type, Typer *)
static Type ToBoolean(Type, Typer *)
static Type SameValueNumbersOnlyTyper(Type, Type, Typer *)
static Type ObjectIsSmi(Type, Typer *)
static Type ToLength(Type, Typer *)
static Type ObjectIsDetectableCallable(Type, Typer *)
static Type ToString(Type, Typer *)
Type Operand(Node *node, int i)
static Type ObjectIsSymbol(Type, Typer *)
static ComparisonOutcome Invert(ComparisonOutcome, Typer *)
static Type ToPrimitive(Type, Typer *)
static Type Increment(Type, Typer *)
static Type ToBigInt(Type, Typer *)
Type(*)(Type, Typer *t) UnaryTyperFun
Type(*)(Type, Type, Typer *t) BinaryTyperFun
static Type ToName(Type, Typer *)
static Type NumberIsNaN(Type, Typer *)
static Type ObjectIsArrayBufferView(Type, Typer *)
static Type FalsifyUndefined(ComparisonOutcome, Typer *)
Reduction Reduce(Node *node) override
static Type ToNumberConvertBigInt(Type, Typer *)
static Type ToNumber(Type, Typer *)
Type TypeConstant(Handle< Object > value)
static Type ObjectIsConstructor(Type, Typer *)
static Type ObjectIsNaN(Type, Typer *)
static Type ObjectIsReceiver(Type, Typer *)
JSHeapBroker * broker() const
OperationTyper * operation_typer()
TickCounter *const tick_counter_
OperationTyper operation_typer_
Typer(JSHeapBroker *broker, Flags flags, TFGraph *graph, TickCounter *tick_counter)
JSHeapBroker *const broker_
ZoneVector< RpoNumber > & result
V8_INLINE const Operation & Get(const Graph &graph, OpIndex index)
FastApiCallParameters const & FastApiCallParametersOf(const Operator *op)
size_t ProjectionIndexOf(const Operator *const op)
const CallRuntimeParameters & CallRuntimeParametersOf(const Operator *op)
Handle< HeapObject > HeapConstantOf(const Operator *op)
ZoneVector< Node * > NodeVector
int ParameterIndexOf(const Operator *const op)
const FieldAccess & FieldAccessOf(const Operator *op)
const ElementAccess & ElementAccessOf(const Operator *op)
Type AllocateTypeOf(const Operator *op)
Handle< FeedbackCell > FeedbackCellOf(const Operator *op)
ExternalArrayType ExternalArrayTypeOf(const Operator *op)
T const & OpParameter(const Operator *op)
std::string ToString(const BytecodeLivenessState &liveness)
CreateArgumentsType const & CreateArgumentsTypeOf(const Operator *op)
const ExitMachineGraphParameters & ExitMachineGraphParametersOf(const Operator *op)
ContextAccess const & ContextAccessOf(Operator const *op)
int OsrValueIndexOf(Operator const *op)
ref_traits< T >::ref_type MakeRef(JSHeapBroker *broker, Tagged< T > object)
constexpr double kMaxSafeInteger
bool IsClassConstructor(FunctionKind kind)
int ToNumber(Register reg)
void Terminate(Isolate *isolate)
V8_EXPORT_PRIVATE FlagValues v8_flags
#define SIMPLIFIED_OTHER_OP_LIST(V)
#define MACHINE_SIMD256_OP_LIST(V)
#define JS_CONTEXT_OP_LIST(V)
#define MACHINE_FLOAT32_UNOP_LIST(V)
#define SIMPLIFIED_BIGINT_UNOP_LIST(V)
#define JS_SIMPLE_UNOP_LIST(V)
#define SIMPLIFIED_BIGINT_BINOP_LIST(V)
#define SIMPLIFIED_CHECKED_OP_LIST(V)
#define JS_OTHER_OP_LIST(V)
#define SIMPLIFIED_NUMBER_UNOP_LIST(V)
#define MACHINE_FLOAT32_BINOP_LIST(V)
#define JS_OBJECT_OP_LIST(V)
#define SIMPLIFIED_SPECULATIVE_BIGINT_UNOP_LIST(V)
#define SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(V)
#define SIMPLIFIED_COMPARE_BINOP_LIST(V)
#define COMMON_OP_LIST(V)
#define JS_SIMPLE_BINOP_LIST(V)
#define MACHINE_FLOAT64_BINOP_LIST(V)
#define MACHINE_UNOP_32_LIST(V)
#define MACHINE_ATOMIC_OP_LIST(V)
#define MACHINE_SIMD128_OP_LIST(V)
#define SIMPLIFIED_SPECULATIVE_BIGINT_BINOP_LIST(V)
#define SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V)
#define SIMPLIFIED_WASM_OP_LIST(V)
#define SIMPLIFIED_NUMBER_BINOP_LIST(V)
#define SIMPLIFIED_CHANGE_OP_LIST(V)
#define MACHINE_FLOAT64_UNOP_LIST(V)
#define DECLARE_METHOD(Name)
#define TYPER_SUPPORTED_MACHINE_BINOP_LIST(V)
#define DCHECK_NE(v1, v2)
#define DCHECK(condition)
#define DCHECK_EQ(v1, v2)
#define DECLARE_BINARY_CASE(x,...)
#define DECLARE_UNARY_CASE(x,...)
#define BIGINT_COMPARISON_BINOP(Name)
#define DECLARE_IMPOSSIBLE_CASE(x,...)
#define DEFINE_METHOD(Name)
#define DECLARE_OTHER_CASE(x,...)
#define V8_UNLIKELY(condition)