@@ -163,6 +163,7 @@ export namespace BuiltinNames {
163
163
export const trunc = "~lib/builtins/trunc" ;
164
164
export const eq = "~lib/builtins/eq" ;
165
165
export const ne = "~lib/builtins/ne" ;
166
+ export const rem = "~lib/builtins/rem" ;
166
167
export const load = "~lib/builtins/load" ;
167
168
export const store = "~lib/builtins/store" ;
168
169
export const atomic_load = "~lib/builtins/atomic.load" ;
@@ -269,6 +270,9 @@ export namespace BuiltinNames {
269
270
export const f32_ne = "~lib/builtins/f32.ne" ;
270
271
export const f64_ne = "~lib/builtins/f64.ne" ;
271
272
273
+ export const i32_rem = "~lib/builtins/i32.rem" ;
274
+ export const i64_rem = "~lib/builtins/i64.rem" ;
275
+
272
276
export const i32_load8_s = "~lib/builtins/i32.load8_s" ;
273
277
export const i32_load8_u = "~lib/builtins/i32.load8_u" ;
274
278
export const i32_load16_s = "~lib/builtins/i32.load16_s" ;
@@ -815,7 +819,7 @@ function builtin_isString(ctx: BuiltinContext): ExpressionRef {
815
819
compiler . currentType = Type . bool ;
816
820
if ( ! type ) return module . unreachable ( ) ;
817
821
var classReference = type . getClass ( ) ;
818
- return reifyConstantType ( ctx ,
822
+ return reifyConstantType ( ctx ,
819
823
module . i32 (
820
824
classReference && classReference . isAssignableTo ( compiler . program . stringInstance )
821
825
? 1
@@ -2231,6 +2235,60 @@ function builtin_store(ctx: BuiltinContext): ExpressionRef {
2231
2235
}
2232
2236
builtins . set ( BuiltinNames . store , builtin_store ) ;
2233
2237
2238
+ // rem<T?>(left: T, right: T) -> T
2239
+ function builtin_rem ( ctx : BuiltinContext ) : ExpressionRef {
2240
+ var compiler = ctx . compiler ;
2241
+ var module = compiler . module ;
2242
+ if ( checkTypeOptional ( ctx , true ) | checkArgsRequired ( ctx , 2 ) ) {
2243
+ return module . unreachable ( ) ;
2244
+ }
2245
+ var operands = ctx . operands ;
2246
+ var typeArguments = ctx . typeArguments ;
2247
+ var left = operands [ 0 ] ;
2248
+ var arg0 = typeArguments
2249
+ ? compiler . compileExpression (
2250
+ left ,
2251
+ typeArguments [ 0 ] ,
2252
+ Constraints . CONV_IMPLICIT
2253
+ )
2254
+ : compiler . compileExpression ( operands [ 0 ] , Type . auto ) ;
2255
+ var type = compiler . currentType ;
2256
+ if ( type . isIntegerValue ) {
2257
+ let arg1 : ExpressionRef ;
2258
+ if ( ! typeArguments && left . isNumericLiteral ) {
2259
+ // prefer right type
2260
+ arg1 = compiler . compileExpression (
2261
+ operands [ 1 ] ,
2262
+ type
2263
+ ) ;
2264
+ if ( compiler . currentType != type ) {
2265
+ arg0 = compiler . compileExpression (
2266
+ left ,
2267
+ ( type = compiler . currentType ) ,
2268
+ Constraints . CONV_IMPLICIT
2269
+ ) ;
2270
+ }
2271
+ } else {
2272
+ arg1 = compiler . compileExpression (
2273
+ operands [ 1 ] ,
2274
+ type ,
2275
+ Constraints . CONV_IMPLICIT
2276
+ ) ;
2277
+ }
2278
+ if ( type . isIntegerValue ) {
2279
+ return compiler . makeRem ( arg0 , arg1 , type , ctx . reportNode ) ;
2280
+ }
2281
+ }
2282
+ compiler . error (
2283
+ DiagnosticCode . Operation_0_cannot_be_applied_to_type_1 ,
2284
+ ctx . reportNode . typeArgumentsRange ,
2285
+ "rem" ,
2286
+ type . toString ( )
2287
+ ) ;
2288
+ return module . unreachable ( ) ;
2289
+ }
2290
+ builtins . set ( BuiltinNames . rem , builtin_rem ) ;
2291
+
2234
2292
// add<T?>(left: T, right: T) -> T
2235
2293
function builtin_add ( ctx : BuiltinContext ) : ExpressionRef {
2236
2294
var compiler = ctx . compiler ;
@@ -6638,6 +6696,24 @@ function builtin_f64_trunc(ctx: BuiltinContext): ExpressionRef {
6638
6696
}
6639
6697
builtins . set ( BuiltinNames . f64_trunc , builtin_f64_trunc ) ;
6640
6698
6699
+ // i32.rem -> rem<i32>
6700
+ function builtin_i32_rem ( ctx : BuiltinContext ) : ExpressionRef {
6701
+ checkTypeAbsent ( ctx ) ;
6702
+ ctx . typeArguments = [ Type . i32 ] ;
6703
+ ctx . contextualType = Type . i32 ;
6704
+ return builtin_rem ( ctx ) ;
6705
+ }
6706
+ builtins . set ( BuiltinNames . i32_rem , builtin_i32_rem ) ;
6707
+
6708
+ // i64.rem -> rem<i64>
6709
+ function builtin_i64_rem ( ctx : BuiltinContext ) : ExpressionRef {
6710
+ checkTypeAbsent ( ctx ) ;
6711
+ ctx . typeArguments = [ Type . i64 ] ;
6712
+ ctx . contextualType = Type . i64 ;
6713
+ return builtin_rem ( ctx ) ;
6714
+ }
6715
+ builtins . set ( BuiltinNames . i64_rem , builtin_i64_rem ) ;
6716
+
6641
6717
// i32.add -> add<i32>
6642
6718
function builtin_i32_add ( ctx : BuiltinContext ) : ExpressionRef {
6643
6719
checkTypeAbsent ( ctx ) ;
0 commit comments