Skip to content

Commit

Permalink
Rename to IteratorReference
Browse files Browse the repository at this point in the history
  • Loading branch information
webmaster128 committed Feb 23, 2024
1 parent 9530fce commit 675ce76
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 47 deletions.
20 changes: 14 additions & 6 deletions internal/api/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,27 +255,31 @@ typedef struct U8SliceView {
uintptr_t len;
} U8SliceView;

typedef struct iterator_t {
/**
* A reference to some tables on the Go side which allow accessing
* the actual iterator instance.
*/
typedef struct IteratorReference {
/**
* An ID assigned to this contract call
*/
uint64_t call_id;
uint64_t iterator_index;
} iterator_t;
} IteratorReference;

typedef struct IteratorVtable {
int32_t (*next)(struct iterator_t iterator,
int32_t (*next)(struct IteratorReference iterator,
struct gas_meter_t *gas_meter,
uint64_t *gas_used,
struct UnmanagedVector *key_out,
struct UnmanagedVector *value_out,
struct UnmanagedVector *err_msg_out);
int32_t (*next_key)(struct iterator_t iterator,
int32_t (*next_key)(struct IteratorReference iterator,
struct gas_meter_t *gas_meter,
uint64_t *gas_used,
struct UnmanagedVector *key_out,
struct UnmanagedVector *err_msg_out);
int32_t (*next_value)(struct iterator_t iterator,
int32_t (*next_value)(struct IteratorReference iterator,
struct gas_meter_t *gas_meter,
uint64_t *gas_used,
struct UnmanagedVector *value_out,
Expand All @@ -284,7 +288,11 @@ typedef struct IteratorVtable {

typedef struct GoIter {
struct gas_meter_t *gas_meter;
struct iterator_t state;
/**
* A reference which identifies the iterator and allows finding and accessing the
* actual iterator instance in Go. Once fully initalized, this is immutable.
*/
struct IteratorReference reference;
struct IteratorVtable vtable;
} GoIter;

Expand Down
24 changes: 12 additions & 12 deletions internal/api/callbacks.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ GoError cSet_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, U8SliceV
GoError cDelete_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, U8SliceView key, UnmanagedVector *errOut);
GoError cScan_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, U8SliceView start, U8SliceView end, int32_t order, GoIter *out, UnmanagedVector *errOut);
// iterator
GoError cNext_cgo(iterator_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *key, UnmanagedVector *val, UnmanagedVector *errOut);
GoError cNextKey_cgo(iterator_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *key, UnmanagedVector *errOut);
GoError cNextValue_cgo(iterator_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *val, UnmanagedVector *errOut);
GoError cNext_cgo(IteratorReference *ref, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *key, UnmanagedVector *val, UnmanagedVector *errOut);
GoError cNextKey_cgo(IteratorReference *ref, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *key, UnmanagedVector *errOut);
GoError cNextValue_cgo(IteratorReference *ref, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *val, UnmanagedVector *errOut);
// api
GoError cHumanizeAddress_cgo(api_t *ptr, U8SliceView src, UnmanagedVector *dest, UnmanagedVector *errOut, uint64_t *used_gas);
GoError cCanonicalizeAddress_cgo(api_t *ptr, U8SliceView src, UnmanagedVector *dest, UnmanagedVector *errOut, uint64_t *used_gas);
Expand Down Expand Up @@ -138,12 +138,12 @@ const frameLenLimit = 32768

// contract: original pointer/struct referenced must live longer than C.Db struct
// since this is only used internally, we can verify the code that this is the case
func buildIterator(callID uint64, it types.Iterator) (C.iterator_t, error) {
func buildIterator(callID uint64, it types.Iterator) (C.IteratorReference, error) {
idx, err := storeIterator(callID, it, frameLenLimit)
if err != nil {
return C.iterator_t{}, err
return C.IteratorReference{}, err
}
return C.iterator_t{
return C.IteratorReference{
call_id: cu64(callID),
iterator_index: cu64(idx),
}, nil
Expand Down Expand Up @@ -257,7 +257,7 @@ func cScan(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *cu64, start C.U8SliceV
gasAfter := gm.GasConsumed()
*usedGas = (cu64)(gasAfter - gasBefore)

cIterator, err := buildIterator(state.CallID, iter)
iteratorRef, err := buildIterator(state.CallID, iter)
if err != nil {
// store the actual error message in the return buffer
*errOut = newUnmanagedVector([]byte(err.Error()))
Expand All @@ -266,15 +266,15 @@ func cScan(ptr *C.db_t, gasMeter *C.gas_meter_t, usedGas *cu64, start C.U8SliceV

*out = C.GoIter{
gas_meter: gasMeter,
state: cIterator,
reference: iteratorRef,
vtable: iterator_vtable,
}

return C.GoError_None
}

//export cNext
func cNext(ref C.iterator_t, gasMeter *C.gas_meter_t, usedGas *cu64, key *C.UnmanagedVector, val *C.UnmanagedVector, errOut *C.UnmanagedVector) (ret C.GoError) {
func cNext(ref C.IteratorReference, gasMeter *C.gas_meter_t, usedGas *cu64, key *C.UnmanagedVector, val *C.UnmanagedVector, errOut *C.UnmanagedVector) (ret C.GoError) {
// typical usage of iterator
// for ; itr.Valid(); itr.Next() {
// k, v := itr.Key(); itr.Value()
Expand Down Expand Up @@ -315,17 +315,17 @@ func cNext(ref C.iterator_t, gasMeter *C.gas_meter_t, usedGas *cu64, key *C.Unma
}

//export cNextKey
func cNextKey(ref C.iterator_t, gasMeter *C.gas_meter_t, usedGas *cu64, key *C.UnmanagedVector, errOut *C.UnmanagedVector) (ret C.GoError) {
func cNextKey(ref C.IteratorReference, gasMeter *C.gas_meter_t, usedGas *cu64, key *C.UnmanagedVector, errOut *C.UnmanagedVector) (ret C.GoError) {
return nextPart(ref, gasMeter, usedGas, key, errOut, func(iter types.Iterator) []byte { return iter.Key() })
}

//export cNextValue
func cNextValue(ref C.iterator_t, gasMeter *C.gas_meter_t, usedGas *cu64, value *C.UnmanagedVector, errOut *C.UnmanagedVector) (ret C.GoError) {
func cNextValue(ref C.IteratorReference, gasMeter *C.gas_meter_t, usedGas *cu64, value *C.UnmanagedVector, errOut *C.UnmanagedVector) (ret C.GoError) {
return nextPart(ref, gasMeter, usedGas, value, errOut, func(iter types.Iterator) []byte { return iter.Value() })
}

// nextPart is a helper function that contains the shared code for key- and value-only iteration.
func nextPart(ref C.iterator_t, gasMeter *C.gas_meter_t, usedGas *cu64, output *C.UnmanagedVector, errOut *C.UnmanagedVector, valFn func(types.Iterator) []byte) (ret C.GoError) {
func nextPart(ref C.IteratorReference, gasMeter *C.gas_meter_t, usedGas *cu64, output *C.UnmanagedVector, errOut *C.UnmanagedVector, valFn func(types.Iterator) []byte) (ret C.GoError) {
// typical usage of iterator
// for ; itr.Valid(); itr.Next() {
// k, v := itr.Key(); itr.Value()
Expand Down
18 changes: 9 additions & 9 deletions internal/api/callbacks_cgo.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ GoError cGet(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, U8SliceView
GoError cDelete(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, U8SliceView key, UnmanagedVector *errOut);
GoError cScan(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, U8SliceView start, U8SliceView end, int32_t order, GoIter *out, UnmanagedVector *errOut);
// imports (iterator)
GoError cNext(iterator_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *key, UnmanagedVector *val, UnmanagedVector *errOut);
GoError cNextKey(iterator_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *key, UnmanagedVector *errOut);
GoError cNextValue(iterator_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *value, UnmanagedVector *errOut);
GoError cNext(IteratorReference *ref, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *key, UnmanagedVector *val, UnmanagedVector *errOut);
GoError cNextKey(IteratorReference *ref, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *key, UnmanagedVector *errOut);
GoError cNextValue(IteratorReference *ref, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *value, UnmanagedVector *errOut);
// imports (api)
GoError cHumanizeAddress(api_t *ptr, U8SliceView src, UnmanagedVector *dest, UnmanagedVector *errOut, uint64_t *used_gas);
GoError cCanonicalizeAddress(api_t *ptr, U8SliceView src, UnmanagedVector *dest, UnmanagedVector *errOut, uint64_t *used_gas);
Expand All @@ -35,14 +35,14 @@ GoError cScan_cgo(db_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, U8Slice
}
// Gateway functions (iterator)
GoError cNext_cgo(iterator_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *key, UnmanagedVector *val, UnmanagedVector *errOut) {
return cNext(ptr, gas_meter, used_gas, key, val, errOut);
GoError cNext_cgo(IteratorReference *ref, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *key, UnmanagedVector *val, UnmanagedVector *errOut) {
return cNext(ref, gas_meter, used_gas, key, val, errOut);
}
GoError cNextKey_cgo(iterator_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *key, UnmanagedVector *errOut) {
return cNextKey(ptr, gas_meter, used_gas, key, errOut);
GoError cNextKey_cgo(IteratorReference *ref, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *key, UnmanagedVector *errOut) {
return cNextKey(ref, gas_meter, used_gas, key, errOut);
}
GoError cNextValue_cgo(iterator_t *ptr, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *val, UnmanagedVector *errOut) {
return cNextValue(ptr, gas_meter, used_gas, val, errOut);
GoError cNextValue_cgo(IteratorReference *ref, gas_meter_t *gas_meter, uint64_t *used_gas, UnmanagedVector *val, UnmanagedVector *errOut) {
return cNextValue(ref, gas_meter, used_gas, val, errOut);
}
// Gateway functions (api)
Expand Down
20 changes: 14 additions & 6 deletions libwasmvm/bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,27 +255,31 @@ typedef struct U8SliceView {
uintptr_t len;
} U8SliceView;

typedef struct iterator_t {
/**
* A reference to some tables on the Go side which allow accessing
* the actual iterator instance.
*/
typedef struct IteratorReference {
/**
* An ID assigned to this contract call
*/
uint64_t call_id;
uint64_t iterator_index;
} iterator_t;
} IteratorReference;

typedef struct IteratorVtable {
int32_t (*next)(struct iterator_t iterator,
int32_t (*next)(struct IteratorReference iterator,
struct gas_meter_t *gas_meter,
uint64_t *gas_used,
struct UnmanagedVector *key_out,
struct UnmanagedVector *value_out,
struct UnmanagedVector *err_msg_out);
int32_t (*next_key)(struct iterator_t iterator,
int32_t (*next_key)(struct IteratorReference iterator,
struct gas_meter_t *gas_meter,
uint64_t *gas_used,
struct UnmanagedVector *key_out,
struct UnmanagedVector *err_msg_out);
int32_t (*next_value)(struct iterator_t iterator,
int32_t (*next_value)(struct IteratorReference iterator,
struct gas_meter_t *gas_meter,
uint64_t *gas_used,
struct UnmanagedVector *value_out,
Expand All @@ -284,7 +288,11 @@ typedef struct IteratorVtable {

typedef struct GoIter {
struct gas_meter_t *gas_meter;
struct iterator_t state;
/**
* A reference which identifies the iterator and allows finding and accessing the
* actual iterator instance in Go. Once fully initalized, this is immutable.
*/
struct IteratorReference reference;
struct IteratorVtable vtable;
} GoIter;

Expand Down
27 changes: 15 additions & 12 deletions libwasmvm/src/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ use crate::gas_meter::gas_meter_t;
use crate::memory::UnmanagedVector;
use crate::vtables::Vtable;

// Iterator maintains integer references to some tables on the Go side
/// A reference to some tables on the Go side which allow accessing
/// the actual iterator instance.
#[repr(C)]
#[derive(Default, Copy, Clone)]
pub struct iterator_t {
pub struct IteratorReference {
/// An ID assigned to this contract call
pub call_id: u64,
pub iterator_index: u64,
Expand All @@ -22,7 +23,7 @@ pub struct iterator_t {
pub struct IteratorVtable {
pub next: Option<
extern "C" fn(
iterator: iterator_t,
iterator: IteratorReference,
gas_meter: *mut gas_meter_t,
gas_used: *mut u64,
key_out: *mut UnmanagedVector,
Expand All @@ -32,7 +33,7 @@ pub struct IteratorVtable {
>,
pub next_key: Option<
extern "C" fn(
iterator: iterator_t,
iterator: IteratorReference,
gas_meter: *mut gas_meter_t,
gas_used: *mut u64,
key_out: *mut UnmanagedVector,
Expand All @@ -41,7 +42,7 @@ pub struct IteratorVtable {
>,
pub next_value: Option<
extern "C" fn(
iterator: iterator_t,
iterator: IteratorReference,
gas_meter: *mut gas_meter_t,
gas_used: *mut u64,
value_out: *mut UnmanagedVector,
Expand All @@ -55,7 +56,9 @@ impl Vtable for IteratorVtable {}
#[repr(C)]
pub struct GoIter {
pub gas_meter: *mut gas_meter_t,
pub state: iterator_t,
/// A reference which identifies the iterator and allows finding and accessing the
/// actual iterator instance in Go. Once fully initalized, this is immutable.
pub reference: IteratorReference,
pub vtable: IteratorVtable,
}

Expand All @@ -67,8 +70,8 @@ impl GoIter {
/// which is then filled in Go (see `fn scan`).
pub fn stub() -> Self {
GoIter {
reference: IteratorReference::default(),
gas_meter: std::ptr::null_mut(),
state: iterator_t::default(),
vtable: IteratorVtable::default(),
}
}
Expand All @@ -84,7 +87,7 @@ impl GoIter {
let mut error_msg = UnmanagedVector::default();
let mut used_gas = 0_u64;
let go_result: GoError = (next)(
self.state,
self.reference,
self.gas_meter,
&mut used_gas as *mut u64,
&mut output_key as *mut UnmanagedVector,
Expand Down Expand Up @@ -141,7 +144,7 @@ impl GoIter {
fn next_key_or_val(
&mut self,
next: extern "C" fn(
iterator: iterator_t,
iterator: IteratorReference,
gas_meter: *mut gas_meter_t,
gas_limit: *mut u64,
key_or_value_out: *mut UnmanagedVector, // key if called from next_key; value if called from next_value
Expand All @@ -152,7 +155,7 @@ impl GoIter {
let mut error_msg = UnmanagedVector::default();
let mut used_gas = 0_u64;
let go_result: GoError = (next)(
self.state,
self.reference,
self.gas_meter,
&mut used_gas as *mut u64,
&mut output as *mut UnmanagedVector,
Expand Down Expand Up @@ -190,8 +193,8 @@ mod test {
// creates an all null-instance
let iter = GoIter::stub();
assert!(iter.gas_meter.is_null());
assert_eq!(iter.state.call_id, 0);
assert_eq!(iter.state.iterator_index, 0);
assert_eq!(iter.reference.call_id, 0);
assert_eq!(iter.reference.iterator_index, 0);
assert!(iter.vtable.next.is_none());
assert!(iter.vtable.next_key.is_none());
assert!(iter.vtable.next_value.is_none());
Expand Down
4 changes: 2 additions & 2 deletions libwasmvm/src/vtables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
///
/// ```
/// # use wasmvm::UnmanagedVector;
/// # struct iterator_t;
/// # struct IteratorReference;
/// # struct gas_meter_t;
/// pub struct IteratorVtable {
/// pub next: Option<
/// extern "C" fn(
/// iterator: iterator_t,
/// iterator: IteratorReference,
/// gas_meter: *mut gas_meter_t,
/// gas_used: *mut u64,
/// key_out: *mut UnmanagedVector,
Expand Down

0 comments on commit 675ce76

Please sign in to comment.