Skip to content

Commit

Permalink
bytecode: better distinction between InvokeStatic and InvokeDirect
Browse files Browse the repository at this point in the history
  • Loading branch information
dinfuehr committed Sep 20, 2020
1 parent d54579d commit add81e7
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 49 deletions.
21 changes: 7 additions & 14 deletions dora/src/bytecode/generator.rs
Expand Up @@ -681,7 +681,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
let fct_id = self.vm.vips.fct.string_buffer_to_string;
self.gen.emit_push_register(buffer_register);
self.gen
.emit_invoke_static(buffer_register, FctDef::fct_id(self.vm, fct_id), expr.pos);
.emit_invoke_direct(buffer_register, FctDef::fct_id(self.vm, fct_id), expr.pos);

buffer_register
}
Expand Down Expand Up @@ -1164,7 +1164,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
expr: &ExprCallType,
fct: &Fct,
call_type: &CallType,
arg_bytecode_types: &[BytecodeType],
_arg_bytecode_types: &[BytecodeType],
return_type: BuiltinType,
pos: Position,
fct_def_id: FctDefId,
Expand All @@ -1190,14 +1190,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
self.emit_invoke_direct(return_type, return_reg, fct_def_id, pos);
}
}
CallType::ModuleMethod(_, _, _) => {
if arg_bytecode_types.is_empty() {
self.emit_invoke_static(return_type, return_reg, fct_def_id, pos);
} else {
self.emit_invoke_direct(return_type, return_reg, fct_def_id, pos);
}
}
CallType::Fct(_, _, _) => {
CallType::ModuleMethod(_, _, _) | CallType::Fct(_, _, _) => {
self.emit_invoke_static(return_type, return_reg, fct_def_id, pos);
}
CallType::Expr(_, _) => {
Expand Down Expand Up @@ -2099,15 +2092,15 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
}
Intrinsic::Float32Sqrt => {
self.gen.emit_push_register(src);
self.gen.emit_invoke_static(
self.gen.emit_invoke_direct(
dest,
FctDef::fct_id(self.vm, info.fct_id.unwrap()),
opnd.pos(),
);
}
Intrinsic::Float64Sqrt => {
self.gen.emit_push_register(src);
self.gen.emit_invoke_static(
self.gen.emit_invoke_direct(
dest,
FctDef::fct_id(self.vm, info.fct_id.unwrap()),
opnd.pos(),
Expand All @@ -2120,7 +2113,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
| Intrinsic::Int32CountOneBitsLeading
| Intrinsic::Int32CountOneBitsTrailing => {
self.gen.emit_push_register(src);
self.gen.emit_invoke_static(
self.gen.emit_invoke_direct(
dest,
FctDef::fct_id(self.vm, info.fct_id.unwrap()),
opnd.pos(),
Expand All @@ -2133,7 +2126,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
| Intrinsic::Int64CountOneBitsLeading
| Intrinsic::Int64CountOneBitsTrailing => {
self.gen.emit_push_register(src);
self.gen.emit_invoke_static(
self.gen.emit_invoke_direct(
dest,
FctDef::fct_id(self.vm, info.fct_id.unwrap()),
opnd.pos(),
Expand Down
78 changes: 43 additions & 35 deletions dora/src/cannon/codegen.rs
Expand Up @@ -1929,56 +1929,63 @@ where
None
};

let arguments = self.argument_stack.drain(..).collect::<Vec<_>>();
let self_register = arguments[0];

let bytecode_type_self = self.bytecode.register_type(self_register);
let position = self.bytecode.offset_position(self.current_offset.to_u32());

if bytecode_type_self.is_ptr() {
self.emit_load_register(self_register, REG_RESULT.into());

self.asm
.test_if_nil_bailout(position, REG_RESULT.into(), Trap::NIL);
}

let fct_def = self.vm.fct_defs.idx(fct_def_id);
let fct_def = fct_def.read();

let fct_id = fct_def.fct_id;
let fct = self.vm.fcts.idx(fct_id);
let fct = fct.read();
assert!(fct.has_self());

let type_params = fct_def.type_params.clone();

let fct_return_type = specialize_type(self.vm, fct.return_type, &type_params);

let result_register = match fct_return_type {
BuiltinType::Tuple(_) => Some(dest.expect("need register for tuple result")),
_ => None,
};
let reg = if let FctKind::Builtin(intrinsic) = fct.kind {
self.emit_invoke_intrinsic(&*fct, &*fct_def, intrinsic)
} else {
let arguments = self.argument_stack.drain(..).collect::<Vec<_>>();
let self_register = arguments[0];

let argsize = self.emit_invoke_arguments(result_register, arguments);
let bytecode_type_self = self.bytecode.register_type(self_register);
let position = self.bytecode.offset_position(self.current_offset.to_u32());

let ptr = self.ptr_for_fct_id(fct_id, type_params.clone());
let gcpoint = self.create_gcpoint();
if bytecode_type_self.is_ptr() {
self.emit_load_register(self_register, REG_RESULT.into());

let (reg, ty) = match bytecode_type {
Some(BytecodeType::Tuple(_)) => (REG_RESULT.into(), BuiltinType::Unit),
Some(bytecode_type) => (result_reg(bytecode_type), bytecode_type.into()),
None => (REG_RESULT.into(), BuiltinType::Unit),
};
self.asm.direct_call(
fct_id,
ptr.to_ptr(),
type_params,
position,
gcpoint,
ty,
reg,
);
self.asm
.test_if_nil_bailout(position, REG_RESULT.into(), Trap::NIL);
}

self.asm.decrease_stack_frame(argsize);
let result_register = match fct_return_type {
BuiltinType::Tuple(_) => Some(dest.expect("need register for tuple result")),
_ => None,
};

let argsize = self.emit_invoke_arguments(result_register, arguments);

let ptr = self.ptr_for_fct_id(fct_id, type_params.clone());
let gcpoint = self.create_gcpoint();

let (reg, ty) = match bytecode_type {
Some(BytecodeType::Tuple(_)) => (REG_RESULT.into(), BuiltinType::Unit),
Some(bytecode_type) => (result_reg(bytecode_type), bytecode_type.into()),
None => (REG_RESULT.into(), BuiltinType::Unit),
};
self.asm.direct_call(
fct_id,
ptr.to_ptr(),
type_params,
position,
gcpoint,
ty,
reg,
);

self.asm.decrease_stack_frame(argsize);

reg
};

if let Some(dest) = dest {
if !fct_return_type.is_tuple() {
Expand All @@ -1994,6 +2001,7 @@ where
let fct_id = fct_def.fct_id;
let fct = self.vm.fcts.idx(fct_id);
let fct = fct.read();
assert!(!fct.has_self());

let type_params = fct_def.type_params.clone();

Expand Down

0 comments on commit add81e7

Please sign in to comment.