Pass function sig in function_body::translate

This commit is contained in:
Sergey Pepyakin
2018-11-29 18:55:49 +01:00
parent 13c36612b5
commit 52c0443368
4 changed files with 75 additions and 28 deletions

View File

@@ -1,6 +1,6 @@
use backend::*; use backend::*;
use error::Error; use error::Error;
use wasmparser::{FunctionBody, Operator, Type}; use wasmparser::{FuncType, FunctionBody, Operator, Type};
// TODO: Use own declared `Type` enum. // TODO: Use own declared `Type` enum.
@@ -86,15 +86,21 @@ impl ControlFrame {
} }
} }
pub fn translate(session: &mut CodeGenSession, body: &FunctionBody) -> Result<(), Error> { pub fn translate(
session: &mut CodeGenSession,
func_type: &FuncType,
body: &FunctionBody,
) -> Result<(), Error> {
let locals = body.get_locals_reader()?; let locals = body.get_locals_reader()?;
// Assume signature is (i32, i32) -> i32 for now. let arg_count = func_type.params.len() as u32;
// TODO: Use a real signature let return_ty = if func_type.returns.len() > 0 {
const ARG_COUNT: u32 = 2; func_type.returns[0]
let return_ty = Type::I32; } else {
Type::EmptyBlockType
};
let mut framesize = ARG_COUNT; let mut framesize = arg_count;
for local in locals { for local in locals {
let (count, _ty) = local?; let (count, _ty) = local?;
framesize += count; framesize += count;
@@ -105,7 +111,7 @@ pub fn translate(session: &mut CodeGenSession, body: &FunctionBody) -> Result<()
prologue(&mut ctx, framesize); prologue(&mut ctx, framesize);
for arg_pos in 0..ARG_COUNT { for arg_pos in 0..arg_count {
copy_incoming_arg(&mut ctx, arg_pos); copy_incoming_arg(&mut ctx, arg_pos);
} }
@@ -191,6 +197,13 @@ pub fn translate(session: &mut CodeGenSession, body: &FunctionBody) -> Result<()
} }
restore_stack_depth(&mut ctx, control_frame.outgoing_stack_depth()); restore_stack_depth(&mut ctx, control_frame.outgoing_stack_depth());
if control_frames.len() == 0 {
// This is the last control frame. Perform the implicit return here.
if return_ty != Type::EmptyBlockType {
prepare_return_value(&mut ctx);
}
}
} }
Operator::I32Eq => { Operator::I32Eq => {
relop_eq_i32(&mut ctx); relop_eq_i32(&mut ctx);
@@ -201,12 +214,26 @@ pub fn translate(session: &mut CodeGenSession, body: &FunctionBody) -> Result<()
Operator::GetLocal { local_index } => { Operator::GetLocal { local_index } => {
get_local_i32(&mut ctx, local_index); get_local_i32(&mut ctx, local_index);
} }
Operator::Call { function_index } => {
// TODO: find out the signature of this function
// this requires to generalize the function types infrasturcture
// TODO: ensure that this function is locally defined
// We would like to support imported functions at some point
// TODO: pop arguments and move them in appropriate positions.
// only 6 for now.
// TODO: jump to the specified position
// this requires us saving function start locations in codegensession.
panic!()
}
_ => { _ => {
trap(&mut ctx); trap(&mut ctx);
} }
} }
} }
prepare_return_value(&mut ctx);
epilogue(&mut ctx); epilogue(&mut ctx);
Ok(()) Ok(())

View File

