Skip to content

Commit

Permalink
bytecode: use const pool instead of FctDef for type params
Browse files Browse the repository at this point in the history
  • Loading branch information
dinfuehr committed Sep 20, 2020
1 parent ba021c5 commit d54579d
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 65 deletions.
37 changes: 27 additions & 10 deletions dora/src/bytecode/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ use std::collections::{HashMap, HashSet};

use dora_parser::lexer::position::Position;

use crate::bytecode::{dump, BytecodeFunction, BytecodeType, BytecodeWriter, Label, Register};
use crate::bytecode::{
dump, BytecodeFunction, BytecodeType, BytecodeWriter, ConstPoolEntry, ConstPoolIdx, Label,
Register,
};
use crate::driver::cmd::Args;
use crate::vm::{ClassDefId, FctDefId, FieldId, GlobalId, TupleId, VM};
use crate::ty::TypeList;
use crate::vm::{ClassDefId, FctDefId, FctId, FieldId, GlobalId, TupleId, VM};

pub struct BytecodeBuilder {
writer: BytecodeWriter,
Expand Down Expand Up @@ -37,6 +41,19 @@ impl BytecodeBuilder {
self.writer.set_arguments(arguments)
}

pub fn add_const(&mut self, entry: ConstPoolEntry) -> ConstPoolIdx {
self.writer.add_const(entry)
}

pub fn add_const_fct(&mut self, id: FctId) -> ConstPoolIdx {
self.writer
.add_const(ConstPoolEntry::Fct(id, TypeList::empty()))
}

pub fn add_const_fct_types(&mut self, id: FctId, type_params: TypeList) -> ConstPoolIdx {
self.writer.add_const(ConstPoolEntry::Fct(id, type_params))
}

pub fn emit_add_int32(&mut self, dest: Register, lhs: Register, rhs: Register) {
assert!(self.def(dest) && self.used(lhs) && self.used(rhs));
self.writer.emit_add_int32(dest, lhs, rhs);
Expand Down Expand Up @@ -834,26 +851,26 @@ impl BytecodeBuilder {
self.writer.emit_invoke_static(dest, fid);
}

pub fn emit_invoke_generic_static_void(&mut self, fid: FctDefId, pos: Position) {
pub fn emit_invoke_generic_static_void(&mut self, idx: ConstPoolIdx, pos: Position) {
self.writer.set_position(pos);
self.writer.emit_invoke_generic_static_void(fid);
self.writer.emit_invoke_generic_static_void(idx);
}

pub fn emit_invoke_generic_static(&mut self, dest: Register, fid: FctDefId, pos: Position) {
pub fn emit_invoke_generic_static(&mut self, dest: Register, idx: ConstPoolIdx, pos: Position) {
assert!(self.def(dest));
self.writer.set_position(pos);
self.writer.emit_invoke_generic_static(dest, fid);
self.writer.emit_invoke_generic_static(dest, idx);
}

pub fn emit_invoke_generic_direct_void(&mut self, fid: FctDefId, pos: Position) {
pub fn emit_invoke_generic_direct_void(&mut self, idx: ConstPoolIdx, pos: Position) {
self.writer.set_position(pos);
self.writer.emit_invoke_generic_direct_void(fid);
self.writer.emit_invoke_generic_direct_void(idx);
}

pub fn emit_invoke_generic_direct(&mut self, dest: Register, fid: FctDefId, pos: Position) {
pub fn emit_invoke_generic_direct(&mut self, dest: Register, idx: ConstPoolIdx, pos: Position) {
assert!(self.def(dest));
self.writer.set_position(pos);
self.writer.emit_invoke_generic_direct(dest, fid);
self.writer.emit_invoke_generic_direct(dest, idx);
}

pub fn emit_new_object(&mut self, dest: Register, cls_id: ClassDefId, pos: Position) {
Expand Down
26 changes: 18 additions & 8 deletions dora/src/bytecode/dumper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,16 @@ impl<'a, 'ast> BytecodeDumper<'a, 'ast> {
writeln!(self.w, " {}, FctDefId({})", r1, fid.to_usize()).expect("write! failed");
}

fn emit_fct_const_void(&mut self, name: &str, fid: ConstPoolIdx) {
self.emit_start(name);
writeln!(self.w, " ConstPoolIdx({})", fid.to_usize()).expect("write! failed");
}

fn emit_fct_const(&mut self, name: &str, r1: Register, fid: ConstPoolIdx) {
self.emit_start(name);
writeln!(self.w, " {}, ConstPoolIdx({})", r1, fid.to_usize()).expect("write! failed");
}

fn emit_new_object(&mut self, name: &str, r1: Register, cls_id: ClassDefId) {
self.emit_start(name);
let cls = self.vm.class_defs.idx(cls_id);
Expand Down Expand Up @@ -825,18 +835,18 @@ impl<'a, 'ast> BytecodeVisitor for BytecodeDumper<'a, 'ast> {
self.emit_fct("InvokeStatic", dest, fctdef);
}

fn visit_invoke_generic_static_void(&mut self, fctdef: FctDefId) {
self.emit_fct_void("InvokeGenericStaticVoid", fctdef);
fn visit_invoke_generic_static_void(&mut self, fct: ConstPoolIdx) {
self.emit_fct_const_void("InvokeGenericStaticVoid", fct);
}
fn visit_invoke_generic_static(&mut self, dest: Register, fctdef: FctDefId) {
self.emit_fct("InvokeGenericStatic", dest, fctdef);
fn visit_invoke_generic_static(&mut self, dest: Register, fct: ConstPoolIdx) {
self.emit_fct_const("InvokeGenericStatic", dest, fct);
}

fn visit_invoke_generic_direct_void(&mut self, fctdef: FctDefId) {
self.emit_fct_void("InvokeGenericDirectVoid", fctdef);
fn visit_invoke_generic_direct_void(&mut self, fct: ConstPoolIdx) {
self.emit_fct_const_void("InvokeGenericDirectVoid", fct);
}
fn visit_invoke_generic_direct(&mut self, dest: Register, fctdef: FctDefId) {
self.emit_fct("InvokeGenericDirect", dest, fctdef);
fn visit_invoke_generic_direct(&mut self, dest: Register, fct: ConstPoolIdx) {
self.emit_fct_const("InvokeGenericDirect", dest, fct);
}

fn visit_new_object(&mut self, dest: Register, cls: ClassDefId) {
Expand Down
37 changes: 21 additions & 16 deletions dora/src/bytecode/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use dora_parser::ast::Expr::*;
use dora_parser::ast::Stmt::*;
use dora_parser::ast::*;

use crate::bytecode::{BytecodeBuilder, BytecodeFunction, BytecodeType, Label, Register};
use crate::bytecode::{
BytecodeBuilder, BytecodeFunction, BytecodeType, ConstPoolIdx, Label, Register,
};
use crate::semck::specialize::{specialize_class_ty, specialize_type};
use crate::semck::{expr_always_returns, expr_block_always_returns};
use crate::size::InstanceSize;
Expand Down Expand Up @@ -636,11 +638,10 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
.find_method(self.vm, name, false)
.expect("Stringable::toString() not found");

self.gen.emit_invoke_generic_direct(
part_register,
FctDef::fct_id(self.vm, to_string_id),
part.pos(),
);
let fct_idx = self.gen.add_const_fct(to_string_id);

self.gen
.emit_invoke_generic_direct(part_register, fct_idx, part.pos());

self.free_if_temp(expr_register);
} else {
Expand Down Expand Up @@ -879,7 +880,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
let callee = callee.read();

// Create FctDefId for this Fct
let callee_def_id = self.specialize_call(&callee, &call_type);
let (callee_def_id, callee_type_params) = self.specialize_call(&callee, &call_type);

// Determine types for arguments and return values
let (arg_types, arg_bytecode_types, return_type) =
Expand Down Expand Up @@ -917,6 +918,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
return_type,
expr.pos,
callee_def_id,
callee_type_params,
return_reg,
);

Expand Down Expand Up @@ -1166,6 +1168,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
return_type: BuiltinType,
pos: Position,
fct_def_id: FctDefId,
fct_type_params: TypeList,
return_reg: Register,
) {
match *call_type {
Expand Down Expand Up @@ -1207,14 +1210,16 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
CallType::TraitObjectMethod(_, _) => unimplemented!(),
CallType::GenericMethod(_, _, _) => {
if self.generic_mode {
self.emit_invoke_generic_direct(return_type, return_reg, fct_def_id, pos);
let callee_idx = self.gen.add_const_fct_types(fct.id, fct_type_params);
self.emit_invoke_generic_direct(return_type, return_reg, callee_idx, pos);
} else {
self.emit_invoke_direct(return_type, return_reg, fct_def_id, pos);
}
}
CallType::GenericStaticMethod(_, _, _) => {
if self.generic_mode {
self.emit_invoke_generic_static(return_type, return_reg, fct_def_id, pos);
let callee_idx = self.gen.add_const_fct_types(fct.id, fct_type_params);
self.emit_invoke_generic_static(return_type, return_reg, callee_idx, pos);
} else {
self.emit_invoke_static(return_type, return_reg, fct_def_id, pos);
}
Expand Down Expand Up @@ -1339,7 +1344,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
&mut self,
return_type: BuiltinType,
return_reg: Register,
callee_id: FctDefId,
callee_id: ConstPoolIdx,
pos: Position,
) {
if return_type.is_unit() {
Expand All @@ -1354,7 +1359,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
&mut self,
return_type: BuiltinType,
return_reg: Register,
callee_id: FctDefId,
callee_id: ConstPoolIdx,
pos: Position,
) {
if return_type.is_unit() {
Expand All @@ -1374,7 +1379,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
let callee = self.vm.fcts.idx(callee_id);
let callee = callee.read();

let fct_def_id = self.specialize_call(&callee, &call_type);
let (fct_def_id, _) = self.specialize_call(&callee, &call_type);

assert!(callee.return_type.is_unit());
let arg_types = callee
Expand Down Expand Up @@ -1615,7 +1620,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
let callee = callee.read();

// Create FctDefId for this callee
let callee_def_id = self.specialize_call(&callee, &call_type);
let (callee_def_id, _) = self.specialize_call(&callee, &call_type);

let function_return_type: BuiltinType =
self.specialize_type_for_call(call_type, callee.return_type);
Expand Down Expand Up @@ -1659,7 +1664,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
let callee = callee.read();

// Create FctDefId for this callee
let callee_def_id = self.specialize_call(&callee, &call_type);
let (callee_def_id, _) = self.specialize_call(&callee, &call_type);

let function_return_type: BuiltinType =
self.specialize_type_for_call(call_type, callee.return_type);
Expand Down Expand Up @@ -2730,7 +2735,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
}
}

fn specialize_call(&self, fct: &Fct, call_type: &CallType) -> FctDefId {
fn specialize_call(&self, fct: &Fct, call_type: &CallType) -> (FctDefId, TypeList) {
let type_params = self.determine_call_type_params(call_type);

let type_params = TypeList::with(
Expand All @@ -2740,7 +2745,7 @@ impl<'a, 'ast> AstBytecodeGen<'a, 'ast> {
.collect::<Vec<_>>(),
);

FctDef::with(self.vm, fct, type_params)
(FctDef::with(self.vm, fct, type_params.clone()), type_params)
}

fn specialize_type_for_call(&self, call_type: &CallType, ty: BuiltinType) -> BuiltinType {
Expand Down
28 changes: 14 additions & 14 deletions dora/src/bytecode/generator_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ fn gen_generic_identity() {
#[test]
fn gen_generic_static_trait() {
let result = gcode("trait Foo { @static fun baz(); } fun f[T: Foo]() { T::baz() }");
let expected = vec![InvokeGenericStaticVoid(FctDefId(0)), RetVoid, RetVoid];
let expected = vec![InvokeGenericStaticVoid(ConstPoolIdx(0)), RetVoid, RetVoid];
assert_eq!(expected, result);
}

Expand All @@ -102,7 +102,7 @@ fn gen_generic_direct_trait() {
let result = gcode("trait Foo { fun baz(); } fun f[T: Foo](obj: T) { obj.baz() }");
let expected = vec![
PushRegister(r(0)),
InvokeGenericDirectVoid(FctDefId(0)),
InvokeGenericDirectVoid(ConstPoolIdx(0)),
RetVoid,
RetVoid,
];
Expand Down Expand Up @@ -3365,11 +3365,11 @@ pub enum Bytecode {
InvokeStaticVoid(FctDefId),
InvokeStatic(Register, FctDefId),

InvokeGenericStaticVoid(FctDefId),
InvokeGenericStatic(Register, FctDefId),
InvokeGenericStaticVoid(ConstPoolIdx),
InvokeGenericStatic(Register, ConstPoolIdx),

InvokeGenericDirectVoid(FctDefId),
InvokeGenericDirect(Register, FctDefId),
InvokeGenericDirectVoid(ConstPoolIdx),
InvokeGenericDirect(Register, ConstPoolIdx),

NewObject(Register, ClassDefId),
NewArray(Register, ClassDefId, Register),
Expand Down Expand Up @@ -4001,18 +4001,18 @@ impl<'a> BytecodeVisitor for BytecodeArrayBuilder<'a> {
self.emit(Bytecode::InvokeStatic(dest, fctdef));
}

fn visit_invoke_generic_static_void(&mut self, fctdef: FctDefId) {
self.emit(Bytecode::InvokeGenericStaticVoid(fctdef));
fn visit_invoke_generic_static_void(&mut self, fct_idx: ConstPoolIdx) {
self.emit(Bytecode::InvokeGenericStaticVoid(fct_idx));
}
fn visit_invoke_generic_static(&mut self, dest: Register, fctdef: FctDefId) {
self.emit(Bytecode::InvokeGenericStatic(dest, fctdef));
fn visit_invoke_generic_static(&mut self, dest: Register, fct_idx: ConstPoolIdx) {
self.emit(Bytecode::InvokeGenericStatic(dest, fct_idx));
}

fn visit_invoke_generic_direct_void(&mut self, fctdef: FctDefId) {
self.emit(Bytecode::InvokeGenericDirectVoid(fctdef));
fn visit_invoke_generic_direct_void(&mut self, fct_idx: ConstPoolIdx) {
self.emit(Bytecode::InvokeGenericDirectVoid(fct_idx));
}
fn visit_invoke_generic_direct(&mut self, dest: Register, fctdef: FctDefId) {
self.emit(Bytecode::InvokeGenericDirect(dest, fctdef));
fn visit_invoke_generic_direct(&mut self, dest: Register, fct_idx: ConstPoolIdx) {
self.emit(Bytecode::InvokeGenericDirect(dest, fct_idx));
}

fn visit_new_object(&mut self, dest: Register, cls: ClassDefId) {
Expand Down
16 changes: 8 additions & 8 deletions dora/src/bytecode/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -947,22 +947,22 @@ where
}

BytecodeOpcode::InvokeGenericStaticVoid => {
let fct = self.read_fct(wide);
let fct = self.read_const_pool_idx(wide);
self.visitor.visit_invoke_generic_static_void(fct);
}
BytecodeOpcode::InvokeGenericStatic => {
let dest = self.read_register(wide);
let fct = self.read_fct(wide);
let fct = self.read_const_pool_idx(wide);
self.visitor.visit_invoke_generic_static(dest, fct);
}

BytecodeOpcode::InvokeGenericDirectVoid => {
let fct = self.read_fct(wide);
let fct = self.read_const_pool_idx(wide);
self.visitor.visit_invoke_generic_direct_void(fct);
}
BytecodeOpcode::InvokeGenericDirect => {
let dest = self.read_register(wide);
let fct = self.read_fct(wide);
let fct = self.read_const_pool_idx(wide);
self.visitor.visit_invoke_generic_direct(dest, fct);
}

Expand Down Expand Up @@ -1755,17 +1755,17 @@ pub trait BytecodeVisitor {
unimplemented!();
}

fn visit_invoke_generic_static_void(&mut self, _fctdef: FctDefId) {
fn visit_invoke_generic_static_void(&mut self, _fct: ConstPoolIdx) {
unimplemented!();
}
fn visit_invoke_generic_static(&mut self, _dest: Register, _fctdef: FctDefId) {
fn visit_invoke_generic_static(&mut self, _dest: Register, _fct: ConstPoolIdx) {
unimplemented!();
}

fn visit_invoke_generic_direct_void(&mut self, _fctdef: FctDefId) {
fn visit_invoke_generic_direct_void(&mut self, _fct: ConstPoolIdx) {
unimplemented!();
}
fn visit_invoke_generic_direct(&mut self, _dest: Register, _fctdef: FctDefId) {
fn visit_invoke_generic_direct(&mut self, _dest: Register, _fct: ConstPoolIdx) {
unimplemented!();
}

Expand Down
Loading

0 comments on commit d54579d

Please sign in to comment.