Skip to content

Commit

Permalink
Merge #116
Browse files Browse the repository at this point in the history
116: feat(module) `Module.exports` uses the new `ExportKind` int enum for the `kind` value r=Hywan a=Hywan

This patch creates a new `ExportKind` int enum defined as:

```python
class ExportKind(IntEnum):
    FUNCTION = 1
    MEMORY = 2
    GLOBAL = 3
    TABLE = 4
```

Since pyo3 doesn't have a mapping from Rust to Python enum (cf PyO3/pyo3#417), we had to find a workaround to create it. I believe the approch taken in this PR isn't too ugly. The enum is created with [the functional API](https://docs.python.org/3/library/enum.html#functional-api), such as:

```python
IntEnum("ExportKind", "FUNCTION MEMORY GLOBAL TABLE")
```

Variants order and variant names are defined by implementations on `ExportKind` in Rust.

Then, this new `ExportKind` enum is used in `Module.exports` as values of the `kind` pair.

Co-authored-by: Ivan Enderlin <ivan.enderlin@hoa-project.net>
  • Loading branch information
bors[bot] and Hywan authored Jan 24, 2020
2 parents 05940cc + 064fd8a commit fcc7885
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 23 deletions.
34 changes: 33 additions & 1 deletion src/instance/exports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,43 @@ use pyo3::{
types::{PyFloat, PyLong, PyTuple},
ToPyObject,
};
use std::{cmp::Ordering, rc::Rc};
use std::{cmp::Ordering, convert::From, rc::Rc, slice};
use wasmer_runtime::{self as runtime, Value as WasmValue};
use wasmer_runtime_core::instance::DynFunc;
use wasmer_runtime_core::types::Type;

#[repr(u8)]
pub enum ExportKind {
Function = 1,
Memory = 2,
Global = 3,
Table = 4,
}

impl ExportKind {
pub fn iter() -> slice::Iter<'static, ExportKind> {
static VARIANTS: [ExportKind; 4] = [
ExportKind::Function,
ExportKind::Memory,
ExportKind::Global,
ExportKind::Table,
];

VARIANTS.iter()
}
}

impl From<&ExportKind> for &'static str {
fn from(value: &ExportKind) -> Self {
match value {
ExportKind::Function => "FUNCTION",
ExportKind::Memory => "MEMORY",
ExportKind::Global => "GLOBAL",
ExportKind::Table => "TABLE",
}
}
}

#[pyclass]
/// `ExportedFunction` is a Python class that represents a WebAssembly
/// exported function. Such a function can be invoked from Python by using the
Expand Down
24 changes: 21 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
#![deny(warnings)]

use pyo3::prelude::*;
use pyo3::{prelude::*, types::PyTuple};

mod instance;
mod memory;
mod module;
mod value;

use instance::Instance;
use instance::{exports::ExportKind, Instance};
use module::Module;
use value::Value;

/// This extension allows to manipulate and to execute WebAssembly binaries.
#[pymodule]
fn wasmer(_py: Python, module: &PyModule) -> PyResult<()> {
fn wasmer(py: Python, module: &PyModule) -> PyResult<()> {
module.add("__version__", env!("CARGO_PKG_VERSION"))?;
module.add("__core_version__", env!("WASMER_RUNTIME_CORE_VERSION"))?;
module.add_class::<Instance>()?;
Expand All @@ -27,5 +27,23 @@ fn wasmer(_py: Python, module: &PyModule) -> PyResult<()> {
module.add_class::<memory::view::Uint32Array>()?;
module.add_class::<memory::view::Uint8Array>()?;

{
let enum_module = py.import("enum")?;
let mut variants = String::new();

for kind in ExportKind::iter() {
variants.push_str(kind.into());
variants.push(' ');
}

module.add(
"ExportKind",
enum_module.call1(
"IntEnum",
PyTuple::new(py, &["ExportKind", variants.as_str()]),
)?,
)?;
}

Ok(())
}
14 changes: 9 additions & 5 deletions src/module.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
//! The `wasmer.Module` Python object to build WebAssembly modules.

use crate::{instance::exports::ExportedFunctions, instance::Instance, memory::Memory};
use crate::{
instance::exports::{ExportKind, ExportedFunctions},
instance::Instance,
memory::Memory,
};
use pyo3::{
exceptions::RuntimeError,
prelude::*,
Expand Down Expand Up @@ -100,10 +104,10 @@ impl Module {
dict.set_item(
"kind",
match export_index {
ExportIndex::Func(_) => "function",
ExportIndex::Memory(_) => "memory",
ExportIndex::Global(_) => "global",
ExportIndex::Table(_) => "table",
ExportIndex::Func(_) => ExportKind::Function as u8,
ExportIndex::Memory(_) => ExportKind::Memory as u8,
ExportIndex::Global(_) => ExportKind::Global as u8,
ExportIndex::Table(_) => ExportKind::Table as u8,
},
)?;

Expand Down
37 changes: 23 additions & 14 deletions tests/test_module.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import wasmer
from wasmer import Module
from wasmer import Module, ExportKind
from enum import IntEnum
import inspect
import os
import pytest
Expand Down Expand Up @@ -29,59 +30,67 @@ def test_failed_to_compile():
def test_instantiate():
assert Module(TEST_BYTES).instantiate().exports.sum(1, 2) == 3

def test_export_kind():
assert issubclass(ExportKind, IntEnum)
assert len(ExportKind) == 4
assert ExportKind.FUNCTION == 1
assert ExportKind.MEMORY == 2
assert ExportKind.GLOBAL == 3
assert ExportKind.TABLE == 4

def test_exports():
assert Module(TEST_BYTES).exports == [
{
"name": "memory",
"kind": "memory",
"kind": ExportKind.MEMORY,
},
{
"name": "__heap_base",
"kind": "global",
"kind": ExportKind.GLOBAL,
},
{
"name": "__data_end",
"kind": "global",
"kind": ExportKind.GLOBAL,
},
{
"name": "sum",
"kind": "function",
"kind": ExportKind.FUNCTION,
},
{
"name": "arity_0",
"kind": "function",
"kind": ExportKind.FUNCTION,
},
{
"name": "i32_i32",
"kind": "function",
"kind": ExportKind.FUNCTION,
},
{
"name": "i64_i64",
"kind": "function",
"kind": ExportKind.FUNCTION,
},
{
"name": "f32_f32",
"kind": "function",
"kind": ExportKind.FUNCTION,
},
{
"name": "f64_f64",
"kind": "function",
"kind": ExportKind.FUNCTION,
},
{
"name": "i32_i64_f32_f64_f64",
"kind": "function",
"kind": ExportKind.FUNCTION,
},
{
"name": "bool_casted_to_i32",
"kind": "function",
"kind": ExportKind.FUNCTION,
},
{
"name": "string",
"kind": "function",
"kind": ExportKind.FUNCTION,
},
{
"name": "void",
"kind": "function",
"kind": ExportKind.FUNCTION,
},
]

Expand Down

0 comments on commit fcc7885

Please sign in to comment.