@@ -1,7 +1,7 @@
use std::mem;
use error::Error;
use translate_sections;
use backend::TranslatedCodeSection; use backend::TranslatedCodeSection;
use error::Error;
use std::mem;
use translate_sections;
use wasmparser::{ModuleReader, SectionCode}; use wasmparser::{ModuleReader, SectionCode};
#[derive(Default)] #[derive(Default)]
@@ -14,7 +14,10 @@ impl TranslatedModule {
// Assume signature is (i32, i32) -> i32 for now. // Assume signature is (i32, i32) -> i32 for now.
// TODO: Handle generic signatures. // TODO: Handle generic signatures.
pub fn execute_func(&self, func_idx: u32, a: usize, b: usize) -> usize { pub fn execute_func(&self, func_idx: u32, a: usize, b: usize) -> usize {
let code_section = self.translated_code_section.as_ref().expect("no code section"); let code_section = self
.translated_code_section
.as_ref()
.expect("no code section");
let start_buf = code_section.func_start(func_idx as usize); let start_buf = code_section.func_start(func_idx as usize);
unsafe { unsafe {
@@ -34,10 +37,12 @@ pub fn translate(data: &[u8]) -> Result<TranslatedModule, Error> {
return Ok(output); return Ok(output);
} }
let mut section = reader.read()?; let mut section = reader.read()?;
let mut types = vec![];
let mut func_ty_indicies = vec![];
if let SectionCode::Type = section.code { if let SectionCode::Type = section.code {
let types = section.get_type_section_reader()?; let types_reader = section.get_type_section_reader()?;
translate_sections::type_(types)?; types = translate_sections::type_(types_reader)?;
reader.skip_custom_sections()?; reader.skip_custom_sections()?;
if reader.eof() { if reader.eof() {
@@ -59,7 +64,7 @@ pub fn translate(data: &[u8]) -> Result<TranslatedModule, Error> {
if let SectionCode::Function = section.code { if let SectionCode::Function = section.code {
let functions = section.get_function_section_reader()?; let functions = section.get_function_section_reader()?;
translate_sections::function(functions)?; func_ty_indicies = translate_sections::function(functions)?;
reader.skip_custom_sections()?; reader.skip_custom_sections()?;
if reader.eof() { if reader.eof() {
@@ -136,7 +141,8 @@ pub fn translate(data: &[u8]) -> Result<TranslatedModule, Error> {
if let SectionCode::Code = section.code { if let SectionCode::Code = section.code {
let code = section.get_code_section_reader()?; let code = section.get_code_section_reader()?;
output.translated_code_section = Some(translate_sections::code(code)?); output.translated_code_section =
Some(translate_sections::code(code, &types, &func_ty_indicies)?);
reader.skip_custom_sections()?; reader.skip_custom_sections()?;
if reader.eof() { if reader.eof() {

View File

@@ -13,6 +13,11 @@ fn execute_wat(wat: &str, a: usize, b: usize) -> usize {
translated.execute_func(0, a, b) translated.execute_func(0, a, b)
} }
#[test]
fn empty() {
let _ = translate_wat("(module (func))");
}
#[test] #[test]
fn adds() { fn adds() {
const CASES: &[(usize, usize, usize)] = &[ const CASES: &[(usize, usize, usize)] = &[

View File

@@ -1,3 +1,4 @@
use backend::{CodeGenSession, TranslatedCodeSection};
use error::Error; use error::Error;
use function_body; use function_body;
#[allow(unused_imports)] // for now #[allow(unused_imports)] // for now
@@ -7,14 +8,14 @@ use wasmparser::{
GlobalSectionReader, GlobalType, Import, ImportSectionEntryType, ImportSectionReader, GlobalSectionReader, GlobalType, Import, ImportSectionEntryType, ImportSectionReader,
MemorySectionReader, MemoryType, Operator, TableSectionReader, Type, TypeSectionReader, MemorySectionReader, MemoryType, Operator, TableSectionReader, Type, TypeSectionReader,
}; };
use backend::{CodeGenSession, TranslatedCodeSection};
/// Parses the Type section of the wasm module. /// Parses the Type section of the wasm module.
pub fn type_(types: TypeSectionReader) -> Result<(), Error> { pub fn type_(types_reader: TypeSectionReader) -> Result<Vec<FuncType>, Error> {
for entry in types { let mut types = vec![];
entry?; // TODO for entry in types_reader {
types.push(entry?);
} }
Ok(()) Ok(types)
} }
/// Parses the Import section of the wasm module. /// Parses the Import section of the wasm module.
@@ -26,11 +27,12 @@ pub fn import(imports: ImportSectionReader) -> Result<(), Error> {
} }
/// Parses the Function section of the wasm module. /// Parses the Function section of the wasm module.
pub fn function(functions: FunctionSectionReader) -> Result<(), Error> { pub fn function(functions: FunctionSectionReader) -> Result<Vec<u32>, Error> {
let mut func_ty_indicies = vec![];
for entry in functions { for entry in functions {
entry?; // TODO func_ty_indicies.push(entry?);
} }
Ok(()) Ok(func_ty_indicies)
} }
/// Parses the Table section of the wasm module. /// Parses the Table section of the wasm module.
@@ -80,10 +82,17 @@ pub fn element(elements: ElementSectionReader) -> Result<(), Error> {
} }
/// Parses the Code section of the wasm module. /// Parses the Code section of the wasm module.
pub fn code(code: CodeSectionReader) -> Result<TranslatedCodeSection, Error> { pub fn code(
code: CodeSectionReader,
types: &[FuncType],
func_ty_indicies: &[u32],
) -> Result<TranslatedCodeSection, Error> {
let mut session = CodeGenSession::new(); let mut session = CodeGenSession::new();
for body in code { for (idx, body) in code.into_iter().enumerate() {
function_body::translate(&mut session, &body?)?; let func_ty_idx = func_ty_indicies[idx];
let func_ty = &types[func_ty_idx as usize];
function_body::translate(&mut session, &func_ty, &body?)?;
} }
Ok(session.into_translated_code_section()?) Ok(session.into_translated_code_section()?)
} }