import_function

This commit is contained in:
Svyatoslav Nikolsky
2017-05-03 09:09:41 +03:00
parent a39112a940
commit 8f2409d4ab
6 changed files with 54 additions and 3 deletions

View File

@ -282,6 +282,12 @@ impl<F> ModuleBuilder<F> where F: Invoke<elements::Module> {
SignaturesBuilder::with_callback(self) SignaturesBuilder::with_callback(self)
} }
/// With inserted export entry
pub fn with_export(mut self, entry: elements::ExportEntry) -> Self {
self.module.export.entries_mut().push(entry);
self
}
/// With inserted import entry /// With inserted import entry
pub fn with_import(mut self, entry: elements::ImportEntry) -> Self { pub fn with_import(mut self, entry: elements::ImportEntry) -> Self {
self.module.import.entries_mut().push(entry); self.module.import.entries_mut().push(entry);

View File

@ -54,6 +54,13 @@ pub struct ExportEntry {
} }
impl ExportEntry { impl ExportEntry {
/// Create new export entry
pub fn new(field: String, internal: Internal) -> Self {
Self {
field_str: field,
internal: internal,
}
}
/// Public name /// Public name
pub fn field(&self) -> &str { &self.field_str } pub fn field(&self) -> &str { &self.field_str }
/// Public name (mutable) /// Public name (mutable)

View File

@ -178,7 +178,8 @@ impl ModuleInstance {
match self.imports.parse_function_index(index) { match self.imports.parse_function_index(index) {
ItemIndex::IndexSpace(_) => unreachable!("parse_function_index resolves IndexSpace option"), ItemIndex::IndexSpace(_) => unreachable!("parse_function_index resolves IndexSpace option"),
ItemIndex::Internal(index) => self.call_internal_function(outer, index, None), ItemIndex::Internal(index) => self.call_internal_function(outer, index, None),
ItemIndex::External(index) => self.module.import_section() ItemIndex::External(index) =>
self.module.import_section()
.ok_or(Error::Function(format!("trying to access external function with index {} in module without import section", index))) .ok_or(Error::Function(format!("trying to access external function with index {} in module without import section", index)))
.and_then(|s| s.entries().get(index as usize) .and_then(|s| s.entries().get(index as usize)
.ok_or(Error::Function(format!("trying to access external function with index {} in module with {}-entries import section", index, s.entries().len())))) .ok_or(Error::Function(format!("trying to access external function with index {} in module with {}-entries import section", index, s.entries().len()))))

View File

@ -0,0 +1,38 @@
use builder::module;
use elements::{ExportEntry, Internal, ImportEntry, External, Opcodes, Opcode};
use interpreter::program::ProgramInstance;
use interpreter::value::RuntimeValue;
#[test]
fn import_function() {
let module1 = module()
.with_export(ExportEntry::new("external_func".into(), Internal::Function(0)))
.function()
.signature().return_type().i32().build()
.body().with_opcodes(Opcodes::new(vec![
Opcode::I32Const(3),
Opcode::End,
])).build()
.build()
.build();
let module2 = module()
.with_import(ImportEntry::new("external_module".into(), "external_func".into(), External::Function(0)))
.function()
.signature().return_type().i32().build()
.body().with_opcodes(Opcodes::new(vec![
Opcode::Call(0),
Opcode::I32Const(7),
Opcode::I32Add,
Opcode::End,
])).build()
.build()
.build();
let program = ProgramInstance::new();
let external_module = program.add_module("external_module", module1).unwrap();
let main_module = program.add_module("main", module2).unwrap();
assert_eq!(external_module.execute(0, vec![]).unwrap().unwrap(), RuntimeValue::I32(3));
assert_eq!(main_module.execute(1, vec![]).unwrap().unwrap(), RuntimeValue::I32(10));
}

View File

@ -1 +1,2 @@
mod import;
mod wabt; mod wabt;

View File

@ -1,7 +1,5 @@
///! Tests from https://github.com/WebAssembly/wabt/tree/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp ///! Tests from https://github.com/WebAssembly/wabt/tree/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp
// TODO: https://github.com/WebAssembly/wabt/blob/8e1f6031e9889ba770c7be4a9b084da5f14456a0/test/interp/import.txt
use std::sync::Weak; use std::sync::Weak;
use builder::module; use builder::module;
use elements::{Module, ValueType, Opcodes, Opcode, BlockType, FunctionType}; use elements::{Module, ValueType, Opcodes, Opcode, BlockType, FunctionType};