@@ -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,11 @@ 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_s = "~lib/builtins/i32.rem_s" ;
274
+ export const i32_rem_u = "~lib/builtins/i32.rem_u" ;
275
+ export const i64_rem_s = "~lib/builtins/i64.rem_s" ;
276
+ export const i64_rem_u = "~lib/builtins/i64.rem_u" ;
277
+
272
278
export const i32_load8_s = "~lib/builtins/i32.load8_s" ;
273
279
export const i32_load8_u = "~lib/builtins/i32.load8_u" ;
274
280
export const i32_load16_s = "~lib/builtins/i32.load16_s" ;
@@ -815,7 +821,7 @@ function builtin_isString(ctx: BuiltinContext): ExpressionRef {
815
821
compiler . currentType = Type . bool ;
816
822
if ( ! type ) return module . unreachable ( ) ;
817
823
var classReference = type . getClass ( ) ;
818
- return reifyConstantType ( ctx ,
824
+ return reifyConstantType ( ctx ,
819
825
module . i32 (
820
826
classReference && classReference . isAssignableTo ( compiler . program . stringInstance )
821
827
? 1
@@ -2231,6 +2237,60 @@ function builtin_store(ctx: BuiltinContext): ExpressionRef {
2231
2237
}
2232
2238
builtins . set ( BuiltinNames . store , builtin_store ) ;
2233
2239
2240
+ // rem<T?>(left: T, right: T) -> T
2241
+ function builtin_rem ( ctx : BuiltinContext ) : ExpressionRef {
2242
+ var compiler = ctx . compiler ;
2243
+ var module = compiler . module ;
2244
+ if ( checkTypeOptional ( ctx , true ) | checkArgsRequired ( ctx , 2 ) ) {
2245
+ return module . unreachable ( ) ;
2246
+ }
2247
+ var operands = ctx . operands ;
2248
+ var typeArguments = ctx . typeArguments ;
2249
+ var left = operands [ 0 ] ;
2250
+ var arg0 = typeArguments
2251
+ ? compiler . compileExpression (
2252
+ left ,
2253
+ typeArguments [ 0 ] ,
2254
+ Constraints . CONV_IMPLICIT
2255
+ )
2256
+ : compiler . compileExpression ( operands [ 0 ] , Type . auto ) ;
2257
+ var type = compiler . currentType ;
2258
+ if ( type . isIntegerValue ) {
2259
+ let arg1 : ExpressionRef ;
2260
+ if ( ! typeArguments && left . isNumericLiteral ) {
2261
+ // prefer right type
2262
+ arg1 = compiler . compileExpression (
2263
+ operands [ 1 ] ,
2264
+ type
2265
+ ) ;
2266
+ if ( compiler . currentType != type ) {
2267
+ arg0 = compiler . compileExpression (
2268
+ left ,
2269
+ ( type = compiler . currentType ) ,
2270
+ Constraints . CONV_IMPLICIT
2271
+ ) ;
2272
+ }
2273
+ } else {
2274
+ arg1 = compiler . compileExpression (
2275
+ operands [ 1 ] ,
2276
+ type ,
2277
+ Constraints . CONV_IMPLICIT
2278
+ ) ;
2279
+ }
2280
+ if ( type . isIntegerValue ) {
2281
+ return compiler . makeRem ( arg0 , arg1 , type , ctx . reportNode ) ;
2282
+ }
2283
+ }
2284
+ compiler . error (
2285
+ DiagnosticCode . Operation_0_cannot_be_applied_to_type_1 ,
2286
+ ctx . reportNode . typeArgumentsRange ,
2287
+ "rem" ,
2288
+ type . toString ( )
2289
+ ) ;
2290
+ return module . unreachable ( ) ;
2291
+ }
2292
+ builtins . set ( BuiltinNames . rem , builtin_rem ) ;
2293
+
2234
2294
// add<T?>(left: T, right: T) -> T
2235
2295
function builtin_add ( ctx : BuiltinContext ) : ExpressionRef {
2236
2296
var compiler = ctx . compiler ;
@@ -6638,6 +6698,42 @@ function builtin_f64_trunc(ctx: BuiltinContext): ExpressionRef {
6638
6698
}
6639
6699
builtins . set ( BuiltinNames . f64_trunc , builtin_f64_trunc ) ;
6640
6700
6701
+ // i32.rem_s -> rem<i32>
6702
+ function builtin_i32_rem_s ( ctx : BuiltinContext ) : ExpressionRef {
6703
+ checkTypeAbsent ( ctx ) ;
6704
+ ctx . typeArguments = [ Type . i32 ] ;
6705
+ ctx . contextualType = Type . i32 ;
6706
+ return builtin_rem ( ctx ) ;
6707
+ }
6708
+ builtins . set ( BuiltinNames . i32_rem_s , builtin_i32_rem_s ) ;
6709
+
6710
+ // i32.rem_u -> rem<u32>
6711
+ function builtin_i32_rem_u ( ctx : BuiltinContext ) : ExpressionRef {
6712
+ checkTypeAbsent ( ctx ) ;
6713
+ ctx . typeArguments = [ Type . u32 ] ;
6714
+ ctx . contextualType = Type . u32 ;
6715
+ return builtin_rem ( ctx ) ;
6716
+ }
6717
+ builtins . set ( BuiltinNames . i32_rem_u , builtin_i32_rem_u ) ;
6718
+
6719
+ // i64.rem_s -> rem<i64>
6720
+ function builtin_i64_rem_s ( ctx : BuiltinContext ) : ExpressionRef {
6721
+ checkTypeAbsent ( ctx ) ;
6722
+ ctx . typeArguments = [ Type . i64 ] ;
6723
+ ctx . contextualType = Type . i64 ;
6724
+ return builtin_rem ( ctx ) ;
6725
+ }
6726
+ builtins . set ( BuiltinNames . i64_rem_s , builtin_i64_rem_s ) ;
6727
+
6728
+ // i64.rem_u -> rem<u64>
6729
+ function builtin_i64_rem_u ( ctx : BuiltinContext ) : ExpressionRef {
6730
+ checkTypeAbsent ( ctx ) ;
6731
+ ctx . typeArguments = [ Type . u64 ] ;
6732
+ ctx . contextualType = Type . u64 ;
6733
+ return builtin_rem ( ctx ) ;
6734
+ }
6735
+ builtins . set ( BuiltinNames . i64_rem_u , builtin_i64_rem_u ) ;
6736
+
6641
6737
// i32.add -> add<i32>
6642
6738
function builtin_i32_add ( ctx : BuiltinContext ) : ExpressionRef {
6643
6739
checkTypeAbsent ( ctx ) ;
0 commit comments