@@ -200,6 +200,10 @@ mutable struct ErrorException <: Exception
200200 ErrorException (msg:: AbstractString ) = new (msg)
201201end
202202
203+ macro _inline_meta ()
204+ Expr (:meta , :inline )
205+ end
206+
203207macro _noinline_meta ()
204208 Expr (:meta , :noinline )
205209end
@@ -437,4 +441,167 @@ show(@nospecialize a) = show(STDOUT, a)
437441print (@nospecialize a... ) = print (STDOUT, a... )
438442println (@nospecialize a... ) = println (STDOUT, a... )
439443
444+ # constructors for built-in types
445+
446+ import . Intrinsics: eq_int, trunc_int, lshr_int, sub_int, shl_int, bitcast, sext_int, zext_int, and_int
447+
448+ throw_inexacterror (f:: Symbol , T:: Type , val) = (@_noinline_meta ; throw (InexactError (f, T, val)))
449+
450+ function is_top_bit_set (x)
451+ @_inline_meta
452+ eq_int (trunc_int (Int8, lshr_int (x, sub_int (shl_int (sizeof (x), 3 ), 1 ))), trunc_int (Int8, 1 ))
453+ end
454+
455+ function check_top_bit (x)
456+ @_inline_meta
457+ is_top_bit_set (x) && throw_inexacterror (:check_top_bit , typeof (x), x)
458+ x
459+ end
460+
461+ function checked_trunc_sint (:: Type{To} , x:: From ) where {To,From}
462+ @_inline_meta
463+ y = trunc_int (To, x)
464+ back = sext_int (From, y)
465+ eq_int (x, back) || throw_inexacterror (:trunc , To, x)
466+ y
467+ end
468+
469+ function checked_trunc_uint (:: Type{To} , x:: From ) where {To,From}
470+ @_inline_meta
471+ y = trunc_int (To, x)
472+ back = zext_int (From, y)
473+ eq_int (x, back) || throw_inexacterror (:trunc , To, x)
474+ y
475+ end
476+
477+ toInt8 (x:: Int8 ) = x
478+ toInt8 (x:: Int16 ) = checked_trunc_sint (Int8, x)
479+ toInt8 (x:: Int32 ) = checked_trunc_sint (Int8, x)
480+ toInt8 (x:: Int64 ) = checked_trunc_sint (Int8, x)
481+ toInt8 (x:: Int128 ) = checked_trunc_sint (Int8, x)
482+ toInt8 (x:: UInt8 ) = bitcast (Int8, check_top_bit (x))
483+ toInt8 (x:: UInt16 ) = checked_trunc_sint (Int8, check_top_bit (x))
484+ toInt8 (x:: UInt32 ) = checked_trunc_sint (Int8, check_top_bit (x))
485+ toInt8 (x:: UInt64 ) = checked_trunc_sint (Int8, check_top_bit (x))
486+ toInt8 (x:: UInt128 ) = checked_trunc_sint (Int8, check_top_bit (x))
487+ toInt8 (x:: Bool ) = and_int (zext_int (Int8, x), Int8 (1 ))
488+ toInt16 (x:: Int8 ) = sext_int (Int16, x)
489+ toInt16 (x:: Int16 ) = x
490+ toInt16 (x:: Int32 ) = checked_trunc_sint (Int16, x)
491+ toInt16 (x:: Int64 ) = checked_trunc_sint (Int16, x)
492+ toInt16 (x:: Int128 ) = checked_trunc_sint (Int16, x)
493+ toInt16 (x:: UInt8 ) = zext_int (Int16, x)
494+ toInt16 (x:: UInt16 ) = bitcast (Int16, check_top_bit (x))
495+ toInt16 (x:: UInt32 ) = checked_trunc_sint (Int16, check_top_bit (x))
496+ toInt16 (x:: UInt64 ) = checked_trunc_sint (Int16, check_top_bit (x))
497+ toInt16 (x:: UInt128 ) = checked_trunc_sint (Int16, check_top_bit (x))
498+ toInt16 (x:: Bool ) = and_int (zext_int (Int16, x), Int16 (1 ))
499+ toInt32 (x:: Int8 ) = sext_int (Int32, x)
500+ toInt32 (x:: Int16 ) = sext_int (Int32, x)
501+ toInt32 (x:: Int32 ) = x
502+ toInt32 (x:: Int64 ) = checked_trunc_sint (Int32, x)
503+ toInt32 (x:: Int128 ) = checked_trunc_sint (Int32, x)
504+ toInt32 (x:: UInt8 ) = zext_int (Int32, x)
505+ toInt32 (x:: UInt16 ) = zext_int (Int32, x)
506+ toInt32 (x:: UInt32 ) = bitcast (Int32, check_top_bit (x))
507+ toInt32 (x:: UInt64 ) = checked_trunc_sint (Int32, check_top_bit (x))
508+ toInt32 (x:: UInt128 ) = checked_trunc_sint (Int32, check_top_bit (x))
509+ toInt32 (x:: Bool ) = and_int (zext_int (Int32, x), Int32 (1 ))
510+ toInt64 (x:: Int8 ) = sext_int (Int64, x)
511+ toInt64 (x:: Int16 ) = sext_int (Int64, x)
512+ toInt64 (x:: Int32 ) = sext_int (Int64, x)
513+ toInt64 (x:: Int64 ) = x
514+ toInt64 (x:: Int128 ) = checked_trunc_sint (Int64, x)
515+ toInt64 (x:: UInt8 ) = zext_int (Int64, x)
516+ toInt64 (x:: UInt16 ) = zext_int (Int64, x)
517+ toInt64 (x:: UInt32 ) = zext_int (Int64, x)
518+ toInt64 (x:: UInt64 ) = bitcast (Int64, check_top_bit (x))
519+ toInt64 (x:: UInt128 ) = checked_trunc_sint (Int64, check_top_bit (x))
520+ toInt64 (x:: Bool ) = and_int (zext_int (Int64, x), Int64 (1 ))
521+ toInt128 (x:: Int8 ) = sext_int (Int128, x)
522+ toInt128 (x:: Int16 ) = sext_int (Int128, x)
523+ toInt128 (x:: Int32 ) = sext_int (Int128, x)
524+ toInt128 (x:: Int64 ) = sext_int (Int128, x)
525+ toInt128 (x:: Int128 ) = x
526+ toInt128 (x:: UInt8 ) = zext_int (Int128, x)
527+ toInt128 (x:: UInt16 ) = zext_int (Int128, x)
528+ toInt128 (x:: UInt32 ) = zext_int (Int128, x)
529+ toInt128 (x:: UInt64 ) = zext_int (Int128, x)
530+ toInt128 (x:: UInt128 ) = bitcast (Int128, check_top_bit (x))
531+ toInt128 (x:: Bool ) = and_int (zext_int (Int128, x), Int128 (1 ))
532+ toUInt8 (x:: Int8 ) = bitcast (UInt8, check_top_bit (x))
533+ toUInt8 (x:: Int16 ) = checked_trunc_uint (UInt8, x)
534+ toUInt8 (x:: Int32 ) = checked_trunc_uint (UInt8, x)
535+ toUInt8 (x:: Int64 ) = checked_trunc_uint (UInt8, x)
536+ toUInt8 (x:: Int128 ) = checked_trunc_uint (UInt8, x)
537+ toUInt8 (x:: UInt8 ) = x
538+ toUInt8 (x:: UInt16 ) = checked_trunc_uint (UInt8, x)
539+ toUInt8 (x:: UInt32 ) = checked_trunc_uint (UInt8, x)
540+ toUInt8 (x:: UInt64 ) = checked_trunc_uint (UInt8, x)
541+ toUInt8 (x:: UInt128 ) = checked_trunc_uint (UInt8, x)
542+ toUInt8 (x:: Bool ) = and_int (zext_int (UInt8, x), UInt8 (1 ))
543+ toUInt16 (x:: Int8 ) = sext_int (UInt16, check_top_bit (x))
544+ toUInt16 (x:: Int16 ) = bitcast (UInt16, check_top_bit (x))
545+ toUInt16 (x:: Int32 ) = checked_trunc_uint (UInt16, x)
546+ toUInt16 (x:: Int64 ) = checked_trunc_uint (UInt16, x)
547+ toUInt16 (x:: Int128 ) = checked_trunc_uint (UInt16, x)
548+ toUInt16 (x:: UInt8 ) = zext_int (UInt16, x)
549+ toUInt16 (x:: UInt16 ) = x
550+ toUInt16 (x:: UInt32 ) = checked_trunc_uint (UInt16, x)
551+ toUInt16 (x:: UInt64 ) = checked_trunc_uint (UInt16, x)
552+ toUInt16 (x:: UInt128 ) = checked_trunc_uint (UInt16, x)
553+ toUInt16 (x:: Bool ) = and_int (zext_int (UInt16, x), UInt16 (1 ))
554+ toUInt32 (x:: Int8 ) = sext_int (UInt32, check_top_bit (x))
555+ toUInt32 (x:: Int16 ) = sext_int (UInt32, check_top_bit (x))
556+ toUInt32 (x:: Int32 ) = bitcast (UInt32, check_top_bit (x))
557+ toUInt32 (x:: Int64 ) = checked_trunc_uint (UInt32, x)
558+ toUInt32 (x:: Int128 ) = checked_trunc_uint (UInt32, x)
559+ toUInt32 (x:: UInt8 ) = zext_int (UInt32, x)
560+ toUInt32 (x:: UInt16 ) = zext_int (UInt32, x)
561+ toUInt32 (x:: UInt32 ) = x
562+ toUInt32 (x:: UInt64 ) = checked_trunc_uint (UInt32, x)
563+ toUInt32 (x:: UInt128 ) = checked_trunc_uint (UInt32, x)
564+ toUInt32 (x:: Bool ) = and_int (zext_int (UInt32, x), UInt32 (1 ))
565+ toUInt64 (x:: Int8 ) = sext_int (UInt64, check_top_bit (x))
566+ toUInt64 (x:: Int16 ) = sext_int (UInt64, check_top_bit (x))
567+ toUInt64 (x:: Int32 ) = sext_int (UInt64, check_top_bit (x))
568+ toUInt64 (x:: Int64 ) = bitcast (UInt64, check_top_bit (x))
569+ toUInt64 (x:: Int128 ) = checked_trunc_uint (UInt64, x)
570+ toUInt64 (x:: UInt8 ) = zext_int (UInt64, x)
571+ toUInt64 (x:: UInt16 ) = zext_int (UInt64, x)
572+ toUInt64 (x:: UInt32 ) = zext_int (UInt64, x)
573+ toUInt64 (x:: UInt64 ) = x
574+ toUInt64 (x:: UInt128 ) = checked_trunc_uint (UInt64, x)
575+ toUInt64 (x:: Bool ) = and_int (zext_int (UInt64, x), UInt64 (1 ))
576+ toUInt128 (x:: Int8 ) = sext_int (UInt128, check_top_bit (x))
577+ toUInt128 (x:: Int16 ) = sext_int (UInt128, check_top_bit (x))
578+ toUInt128 (x:: Int32 ) = sext_int (UInt128, check_top_bit (x))
579+ toUInt128 (x:: Int64 ) = sext_int (UInt128, check_top_bit (x))
580+ toUInt128 (x:: Int128 ) = bitcast (UInt128, check_top_bit (x))
581+ toUInt128 (x:: UInt8 ) = zext_int (UInt128, x)
582+ toUInt128 (x:: UInt16 ) = zext_int (UInt128, x)
583+ toUInt128 (x:: UInt32 ) = zext_int (UInt128, x)
584+ toUInt128 (x:: UInt64 ) = zext_int (UInt128, x)
585+ toUInt128 (x:: UInt128 ) = x
586+ toUInt128 (x:: Bool ) = and_int (zext_int (UInt128, x), UInt128 (1 ))
587+
588+ # TODO : this is here to work around the 4 method limit in inference (#23210).
589+ const BuiltinInts = Union{Int128, Int16, Int32, Int64, Int8, UInt128, UInt16, UInt32, UInt64, UInt8, Bool}
590+ Int8 (x:: BuiltinInts ) = toInt8 (x):: Int8
591+ Int16 (x:: BuiltinInts ) = toInt16 (x):: Int16
592+ Int32 (x:: BuiltinInts ) = toInt32 (x):: Int32
593+ Int64 (x:: BuiltinInts ) = toInt64 (x):: Int64
594+ Int128 (x:: BuiltinInts ) = toInt128 (x):: Int128
595+ UInt8 (x:: BuiltinInts ) = toUInt8 (x):: UInt8
596+ UInt16 (x:: BuiltinInts ) = toUInt16 (x):: UInt16
597+ UInt32 (x:: BuiltinInts ) = toUInt32 (x):: UInt32
598+ UInt64 (x:: BuiltinInts ) = toUInt64 (x):: UInt64
599+ UInt128 (x:: BuiltinInts ) = toUInt128 (x):: UInt128
600+
601+ Bool (x:: Bool ) = x
602+
603+ Int (x:: Ptr ) = bitcast (Int, x)
604+ UInt (x:: Ptr ) = bitcast (UInt, x)
605+ Ptr {T} (x:: Union{Int,UInt,Ptr} ) where {T} = bitcast (Ptr{T}, x)
606+
440607ccall (:jl_set_istopmod , Void, (Any, Bool), Core, true )
0 commit comments