@@ -21,14 +21,33 @@ struct Local {
2121}
2222
2323#[ derive( Debug ) ]
24- struct JitValue {
25- val : Value ,
26- ty : JitType ,
24+ enum JitValue {
25+ Int ( Value ) ,
26+ Float ( Value ) ,
27+ Bool ( Value ) ,
2728}
2829
2930impl 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+ }
3251 }
3352}
3453
@@ -60,7 +79,7 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
6079 let params = compiler. builder . func . dfg . block_params ( entry_block) . to_vec ( ) ;
6180 for ( i, ( ty, val) ) in arg_types. iter ( ) . zip ( params) . enumerate ( ) {
6281 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 ) )
6483 . unwrap ( ) ;
6584 }
6685 compiler
@@ -72,36 +91,37 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
7291 val : JitValue ,
7392 ) -> Result < ( ) , JitCompileError > {
7493 let builder = & mut self . builder ;
94+ let ty = val. to_jit_type ( ) . ok_or ( JitCompileError :: NotSupported ) ?;
7595 let local = self . variables [ idx as usize ] . get_or_insert_with ( || {
7696 let var = Variable :: new ( idx as usize ) ;
7797 let local = Local {
7898 var,
79- ty : val . ty . clone ( ) ,
99+ ty : ty. clone ( ) ,
80100 } ;
81- builder. declare_var ( var, val . ty . to_cranelift ( ) ) ;
101+ builder. declare_var ( var, ty. to_cranelift ( ) ) ;
82102 local
83103 } ) ;
84- if val . ty != local. ty {
104+ if ty != local. ty {
85105 Err ( JitCompileError :: NotSupported )
86106 } else {
87- self . builder . def_var ( local. var , val. val ) ;
107+ self . builder . def_var ( local. var , val. into_value ( ) . unwrap ( ) ) ;
88108 Ok ( ( ) )
89109 }
90110 }
91111
92112 fn boolean_val ( & mut self , val : JitValue ) -> Result < Value , JitCompileError > {
93- match val. ty {
94- JitType :: Float => {
113+ match val {
114+ JitValue :: Float ( val ) => {
95115 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) ;
97117 Ok ( self . builder . ins ( ) . bint ( types:: I8 , val) )
98118 }
99- JitType :: Int => {
119+ JitValue :: Int ( val ) => {
100120 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) ;
102122 Ok ( self . builder . ins ( ) . bint ( types:: I8 , val) )
103123 }
104- JitType :: Bool => Ok ( val . val ) ,
124+ JitValue :: Bool ( val ) => Ok ( val) ,
105125 }
106126 }
107127
@@ -160,26 +180,17 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
160180 types:: I64 ,
161181 value. to_i64 ( ) . ok_or ( JitCompileError :: NotSupported ) ?,
162182 ) ;
163- self . stack . push ( JitValue {
164- val,
165- ty : JitType :: Int ,
166- } ) ;
183+ self . stack . push ( JitValue :: Int ( val) ) ;
167184 Ok ( ( ) )
168185 }
169186 BorrowedConstant :: Float { value } => {
170187 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) ) ;
175189 Ok ( ( ) )
176190 }
177191 BorrowedConstant :: Boolean { value } => {
178192 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) ) ;
183194 Ok ( ( ) )
184195 }
185196 _ => Err ( JitCompileError :: NotSupported ) ,
@@ -228,10 +239,10 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
228239 let local = self . variables [ * idx as usize ]
229240 . as_ref ( )
230241 . 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+ ) ) ;
235246 Ok ( ( ) )
236247 }
237248 Instruction :: StoreFast ( idx) => {
@@ -244,27 +255,28 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
244255 Instruction :: ReturnValue => {
245256 let val = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
246257 if let Some ( ref ty) = self . sig . ret {
247- if val. ty != * ty {
258+ if val. to_jit_type ( ) . as_ref ( ) != Some ( ty ) {
248259 return Err ( JitCompileError :: NotSupported ) ;
249260 }
250261 } 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 ( ) ) ;
252264 self . builder
253265 . func
254266 . signature
255267 . returns
256- . push ( AbiParam :: new ( val . ty . to_cranelift ( ) ) ) ;
268+ . push ( AbiParam :: new ( ty. to_cranelift ( ) ) ) ;
257269 }
258- self . builder . ins ( ) . return_ ( & [ val. val ] ) ;
270+ self . builder . ins ( ) . return_ ( & [ val. into_value ( ) . unwrap ( ) ] ) ;
259271 Ok ( ( ) )
260272 }
261273 Instruction :: CompareOperation { op, .. } => {
262274 // the rhs is popped off first
263275 let b = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
264276 let a = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
265277
266- match ( a. ty , b. ty ) {
267- ( JitType :: Int , JitType :: Int ) => {
278+ match ( a, b) {
279+ ( JitValue :: Int ( a ) , JitValue :: Int ( b ) ) => {
268280 let cond = match op {
269281 ComparisonOperator :: Equal => IntCC :: Equal ,
270282 ComparisonOperator :: NotEqual => IntCC :: NotEqual ,
@@ -274,16 +286,13 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
274286 ComparisonOperator :: GreaterOrEqual => IntCC :: SignedLessThanOrEqual ,
275287 } ;
276288
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) ) ) ;
284293 Ok ( ( ) )
285294 }
286- ( JitType :: Float , JitType :: Float ) => {
295+ ( JitValue :: Float ( a ) , JitValue :: Float ( b ) ) => {
287296 let cond = match op {
288297 ComparisonOperator :: Equal => FloatCC :: Equal ,
289298 ComparisonOperator :: NotEqual => FloatCC :: NotEqual ,
@@ -293,13 +302,10 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
293302 ComparisonOperator :: GreaterOrEqual => FloatCC :: GreaterThanOrEqual ,
294303 } ;
295304
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) ) ) ;
303309 Ok ( ( ) )
304310 }
305311 _ => Err ( JitCompileError :: NotSupported ) ,
@@ -308,16 +314,13 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
308314 Instruction :: UnaryOperation { op, .. } => {
309315 let a = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
310316
311- match a. ty {
312- JitType :: Int => match op {
317+ match a {
318+ JitValue :: Int ( val ) => match op {
313319 UnaryOperator :: Minus => {
314320 // Compile minus as 0 - a.
315321 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) ) ;
321324 Ok ( ( ) )
322325 }
323326 UnaryOperator :: Plus => {
@@ -327,14 +330,10 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
327330 }
328331 _ => Err ( JitCompileError :: NotSupported ) ,
329332 } ,
330- JitType :: Bool => match op {
333+ JitValue :: Bool ( val ) => match op {
331334 UnaryOperator :: Not => {
332- let val = self . boolean_val ( a) ?;
333335 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) ) ;
338337 Ok ( ( ) )
339338 }
340339 _ => Err ( JitCompileError :: NotSupported ) ,
@@ -346,73 +345,71 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
346345 // the rhs is popped off first
347346 let b = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
348347 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) ;
352351 self . builder . ins ( ) . trapif (
353352 IntCC :: Overflow ,
354353 carry,
355354 TrapCode :: IntegerOverflow ,
356355 ) ;
357- ( out , JitType :: Int )
356+ JitValue :: Int ( out )
358357 }
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) )
361360 }
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) )
364363 }
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) )
367366 }
368367 (
369368 BinaryOperator :: Lshift | BinaryOperator :: Rshift ,
370- JitType :: Int ,
371- JitType :: Int ,
369+ JitValue :: Int ( a ) ,
370+ JitValue :: Int ( b ) ,
372371 ) => {
373372 // Shifts throw an exception if we have a negative shift count
374373 // 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 ) ;
376375 self . builder . ins ( ) . trapnz (
377376 sign,
378377 TrapCode :: User ( CustomTrapCode :: NegativeShiftCount as u16 ) ,
379378 ) ;
380379
381380 let out = if * op == BinaryOperator :: Lshift {
382- self . builder . ins ( ) . ishl ( a. val , b. val )
381+ self . builder . ins ( ) . ishl ( a, b)
383382 } else {
384- self . builder . ins ( ) . sshr ( a. val , b. val )
383+ self . builder . ins ( ) . sshr ( a, b)
385384 } ;
386-
387- ( out, JitType :: Int )
385+ JitValue :: Int ( out)
388386 }
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) )
391389 }
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) )
394392 }
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) )
397395 }
398396
399397 // 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) )
402400 }
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) )
405403 }
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) )
408406 }
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) )
411409 }
412410 _ => return Err ( JitCompileError :: NotSupported ) ,
413411 } ;
414-
415- self . stack . push ( JitValue { val, ty } ) ;
412+ self . stack . push ( val) ;
416413
417414 Ok ( ( ) )
418415 }
0 commit comments