77 Class ,
88 FunctionTarget ,
99 Program ,
10- DecoratorFlags
10+ DecoratorFlags ,
11+ Local
1112} from "./program" ;
1213
1314import {
@@ -95,7 +96,9 @@ export const enum TypeFlags {
9596 /** Is a vector type. */
9697 VECTOR = 1 << 10 ,
9798 /** Is a host type. */
98- HOST = 1 << 11
99+ HOST = 1 << 11 ,
100+ /** Is a closure type. */
101+ IN_SCOPE_CLOSURE = 1 << 12
99102}
100103
101104/** Represents a resolved type. */
@@ -113,6 +116,8 @@ export class Type {
113116 classReference : Class | null ;
114117 /** Underlying signature reference, if a function type. */
115118 signatureReference : Signature | null ;
119+ /** closed over locals */
120+ locals : Map < string , Local > | null ;
116121 /** Respective non-nullable type, if nullable. */
117122 nonNullableType : Type ;
118123 /** Cached nullable type, if non-nullable. */
@@ -127,6 +132,7 @@ export class Type {
127132 this . classReference = null ;
128133 this . signatureReference = null ;
129134 this . nonNullableType = this ;
135+ this . locals = null ;
130136 }
131137
132138 /** Returns the closest int type representing this type. */
@@ -163,6 +169,7 @@ export class Type {
163169
164170 /** Tests if this is a managed type that needs GC hooks. */
165171 get isManaged ( ) : bool {
172+ if ( this . isFunctionIndex ) return true ;
166173 if ( this . is ( TypeFlags . INTEGER | TypeFlags . REFERENCE ) ) {
167174 let classReference = this . classReference ;
168175 if ( classReference ) return ! classReference . hasDecorator ( DecoratorFlags . UNMANAGED ) ;
@@ -177,6 +184,10 @@ export class Type {
177184 return classReference !== null && classReference . hasDecorator ( DecoratorFlags . UNMANAGED ) ;
178185 }
179186
187+ get isFunctionIndex ( ) : bool {
188+ return this . signatureReference !== null && ! this . is ( TypeFlags . IN_SCOPE_CLOSURE ) ;
189+ }
190+
180191 /** Computes the sign-extending shift in the target type. */
181192 computeSmallIntegerShift ( targetType : Type ) : i32 {
182193 return targetType . size - this . size ;
@@ -517,6 +528,13 @@ export class Type {
517528
518529 /** Alias of i32 indicating type inference of locals and globals with just an initializer. */
519530 static readonly auto : Type = new Type ( Type . i32 . kind , Type . i32 . flags , Type . i32 . size ) ;
531+
532+ /** Type of an in-context local */
533+ static readonly closure32 : Type = new Type ( Type . i32 . kind ,
534+ TypeFlags . IN_SCOPE_CLOSURE |
535+ TypeFlags . REFERENCE ,
536+ Type . i32 . size
537+ ) ;
520538}
521539
522540/** Converts an array of types to an array of native types. */
@@ -626,18 +644,8 @@ export class Signature {
626644 : getDefaultParameterName ( index ) ;
627645 }
628646
629- /** Tests if this signature equals the specified. */
630- equals ( other : Signature ) : bool {
631-
632- // check `this` type
633- var thisThisType = this . thisType ;
634- var otherThisType = other . thisType ;
635- if ( thisThisType !== null ) {
636- if ( otherThisType === null || ! thisThisType . equals ( otherThisType ) ) return false ;
637- } else if ( otherThisType ) {
638- return false ;
639- }
640-
647+ // Check to see if this signature is equivalent to the caller, ignoring the this type
648+ externalEquals ( other : Signature ) : bool {
641649 // check rest parameter
642650 if ( this . hasRest != other . hasRest ) return false ;
643651
@@ -654,6 +662,20 @@ export class Signature {
654662 return this . returnType . equals ( other . returnType ) ;
655663 }
656664
665+ /** Tests if this signature equals the specified. */
666+ equals ( other : Signature ) : bool {
667+ // check `this` type
668+ var thisThisType = this . thisType ;
669+ var otherThisType = other . thisType ;
670+ if ( thisThisType !== null ) {
671+ if ( otherThisType === null || ! thisThisType . equals ( otherThisType ) ) return false ;
672+ } else if ( otherThisType !== null ) {
673+ return false ;
674+ }
675+
676+ return this . externalEquals ( other ) ;
677+ }
678+
657679 /** Tests if a value of this function type is assignable to a target of the specified function type. */
658680 isAssignableTo ( target : Signature , requireSameSize : bool = false ) : bool {
659681
@@ -720,6 +742,20 @@ export class Signature {
720742 return sb . join ( "" ) ;
721743 }
722744
745+ toClosureSignature ( ) : Signature {
746+ var closureSignature = this . clone ( ) ;
747+ closureSignature . thisType = this . program . options . usizeType ;
748+ return closureSignature ;
749+ }
750+
751+ // Reverses toClosureSignature, for when we recompile a function with the context argument
752+ // Not convinced this is the right way to go about getting the original unmodified signature, but it works
753+ toAnonymousSignature ( ) : Signature {
754+ var normalSignature = this . clone ( ) ;
755+ normalSignature . thisType = null ;
756+ return normalSignature ;
757+ }
758+
723759 /** Creates a clone of this signature that is safe to modify. */
724760 clone ( ) : Signature {
725761 var parameterTypes = this . parameterTypes ;
@@ -738,6 +774,7 @@ export class Signature {
738774 }
739775 clone . parameterNames = cloneParameterNames ;
740776 }
777+ clone . requiredParameters = this . requiredParameters ;
741778 return clone ;
742779 }
743780}
0 commit comments