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(refer:Reference) -> Vec<u8>`
|
||||||
`encode_raw(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`
|
`*Dereference -> Reference`
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -151,7 +159,7 @@ Stores a value of any other type.
|
|||||||
|
|
||||||
`is_null() -> bool`
|
`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
|
## Boolean
|
||||||
Stores the value true or false.
|
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
|
## Significant
|
||||||
Stores a fixed-precision, variable-magnitude number.
|
Stores a fixed-precision, variable-magnitude number.
|
||||||
|
|
||||||
|
> Not implemented.
|
||||||
|
|
||||||
`get() -> f64`
|
`get() -> f64`
|
||||||
|
|
||||||
|
Returns the contained value.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`set(value:f64)`
|
`set(value:f64)`
|
||||||
|
|
||||||
|
Replaces the contained value.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
@ -267,61 +291,129 @@ Constant-sized series of bytes.
|
|||||||
|
|
||||||
`new(size:usize) -> Block`
|
`new(size:usize) -> Block`
|
||||||
|
|
||||||
|
Produces a
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`length() -> usize`
|
`size() -> usize`
|
||||||
|
|
||||||
|
Returns the size of the allocated block.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`get() -> Vec<u8>`
|
`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>)`
|
`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
|
## Sequence
|
||||||
Variable-sized series of bytes.
|
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`
|
`get() -> String`
|
||||||
|
|
||||||
|
Returns a UTF-8 string representation of the series.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`get_raw() -> Vec<u8>`
|
`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)`
|
`set(data:&str)`
|
||||||
|
|
||||||
|
Replaces the contents with the byte representation of a string.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`set_raw(data:Vec<u8>)`
|
`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
|
## Array
|
||||||
Constant-sized, ordered collection of items.
|
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`
|
`length() -> usize`
|
||||||
|
|
||||||
|
Returns the length of the array.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`at(index:usize) -> Reference`
|
`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`
|
`new(type_id:usize) -> List`
|
||||||
|
|
||||||
---
|
Produces a new list of the given type.
|
||||||
|
|
||||||
`length() -> usize`
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`capacity() -> usize`
|
`capacity() -> usize`
|
||||||
|
|
||||||
|
Returns the allocated capacity of the list.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
`length() -> usize`
|
||||||
|
|
||||||
|
Returns the length of the list.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`at(index:usize) -> Reference`
|
`at(index:usize) -> Reference`
|
||||||
|
|
||||||
---
|
Returns the object at the given index or a null reference if out of bounds.
|
||||||
|
|
||||||
`set(index:usize, refer:Reference)`
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`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)`
|
`remove(index:usize)`
|
||||||
|
|
||||||
|
Removes the object at the given index from the list.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`reserve(capacity:usize)`
|
`reserve(capacity:usize)`
|
||||||
|
|
||||||
|
Reallocates the list to have capacity not less than the specified size.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`clear()`
|
`clear()`
|
||||||
|
|
||||||
|
Removes all elements from the list.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
## Schema
|
## Schema
|
||||||
Definition of an abstract structure composed of named items.
|
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`
|
`get(index:usize) -> usize`
|
||||||
|
|
||||||
|
Returns the type identifier of the given index or zero if out of bounds.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`add(type_id:usize) -> usize`
|
`add(type_id:usize) -> usize`
|
||||||
|
|
||||||
|
Appends a member of the specified type to the schema.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`remove(index:usize)`
|
`remove(index:usize)`
|
||||||
|
|
||||||
|
Removes the member at the given index from the schema.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`assign(key:&str, type_id:usize) -> usize`
|
`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)`
|
`map(key:&str, index:usize)`
|
||||||
|
|
||||||
|
Maps a string to the specified index.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`unmap(key:&str)`
|
`unmap(key:&str)`
|
||||||
|
|
||||||
|
Removes a mapping of the specified string from the schema.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`clear()`
|
`clear()`
|
||||||
|
|
||||||
|
Removes all members and mappings from the schema.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`bind(id:usize)`
|
`bind(id:usize)`
|
||||||
|
|
||||||
|
Submits the schema to the
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
## Record
|
## Record
|
||||||
Instance of a schema.
|
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`
|
`at(index:usize) -> Reference`
|
||||||
|
|
||||||
|
Returns a reference to the member at the given index.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`set(index:usize, source:Reference)`
|
`set(index:usize, source:Reference)`
|
||||||
|
|
||||||
|
Replaces the member at the given index with a copy of the source.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`keyof(index:usize) -> String`
|
`keyof(index:usize) -> String`
|
||||||
|
|
||||||
|
Returns the string mapped to the specified index or an empty string if no mapping exists.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
`indexof(key:&str) -> usize`
|
`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();
|
let mut obj = Self::new();
|
||||||
for binding in data {
|
for binding in members {
|
||||||
let (key, type_id) = binding;
|
let (key, type_id) = binding;
|
||||||
obj.assign(key, type_id);
|
obj.assign(key, type_id);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ use crate::runtime::{
|
|||||||
Reference,
|
Reference,
|
||||||
acquire, release,
|
acquire, release,
|
||||||
type_key,
|
type_key,
|
||||||
sequence_length,
|
sequence_capacity, sequence_length,
|
||||||
sequence_clear, sequence_reserve,
|
sequence_clear, sequence_reserve,
|
||||||
sequence_get,
|
sequence_get,
|
||||||
sequence_insert,
|
sequence_insert,
|
||||||
@ -43,7 +43,6 @@ impl Sequence {
|
|||||||
pub fn with(data:&str) -> Self
|
pub fn with(data:&str) -> Self
|
||||||
{
|
{
|
||||||
let mut obj = Self::new();
|
let mut obj = Self::new();
|
||||||
println!("a");
|
|
||||||
obj.set(data);
|
obj.set(data);
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@ -59,6 +58,11 @@ impl Sequence {
|
|||||||
unsafe { release(self.addr); }
|
unsafe { release(self.addr); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn capacity(&self) -> usize
|
||||||
|
{
|
||||||
|
unsafe {sequence_capacity(self.addr)}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn size(&self) -> usize
|
pub fn size(&self) -> usize
|
||||||
{
|
{
|
||||||
unsafe {sequence_length(self.addr)}
|
unsafe {sequence_length(self.addr)}
|
||||||
@ -67,7 +71,6 @@ impl Sequence {
|
|||||||
pub fn set_raw(&mut self, data:Vec<u8>)
|
pub fn set_raw(&mut self, data:Vec<u8>)
|
||||||
{
|
{
|
||||||
unsafe { sequence_clear(self.addr); }
|
unsafe { sequence_clear(self.addr); }
|
||||||
println!("c {}", data.len());
|
|
||||||
if data.len() > 0 {
|
if data.len() > 0 {
|
||||||
unsafe { sequence_reserve(self.addr, data.len()); }
|
unsafe { sequence_reserve(self.addr, data.len()); }
|
||||||
for i in 0..data.len() {
|
for i in 0..data.len() {
|
||||||
@ -85,7 +88,6 @@ impl Sequence {
|
|||||||
{
|
{
|
||||||
let length = unsafe {sequence_length(self.addr)};
|
let length = unsafe {sequence_length(self.addr)};
|
||||||
let mut result = Vec::<u8>::new();
|
let mut result = Vec::<u8>::new();
|
||||||
println!("d {}", length);
|
|
||||||
|
|
||||||
if length > 0 {
|
if length > 0 {
|
||||||
result.reserve_exact(length);
|
result.reserve_exact(length);
|
||||||
|
@ -10,12 +10,14 @@ pub fn release(addr:runtime::Reference)
|
|||||||
unsafe {runtime::release(addr)}
|
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,
|
acquire, release,
|
||||||
type_key,
|
type_key,
|
||||||
varying_get, varying_set,
|
varying_get, varying_set,
|
||||||
|
varying_clear,
|
||||||
};
|
};
|
||||||
use crate::tag;
|
use crate::tag;
|
||||||
use super::varying;
|
use super::varying;
|
||||||
@ -51,6 +52,11 @@ impl Varying {
|
|||||||
unsafe { varying_set(self.addr, source); }
|
unsafe { varying_set(self.addr, source); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clear(&mut self)
|
||||||
|
{
|
||||||
|
unsafe { varying_clear(self.addr); }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get(&self) -> Reference
|
pub fn get(&self) -> Reference
|
||||||
{
|
{
|
||||||
unsafe { varying_get(self.addr) }
|
unsafe { varying_get(self.addr) }
|
||||||
|
11
src/lib.rs
11
src/lib.rs
@ -19,7 +19,7 @@ pub fn test() {
|
|||||||
("rec", record(9)),
|
("rec", record(9)),
|
||||||
]).bind(10);
|
]).bind(10);
|
||||||
|
|
||||||
let out = encode(*Record::with(10, vec![
|
let rec = Record::with(10, vec![
|
||||||
("str", *Sequence::with("hello!")),
|
("str", *Sequence::with("hello!")),
|
||||||
("int", *Integer::with(-70)),
|
("int", *Integer::with(-70)),
|
||||||
("bool", *Boolean::with(true)),
|
("bool", *Boolean::with(true)),
|
||||||
@ -27,7 +27,14 @@ pub fn test() {
|
|||||||
("nat", *Natural::with(8)),
|
("nat", *Natural::with(8)),
|
||||||
("pass", *Block::with(6, vec![1, 2, 3, 4, 5, 6])),
|
("pass", *Block::with(6, vec![1, 2, 3, 4, 5, 6])),
|
||||||
]).unwrap()),
|
]).unwrap()),
|
||||||
]).unwrap());
|
]).unwrap();
|
||||||
|
|
||||||
|
let out = encode(*rec);
|
||||||
|
print!("[{}]: ", out.len());
|
||||||
|
for byte in &out {
|
||||||
|
print!("{:02x} ", *byte);
|
||||||
|
} println!("\n");
|
||||||
|
|
||||||
match decode(&out, &mut 0) {
|
match decode(&out, &mut 0) {
|
||||||
Ok(ty) => match ty {
|
Ok(ty) => match ty {
|
||||||
Type::Record(rec) => {
|
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)
|
extern "C" size_t name_indexof(const uint8_t* bytes, size_t length)
|
||||||
{
|
{
|
||||||
std::string str(reinterpret_cast<const char*>(bytes), 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)
|
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) {
|
if(src.address != dst.address) {
|
||||||
Reference source = src;
|
Reference source = src;
|
||||||
@ -271,6 +274,8 @@ bool copy(Reference src, Reference dst)
|
|||||||
|
|
||||||
// copy data into destination
|
// copy data into destination
|
||||||
if(source.type == destination.type) {
|
if(source.type == destination.type) {
|
||||||
|
drop(destination);
|
||||||
|
|
||||||
switch(type_key(destination.type)) {
|
switch(type_key(destination.type)) {
|
||||||
case Type::Tag::Null: { } break;
|
case Type::Tag::Null: { } break;
|
||||||
|
|
||||||
@ -288,11 +293,12 @@ bool copy(Reference src, Reference dst)
|
|||||||
rawlist_clear(dst_seq.data);
|
rawlist_clear(dst_seq.data);
|
||||||
rawlist_reserve(dst_seq.data, sizeof(uint8_t), src_seq.data.length);
|
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);
|
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;
|
} break;
|
||||||
|
|
||||||
case Type::Tag::Array: {
|
case Type::Tag::Array: {
|
||||||
for(size_t i = 0; i < array_length(source); ++i) {
|
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;
|
} break;
|
||||||
|
|
||||||
@ -300,12 +306,11 @@ bool copy(Reference src, Reference dst)
|
|||||||
auto& src_list = *reinterpret_cast<Type::List*>(source.address);
|
auto& src_list = *reinterpret_cast<Type::List*>(source.address);
|
||||||
auto& dst_list = *reinterpret_cast<Type::List*>(destination.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);
|
rawlist_reserve(dst_list.data, type_size(type_inner(source.type)), src_list.data.capacity);
|
||||||
dst_list.data.length = src_list.data.length;
|
dst_list.data.length = src_list.data.length;
|
||||||
|
|
||||||
for(size_t i = 0; i < src_list.data.length; ++i) {
|
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;
|
} break;
|
||||||
|
|
||||||
@ -316,7 +321,7 @@ bool copy(Reference src, Reference dst)
|
|||||||
for(size_t i = 0; i < binding->data.size(); ++i) {
|
for(size_t i = 0; i < binding->data.size(); ++i) {
|
||||||
auto src_cell = record_cell(source, i);
|
auto src_cell = record_cell(source, i);
|
||||||
auto dst_cell = record_cell(destination, i);
|
auto dst_cell = record_cell(destination, i);
|
||||||
copy(src_cell, dst_cell);
|
copy(dst_cell, src_cell);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -354,6 +359,43 @@ bool copy(Reference src, Reference dst)
|
|||||||
return false;
|
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 resolve_addr(Reference addr)
|
||||||
{
|
{
|
||||||
Reference result = addr;
|
Reference result = addr;
|
||||||
@ -394,7 +436,7 @@ extern "C" void varying_set(Reference addr, Reference source)
|
|||||||
var.address = allocate(source.type, 1);
|
var.address = allocate(source.type, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
copy(source, var);
|
copy(var, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void varying_clear(Reference addr)
|
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 //
|
// 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)
|
extern "C" size_t sequence_length(Reference addr)
|
||||||
{
|
{
|
||||||
Type::Sequence& seq = *reinterpret_cast<Type::Sequence*>(addr.address);
|
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);
|
varying_set(cell, source);
|
||||||
}
|
}
|
||||||
else {
|
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);
|
varying_set(list_cell(addr, index), source);
|
||||||
}
|
}
|
||||||
else {
|
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);
|
varying_set(list_cell(addr, index), source);
|
||||||
}
|
}
|
||||||
else {
|
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()) {
|
if(index < binding->data.size()) {
|
||||||
destination.type = binding->data[index].type;
|
destination.type = binding->data[index].type;
|
||||||
destination.address = addr.address + binding->data[index].offset;
|
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_innerkey(size_t id);
|
||||||
extern "C" size_t type_size(size_t type_id);
|
extern "C" size_t type_size(size_t type_id);
|
||||||
size_t type_alignment(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);
|
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);
|
uint8_t* allocate(size_t type_id, size_t count);
|
||||||
extern "C" Reference acquire(size_t type_id);
|
extern "C" Reference acquire(size_t type_id);
|
||||||
extern "C" void release(Reference 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);
|
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);
|
extern "C" void block_set(Reference addr, size_t index, uint8_t value);
|
||||||
|
|
||||||
// String //
|
// String //
|
||||||
|
extern "C" size_t sequence_capacity(Reference addr);
|
||||||
extern "C" size_t sequence_length(Reference addr);
|
extern "C" size_t sequence_length(Reference addr);
|
||||||
extern "C" uint8_t sequence_get(Reference addr, size_t index);
|
extern "C" uint8_t sequence_get(Reference addr, size_t index);
|
||||||
extern "C" void sequence_clear(Reference addr);
|
extern "C" void sequence_clear(Reference addr);
|
||||||
|
@ -34,6 +34,9 @@ extern "C" {
|
|||||||
pub fn acquire(type_id:usize) -> Reference;
|
pub fn acquire(type_id:usize) -> Reference;
|
||||||
pub fn release(addr: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_outer(type_id:usize, key:usize) -> usize;
|
||||||
pub fn type_inner(type_id:usize) -> usize;
|
pub fn type_inner(type_id:usize) -> usize;
|
||||||
pub fn type_key(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_set(addr:Reference, index:usize, data:u8);
|
||||||
pub fn block_get(addr:Reference, index:usize) -> 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_length(addr:Reference) -> usize;
|
||||||
pub fn sequence_get(addr:Reference, index:usize) -> u8;
|
pub fn sequence_get(addr:Reference, index:usize) -> u8;
|
||||||
pub fn sequence_clear(addr:Reference);
|
pub fn sequence_clear(addr:Reference);
|
||||||
|
Reference in New Issue
Block a user