pub struct Function { /* private fields */ }Expand description
One function of a module: its frame layout, its tables, its code, and its debug information.
Built with FunctionBuilder or produced by
decode; read-only afterwards.
§Examples
use bytecode_lang::{Inst, ModuleBuilder, ValType};
let mut m = ModuleBuilder::new();
let mut f = m.function("id", &[ValType::I64], &[ValType::I64]);
let x = f.param(0);
f.ret(x);
let id = m.add_function(f).unwrap();
let module = m.finish().unwrap();
let func = module.function(id).unwrap();
assert_eq!(func.regs(), &[ValType::I64]);
assert_eq!(func.code(), &[Inst::Ret { src: x }]);Implementations§
Source§impl Function
impl Function
Sourcepub fn name(&self) -> StrId
pub fn name(&self) -> StrId
The function’s name.
§Examples
use bytecode_lang::ModuleBuilder;
let mut m = ModuleBuilder::new();
let mut f = m.function("main", &[], &[]);
f.ret_void();
let id = m.add_function(f).unwrap();
let module = m.finish().unwrap();
let func = module.function(id).unwrap();
assert_eq!(module.string(func.name()), Some("main"));Sourcepub fn sig(&self) -> TypeId
pub fn sig(&self) -> TypeId
The function’s signature (a TypeDef::Func entry).
§Examples
use bytecode_lang::{FuncType, ModuleBuilder, TypeDef, ValType};
let mut m = ModuleBuilder::new();
let mut f = m.function("main", &[], &[]);
f.ret_void();
let id = m.add_function(f).unwrap();
let module = m.finish().unwrap();
let sig = module.function(id).unwrap().sig();
assert_eq!(module.type_def(sig), Some(&TypeDef::Func(FuncType::default())));Sourcepub fn params(&self) -> Option<&ParamList>
pub fn params(&self) -> Option<&ParamList>
The function’s dynamic-call signature, if it has one (see
ParamList); None means dynamic calls must pass exactly its
parameters, positionally.
§Examples
use bytecode_lang::{ModuleBuilder, Param, ParamList, ValType};
let mut m = ModuleBuilder::new();
let x = m.string("x");
let mut f = m.function("f", &[ValType::Dyn], &[]);
f.set_params(ParamList::new(vec![Param::normal(x)]));
f.ret_void();
let id = m.add_function(f).unwrap();
let module = m.finish().unwrap();
assert_eq!(module.function(id).unwrap().params().map(|p| p.params.len()), Some(1));Sourcepub fn regs(&self) -> &[ValType]
pub fn regs(&self) -> &[ValType]
The declared type of every register; the parameters come first.
§Examples
use bytecode_lang::{ModuleBuilder, ValType};
let mut m = ModuleBuilder::new();
let mut f = m.function("f", &[ValType::Bool], &[]);
let _tmp = f.reg(ValType::Dyn);
f.ret_void();
let id = m.add_function(f).unwrap();
let module = m.finish().unwrap();
assert_eq!(module.function(id).unwrap().regs(), &[ValType::Bool, ValType::Dyn]);Sourcepub fn captures(&self) -> &[ValType]
pub fn captures(&self) -> &[ValType]
The types of the values a closure of this function captures, read
with Inst::GetUpval.
§Examples
use bytecode_lang::{ModuleBuilder, UpvalIdx, ValType};
let mut m = ModuleBuilder::new();
let mut f = m.function("inner", &[], &[]);
assert_eq!(f.capture(ValType::Dyn), UpvalIdx(0));
f.ret_void();
let id = m.add_function(f).unwrap();
let module = m.finish().unwrap();
assert_eq!(module.function(id).unwrap().captures(), &[ValType::Dyn]);Sourcepub fn names(&self) -> &[StrId]
pub fn names(&self) -> &[StrId]
The function’s name list, indexed by NameRef.
§Examples
use bytecode_lang::ModuleBuilder;
let mut m = ModuleBuilder::new();
let x = m.string("x");
let mut f = m.function("f", &[], &[]);
let n = f.name_ref(x);
f.ret_void();
let id = m.add_function(f).unwrap();
let module = m.finish().unwrap();
assert_eq!(module.function(id).unwrap().names()[n.index()], x);Sourcepub fn type_refs(&self) -> &[TypeId]
pub fn type_refs(&self) -> &[TypeId]
The function’s type list, indexed by TypeRef.
§Examples
use bytecode_lang::{ModuleBuilder, TypeDef, ValType};
let mut m = ModuleBuilder::new();
let arr = m.add_type(TypeDef::Array(ValType::I64));
let mut f = m.function("f", &[], &[]);
let t = f.type_ref(arr);
f.ret_void();
let id = m.add_function(f).unwrap();
let module = m.finish().unwrap();
assert_eq!(module.function(id).unwrap().type_refs()[t.index()], arr);Sourcepub fn tables(&self) -> &[JumpTable]
pub fn tables(&self) -> &[JumpTable]
The function’s jump tables, indexed by TableId.
§Examples
use bytecode_lang::{IntTy, ModuleBuilder, Target, ValType};
let mut m = ModuleBuilder::new();
let mut f = m.function("f", &[ValType::I64], &[]);
let (a, b) = (f.label(), f.label());
f.switch(IntTy::I64, f.param(0), &[a], b);
f.bind(a);
f.bind(b);
f.ret_void();
let id = m.add_function(f).unwrap();
let module = m.finish().unwrap();
let table = &module.function(id).unwrap().tables()[0];
assert_eq!((table.targets.as_slice(), table.default), (&[Target(1)][..], Target(1)));Sourcepub fn shapes(&self) -> &[CallShape]
pub fn shapes(&self) -> &[CallShape]
The function’s call shapes, indexed by ShapeId.
§Examples
use bytecode_lang::{ArgKind, ModuleBuilder};
let mut m = ModuleBuilder::new();
let mut f = m.function("f", &[], &[]);
let s = f.call_shape(&[ArgKind::Positional, ArgKind::Spread]);
f.ret_void();
let id = m.add_function(f).unwrap();
let module = m.finish().unwrap();
assert_eq!(module.function(id).unwrap().shapes()[s.index()].args.len(), 2);Sourcepub fn handlers(&self) -> &[Handler]
pub fn handlers(&self) -> &[Handler]
The function’s exception-handling regions, innermost first.
§Examples
use bytecode_lang::{Inst, ModuleBuilder, ValType};
let mut m = ModuleBuilder::new();
let mut f = m.function("f", &[], &[]);
let err = f.reg(ValType::Dyn);
let (start, end, catch) = (f.label(), f.label(), f.label());
f.bind(start);
f.emit(Inst::Nop {});
f.bind(end);
f.ret_void();
f.bind(catch);
f.ret_void();
f.try_region(start, end, catch, err);
let id = m.add_function(f).unwrap();
let module = m.finish().unwrap();
let h = module.function(id).unwrap().handlers()[0];
assert_eq!((h.start, h.end, h.target.0), (0, 1, 2));Sourcepub fn code(&self) -> &[Inst]
pub fn code(&self) -> &[Inst]
The function’s instructions; code()[pc] is the instruction at pc.
§Examples
use bytecode_lang::{Inst, ModuleBuilder};
let mut m = ModuleBuilder::new();
let mut f = m.function("f", &[], &[]);
f.ret_void();
let id = m.add_function(f).unwrap();
let module = m.finish().unwrap();
assert_eq!(module.function(id).unwrap().code(), &[Inst::RetVoid {}]);Sourcepub fn lines(&self) -> &[LineRow]
pub fn lines(&self) -> &[LineRow]
The line table, ordered by pc.
§Examples
use bytecode_lang::ModuleBuilder;
let mut m = ModuleBuilder::new();
let file = m.string("main.mox");
let mut f = m.function("f", &[], &[]);
f.set_location(file, 3, 1);
f.ret_void();
let id = m.add_function(f).unwrap();
let module = m.finish().unwrap();
assert_eq!(module.function(id).unwrap().lines()[0].line, 3);Sourcepub fn locals(&self) -> &[LocalVar]
pub fn locals(&self) -> &[LocalVar]
The named source variables.
§Examples
use bytecode_lang::{ModuleBuilder, ValType};
let mut m = ModuleBuilder::new();
let name = m.string("x");
let mut f = m.function("f", &[ValType::I64], &[]);
let (start, end) = (f.label(), f.label());
f.bind(start);
f.ret_void();
f.bind(end);
f.local(f.param(0), name, start, end);
let id = m.add_function(f).unwrap();
let module = m.finish().unwrap();
assert_eq!(module.function(id).unwrap().locals()[0].end, 1);