Skip to content

Commit d5abcdb

Browse files
committed
Sort match arms
1 parent 6d52107 commit d5abcdb

File tree

1 file changed

+183
-184
lines changed

1 file changed

+183
-184
lines changed

crates/jit/src/instructions.rs

Lines changed: 183 additions & 184 deletions
Original file line numberDiff line numberDiff line change
@@ -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::BinaryOperation(op) | Instruction::BinaryOperationInplace(op) => {
440279
let op = op.get(arg);
441280
// the rhs is popped off first
@@ -561,26 +400,11 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
561400

562401
Ok(())
563402
}
564-
Instruction::SetupLoop => {
565-
let loop_head = self.builder.create_block();
566-
self.builder.ins().jump(loop_head, &[]);
567-
self.builder.switch_to_block(loop_head);
568-
Ok(())
569-
}
570-
Instruction::PopBlock => {
571-
// TODO: block support
403+
Instruction::BuildTuple(size) => {
404+
let elements = self.pop_multiple(size.get(arg) as usize);
405+
self.stack.push(JitValue::Tuple(elements));
572406
Ok(())
573407
}
574-
Instruction::LoadGlobal(idx) => {
575-
let name = &bytecode.names[idx.get(arg) as usize];
576-
577-
if name.as_ref() != bytecode.obj_name.as_ref() {
578-
Err(JitCompileError::NotSupported)
579-
} else {
580-
self.stack.push(JitValue::FuncRef(func_ref));
581-
Ok(())
582-
}
583-
}
584408
Instruction::CallFunctionPositional(nargs) => {
585409
let nargs = nargs.get(arg);
586410

@@ -601,20 +425,195 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
601425
_ => Err(JitCompileError::BadBytecode),
602426
}
603427
}
428+
Instruction::CompareOperation(op) => {
429+
let op = op.get(arg);
430+
// the rhs is popped off first
431+
let b = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
432+
let a = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
433+
434+
let a_type: Option<JitType> = a.to_jit_type();
435+
let b_type: Option<JitType> = b.to_jit_type();
436+
437+
match (a, b) {
438+
(JitValue::Int(a), JitValue::Int(b))
439+
| (JitValue::Bool(a), JitValue::Bool(b))
440+
| (JitValue::Bool(a), JitValue::Int(b))
441+
| (JitValue::Int(a), JitValue::Bool(b)) => {
442+
let operand_one = match a_type.unwrap() {
443+
JitType::Bool => self.builder.ins().uextend(types::I64, a),
444+
_ => a,
445+
};
446+
447+
let operand_two = match b_type.unwrap() {
448+
JitType::Bool => self.builder.ins().uextend(types::I64, b),
449+
_ => b,
450+
};
451+
452+
let cond = match op {
453+
ComparisonOperator::Equal => IntCC::Equal,
454+
ComparisonOperator::NotEqual => IntCC::NotEqual,
455+
ComparisonOperator::Less => IntCC::SignedLessThan,
456+
ComparisonOperator::LessOrEqual => IntCC::SignedLessThanOrEqual,
457+
ComparisonOperator::Greater => IntCC::SignedGreaterThan,
458+
ComparisonOperator::GreaterOrEqual => IntCC::SignedGreaterThanOrEqual,
459+
};
460+
461+
let val = self.builder.ins().icmp(cond, operand_one, operand_two);
462+
self.stack.push(JitValue::Bool(val));
463+
Ok(())
464+
}
465+
(JitValue::Float(a), JitValue::Float(b)) => {
466+
let cond = match op {
467+
ComparisonOperator::Equal => FloatCC::Equal,
468+
ComparisonOperator::NotEqual => FloatCC::NotEqual,
469+
ComparisonOperator::Less => FloatCC::LessThan,
470+
ComparisonOperator::LessOrEqual => FloatCC::LessThanOrEqual,
471+
ComparisonOperator::Greater => FloatCC::GreaterThan,
472+
ComparisonOperator::GreaterOrEqual => FloatCC::GreaterThanOrEqual,
473+
};
474+
475+
let val = self.builder.ins().fcmp(cond, a, b);
476+
self.stack.push(JitValue::Bool(val));
477+
Ok(())
478+
}
479+
_ => Err(JitCompileError::NotSupported),
480+
}
481+
}
482+
Instruction::ExtendedArg => Ok(()),
483+
Instruction::Jump(target) => {
484+
let target_block = self.get_or_create_block(target.get(arg));
485+
self.builder.ins().jump(target_block, &[]);
486+
Ok(())
487+
}
488+
Instruction::LoadConst { idx } => {
489+
let val = self
490+
.prepare_const(bytecode.constants[idx.get(arg) as usize].borrow_constant())?;
491+
self.stack.push(val);
492+
Ok(())
493+
}
494+
Instruction::LoadFast(idx) => {
495+
let local = self.variables[idx.get(arg) as usize]
496+
.as_ref()
497+
.ok_or(JitCompileError::BadBytecode)?;
498+
self.stack.push(JitValue::from_type_and_value(
499+
local.ty.clone(),
500+
self.builder.use_var(local.var),
501+
));
502+
Ok(())
503+
}
504+
Instruction::LoadGlobal(idx) => {
505+
let name = &bytecode.names[idx.get(arg) as usize];
506+
507+
if name.as_ref() != bytecode.obj_name.as_ref() {
508+
Err(JitCompileError::NotSupported)
509+
} else {
510+
self.stack.push(JitValue::FuncRef(func_ref));
511+
Ok(())
512+
}
513+
}
604514
Instruction::Nop => Ok(()),
515+
Instruction::Pop => {
516+
self.stack.pop();
517+
Ok(())
518+
}
519+
Instruction::PopBlock => {
520+
// TODO: block support
521+
Ok(())
522+
}
523+
Instruction::PopJumpIfFalse(target) => {
524+
let cond = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
525+
let val = self.boolean_val(cond)?;
526+
let then_block = self.get_or_create_block(target.get(arg));
527+
let else_block = self.builder.create_block();
528+
529+
self.builder
530+
.ins()
531+
.brif(val, else_block, &[], then_block, &[]);
532+
self.builder.switch_to_block(else_block);
533+
534+
Ok(())
535+
}
536+
Instruction::PopJumpIfTrue(target) => {
537+
let cond = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
538+
let val = self.boolean_val(cond)?;
539+
let then_block = self.get_or_create_block(target.get(arg));
540+
let else_block = self.builder.create_block();
541+
542+
self.builder
543+
.ins()
544+
.brif(val, then_block, &[], else_block, &[]);
545+
self.builder.switch_to_block(else_block);
546+
547+
Ok(())
548+
}
549+
Instruction::Resume(_resume_arg) => {
550+
// TODO: Implement the resume instruction
551+
Ok(())
552+
}
553+
Instruction::ReturnConst(idx) => {
554+
let val = self
555+
.prepare_const(bytecode.constants[idx.get(arg) as usize].borrow_constant())?;
556+
self.return_value(val)
557+
}
558+
Instruction::ReturnValue => {
559+
let val = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
560+
self.return_value(val)
561+
}
562+
Instruction::SetupLoop => {
563+
let loop_head = self.builder.create_block();
564+
self.builder.ins().jump(loop_head, &[]);
565+
self.builder.switch_to_block(loop_head);
566+
Ok(())
567+
}
568+
Instruction::StoreFast(idx) => {
569+
let val = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
570+
self.store_variable(idx.get(arg), val)
571+
}
605572
Instruction::Swap(index) => {
606573
let len = self.stack.len();
607574
let i = len - 1;
608575
let j = len - 1 - index.get(arg) as usize;
609576
self.stack.swap(i, j);
610577
Ok(())
611578
}
612-
Instruction::Pop => {
613-
self.stack.pop();
614-
Ok(())
579+
Instruction::UnaryOperation(op) => {
580+
let op = op.get(arg);
581+
let a = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
582+
match (op, a) {
583+
(UnaryOperator::Minus, JitValue::Int(val)) => {
584+
// Compile minus as 0 - a.
585+
let zero = self.builder.ins().iconst(types::I64, 0);
586+
let out = self.compile_sub(zero, val);
587+
self.stack.push(JitValue::Int(out));
588+
Ok(())
589+
}
590+
(UnaryOperator::Plus, JitValue::Int(val)) => {
591+
// Nothing to do
592+
self.stack.push(JitValue::Int(val));
593+
Ok(())
594+
}
595+
(UnaryOperator::Not, a) => {
596+
let boolean = self.boolean_val(a)?;
597+
let not_boolean = self.builder.ins().bxor_imm(boolean, 1);
598+
self.stack.push(JitValue::Bool(not_boolean));
599+
Ok(())
600+
}
601+
_ => Err(JitCompileError::NotSupported),
602+
}
615603
}
616-
Instruction::Resume(_resume_arg) => {
617-
// TODO: Implement the resume instruction
604+
Instruction::UnpackSequence(size) => {
605+
let val = self.stack.pop().ok_or(JitCompileError::BadBytecode)?;
606+
607+
let elements = match val {
608+
JitValue::Tuple(elements) => elements,
609+
_ => return Err(JitCompileError::NotSupported),
610+
};
611+
612+
if elements.len() != size.get(arg) as usize {
613+
return Err(JitCompileError::NotSupported);
614+
}
615+
616+
self.stack.extend(elements.into_iter().rev());
618617
Ok(())
619618
}
620619
_ => Err(JitCompileError::NotSupported),

0 commit comments

Comments
 (0)