@@ -60,7 +60,8 @@ import {
60
60
CommonNames ,
61
61
INDEX_SUFFIX ,
62
62
Feature ,
63
- Target
63
+ Target ,
64
+ featureToString
64
65
} from "./common" ;
65
66
66
67
import {
@@ -113,6 +114,7 @@ import {
113
114
DecoratorKind ,
114
115
AssertionKind ,
115
116
SourceKind ,
117
+ FunctionTypeNode ,
116
118
117
119
Statement ,
118
120
BlockStatement ,
@@ -961,6 +963,7 @@ export class Compiler extends DiagnosticEmitter {
961
963
return false ;
962
964
}
963
965
global . setType ( resolvedType ) ;
966
+ this . checkTypeSupported ( global . type , typeNode ) ;
964
967
965
968
// Otherwise infer type from initializer
966
969
} else if ( initializerNode ) {
@@ -1268,6 +1271,9 @@ export class Compiler extends DiagnosticEmitter {
1268
1271
var module = this . module ;
1269
1272
var signature = instance . signature ;
1270
1273
var bodyNode = instance . prototype . bodyNode ;
1274
+ var declarationNode = instance . declaration ;
1275
+ assert ( declarationNode . kind == NodeKind . FUNCTIONDECLARATION || declarationNode . kind == NodeKind . METHODDECLARATION ) ;
1276
+ this . checkSignatureSupported ( instance . signature , ( < FunctionDeclaration > declarationNode ) . signature ) ;
1271
1277
1272
1278
var funcRef : FunctionRef ;
1273
1279
@@ -1343,7 +1349,7 @@ export class Compiler extends DiagnosticEmitter {
1343
1349
// imported function
1344
1350
} else if ( instance . is ( CommonFlags . AMBIENT ) ) {
1345
1351
instance . set ( CommonFlags . MODULE_IMPORT ) ;
1346
- mangleImportName ( instance , instance . declaration ) ; // TODO: check for duplicates
1352
+ mangleImportName ( instance , declarationNode ) ; // TODO: check for duplicates
1347
1353
module . addFunctionImport (
1348
1354
instance . internalName ,
1349
1355
mangleImportName_moduleName ,
@@ -1576,7 +1582,12 @@ export class Compiler extends DiagnosticEmitter {
1576
1582
) ;
1577
1583
if ( type . isManaged ) valueExpr = this . makeRetain ( valueExpr ) ;
1578
1584
instance . getterRef = module . addFunction ( instance . internalGetterName , nativeThisType , nativeValueType , null , valueExpr ) ;
1579
- if ( instance . setterRef ) instance . set ( CommonFlags . COMPILED ) ;
1585
+ if ( instance . setterRef ) {
1586
+ instance . set ( CommonFlags . COMPILED ) ;
1587
+ } else {
1588
+ let typeNode = instance . typeNode ;
1589
+ if ( typeNode ) this . checkTypeSupported ( instance . type , typeNode ) ;
1590
+ }
1580
1591
return true ;
1581
1592
}
1582
1593
@@ -1624,7 +1635,12 @@ export class Compiler extends DiagnosticEmitter {
1624
1635
nativeValueType , instance . memoryOffset
1625
1636
)
1626
1637
) ;
1627
- if ( instance . getterRef ) instance . set ( CommonFlags . COMPILED ) ;
1638
+ if ( instance . getterRef ) {
1639
+ instance . set ( CommonFlags . COMPILED ) ;
1640
+ } else {
1641
+ let typeNode = instance . typeNode ;
1642
+ if ( typeNode ) this . checkTypeSupported ( instance . type , typeNode ) ;
1643
+ }
1628
1644
return true ;
1629
1645
}
1630
1646
@@ -2856,6 +2872,8 @@ export class Compiler extends DiagnosticEmitter {
2856
2872
makeMap ( flow . contextualTypeArguments )
2857
2873
) ;
2858
2874
if ( ! type ) continue ;
2875
+ this . checkTypeSupported ( type , typeNode ) ;
2876
+
2859
2877
if ( initializerNode ) {
2860
2878
initExpr = this . compileExpression ( initializerNode , type , // reports
2861
2879
Constraints . CONV_IMPLICIT | Constraints . WILL_RETAIN
@@ -6228,6 +6246,12 @@ export class Compiler extends DiagnosticEmitter {
6228
6246
var thisType = ( < Class > field . parent ) . type ;
6229
6247
var nativeThisType = thisType . toNativeType ( ) ;
6230
6248
6249
+ if ( ! field . is ( CommonFlags . COMPILED ) ) {
6250
+ field . set ( CommonFlags . COMPILED ) ;
6251
+ let typeNode = field . typeNode ;
6252
+ if ( typeNode ) this . checkTypeSupported ( field . type , typeNode ) ;
6253
+ }
6254
+
6231
6255
if ( fieldType . isManaged && thisType . isManaged ) {
6232
6256
let tempThis = flow . getTempLocal ( thisType , findUsedLocals ( valueExpr ) ) ;
6233
6257
// set before and read after valueExpr executes below ^
@@ -8818,7 +8842,6 @@ export class Compiler extends DiagnosticEmitter {
8818
8842
for ( let i = 0 ; i < numParameters ; ++ i ) {
8819
8843
operands [ i + 1 ] = module . local_get ( i + 1 , parameterTypes [ i ] . toNativeType ( ) ) ;
8820
8844
}
8821
- // TODO: base constructor might be inlined, but makeCallDirect can't do this
8822
8845
stmts . push (
8823
8846
module . local_set ( 0 ,
8824
8847
this . makeCallDirect ( assert ( baseClass . constructorInstance ) , operands , reportNode , false , true )
@@ -8927,6 +8950,11 @@ export class Compiler extends DiagnosticEmitter {
8927
8950
) ;
8928
8951
}
8929
8952
}
8953
+ if ( ! fieldInstance . is ( CommonFlags . COMPILED ) ) {
8954
+ fieldInstance . set ( CommonFlags . COMPILED ) ;
8955
+ let typeNode = fieldInstance . typeNode ;
8956
+ if ( typeNode ) this . checkTypeSupported ( fieldInstance . type , typeNode ) ;
8957
+ }
8930
8958
this . currentType = fieldType ;
8931
8959
return module . load (
8932
8960
fieldType . byteSize ,
@@ -9849,6 +9877,62 @@ export class Compiler extends DiagnosticEmitter {
9849
9877
parentFunction . debugLocations . push ( range ) ;
9850
9878
}
9851
9879
9880
+ /** Checks whether a particular feature is enabled. */
9881
+ checkFeatureEnabled ( feature : Feature , reportNode : Node ) : bool {
9882
+ if ( ! this . options . hasFeature ( feature ) ) {
9883
+ this . error (
9884
+ DiagnosticCode . Feature_0_is_not_enabled ,
9885
+ reportNode . range , featureToString ( feature )
9886
+ ) ;
9887
+ return false ;
9888
+ }
9889
+ return true ;
9890
+ }
9891
+
9892
+ /** Checks whether a particular type is supported. */
9893
+ checkTypeSupported ( type : Type , reportNode : Node ) : bool {
9894
+ switch ( type . kind ) {
9895
+ case TypeKind . V128 : return this . checkFeatureEnabled ( Feature . SIMD , reportNode ) ;
9896
+ case TypeKind . ANYREF : return this . checkFeatureEnabled ( Feature . REFERENCE_TYPES , reportNode ) ;
9897
+ }
9898
+ if ( type . is ( TypeFlags . REFERENCE ) ) {
9899
+ let classReference = type . classReference ;
9900
+ while ( classReference ) {
9901
+ let typeArguments = classReference . typeArguments ;
9902
+ if ( typeArguments ) {
9903
+ for ( let i = 0 , k = typeArguments . length ; i < k ; ++ i ) {
9904
+ if ( ! this . checkTypeSupported ( typeArguments [ i ] , reportNode ) ) {
9905
+ return false ;
9906
+ }
9907
+ }
9908
+ }
9909
+ classReference = classReference . base ;
9910
+ }
9911
+ }
9912
+ return true ;
9913
+ }
9914
+
9915
+ /** Checks whether a particular function signature is supported. */
9916
+ checkSignatureSupported ( signature : Signature , reportNode : FunctionTypeNode ) : bool {
9917
+ var supported = true ;
9918
+ var explicitThisType = reportNode . explicitThisType ;
9919
+ if ( explicitThisType ) {
9920
+ if ( ! this . checkTypeSupported ( assert ( signature . thisType ) , explicitThisType ) ) {
9921
+ supported = false ;
9922
+ }
9923
+ }
9924
+ var parameterTypes = signature . parameterTypes ;
9925
+ for ( let i = 0 , k = parameterTypes . length ; i < k ; ++ i ) {
9926
+ if ( ! this . checkTypeSupported ( parameterTypes [ i ] , reportNode . parameters [ i ] ) ) {
9927
+ supported = false ;
9928
+ }
9929
+ }
9930
+ if ( ! this . checkTypeSupported ( signature . returnType , reportNode . returnType ) ) {
9931
+ supported = false ;
9932
+ }
9933
+ return supported ;
9934
+ }
9935
+
9852
9936
// === Specialized code generation ==============================================================
9853
9937
9854
9938
/** Makes a constant zero of the specified type. */
@@ -10039,6 +10123,8 @@ export class Compiler extends DiagnosticEmitter {
10039
10123
let initializerNode = fieldPrototype . initializerNode ;
10040
10124
let parameterIndex = fieldPrototype . parameterIndex ;
10041
10125
let initExpr : ExpressionRef ;
10126
+ let typeNode = field . typeNode ;
10127
+ if ( typeNode ) this . checkTypeSupported ( fieldType , typeNode ) ;
10042
10128
10043
10129
// if declared as a constructor parameter, use its value
10044
10130
if ( parameterIndex >= 0 ) {
0 commit comments