Fix bugs, update interface, update README.
This commit is contained in:
parent
7addefd634
commit
ac28278830
192
README.md
192
README.md
@ -90,6 +90,8 @@ Copy the contents of an objcet to another location, keeping the original.
|
||||
|
||||
---
|
||||
|
||||
## Encoding
|
||||
Encoding converts data between runtime memory and binary serialization.
|
||||
|
||||
`encode(refer:Reference) -> Vec<u8>`
|
||||
`encode_raw(refer:Reference) -> Vec<u8>`
|
||||
@ -138,6 +140,12 @@ let b = Boolean::with(true);
|
||||
```
|
||||
---
|
||||
|
||||
`detatch()`
|
||||
|
||||
Prevents an allocated object from being dropped when the interface goes out of scope.
|
||||
|
||||
---
|
||||
|
||||
`*Dereference -> Reference`
|
||||
|
||||
```
|
||||
@ -151,7 +159,7 @@ Stores a value of any other type.
|
||||
|
||||
`is_null() -> bool`
|
||||
|
||||
Specifies whether or not the variable contains a object.
|
||||
Indicates whether or not the variable contains a object.
|
||||
|
||||
---
|
||||
|
||||
@ -175,6 +183,12 @@ var.set(*Sequence::with("Hello!"));
|
||||
```
|
||||
---
|
||||
|
||||
`clear()`
|
||||
|
||||
Removes the contained object.
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Boolean
|
||||
Stores the value true or false.
|
||||
@ -249,16 +263,26 @@ value.set(-273);
|
||||
```
|
||||
---
|
||||
|
||||
## Decimal
|
||||
Stores a constant-magnitude number with whole and decimal components.
|
||||
|
||||
> Not implemented.
|
||||
|
||||
## Significant
|
||||
Stores a fixed-precision, variable-magnitude number.
|
||||
|
||||
> Not implemented.
|
||||
|
||||
`get() -> f64`
|
||||
|
||||
Returns the contained value.
|
||||
|
||||
---
|
||||
|
||||
`set(value:f64)`
|
||||
|
||||
Replaces the contained value.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -267,61 +291,129 @@ Constant-sized series of bytes.
|
||||
|
||||
`new(size:usize) -> Block`
|
||||
|
||||
Produces a
|
||||
|
||||
---
|
||||
|
||||
`length() -> usize`
|
||||
`size() -> usize`
|
||||
|
||||
Returns the size of the allocated block.
|
||||
|
||||
---
|
||||
|
||||
`get() -> Vec<u8>`
|
||||
|
||||
Returns the contents of the block.
|
||||
|
||||
---
|
||||
|
||||
`at(index:usize) -> u8`
|
||||
|
||||
Returns the byte at the specified index or zero if out of bounds.
|
||||
|
||||
---
|
||||
|
||||
`set(data:Vec<u8>)`
|
||||
|
||||
Replaces the contents of the block up to the length of the parameter.
|
||||
|
||||
---
|
||||
|
||||
`set_at(index:usize, data:u8)`
|
||||
|
||||
Replaces the byte at the given index.
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Sequence
|
||||
Variable-sized series of bytes.
|
||||
|
||||
`length() -> usize`
|
||||
`capacity() -> usize`
|
||||
|
||||
Returns the memory capacity of the sequeunce.
|
||||
|
||||
---
|
||||
|
||||
`size() -> usize`
|
||||
|
||||
Returns the length of the series.
|
||||
|
||||
---
|
||||
|
||||
`get() -> String`
|
||||
|
||||
Returns a UTF-8 string representation of the series.
|
||||
|
||||
---
|
||||
|
||||
`get_raw() -> Vec<u8>`
|
||||
|
||||
Returns the contents of the series.
|
||||
|
||||
---
|
||||
|
||||
`at(index:usize) -> u8`
|
||||
|
||||
Returns the byte at the specified index or zero if out of bounds.
|
||||
|
||||
---
|
||||
|
||||
`set(data:&str)`
|
||||
|
||||
Replaces the contents with the byte representation of a string.
|
||||
|
||||
---
|
||||
|
||||
`set_raw(data:Vec<u8>)`
|
||||
|
||||
Replaces the contents with a series of bytes.
|
||||
|
||||
---
|
||||
|
||||
`set_at(index:usize, data:u8)`
|
||||
|
||||
Replaces a byte at the given index.
|
||||
|
||||
---
|
||||
|
||||
`reserve(capacity:usize)`
|
||||
|
||||
Reallocates the sequeunce to have capacity not less than the specified size.
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Array
|
||||
Constant-sized, ordered collection of items.
|
||||
|
||||
`new(size:usize, type_id:usize) -> Array`
|
||||
`new(length:usize, type_id:usize) -> Array`
|
||||
|
||||
Produces a new array of given type and length.
|
||||
|
||||
---
|
||||
|
||||
`length() -> usize`
|
||||
|
||||
Returns the length of the array.
|
||||
|
||||
---
|
||||
|
||||
`at(index:usize) -> Reference`
|
||||
|
||||
Returns a reference to the element at the given index or a null reference if out of bounds.
|
||||
|
||||
---
|
||||
|
||||
`set(index:usize, refer:Reference)`
|
||||
`set(index:usize, source:Reference)`
|
||||
|
||||
Replaces the element at the given index with a copy of the source.
|
||||
|
||||
---
|
||||
|
||||
`kindof() -> usize`
|
||||
|
||||
Returns the type identifier of the contents.
|
||||
|
||||
---
|
||||
|
||||
@ -331,96 +423,170 @@ Variable-sized, ordered collection of items.
|
||||
|
||||
`new(type_id:usize) -> List`
|
||||
|
||||
---
|
||||
|
||||
`length() -> usize`
|
||||
Produces a new list of the given type.
|
||||
|
||||
---
|
||||
|
||||
`capacity() -> usize`
|
||||
|
||||
Returns the allocated capacity of the list.
|
||||
|
||||
---
|
||||
|
||||
`length() -> usize`
|
||||
|
||||
Returns the length of the list.
|
||||
|
||||
---
|
||||
|
||||
`at(index:usize) -> Reference`
|
||||
|
||||
---
|
||||
|
||||
`set(index:usize, refer:Reference)`
|
||||
Returns the object at the given index or a null reference if out of bounds.
|
||||
|
||||
---
|
||||
|
||||
`insert(index:usize, refer:Reference)`
|
||||
`set(index:usize, source:Reference)`
|
||||
|
||||
Replaces the object at the given index with a copy of the source.
|
||||
|
||||
---
|
||||
|
||||
`insert(index:usize, source:Reference)`
|
||||
|
||||
Inserts a copy of the source at a given index.
|
||||
|
||||
---
|
||||
|
||||
`remove(index:usize)`
|
||||
|
||||
Removes the object at the given index from the list.
|
||||
|
||||
---
|
||||
|
||||
`reserve(capacity:usize)`
|
||||
|
||||
Reallocates the list to have capacity not less than the specified size.
|
||||
|
||||
---
|
||||
|
||||
`clear()`
|
||||
|
||||
Removes all elements from the list.
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Schema
|
||||
Definition of an abstract structure composed of named items.
|
||||
|
||||
`with(members:Vec<(&str, usize)>) -> Schema`
|
||||
|
||||
Produces a schema with the provided member assignments.
|
||||
|
||||
---
|
||||
|
||||
`get(index:usize) -> usize`
|
||||
|
||||
Returns the type identifier of the given index or zero if out of bounds.
|
||||
|
||||
---
|
||||
|
||||
`add(type_id:usize) -> usize`
|
||||
|
||||
Appends a member of the specified type to the schema.
|
||||
|
||||
---
|
||||
|
||||
`remove(index:usize)`
|
||||
|
||||
Removes the member at the given index from the schema.
|
||||
|
||||
---
|
||||
|
||||
`assign(key:&str, type_id:usize) -> usize`
|
||||
|
||||
Appends a member of the specified type to the schema and maps the provided string to that index.
|
||||
|
||||
---
|
||||
|
||||
`map(key:&str, index:usize)`
|
||||
|
||||
Maps a string to the specified index.
|
||||
|
||||
---
|
||||
|
||||
`unmap(key:&str)`
|
||||
|
||||
Removes a mapping of the specified string from the schema.
|
||||
|
||||
---
|
||||
|
||||
`clear()`
|
||||
|
||||
Removes all members and mappings from the schema.
|
||||
|
||||
---
|
||||
|
||||
`bind(id:usize)`
|
||||
|
||||
Submits the schema to the
|
||||
|
||||
---
|
||||
|
||||
|
||||
## Record
|
||||
Instance of a schema.
|
||||
|
||||
`new(schema_id:usize) -> Record`
|
||||
`new(schema_id:usize) -> Result<Record,()>`
|
||||
|
||||
Produces a new record of the provided schema.
|
||||
|
||||
---
|
||||
|
||||
`with(schema_id:usize, data:Vec<(&str, Reference)>) -> Result<Record,()>`
|
||||
|
||||
Produces a record of the provided schema and keyed assignments.
|
||||
|
||||
---
|
||||
|
||||
`with_values(schema_id:usize, data:Vec<Reference>) -> Result<Record,()>`
|
||||
|
||||
Produces a record of the provided schema and indexed assignments.
|
||||
|
||||
---
|
||||
|
||||
`length() -> usisze`
|
||||
|
||||
Returns the number of elements in the record.
|
||||
|
||||
---
|
||||
|
||||
`at(index:usize) -> Reference`
|
||||
|
||||
Returns a reference to the member at the given index.
|
||||
|
||||
---
|
||||
|
||||
`set(index:usize, source:Reference)`
|
||||
|
||||
Replaces the member at the given index with a copy of the source.
|
||||
|
||||
---
|
||||
|
||||
`keyof(index:usize) -> String`
|
||||
|
||||
Returns the string mapped to the specified index or an empty string if no mapping exists.
|
||||
|
||||
---
|
||||
|
||||
`indexof(key:&str) -> usize`
|
||||
|
||||
Returns the index of a mapped string or the number of elements in the record if no mapping exists.
|
||||
|
||||
---
|
||||
|
||||
`kindof(index:usize) -> usize`
|
||||
|
||||
Returns the type identifier of the given index.
|
||||
|
||||
---
|
||||
|
@ -35,10 +35,10 @@ impl Schema {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(data:Vec<(&str, usize)>) -> Self
|
||||
pub fn with(members:Vec<(&str, usize)>) -> Self
|
||||
{
|
||||
let mut obj = Self::new();
|
||||
for binding in data {
|
||||
for binding in members {
|
||||
let (key, type_id) = binding;
|
||||
obj.assign(key, type_id);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
sequence_length,
|
||||
sequence_capacity, sequence_length,
|
||||
sequence_clear, sequence_reserve,
|
||||
sequence_get,
|
||||
sequence_insert,
|
||||
@ -43,7 +43,6 @@ impl Sequence {
|
||||
pub fn with(data:&str) -> Self
|
||||
{
|
||||
let mut obj = Self::new();
|
||||
println!("a");
|
||||
obj.set(data);
|
||||
return obj;
|
||||
}
|
||||
@ -59,6 +58,11 @@ impl Sequence {
|
||||
unsafe { release(self.addr); }
|
||||
}
|
||||
|
||||
pub fn capacity(&self) -> usize
|
||||
{
|
||||
unsafe {sequence_capacity(self.addr)}
|
||||
}
|
||||
|
||||
pub fn size(&self) -> usize
|
||||
{
|
||||
unsafe {sequence_length(self.addr)}
|
||||
@ -67,7 +71,6 @@ impl Sequence {
|
||||
pub fn set_raw(&mut self, data:Vec<u8>)
|
||||
{
|
||||
unsafe { sequence_clear(self.addr); }
|
||||
println!("c {}", data.len());
|
||||
if data.len() > 0 {
|
||||
unsafe { sequence_reserve(self.addr, data.len()); }
|
||||
for i in 0..data.len() {
|
||||
@ -85,7 +88,6 @@ impl Sequence {
|
||||
{
|
||||
let length = unsafe {sequence_length(self.addr)};
|
||||
let mut result = Vec::<u8>::new();
|
||||
println!("d {}", length);
|
||||
|
||||
if length > 0 {
|
||||
result.reserve_exact(length);
|
||||
|
@ -10,12 +10,14 @@ pub fn release(addr:runtime::Reference)
|
||||
unsafe {runtime::release(addr)}
|
||||
}
|
||||
|
||||
pub fn copy(_dst:runtime::Reference, _src:runtime::Reference) -> Result<(),()>
|
||||
pub fn copy(dst:runtime::Reference, src:runtime::Reference) -> Result<(),()>
|
||||
{
|
||||
Err(())
|
||||
if unsafe {runtime::copy(dst, src)} { Ok(()) }
|
||||
else { Err(()) }
|
||||
}
|
||||
|
||||
pub fn transfer(_dst:runtime::Reference, _src:runtime::Reference) -> Result<(),()>
|
||||
pub fn transfer(dst:runtime::Reference, src:runtime::Reference) -> Result<(),()>
|
||||
{
|
||||
Err(())
|
||||
if unsafe {runtime::transfer(dst, src)} { Ok(()) }
|
||||
else { Err(()) }
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ use crate::runtime::{
|
||||
acquire, release,
|
||||
type_key,
|
||||
varying_get, varying_set,
|
||||
varying_clear,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::varying;
|
||||
@ -51,6 +52,11 @@ impl Varying {
|
||||
unsafe { varying_set(self.addr, source); }
|
||||
}
|
||||
|
||||
pub fn clear(&mut self)
|
||||
{
|
||||
unsafe { varying_clear(self.addr); }
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Reference
|
||||
{
|
||||
unsafe { varying_get(self.addr) }
|
||||
|
11
src/lib.rs
11
src/lib.rs
@ -19,7 +19,7 @@ pub fn test() {
|
||||
("rec", record(9)),
|
||||
]).bind(10);
|
||||
|
||||
let out = encode(*Record::with(10, vec![
|
||||
let rec = Record::with(10, vec![
|
||||
("str", *Sequence::with("hello!")),
|
||||
("int", *Integer::with(-70)),
|
||||
("bool", *Boolean::with(true)),
|
||||
@ -27,7 +27,14 @@ pub fn test() {
|
||||
("nat", *Natural::with(8)),
|
||||
("pass", *Block::with(6, vec![1, 2, 3, 4, 5, 6])),
|
||||
]).unwrap()),
|
||||
]).unwrap());
|
||||
]).unwrap();
|
||||
|
||||
let out = encode(*rec);
|
||||
print!("[{}]: ", out.len());
|
||||
for byte in &out {
|
||||
print!("{:02x} ", *byte);
|
||||
} println!("\n");
|
||||
|
||||
match decode(&out, &mut 0) {
|
||||
Ok(ty) => match ty {
|
||||
Type::Record(rec) => {
|
||||
|
@ -129,7 +129,10 @@ extern "C" size_t type_hasinner(size_t type_id)
|
||||
extern "C" size_t name_indexof(const uint8_t* bytes, size_t length)
|
||||
{
|
||||
std::string str(reinterpret_cast<const char*>(bytes), length);
|
||||
return DB_NAME.indexof(str);
|
||||
if(str.size() > 0) {
|
||||
return DB_NAME.indexof(str);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" Str name_keyof(size_t index)
|
||||
@ -243,7 +246,7 @@ extern "C" void release(Reference addr)
|
||||
}
|
||||
}
|
||||
|
||||
bool copy(Reference src, Reference dst)
|
||||
extern "C" bool copy(Reference dst, Reference src)
|
||||
{
|
||||
if(src.address != dst.address) {
|
||||
Reference source = src;
|
||||
@ -271,6 +274,8 @@ bool copy(Reference src, Reference dst)
|
||||
|
||||
// copy data into destination
|
||||
if(source.type == destination.type) {
|
||||
drop(destination);
|
||||
|
||||
switch(type_key(destination.type)) {
|
||||
case Type::Tag::Null: { } break;
|
||||
|
||||
@ -288,11 +293,12 @@ bool copy(Reference src, Reference dst)
|
||||
rawlist_clear(dst_seq.data);
|
||||
rawlist_reserve(dst_seq.data, sizeof(uint8_t), src_seq.data.length);
|
||||
memcpy(dst_seq.data.data, src_seq.data.data, sizeof(uint8_t) * src_seq.data.length);
|
||||
dst_seq.data.length = src_seq.data.length;
|
||||
} break;
|
||||
|
||||
case Type::Tag::Array: {
|
||||
for(size_t i = 0; i < array_length(source); ++i) {
|
||||
copy(array_cell(source, i), array_cell(destination, i));
|
||||
copy(array_cell(destination, i), array_cell(source, i));
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -300,12 +306,11 @@ bool copy(Reference src, Reference dst)
|
||||
auto& src_list = *reinterpret_cast<Type::List*>(source.address);
|
||||
auto& dst_list = *reinterpret_cast<Type::List*>(destination.address);
|
||||
|
||||
drop(destination);
|
||||
rawlist_reserve(dst_list.data, type_size(type_inner(source.type)), src_list.data.capacity);
|
||||
dst_list.data.length = src_list.data.length;
|
||||
|
||||
for(size_t i = 0; i < src_list.data.length; ++i) {
|
||||
copy(list_at(source, i), list_at(destination, i));
|
||||
copy(list_at(destination, i), list_at(source, i));
|
||||
}
|
||||
} break;
|
||||
|
||||
@ -316,7 +321,7 @@ bool copy(Reference src, Reference dst)
|
||||
for(size_t i = 0; i < binding->data.size(); ++i) {
|
||||
auto src_cell = record_cell(source, i);
|
||||
auto dst_cell = record_cell(destination, i);
|
||||
copy(src_cell, dst_cell);
|
||||
copy(dst_cell, src_cell);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
@ -354,6 +359,43 @@ bool copy(Reference src, Reference dst)
|
||||
return false;
|
||||
}
|
||||
|
||||
extern "C" bool transfer(Reference dst, Reference src)
|
||||
{
|
||||
if(src.address != dst.address) {
|
||||
Reference source = src;
|
||||
Reference destination = dst;
|
||||
|
||||
// dereference varying data
|
||||
if(type_key(src.type) == Type::Tag::Varying) {
|
||||
source = *reinterpret_cast<Reference*>(src.address);
|
||||
}
|
||||
|
||||
// prepare destination for varying data
|
||||
if(type_key(dst.type) == Type::Tag::Varying) {
|
||||
auto& dest_ref = *reinterpret_cast<Reference*>(dst.address);
|
||||
|
||||
// determine if memory can be reused, otherwise free and reallocate
|
||||
if(source.type != dest_ref.type) {
|
||||
if(dest_ref.address != nullptr) {
|
||||
free(dest_ref.address);
|
||||
dest_ref.type = Type::Tag::Null;
|
||||
dest_ref.address = nullptr;
|
||||
}
|
||||
dest_ref = acquire(source.type);
|
||||
}
|
||||
}
|
||||
|
||||
// copy data into destination
|
||||
if(source.type == destination.type) {
|
||||
drop(destination);
|
||||
memcpy(destination.address, source.address, type_size(source.type));
|
||||
memset(source.address, 0, type_size(source.type));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference resolve_addr(Reference addr)
|
||||
{
|
||||
Reference result = addr;
|
||||
@ -394,7 +436,7 @@ extern "C" void varying_set(Reference addr, Reference source)
|
||||
var.address = allocate(source.type, 1);
|
||||
}
|
||||
|
||||
copy(source, var);
|
||||
copy(var, source);
|
||||
}
|
||||
|
||||
extern "C" void varying_clear(Reference addr)
|
||||
@ -476,6 +518,12 @@ extern "C" void block_set(Reference addr, size_t index, uint8_t value)
|
||||
|
||||
// Sequence //
|
||||
|
||||
extern "C" size_t sequence_capacity(Reference addr)
|
||||
{
|
||||
Type::Sequence& seq = *reinterpret_cast<Type::Sequence*>(addr.address);
|
||||
return seq.data.capacity;
|
||||
}
|
||||
|
||||
extern "C" size_t sequence_length(Reference addr)
|
||||
{
|
||||
Type::Sequence& seq = *reinterpret_cast<Type::Sequence*>(addr.address);
|
||||
@ -567,7 +615,7 @@ extern "C" void array_update(Reference addr, size_t index, Reference source)
|
||||
varying_set(cell, source);
|
||||
}
|
||||
else {
|
||||
copy(source, cell);
|
||||
copy(cell, source);
|
||||
}
|
||||
}
|
||||
|
||||
@ -658,7 +706,7 @@ extern "C" void list_insert(Reference addr, size_t index, Reference source)
|
||||
varying_set(list_cell(addr, index), source);
|
||||
}
|
||||
else {
|
||||
copy(source, list_cell(addr, index));
|
||||
copy(list_cell(addr, index), source);
|
||||
}
|
||||
}
|
||||
|
||||
@ -684,7 +732,7 @@ extern "C" void list_update(Reference addr, size_t index, Reference source)
|
||||
varying_set(list_cell(addr, index), source);
|
||||
}
|
||||
else {
|
||||
copy(source, list_cell(addr, index));
|
||||
copy(list_cell(addr, index), source);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -784,7 +832,7 @@ extern "C" void record_update(Reference addr, size_t index, Reference source)
|
||||
if(index < binding->data.size()) {
|
||||
destination.type = binding->data[index].type;
|
||||
destination.address = addr.address + binding->data[index].offset;
|
||||
copy(source, destination);
|
||||
copy(destination, source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ extern "C" size_t type_key(size_t id);
|
||||
extern "C" size_t type_innerkey(size_t id);
|
||||
extern "C" size_t type_size(size_t type_id);
|
||||
size_t type_alignment(size_t type_id);
|
||||
extern "C" size_t kind_hasinner(size_t kind);
|
||||
extern "C" size_t type_hasinner(size_t type_id);
|
||||
|
||||
|
||||
@ -37,7 +38,8 @@ extern "C" Str name_keyof(size_t index);
|
||||
uint8_t* allocate(size_t type_id, size_t count);
|
||||
extern "C" Reference acquire(size_t type_id);
|
||||
extern "C" void release(Reference id);
|
||||
extern "C" bool copy(Reference src, Reference dst);
|
||||
extern "C" bool copy(Reference dst, Reference src);
|
||||
extern "C" bool transfer(Reference dst, Reference src);
|
||||
|
||||
Reference resolve_addr(Reference addr);
|
||||
|
||||
@ -64,6 +66,7 @@ extern "C" uint8_t block_get(Reference addr, size_t index);
|
||||
extern "C" void block_set(Reference addr, size_t index, uint8_t value);
|
||||
|
||||
// String //
|
||||
extern "C" size_t sequence_capacity(Reference addr);
|
||||
extern "C" size_t sequence_length(Reference addr);
|
||||
extern "C" uint8_t sequence_get(Reference addr, size_t index);
|
||||
extern "C" void sequence_clear(Reference addr);
|
||||
|
@ -34,6 +34,9 @@ extern "C" {
|
||||
pub fn acquire(type_id:usize) -> Reference;
|
||||
pub fn release(addr:Reference);
|
||||
|
||||
pub fn copy(dst:Reference, src:Reference) -> bool;
|
||||
pub fn transfer(dst:Reference, src:Reference) -> bool;
|
||||
|
||||
pub fn type_outer(type_id:usize, key:usize) -> usize;
|
||||
pub fn type_inner(type_id:usize) -> usize;
|
||||
pub fn type_key(type_id:usize) -> usize;
|
||||
@ -64,6 +67,7 @@ extern "C" {
|
||||
pub fn block_set(addr:Reference, index:usize, data:u8);
|
||||
pub fn block_get(addr:Reference, index:usize) -> u8;
|
||||
|
||||
pub fn sequence_capacity(addr:Reference) -> usize;
|
||||
pub fn sequence_length(addr:Reference) -> usize;
|
||||
pub fn sequence_get(addr:Reference, index:usize) -> u8;
|
||||
pub fn sequence_clear(addr:Reference);
|
||||
|
Reference in New Issue
Block a user