@@ -275,167 +275,6 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
275275 arg : OpArg ,
276276 ) -> Result < ( ) , JitCompileError > {
277277 match instruction {
278- Instruction :: ExtendedArg => Ok ( ( ) ) ,
279- Instruction :: PopJumpIfFalse { target } => {
280- let cond = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
281- let val = self . boolean_val ( cond) ?;
282- let then_block = self . get_or_create_block ( target. get ( arg) ) ;
283- let else_block = self . builder . create_block ( ) ;
284-
285- self . builder
286- . ins ( )
287- . brif ( val, else_block, & [ ] , then_block, & [ ] ) ;
288- self . builder . switch_to_block ( else_block) ;
289-
290- Ok ( ( ) )
291- }
292- Instruction :: PopJumpIfTrue { target } => {
293- let cond = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
294- let val = self . boolean_val ( cond) ?;
295- let then_block = self . get_or_create_block ( target. get ( arg) ) ;
296- let else_block = self . builder . create_block ( ) ;
297-
298- self . builder
299- . ins ( )
300- . brif ( val, then_block, & [ ] , else_block, & [ ] ) ;
301- self . builder . switch_to_block ( else_block) ;
302-
303- Ok ( ( ) )
304- }
305-
306- Instruction :: Jump { target } => {
307- let target_block = self . get_or_create_block ( target. get ( arg) ) ;
308- self . builder . ins ( ) . jump ( target_block, & [ ] ) ;
309- Ok ( ( ) )
310- }
311- Instruction :: LoadFast ( idx) => {
312- let local = self . variables [ idx. get ( arg) as usize ]
313- . as_ref ( )
314- . ok_or ( JitCompileError :: BadBytecode ) ?;
315- self . stack . push ( JitValue :: from_type_and_value (
316- local. ty . clone ( ) ,
317- self . builder . use_var ( local. var ) ,
318- ) ) ;
319- Ok ( ( ) )
320- }
321- Instruction :: StoreFast ( idx) => {
322- let val = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
323- self . store_variable ( idx. get ( arg) , val)
324- }
325- Instruction :: LoadConst { idx } => {
326- let val = self
327- . prepare_const ( bytecode. constants [ idx. get ( arg) as usize ] . borrow_constant ( ) ) ?;
328- self . stack . push ( val) ;
329- Ok ( ( ) )
330- }
331- Instruction :: BuildTuple { size } => {
332- let elements = self . pop_multiple ( size. get ( arg) as usize ) ;
333- self . stack . push ( JitValue :: Tuple ( elements) ) ;
334- Ok ( ( ) )
335- }
336- Instruction :: UnpackSequence { size } => {
337- let val = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
338-
339- let elements = match val {
340- JitValue :: Tuple ( elements) => elements,
341- _ => return Err ( JitCompileError :: NotSupported ) ,
342- } ;
343-
344- if elements. len ( ) != size. get ( arg) as usize {
345- return Err ( JitCompileError :: NotSupported ) ;
346- }
347-
348- self . stack . extend ( elements. into_iter ( ) . rev ( ) ) ;
349- Ok ( ( ) )
350- }
351- Instruction :: ReturnValue => {
352- let val = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
353- self . return_value ( val)
354- }
355- Instruction :: ReturnConst { idx } => {
356- let val = self
357- . prepare_const ( bytecode. constants [ idx. get ( arg) as usize ] . borrow_constant ( ) ) ?;
358- self . return_value ( val)
359- }
360- Instruction :: CompareOperation { op, .. } => {
361- let op = op. get ( arg) ;
362- // the rhs is popped off first
363- let b = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
364- let a = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
365-
366- let a_type: Option < JitType > = a. to_jit_type ( ) ;
367- let b_type: Option < JitType > = b. to_jit_type ( ) ;
368-
369- match ( a, b) {
370- ( JitValue :: Int ( a) , JitValue :: Int ( b) )
371- | ( JitValue :: Bool ( a) , JitValue :: Bool ( b) )
372- | ( JitValue :: Bool ( a) , JitValue :: Int ( b) )
373- | ( JitValue :: Int ( a) , JitValue :: Bool ( b) ) => {
374- let operand_one = match a_type. unwrap ( ) {
375- JitType :: Bool => self . builder . ins ( ) . uextend ( types:: I64 , a) ,
376- _ => a,
377- } ;
378-
379- let operand_two = match b_type. unwrap ( ) {
380- JitType :: Bool => self . builder . ins ( ) . uextend ( types:: I64 , b) ,
381- _ => b,
382- } ;
383-
384- let cond = match op {
385- ComparisonOperator :: Equal => IntCC :: Equal ,
386- ComparisonOperator :: NotEqual => IntCC :: NotEqual ,
387- ComparisonOperator :: Less => IntCC :: SignedLessThan ,
388- ComparisonOperator :: LessOrEqual => IntCC :: SignedLessThanOrEqual ,
389- ComparisonOperator :: Greater => IntCC :: SignedGreaterThan ,
390- ComparisonOperator :: GreaterOrEqual => IntCC :: SignedGreaterThanOrEqual ,
391- } ;
392-
393- let val = self . builder . ins ( ) . icmp ( cond, operand_one, operand_two) ;
394- self . stack . push ( JitValue :: Bool ( val) ) ;
395- Ok ( ( ) )
396- }
397- ( JitValue :: Float ( a) , JitValue :: Float ( b) ) => {
398- let cond = match op {
399- ComparisonOperator :: Equal => FloatCC :: Equal ,
400- ComparisonOperator :: NotEqual => FloatCC :: NotEqual ,
401- ComparisonOperator :: Less => FloatCC :: LessThan ,
402- ComparisonOperator :: LessOrEqual => FloatCC :: LessThanOrEqual ,
403- ComparisonOperator :: Greater => FloatCC :: GreaterThan ,
404- ComparisonOperator :: GreaterOrEqual => FloatCC :: GreaterThanOrEqual ,
405- } ;
406-
407- let val = self . builder . ins ( ) . fcmp ( cond, a, b) ;
408- self . stack . push ( JitValue :: Bool ( val) ) ;
409- Ok ( ( ) )
410- }
411- _ => Err ( JitCompileError :: NotSupported ) ,
412- }
413- }
414- Instruction :: UnaryOperation { op, .. } => {
415- let op = op. get ( arg) ;
416- let a = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
417- match ( op, a) {
418- ( UnaryOperator :: Minus , JitValue :: Int ( val) ) => {
419- // Compile minus as 0 - a.
420- let zero = self . builder . ins ( ) . iconst ( types:: I64 , 0 ) ;
421- let out = self . compile_sub ( zero, val) ;
422- self . stack . push ( JitValue :: Int ( out) ) ;
423- Ok ( ( ) )
424- }
425- ( UnaryOperator :: Plus , JitValue :: Int ( val) ) => {
426- // Nothing to do
427- self . stack . push ( JitValue :: Int ( val) ) ;
428- Ok ( ( ) )
429- }
430- ( UnaryOperator :: Not , a) => {
431- let boolean = self . boolean_val ( a) ?;
432- let not_boolean = self . builder . ins ( ) . bxor_imm ( boolean, 1 ) ;
433- self . stack . push ( JitValue :: Bool ( not_boolean) ) ;
434- Ok ( ( ) )
435- }
436- _ => Err ( JitCompileError :: NotSupported ) ,
437- }
438- }
439278 Instruction :: BinaryOp { op } => {
440279 let op = op. get ( arg) ;
441280 // the rhs is popped off first
@@ -597,26 +436,11 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
597436
598437 Ok ( ( ) )
599438 }
600- Instruction :: SetupLoop => {
601- let loop_head = self . builder . create_block ( ) ;
602- self . builder . ins ( ) . jump ( loop_head, & [ ] ) ;
603- self . builder . switch_to_block ( loop_head) ;
604- Ok ( ( ) )
605- }
606- Instruction :: PopBlock => {
607- // TODO: block support
439+ Instruction :: BuildTuple { size } => {
440+ let elements = self . pop_multiple ( size. get ( arg) as usize ) ;
441+ self . stack . push ( JitValue :: Tuple ( elements) ) ;
608442 Ok ( ( ) )
609443 }
610- Instruction :: LoadGlobal ( idx) => {
611- let name = & bytecode. names [ idx. get ( arg) as usize ] ;
612-
613- if name. as_ref ( ) != bytecode. obj_name . as_ref ( ) {
614- Err ( JitCompileError :: NotSupported )
615- } else {
616- self . stack . push ( JitValue :: FuncRef ( func_ref) ) ;
617- Ok ( ( ) )
618- }
619- }
620444 Instruction :: CallFunctionPositional { nargs } => {
621445 let nargs = nargs. get ( arg) ;
622446
@@ -637,20 +461,196 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
637461 _ => Err ( JitCompileError :: BadBytecode ) ,
638462 }
639463 }
464+ Instruction :: CompareOperation { op, .. } => {
465+ let op = op. get ( arg) ;
466+ // the rhs is popped off first
467+ let b = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
468+ let a = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
469+
470+ let a_type: Option < JitType > = a. to_jit_type ( ) ;
471+ let b_type: Option < JitType > = b. to_jit_type ( ) ;
472+
473+ match ( a, b) {
474+ ( JitValue :: Int ( a) , JitValue :: Int ( b) )
475+ | ( JitValue :: Bool ( a) , JitValue :: Bool ( b) )
476+ | ( JitValue :: Bool ( a) , JitValue :: Int ( b) )
477+ | ( JitValue :: Int ( a) , JitValue :: Bool ( b) ) => {
478+ let operand_one = match a_type. unwrap ( ) {
479+ JitType :: Bool => self . builder . ins ( ) . uextend ( types:: I64 , a) ,
480+ _ => a,
481+ } ;
482+
483+ let operand_two = match b_type. unwrap ( ) {
484+ JitType :: Bool => self . builder . ins ( ) . uextend ( types:: I64 , b) ,
485+ _ => b,
486+ } ;
487+
488+ let cond = match op {
489+ ComparisonOperator :: Equal => IntCC :: Equal ,
490+ ComparisonOperator :: NotEqual => IntCC :: NotEqual ,
491+ ComparisonOperator :: Less => IntCC :: SignedLessThan ,
492+ ComparisonOperator :: LessOrEqual => IntCC :: SignedLessThanOrEqual ,
493+ ComparisonOperator :: Greater => IntCC :: SignedGreaterThan ,
494+ ComparisonOperator :: GreaterOrEqual => IntCC :: SignedGreaterThanOrEqual ,
495+ } ;
496+
497+ let val = self . builder . ins ( ) . icmp ( cond, operand_one, operand_two) ;
498+ self . stack . push ( JitValue :: Bool ( val) ) ;
499+ Ok ( ( ) )
500+ }
501+ ( JitValue :: Float ( a) , JitValue :: Float ( b) ) => {
502+ let cond = match op {
503+ ComparisonOperator :: Equal => FloatCC :: Equal ,
504+ ComparisonOperator :: NotEqual => FloatCC :: NotEqual ,
505+ ComparisonOperator :: Less => FloatCC :: LessThan ,
506+ ComparisonOperator :: LessOrEqual => FloatCC :: LessThanOrEqual ,
507+ ComparisonOperator :: Greater => FloatCC :: GreaterThan ,
508+ ComparisonOperator :: GreaterOrEqual => FloatCC :: GreaterThanOrEqual ,
509+ } ;
510+
511+ let val = self . builder . ins ( ) . fcmp ( cond, a, b) ;
512+ self . stack . push ( JitValue :: Bool ( val) ) ;
513+ Ok ( ( ) )
514+ }
515+ _ => Err ( JitCompileError :: NotSupported ) ,
516+ }
517+ }
518+ Instruction :: ExtendedArg => Ok ( ( ) ) ,
519+
520+ Instruction :: Jump { target } => {
521+ let target_block = self . get_or_create_block ( target. get ( arg) ) ;
522+ self . builder . ins ( ) . jump ( target_block, & [ ] ) ;
523+ Ok ( ( ) )
524+ }
525+ Instruction :: LoadConst { idx } => {
526+ let val = self
527+ . prepare_const ( bytecode. constants [ idx. get ( arg) as usize ] . borrow_constant ( ) ) ?;
528+ self . stack . push ( val) ;
529+ Ok ( ( ) )
530+ }
531+ Instruction :: LoadFast ( idx) => {
532+ let local = self . variables [ idx. get ( arg) as usize ]
533+ . as_ref ( )
534+ . ok_or ( JitCompileError :: BadBytecode ) ?;
535+ self . stack . push ( JitValue :: from_type_and_value (
536+ local. ty . clone ( ) ,
537+ self . builder . use_var ( local. var ) ,
538+ ) ) ;
539+ Ok ( ( ) )
540+ }
541+ Instruction :: LoadGlobal ( idx) => {
542+ let name = & bytecode. names [ idx. get ( arg) as usize ] ;
543+
544+ if name. as_ref ( ) != bytecode. obj_name . as_ref ( ) {
545+ Err ( JitCompileError :: NotSupported )
546+ } else {
547+ self . stack . push ( JitValue :: FuncRef ( func_ref) ) ;
548+ Ok ( ( ) )
549+ }
550+ }
640551 Instruction :: Nop => Ok ( ( ) ) ,
552+ Instruction :: Pop => {
553+ self . stack . pop ( ) ;
554+ Ok ( ( ) )
555+ }
556+ Instruction :: PopBlock => {
557+ // TODO: block support
558+ Ok ( ( ) )
559+ }
560+ Instruction :: PopJumpIfFalse { target } => {
561+ let cond = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
562+ let val = self . boolean_val ( cond) ?;
563+ let then_block = self . get_or_create_block ( target. get ( arg) ) ;
564+ let else_block = self . builder . create_block ( ) ;
565+
566+ self . builder
567+ . ins ( )
568+ . brif ( val, else_block, & [ ] , then_block, & [ ] ) ;
569+ self . builder . switch_to_block ( else_block) ;
570+
571+ Ok ( ( ) )
572+ }
573+ Instruction :: PopJumpIfTrue { target } => {
574+ let cond = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
575+ let val = self . boolean_val ( cond) ?;
576+ let then_block = self . get_or_create_block ( target. get ( arg) ) ;
577+ let else_block = self . builder . create_block ( ) ;
578+
579+ self . builder
580+ . ins ( )
581+ . brif ( val, then_block, & [ ] , else_block, & [ ] ) ;
582+ self . builder . switch_to_block ( else_block) ;
583+
584+ Ok ( ( ) )
585+ }
586+ Instruction :: Resume { arg : _resume_arg } => {
587+ // TODO: Implement the resume instruction
588+ Ok ( ( ) )
589+ }
590+ Instruction :: ReturnConst { idx } => {
591+ let val = self
592+ . prepare_const ( bytecode. constants [ idx. get ( arg) as usize ] . borrow_constant ( ) ) ?;
593+ self . return_value ( val)
594+ }
595+ Instruction :: ReturnValue => {
596+ let val = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
597+ self . return_value ( val)
598+ }
599+ Instruction :: SetupLoop => {
600+ let loop_head = self . builder . create_block ( ) ;
601+ self . builder . ins ( ) . jump ( loop_head, & [ ] ) ;
602+ self . builder . switch_to_block ( loop_head) ;
603+ Ok ( ( ) )
604+ }
605+ Instruction :: StoreFast ( idx) => {
606+ let val = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
607+ self . store_variable ( idx. get ( arg) , val)
608+ }
641609 Instruction :: Swap { index } => {
642610 let len = self . stack . len ( ) ;
643611 let i = len - 1 ;
644612 let j = len - 1 - index. get ( arg) as usize ;
645613 self . stack . swap ( i, j) ;
646614 Ok ( ( ) )
647615 }
648- Instruction :: Pop => {
649- self . stack . pop ( ) ;
650- Ok ( ( ) )
616+ Instruction :: UnaryOperation { op, .. } => {
617+ let op = op. get ( arg) ;
618+ let a = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
619+ match ( op, a) {
620+ ( UnaryOperator :: Minus , JitValue :: Int ( val) ) => {
621+ // Compile minus as 0 - a.
622+ let zero = self . builder . ins ( ) . iconst ( types:: I64 , 0 ) ;
623+ let out = self . compile_sub ( zero, val) ;
624+ self . stack . push ( JitValue :: Int ( out) ) ;
625+ Ok ( ( ) )
626+ }
627+ ( UnaryOperator :: Plus , JitValue :: Int ( val) ) => {
628+ // Nothing to do
629+ self . stack . push ( JitValue :: Int ( val) ) ;
630+ Ok ( ( ) )
631+ }
632+ ( UnaryOperator :: Not , a) => {
633+ let boolean = self . boolean_val ( a) ?;
634+ let not_boolean = self . builder . ins ( ) . bxor_imm ( boolean, 1 ) ;
635+ self . stack . push ( JitValue :: Bool ( not_boolean) ) ;
636+ Ok ( ( ) )
637+ }
638+ _ => Err ( JitCompileError :: NotSupported ) ,
639+ }
651640 }
652- Instruction :: Resume { arg : _resume_arg } => {
653- // TODO: Implement the resume instruction
641+ Instruction :: UnpackSequence { size } => {
642+ let val = self . stack . pop ( ) . ok_or ( JitCompileError :: BadBytecode ) ?;
643+
644+ let elements = match val {
645+ JitValue :: Tuple ( elements) => elements,
646+ _ => return Err ( JitCompileError :: NotSupported ) ,
647+ } ;
648+
649+ if elements. len ( ) != size. get ( arg) as usize {
650+ return Err ( JitCompileError :: NotSupported ) ;
651+ }
652+
653+ self . stack . extend ( elements. into_iter ( ) . rev ( ) ) ;
654654 Ok ( ( ) )
655655 }
656656 _ => Err ( JitCompileError :: NotSupported ) ,
0 commit comments