Skip to content

Commit

Permalink
Merge pull request #482 from CosmWasm/improve-vtables
Browse files Browse the repository at this point in the history
Improve vtables code
  • Loading branch information
webmaster128 committed Nov 29, 2023
2 parents e8bf2f2 + d9b822c commit 7b6ba25
Show file tree
Hide file tree
Showing 11 changed files with 230 additions and 125 deletions.
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

0 comments on commit 7b6ba25

Please sign in to comment.