@@ -21,14 +21,33 @@ struct Local {
21
21
}
22
22
23
23
#[ derive( Debug ) ]
24
- struct JitValue {
25
- val : Value ,
26
- ty : JitType ,
24
+ enum JitValue {
25
+ Int ( Value ) ,
26
+ Float ( Value ) ,
27
+ Bool ( Value ) ,
27
28
}
28
29
29
30
impl JitValue {
30
- fn new ( val : Value , ty : JitType ) -> JitValue {
31
- JitValue { val, ty }
31
+ fn from_type_and_value ( ty : JitType , val : Value ) -> JitValue {
32
+ match ty {
33
+ JitType :: Int => JitValue :: Int ( val) ,
34
+ JitType :: Float => JitValue :: Float ( val) ,
35
+ JitType :: Bool => JitValue :: Bool ( val) ,
36
+ }
37
+ }
38
+
39
+ fn to_jit_type ( & self ) -> Option < JitType > {
40
+ match self {
41
+ JitValue :: Int ( _) => Some ( JitType :: Int ) ,
42
+ JitValue :: Float ( _) => Some ( JitType :: Float ) ,
43
+ JitValue :: Bool ( _) => Some ( JitType :: Bool ) ,
44
+ }
45
+ }
46
+
47
+ fn into_value ( self ) -> Option < Value > {
48
+ match self {
49
+ JitValue :: Int ( val) | JitValue :: Float ( val) | JitValue :: Bool ( val) => Some ( val) ,
50
+ }
32
51
}
33
52
}
34
53
@@ -60,7 +79,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
60
79
let params = compiler. builder . func . dfg . block_params ( entry_block) . to_vec ( ) ;
61
80
for ( i, ( ty, val) ) in arg_types. iter ( ) . zip ( params) . enumerate ( ) {
62
81
compiler
63
- . store_variable ( i as u32 , JitValue :: new ( val , ty. clone ( ) ) )
82
+ . store_variable ( i as u32 , JitValue :: from_type_and_value ( ty. clone ( ) , val ) )
64
83
. unwrap ( ) ;
65
84
}
66
85
compiler
@@ -72,36 +91,37 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
72
91
val : JitValue ,
73
92
) -> Result < ( ) , JitCompileError > {
74
93
let builder = & mut self . builder ;
94
+ let ty = val. to_jit_type ( ) . ok_or ( JitCompileError :: NotSupported ) ?;
75
95
let local = self . variables [ idx as usize ] . get_or_insert_with ( || {
76
96
let var = Variable :: new ( idx as usize ) ;
77
97
let local = Local {
78
98
var,
79
- ty : val . ty . clone ( ) ,
99
+ ty : ty. clone ( ) ,
80
100
} ;
81
- builder. declare_var ( var, val . ty . to_cranelift ( ) ) ;
101
+ builder. declare_var ( var, ty. to_cranelift ( ) ) ;
82
102
local
83
103
} ) ;
84
- if val . ty != local. ty {
104
+ if ty != local. ty {
85
105
Err ( JitCompileError :: NotSupported )
86
106
} else {
87
- self . builder . def_var ( local. var , val. val ) ;
107
+ self . builder . def_var ( local. var , val. into_value ( ) . unwrap ( ) ) ;
88
108
Ok ( ( ) )
89
109
}
90
110
}
91
111
92
112
fn boolean_val ( & mut self , val : JitValue ) -> Result < Value , JitCompileError > {
93
- match val. ty {
94
- JitType :: Float => {
113
+ match val {
114
+ JitValue :: Float ( val ) => {
95
115
let zero = self . builder . ins ( ) . f64const ( 0 ) ;
96
- let val = self . builder . ins ( ) . fcmp ( FloatCC :: NotEqual , val. val , zero) ;
116
+ let val = self . builder . ins ( ) . fcmp ( FloatCC :: NotEqual , val, zero) ;
97
117
Ok ( self . builder . ins ( ) . bint ( types:: I8 , val) )
98
118
}
99
- JitType :: Int => {
119
+ JitValue :: Int ( val ) => {
100
120
let zero = self . builder . ins ( ) . iconst ( types:: I64 , 0 ) ;
101
- let val = self . builder . ins ( ) . icmp ( IntCC :: NotEqual , val. val , zero) ;
121
+ let val = self . builder . ins ( ) . icmp ( IntCC :: NotEqual , val, zero) ;
102
122
Ok ( self . builder . ins ( ) . bint ( types:: I8 , val) )
103
123
}
104
- JitType :: Bool => Ok ( val . val ) ,
124
+ JitValue :: Bool ( val ) => Ok ( val) ,
105
125
}
106
126
}
107
127
@@ -160,26 +180,17 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
160
180
types:: I64 ,
161
181
value. to_i64 ( ) . ok_or ( JitCompileError :: NotSupported ) ?,
162
182
) ;
163
- self . stack . push ( JitValue {
164
- val,
165
- ty : JitType :: Int ,
166
- } ) ;
183
+ self . stack . push ( JitValue :: Int ( val) ) ;
167
184
Ok ( ( ) )
168
185
}
169
186
BorrowedConstant :: Float { value } => {
170
187
let val = self . builder . ins ( ) . f64const ( value) ;
171
- self . stack . push ( JitValue {
172
- val,
173
- ty : JitType :: Float ,
174
- } ) ;
188
+ self . stack . push ( JitValue :: Float ( val) ) ;
175
189
Ok ( ( ) )
176
190
}
177
191
BorrowedConstant :: Boolean { value } => {
178
192
let val = self . builder . ins ( ) . iconst ( types:: I8 , value as i64 ) ;
179
- self . stack . push ( JitValue {
180
- val,
181
- ty : JitType :: Bool ,
182
- } ) ;
193
+ self . stack . push ( JitValue :: Bool ( val) ) ;
183
194
Ok ( ( ) )
184
195
}
185
196
_ => Err ( JitCompileError :: NotSupported ) ,
@@ -228,10 +239,10 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
228
239
let local = self . variables [ * idx as usize ]
229
240
. as_ref ( )
230
241
. ok_or ( JitCompileError :: BadBytecode ) ?;
231
- self . stack . push ( JitValue {
232
- val : self . builder . use_var ( local . var ) ,
233
- ty : local . ty . clone ( ) ,
234
- } ) ;
242
+ self . stack . push ( JitValue :: from_type_and_value (
243
+ local . ty . clone ( ) ,
244
+ self . builder . use_var ( local . var ) ,
245
+ ) ) ;
235
246
Ok ( ( ) )
236
247
}
237
248
Instruction :: StoreFast ( idx) => {
@@ -244,27 +255,28 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
244
255
Instruction :: ReturnValue => {
245
256
let val = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
246
257
if let Some ( ref ty) = self . sig . ret {
247
- if val. ty != * ty {
258
+ if val. to_jit_type ( ) . as_ref ( ) != Some ( ty ) {
248
259
return Err ( JitCompileError :: NotSupported ) ;
249
260
}
250
261
} else {
251
- self . sig . ret = Some ( val. ty . clone ( ) ) ;
262
+ let ty = val. to_jit_type ( ) . ok_or ( JitCompileError :: NotSupported ) ?;
263
+ self . sig . ret = Some ( ty. clone ( ) ) ;
252
264
self . builder
253
265
. func
254
266
. signature
255
267
. returns
256
- . push ( AbiParam :: new ( val . ty . to_cranelift ( ) ) ) ;
268
+ . push ( AbiParam :: new ( ty. to_cranelift ( ) ) ) ;
257
269
}
258
- self . builder . ins ( ) . return_ ( & [ val. val ] ) ;
270
+ self . builder . ins ( ) . return_ ( & [ val. into_value ( ) . unwrap ( ) ] ) ;
259
271
Ok ( ( ) )
260
272
}
261
273
Instruction :: CompareOperation { op, .. } => {
262
274
// the rhs is popped off first
263
275
let b = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
264
276
let a = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
265
277
266
- match ( a. ty , b. ty ) {
267
- ( JitType :: Int , JitType :: Int ) => {
278
+ match ( a, b) {
279
+ ( JitValue :: Int ( a ) , JitValue :: Int ( b ) ) => {
268
280
let cond = match op {
269
281
ComparisonOperator :: Equal => IntCC :: Equal ,
270
282
ComparisonOperator :: NotEqual => IntCC :: NotEqual ,
@@ -274,16 +286,13 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
274
286
ComparisonOperator :: GreaterOrEqual => IntCC :: SignedLessThanOrEqual ,
275
287
} ;
276
288
277
- let val = self . builder . ins ( ) . icmp ( cond, a. val , b. val ) ;
278
- self . stack . push ( JitValue {
279
- // TODO: Remove this `bint` in cranelift 0.90 as icmp now returns i8
280
- val : self . builder . ins ( ) . bint ( types:: I8 , val) ,
281
- ty : JitType :: Bool ,
282
- } ) ;
283
-
289
+ let val = self . builder . ins ( ) . icmp ( cond, a, b) ;
290
+ // TODO: Remove this `bint` in cranelift 0.90 as icmp now returns i8
291
+ self . stack
292
+ . push ( JitValue :: Bool ( self . builder . ins ( ) . bint ( types:: I8 , val) ) ) ;
284
293
Ok ( ( ) )
285
294
}
286
- ( JitType :: Float , JitType :: Float ) => {
295
+ ( JitValue :: Float ( a ) , JitValue :: Float ( b ) ) => {
287
296
let cond = match op {
288
297
ComparisonOperator :: Equal => FloatCC :: Equal ,
289
298
ComparisonOperator :: NotEqual => FloatCC :: NotEqual ,
@@ -293,13 +302,10 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
293
302
ComparisonOperator :: GreaterOrEqual => FloatCC :: GreaterThanOrEqual ,
294
303
} ;
295
304
296
- let val = self . builder . ins ( ) . fcmp ( cond, a. val , b. val ) ;
297
- self . stack . push ( JitValue {
298
- // TODO: Remove this `bint` in cranelift 0.90 as fcmp now returns i8
299
- val : self . builder . ins ( ) . bint ( types:: I8 , val) ,
300
- ty : JitType :: Bool ,
301
- } ) ;
302
-
305
+ let val = self . builder . ins ( ) . fcmp ( cond, a, b) ;
306
+ // TODO: Remove this `bint` in cranelift 0.90 as fcmp now returns i8
307
+ self . stack
308
+ . push ( JitValue :: Bool ( self . builder . ins ( ) . bint ( types:: I8 , val) ) ) ;
303
309
Ok ( ( ) )
304
310
}
305
311
_ => Err ( JitCompileError :: NotSupported ) ,
@@ -308,16 +314,13 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
308
314
Instruction :: UnaryOperation { op, .. } => {
309
315
let a = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
310
316
311
- match a. ty {
312
- JitType :: Int => match op {
317
+ match a {
318
+ JitValue :: Int ( val ) => match op {
313
319
UnaryOperator :: Minus => {
314
320
// Compile minus as 0 - a.
315
321
let zero = self . builder . ins ( ) . iconst ( types:: I64 , 0 ) ;
316
- let out = self . compile_sub ( zero, a. val ) ;
317
- self . stack . push ( JitValue {
318
- val : out,
319
- ty : JitType :: Int ,
320
- } ) ;
322
+ let out = self . compile_sub ( zero, val) ;
323
+ self . stack . push ( JitValue :: Int ( out) ) ;
321
324
Ok ( ( ) )
322
325
}
323
326
UnaryOperator :: Plus => {
@@ -327,14 +330,10 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
327
330
}
328
331
_ => Err ( JitCompileError :: NotSupported ) ,
329
332
} ,
330
- JitType :: Bool => match op {
333
+ JitValue :: Bool ( val ) => match op {
331
334
UnaryOperator :: Not => {
332
- let val = self . boolean_val ( a) ?;
333
335
let not_val = self . builder . ins ( ) . bxor_imm ( val, 1 ) ;
334
- self . stack . push ( JitValue {
335
- val : not_val,
336
- ty : JitType :: Bool ,
337
- } ) ;
336
+ self . stack . push ( JitValue :: Bool ( not_val) ) ;
338
337
Ok ( ( ) )
339
338
}
340
339
_ => Err ( JitCompileError :: NotSupported ) ,
@@ -346,73 +345,71 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
346
345
// the rhs is popped off first
347
346
let b = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
348
347
let a = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
349
- let ( val, ty ) = match ( op, a. ty , b. ty ) {
350
- ( BinaryOperator :: Add , JitType :: Int , JitType :: Int ) => {
351
- let ( out, carry) = self . builder . ins ( ) . iadd_ifcout ( a. val , b. val ) ;
348
+ let val = match ( op, a, b) {
349
+ ( BinaryOperator :: Add , JitValue :: Int ( a ) , JitValue :: Int ( b ) ) => {
350
+ let ( out, carry) = self . builder . ins ( ) . iadd_ifcout ( a, b) ;
352
351
self . builder . ins ( ) . trapif (
353
352
IntCC :: Overflow ,
354
353
carry,
355
354
TrapCode :: IntegerOverflow ,
356
355
) ;
357
- ( out , JitType :: Int )
356
+ JitValue :: Int ( out )
358
357
}
359
- ( BinaryOperator :: Subtract , JitType :: Int , JitType :: Int ) => {
360
- ( self . compile_sub ( a. val , b. val ) , JitType :: Int )
358
+ ( BinaryOperator :: Subtract , JitValue :: Int ( a ) , JitValue :: Int ( b ) ) => {
359
+ JitValue :: Int ( self . compile_sub ( a, b) )
361
360
}
362
- ( BinaryOperator :: FloorDivide , JitType :: Int , JitType :: Int ) => {
363
- ( self . builder . ins ( ) . sdiv ( a. val , b. val ) , JitType :: Int )
361
+ ( BinaryOperator :: FloorDivide , JitValue :: Int ( a ) , JitValue :: Int ( b ) ) => {
362
+ JitValue :: Int ( self . builder . ins ( ) . sdiv ( a, b) )
364
363
}
365
- ( BinaryOperator :: Modulo , JitType :: Int , JitType :: Int ) => {
366
- ( self . builder . ins ( ) . srem ( a. val , b. val ) , JitType :: Int )
364
+ ( BinaryOperator :: Modulo , JitValue :: Int ( a ) , JitValue :: Int ( b ) ) => {
365
+ JitValue :: Int ( self . builder . ins ( ) . srem ( a, b) )
367
366
}
368
367
(
369
368
BinaryOperator :: Lshift | BinaryOperator :: Rshift ,
370
- JitType :: Int ,
371
- JitType :: Int ,
369
+ JitValue :: Int ( a ) ,
370
+ JitValue :: Int ( b ) ,
372
371
) => {
373
372
// Shifts throw an exception if we have a negative shift count
374
373
// Remove all bits except the sign bit, and trap if its 1 (i.e. negative).
375
- let sign = self . builder . ins ( ) . ushr_imm ( b. val , 63 ) ;
374
+ let sign = self . builder . ins ( ) . ushr_imm ( b, 63 ) ;
376
375
self . builder . ins ( ) . trapnz (
377
376
sign,
378
377
TrapCode :: User ( CustomTrapCode :: NegativeShiftCount as u16 ) ,
379
378
) ;
380
379
381
380
let out = if * op == BinaryOperator :: Lshift {
382
- self . builder . ins ( ) . ishl ( a. val , b. val )
381
+ self . builder . ins ( ) . ishl ( a, b)
383
382
} else {
384
- self . builder . ins ( ) . sshr ( a. val , b. val )
383
+ self . builder . ins ( ) . sshr ( a, b)
385
384
} ;
386
-
387
- ( out, JitType :: Int )
385
+ JitValue :: Int ( out)
388
386
}
389
- ( BinaryOperator :: And , JitType :: Int , JitType :: Int ) => {
390
- ( self . builder . ins ( ) . band ( a. val , b. val ) , JitType :: Int )
387
+ ( BinaryOperator :: And , JitValue :: Int ( a ) , JitValue :: Int ( b ) ) => {
388
+ JitValue :: Int ( self . builder . ins ( ) . band ( a, b) )
391
389
}
392
- ( BinaryOperator :: Or , JitType :: Int , JitType :: Int ) => {
393
- ( self . builder . ins ( ) . bor ( a. val , b. val ) , JitType :: Int )
390
+ ( BinaryOperator :: Or , JitValue :: Int ( a ) , JitValue :: Int ( b ) ) => {
391
+ JitValue :: Int ( self . builder . ins ( ) . bor ( a, b) )
394
392
}
395
- ( BinaryOperator :: Xor , JitType :: Int , JitType :: Int ) => {
396
- ( self . builder . ins ( ) . bxor ( a. val , b. val ) , JitType :: Int )
393
+ ( BinaryOperator :: Xor , JitValue :: Int ( a ) , JitValue :: Int ( b ) ) => {
394
+ JitValue :: Int ( self . builder . ins ( ) . bxor ( a, b) )
397
395
}
398
396
399
397
// Floats
400
- ( BinaryOperator :: Add , JitType :: Float , JitType :: Float ) => {
401
- ( self . builder . ins ( ) . fadd ( a. val , b. val ) , JitType :: Float )
398
+ ( BinaryOperator :: Add , JitValue :: Float ( a ) , JitValue :: Float ( b ) ) => {
399
+ JitValue :: Float ( self . builder . ins ( ) . fadd ( a, b) )
402
400
}
403
- ( BinaryOperator :: Subtract , JitType :: Float , JitType :: Float ) => {
404
- ( self . builder . ins ( ) . fsub ( a. val , b. val ) , JitType :: Float )
401
+ ( BinaryOperator :: Subtract , JitValue :: Float ( a ) , JitValue :: Float ( b ) ) => {
402
+ JitValue :: Float ( self . builder . ins ( ) . fsub ( a, b) )
405
403
}
406
- ( BinaryOperator :: Multiply , JitType :: Float , JitType :: Float ) => {
407
- ( self . builder . ins ( ) . fmul ( a. val , b. val ) , JitType :: Float )
404
+ ( BinaryOperator :: Multiply , JitValue :: Float ( a ) , JitValue :: Float ( b ) ) => {
405
+ JitValue :: Float ( self . builder . ins ( ) . fmul ( a, b) )
408
406
}
409
- ( BinaryOperator :: Divide , JitType :: Float , JitType :: Float ) => {
410
- ( self . builder . ins ( ) . fdiv ( a. val , b. val ) , JitType :: Float )
407
+ ( BinaryOperator :: Divide , JitValue :: Float ( a ) , JitValue :: Float ( b ) ) => {
408
+ JitValue :: Float ( self . builder . ins ( ) . fdiv ( a, b) )
411
409
}
412
410
_ => return Err ( JitCompileError :: NotSupported ) ,
413
411
} ;
414
-
415
- self . stack . push ( JitValue { val, ty } ) ;
412
+ self . stack . push ( val) ;
416
413
417
414
Ok ( ( ) )
418
415
}
0 commit comments