7
7
Class ,
8
8
FunctionTarget ,
9
9
Program ,
10
- DecoratorFlags
10
+ DecoratorFlags ,
11
+ Local
11
12
} from "./program" ;
12
13
13
14
import {
@@ -95,7 +96,9 @@ export const enum TypeFlags {
95
96
/** Is a vector type. */
96
97
VECTOR = 1 << 10 ,
97
98
/** Is a host type. */
98
- HOST = 1 << 11
99
+ HOST = 1 << 11 ,
100
+ /** Is a closure type. */
101
+ IN_SCOPE_CLOSURE = 1 << 12
99
102
}
100
103
101
104
/** Represents a resolved type. */
@@ -113,6 +116,8 @@ export class Type {
113
116
classReference : Class | null ;
114
117
/** Underlying signature reference, if a function type. */
115
118
signatureReference : Signature | null ;
119
+ /** closed over locals */
120
+ locals : Map < string , Local > | null ;
116
121
/** Respective non-nullable type, if nullable. */
117
122
nonNullableType : Type ;
118
123
/** Cached nullable type, if non-nullable. */
@@ -127,6 +132,7 @@ export class Type {
127
132
this . classReference = null ;
128
133
this . signatureReference = null ;
129
134
this . nonNullableType = this ;
135
+ this . locals = null ;
130
136
}
131
137
132
138
/** Returns the closest int type representing this type. */
@@ -163,6 +169,7 @@ export class Type {
163
169
164
170
/** Tests if this is a managed type that needs GC hooks. */
165
171
get isManaged ( ) : bool {
172
+ if ( this . isFunctionIndex ) return true ;
166
173
if ( this . is ( TypeFlags . INTEGER | TypeFlags . REFERENCE ) ) {
167
174
let classReference = this . classReference ;
168
175
if ( classReference ) return ! classReference . hasDecorator ( DecoratorFlags . UNMANAGED ) ;
@@ -177,6 +184,10 @@ export class Type {
177
184
return classReference !== null && classReference . hasDecorator ( DecoratorFlags . UNMANAGED ) ;
178
185
}
179
186
187
+ get isFunctionIndex ( ) : bool {
188
+ return this . signatureReference !== null && ! this . is ( TypeFlags . IN_SCOPE_CLOSURE ) ;
189
+ }
190
+
180
191
/** Computes the sign-extending shift in the target type. */
181
192
computeSmallIntegerShift ( targetType : Type ) : i32 {
182
193
return targetType . size - this . size ;
@@ -517,6 +528,13 @@ export class Type {
517
528
518
529
/** Alias of i32 indicating type inference of locals and globals with just an initializer. */
519
530
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
+ ) ;
520
538
}
521
539
522
540
/** Converts an array of types to an array of native types. */
@@ -626,18 +644,8 @@ export class Signature {
626
644
: getDefaultParameterName ( index ) ;
627
645
}
628
646
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 {
641
649
// check rest parameter
642
650
if ( this . hasRest != other . hasRest ) return false ;
643
651
@@ -654,6 +662,20 @@ export class Signature {
654
662
return this . returnType . equals ( other . returnType ) ;
655
663
}
656
664
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
+
657
679
/** Tests if a value of this function type is assignable to a target of the specified function type. */
658
680
isAssignableTo ( target : Signature , requireSameSize : bool = false ) : bool {
659
681
@@ -720,6 +742,20 @@ export class Signature {
720
742
return sb . join ( "" ) ;
721
743
}
722
744
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
+
723
759
/** Creates a clone of this signature that is safe to modify. */
724
760
clone ( ) : Signature {
725
761
var parameterTypes = this . parameterTypes ;
@@ -738,6 +774,7 @@ export class Signature {
738
774
}
739
775
clone . parameterNames = cloneParameterNames ;
740
776
}
777
+ clone . requiredParameters = this . requiredParameters ;
741
778
return clone ;
742
779
}
743
780
}
0 commit comments