Pass function sig in function_body::translate
This commit is contained in:
@@ -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(())
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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)] = &[
|
||||||
|
|||||||
@@ -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()?)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user