@@ -102,6 +102,7 @@ export namespace BuiltinSymbols {
102102 export const isDefined = "~lib/builtins/isDefined" ;
103103 export const isConstant = "~lib/builtins/isConstant" ;
104104 export const isManaged = "~lib/builtins/isManaged" ;
105+ export const isVoid = "~lib/builtins/isVoid" ;
105106
106107 export const clz = "~lib/builtins/clz" ;
107108 export const ctz = "~lib/builtins/ctz" ;
@@ -135,6 +136,8 @@ export namespace BuiltinSymbols {
135136 export const sizeof = "~lib/builtins/sizeof" ;
136137 export const alignof = "~lib/builtins/alignof" ;
137138 export const offsetof = "~lib/builtins/offsetof" ;
139+ export const nameof = "~lib/builtins/nameof" ;
140+ export const lengthof = "~lib/builtins/lengthof" ;
138141 export const select = "~lib/builtins/select" ;
139142 export const unreachable = "~lib/builtins/unreachable" ;
140143 export const changetype = "~lib/builtins/changetype" ;
@@ -658,6 +661,30 @@ export function compileCall(
658661 if ( ! type ) return module . unreachable ( ) ;
659662 return module . i32 ( type . isManaged ? 1 : 0 ) ;
660663 }
664+ case BuiltinSymbols . isVoid : { // isVoid<T>() -> bool
665+ let type = evaluateConstantType ( compiler , typeArguments , operands , reportNode ) ;
666+ compiler . currentType = Type . bool ;
667+ if ( ! type ) return module . unreachable ( ) ;
668+ return module . i32 ( type . kind == TypeKind . VOID ? 1 : 0 ) ;
669+ }
670+ case BuiltinSymbols . lengthof : { // lengthof<T>(): i32
671+ let type = evaluateConstantType ( compiler , typeArguments , operands , reportNode ) ;
672+ compiler . currentType = Type . i32 ;
673+ if ( ! type ) return module . unreachable ( ) ;
674+
675+ // Report if there is no call signature
676+ let signatureReference = type . signatureReference ;
677+ if ( ! signatureReference ) {
678+ compiler . error (
679+ DiagnosticCode . Type_0_has_no_call_signatures ,
680+ reportNode . range , "1" , ( typeArguments ? typeArguments . length : 1 ) . toString ( 10 )
681+ ) ;
682+ return module . unreachable ( ) ;
683+ }
684+
685+ let parameterNames = signatureReference . parameterNames ;
686+ return module . i32 ( ! parameterNames ? 0 : parameterNames . length ) ;
687+ }
661688 case BuiltinSymbols . sizeof : { // sizeof<T!>() -> usize
662689 compiler . currentType = compiler . options . usizeType ;
663690 if (
@@ -771,6 +798,45 @@ export function compileCall(
771798 }
772799 }
773800 }
801+ case BuiltinSymbols . nameof : {
802+ // Check to make sure a parameter or a type was passed to the builtin
803+ let resultType = evaluateConstantType ( compiler , typeArguments , operands , reportNode ) ;
804+ if ( ! resultType ) return module . unreachable ( ) ;
805+
806+ let value : string ;
807+ if ( resultType . is ( TypeFlags . REFERENCE ) ) {
808+ let classReference = resultType . classReference ;
809+ if ( ! classReference ) {
810+ assert ( resultType . signatureReference ) ;
811+ value = "Function" ;
812+ } else {
813+ value = classReference . name ;
814+ }
815+ } else {
816+ switch ( resultType . kind ) {
817+ case TypeKind . BOOL : { value = "bool" ; break ; }
818+ case TypeKind . I8 : { value = "i8" ; break ; }
819+ case TypeKind . U8 : { value = "u8" ; break ; }
820+ case TypeKind . I16 : { value = "i16" ; break ; }
821+ case TypeKind . U16 : { value = "u16" ; break ; }
822+ case TypeKind . I32 : { value = "i32" ; break ; }
823+ case TypeKind . U32 : { value = "u32" ; break ; }
824+ case TypeKind . F32 : { value = "f32" ; break ; }
825+ case TypeKind . I64 : { value = "i64" ; break ; }
826+ case TypeKind . U64 : { value = "u64" ; break ; }
827+ case TypeKind . F64 : { value = "f64" ; break ; }
828+ case TypeKind . ISIZE : { value = "isize" ; break ; }
829+ case TypeKind . USIZE : { value = "usize" ; break ; }
830+ case TypeKind . V128 : { value = "v128" ; break ; }
831+ // If the kind is not set properly, throw an error.
832+ // The default case falls through to satisfy that value is always set, and never null.
833+ default : assert ( false ) ;
834+ case TypeKind . VOID : { value = "void" ; break ; }
835+ }
836+ }
837+
838+ return compiler . ensureStaticString ( value ) ;
839+ }
774840
775841 // === Math ===================================================================================
776842
@@ -3593,6 +3659,11 @@ export function compileCall(
35933659 let type = evaluateConstantType ( compiler , typeArguments , operands , reportNode ) ;
35943660 compiler . currentType = Type . u32 ;
35953661 if ( ! type ) return module . unreachable ( ) ;
3662+ let signatureReference = type . signatureReference ;
3663+ if ( type . is ( TypeFlags . REFERENCE ) && signatureReference !== null ) {
3664+ return module . i32 ( signatureReference . id ) ;
3665+ }
3666+
35963667 let classReference = type . classReference ;
35973668 if ( ! classReference || classReference . hasDecorator ( DecoratorFlags . UNMANAGED ) ) {
35983669 compiler . error (
0 commit comments