Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve vtables code #482

Merged
merged 3 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions internal/api/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,9 @@ typedef struct ByteSliceView {
* // …
* # let mut error_msg = UnmanagedVector::default();
* # let mut used_gas = 0_u64;
* # let read_db = db.vtable.read_db.unwrap();
*
* let go_error: GoError = (db.vtable.read_db)(
* let go_error: GoError = read_db(
* db.state,
* db.gas_meter,
* &mut used_gas as *mut u64,
Expand Down Expand Up @@ -253,7 +254,7 @@ typedef struct iterator_t {
uint64_t iterator_index;
} iterator_t;

typedef struct Iterator_vtable {
typedef struct IteratorVtable {
int32_t (*next)(struct iterator_t,
struct gas_meter_t*,
uint64_t*,
Expand All @@ -270,15 +271,15 @@ typedef struct Iterator_vtable {
uint64_t*,
struct UnmanagedVector*,
struct UnmanagedVector*);
} Iterator_vtable;
} IteratorVtable;

typedef struct GoIter {
struct gas_meter_t *gas_meter;
struct iterator_t state;
struct Iterator_vtable vtable;
struct IteratorVtable vtable;
} GoIter;

typedef struct Db_vtable {
typedef struct DbVtable {
int32_t (*read_db)(struct db_t*,
struct gas_meter_t*,
uint64_t*,
Expand All @@ -304,19 +305,19 @@ typedef struct Db_vtable {
int32_t,
struct GoIter*,
struct UnmanagedVector*);
} Db_vtable;
} DbVtable;

typedef struct Db {
struct gas_meter_t *gas_meter;
struct db_t *state;
struct Db_vtable vtable;
struct DbVtable vtable;
} Db;

typedef struct api_t {
uint8_t _private[0];
} api_t;

typedef struct GoApi_vtable {
typedef struct GoApiVtable {
int32_t (*humanize_address)(const struct api_t*,
struct U8SliceView,
struct UnmanagedVector*,
Expand All @@ -327,29 +328,29 @@ typedef struct GoApi_vtable {
struct UnmanagedVector*,
struct UnmanagedVector*,
uint64_t*);
} GoApi_vtable;
} GoApiVtable;

typedef struct GoApi {
const struct api_t *state;
struct GoApi_vtable vtable;
struct GoApiVtable vtable;
} GoApi;

typedef struct querier_t {
uint8_t _private[0];
} querier_t;

typedef struct Querier_vtable {
typedef struct QuerierVtable {
int32_t (*query_external)(const struct querier_t*,
uint64_t,
uint64_t*,
struct U8SliceView,
struct UnmanagedVector*,
struct UnmanagedVector*);
} Querier_vtable;
} QuerierVtable;

typedef struct GoQuerier {
const struct querier_t *state;
struct Querier_vtable vtable;
struct QuerierVtable vtable;
} GoQuerier;

typedef struct GasReport {
Expand Down
8 changes: 4 additions & 4 deletions internal/api/callbacks.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func recoverPanic(ret *C.GoError) {

/****** DB ********/

var db_vtable = C.Db_vtable{
var db_vtable = C.DbVtable{
read_db: C.any_function_t(C.cGet_cgo),
write_db: C.any_function_t(C.cSet_cgo),
remove_db: C.any_function_t(C.cDelete_cgo),
Expand Down Expand Up @@ -124,7 +124,7 @@ func buildDB(state *DBState, gm *types.GasMeter) C.Db {
}
}

var iterator_vtable = C.Iterator_vtable{
var iterator_vtable = C.IteratorVtable{
next: C.any_function_t(C.cNext_cgo),
next_key: C.any_function_t(C.cNextKey_cgo),
next_value: C.any_function_t(C.cNextValue_cgo),
Expand Down Expand Up @@ -358,7 +358,7 @@ func nextPart(ref C.iterator_t, gasMeter *C.gas_meter_t, usedGas *cu64, output *
return C.GoError_None
}

var api_vtable = C.GoApi_vtable{
var api_vtable = C.GoApiVtable{
humanize_address: C.any_function_t(C.cHumanAddress_cgo),
canonicalize_address: C.any_function_t(C.cCanonicalAddress_cgo),
}
Expand Down Expand Up @@ -429,7 +429,7 @@ func cCanonicalAddress(ptr *C.api_t, src C.U8SliceView, dest *C.UnmanagedVector,

/****** Go Querier ********/

var querier_vtable = C.Querier_vtable{
var querier_vtable = C.QuerierVtable{
query_external: C.any_function_t(C.cQueryExternal_cgo),
}

Expand Down
27 changes: 14 additions & 13 deletions libwasmvm/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,9 @@ typedef struct ByteSliceView {
* // …
* # let mut error_msg = UnmanagedVector::default();
* # let mut used_gas = 0_u64;
* # let read_db = db.vtable.read_db.unwrap();
*
* let go_error: GoError = (db.vtable.read_db)(
* let go_error: GoError = read_db(
* db.state,
* db.gas_meter,
* &mut used_gas as *mut u64,
Expand Down Expand Up @@ -253,7 +254,7 @@ typedef struct iterator_t {
uint64_t iterator_index;
} iterator_t;

typedef struct Iterator_vtable {
typedef struct IteratorVtable {
int32_t (*next)(struct iterator_t,
struct gas_meter_t*,
uint64_t*,
Expand All @@ -270,15 +271,15 @@ typedef struct Iterator_vtable {
uint64_t*,
struct UnmanagedVector*,
struct UnmanagedVector*);
} Iterator_vtable;
} IteratorVtable;

typedef struct GoIter {
struct gas_meter_t *gas_meter;
struct iterator_t state;
struct Iterator_vtable vtable;
struct IteratorVtable vtable;
} GoIter;

typedef struct Db_vtable {
typedef struct DbVtable {
int32_t (*read_db)(struct db_t*,
struct gas_meter_t*,
uint64_t*,
Expand All @@ -304,19 +305,19 @@ typedef struct Db_vtable {
int32_t,
struct GoIter*,
struct UnmanagedVector*);
} Db_vtable;
} DbVtable;

typedef struct Db {
struct gas_meter_t *gas_meter;
struct db_t *state;
struct Db_vtable vtable;
struct DbVtable vtable;
} Db;

typedef struct api_t {
uint8_t _private[0];
} api_t;

typedef struct GoApi_vtable {
typedef struct GoApiVtable {
int32_t (*humanize_address)(const struct api_t*,
struct U8SliceView,
struct UnmanagedVector*,
Expand All @@ -327,29 +328,29 @@ typedef struct GoApi_vtable {
struct UnmanagedVector*,
struct UnmanagedVector*,
uint64_t*);
} GoApi_vtable;
} GoApiVtable;

typedef struct GoApi {
const struct api_t *state;
struct GoApi_vtable vtable;
struct GoApiVtable vtable;
} GoApi;

typedef struct querier_t {
uint8_t _private[0];
} querier_t;

typedef struct Querier_vtable {
typedef struct QuerierVtable {
int32_t (*query_external)(const struct querier_t*,
uint64_t,
uint64_t*,
struct U8SliceView,
struct UnmanagedVector*,
struct UnmanagedVector*);
} Querier_vtable;
} QuerierVtable;

typedef struct GoQuerier {
const struct querier_t *state;
struct Querier_vtable vtable;
struct QuerierVtable vtable;
} GoQuerier;

typedef struct GasReport {
Expand Down
53 changes: 34 additions & 19 deletions libwasmvm/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use cosmwasm_vm::{BackendApi, BackendError, BackendResult, GasInfo};

use crate::error::GoError;
use crate::memory::{U8SliceView, UnmanagedVector};
use crate::Vtable;

// this represents something passed in from the caller side of FFI
// in this case a struct with go function pointers
Expand All @@ -13,29 +14,35 @@ pub struct api_t {
// These functions should return GoError but because we don't trust them here, we treat the return value as i32
// and then check it when converting to GoError manually
#[repr(C)]
#[derive(Copy, Clone)]
pub struct GoApi_vtable {
pub humanize_address: extern "C" fn(
*const api_t,
U8SliceView,
*mut UnmanagedVector, // human output
*mut UnmanagedVector, // error message output
*mut u64,
) -> i32,
pub canonicalize_address: extern "C" fn(
*const api_t,
U8SliceView,
*mut UnmanagedVector, // canonical output
*mut UnmanagedVector, // error message output
*mut u64,
) -> i32,
#[derive(Copy, Clone, Default)]
pub struct GoApiVtable {
pub humanize_address: Option<
extern "C" fn(
*const api_t,
U8SliceView,
*mut UnmanagedVector, // human output
*mut UnmanagedVector, // error message output
*mut u64,
) -> i32,
>,
pub canonicalize_address: Option<
extern "C" fn(
*const api_t,
U8SliceView,
*mut UnmanagedVector, // canonical output
*mut UnmanagedVector, // error message output
*mut u64,
) -> i32,
>,
}

impl Vtable for GoApiVtable {}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct GoApi {
pub state: *const api_t,
pub vtable: GoApi_vtable,
pub vtable: GoApiVtable,
}

// We must declare that these are safe to Send, to use in wasm.
Expand All @@ -50,7 +57,11 @@ impl BackendApi for GoApi {
let mut output = UnmanagedVector::default();
let mut error_msg = UnmanagedVector::default();
let mut used_gas = 0_u64;
let go_error: GoError = (self.vtable.canonicalize_address)(
let canonicalize_address = self
.vtable
.canonicalize_address
.expect("vtable function 'canonicalize_address' not set");
let go_error: GoError = canonicalize_address(
self.state,
U8SliceView::new(Some(human.as_bytes())),
&mut output as *mut UnmanagedVector,
Expand Down Expand Up @@ -79,7 +90,11 @@ impl BackendApi for GoApi {
let mut output = UnmanagedVector::default();
let mut error_msg = UnmanagedVector::default();
let mut used_gas = 0_u64;
let go_error: GoError = (self.vtable.humanize_address)(
let humanize_address = self
.vtable
.humanize_address
.expect("vtable function 'humanize_address' not set");
let go_error: GoError = humanize_address(
self.state,
U8SliceView::new(Some(canonical)),
&mut output as *mut UnmanagedVector,
Expand Down
Loading