Attempt to add memory copy/fill (2)
This commit is contained in:
parent
2f8eadad6c
commit
50b93641f2
@ -4,8 +4,8 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use wasm_ast::node::{
|
use wasm_ast::node::{
|
||||||
Block, Br, BrIf, BrTable, Call, CallIndirect, FuncData, If, LabelType, MemoryGrow, SetGlobal,
|
Block, Br, BrIf, BrTable, Call, CallIndirect, FuncData, If, LabelType, MemoryGrow, MemoryCopy,
|
||||||
SetLocal, SetTemporary, Statement, StoreAt, Terminator,
|
MemoryFill, SetGlobal, SetLocal, SetTemporary, Statement, StoreAt, Terminator,
|
||||||
};
|
};
|
||||||
use wasmparser::ValType;
|
use wasmparser::ValType;
|
||||||
|
|
||||||
@ -282,6 +282,32 @@ impl DriverNoContext for MemoryGrow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl DriverNoContext for MemoryCopy {
|
||||||
|
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||||
|
let dst = self.dst();
|
||||||
|
let src = self.src();
|
||||||
|
|
||||||
|
write!(w, "rt.allocator.copy(memory_at_0, {dst}, {src}, ")?;
|
||||||
|
self.size().write(w)?;
|
||||||
|
write!(w, ")")
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DriverNoContext for MemoryFill {
|
||||||
|
fn write(&self, w: &mut dyn Write) -> Result<()> {
|
||||||
|
let mem = self.mem();
|
||||||
|
let value = self.value();
|
||||||
|
let n = self.n();
|
||||||
|
|
||||||
|
write!(w, "rt.allocator.fill(memory_at_0, {mem}, ")?;
|
||||||
|
value.write(w)?;
|
||||||
|
write!(w, ", ")?;
|
||||||
|
n.write(w)?;
|
||||||
|
write!(w, ")")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn write_stat(stat: &dyn DriverNoContext, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
fn write_stat(stat: &dyn DriverNoContext, mng: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||||
indentation!(mng, w)?;
|
indentation!(mng, w)?;
|
||||||
stat.write(w)?;
|
stat.write(w)?;
|
||||||
@ -301,6 +327,8 @@ impl Driver for Statement {
|
|||||||
Self::SetGlobal(s) => write_stat(s, mng, w),
|
Self::SetGlobal(s) => write_stat(s, mng, w),
|
||||||
Self::StoreAt(s) => write_stat(s, mng, w),
|
Self::StoreAt(s) => write_stat(s, mng, w),
|
||||||
Self::MemoryGrow(s) => write_stat(s, mng, w),
|
Self::MemoryGrow(s) => write_stat(s, mng, w),
|
||||||
|
Self::MemoryCopy(s) => write_stat(s, mng, w),
|
||||||
|
Self::MemoryFill(s) => write_stat(s, mng, w)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -945,9 +945,24 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function allocator.copy(memory, dst, src, len)
|
||||||
|
for i = 1, len do
|
||||||
|
local v = load_byte(memory, src + i - 1)
|
||||||
|
|
||||||
|
store_byte(memory, dst + i - 1, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function allocator.fill(memory, dst, value, len)
|
||||||
|
for i = 1, len do
|
||||||
|
store_byte(memory, dst + i - 1, value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
module.load = load
|
module.load = load
|
||||||
module.store = store
|
module.store = store
|
||||||
module.allocator = allocator
|
module.allocator = allocator
|
||||||
end
|
end
|
||||||
|
|
||||||
return module
|
return module
|
||||||
|
|
||||||
|
@ -5,8 +5,8 @@ use crate::{
|
|||||||
node::{
|
node::{
|
||||||
BinOp, BinOpType, Block, Br, BrIf, BrTable, Call, CallIndirect, CmpOp, CmpOpType,
|
BinOp, BinOpType, Block, Br, BrIf, BrTable, Call, CallIndirect, CmpOp, CmpOpType,
|
||||||
Expression, FuncData, GetGlobal, GetLocal, If, LabelType, LoadAt, LoadType, MemoryGrow,
|
Expression, FuncData, GetGlobal, GetLocal, If, LabelType, LoadAt, LoadType, MemoryGrow,
|
||||||
MemorySize, Select, SetGlobal, SetLocal, Statement, StoreAt, StoreType, Terminator, UnOp,
|
MemoryCopy, MemoryFill, MemorySize, Select, SetGlobal, SetLocal, Statement, StoreAt,
|
||||||
UnOpType, Value,
|
StoreType, Terminator, UnOp, UnOpType, Value,
|
||||||
},
|
},
|
||||||
stack::{ReadType, Stack},
|
stack::{ReadType, Stack},
|
||||||
};
|
};
|
||||||
@ -609,6 +609,29 @@ impl<'a> Factory<'a> {
|
|||||||
self.target.leak_memory_write(memory);
|
self.target.leak_memory_write(memory);
|
||||||
self.target.code.push(data);
|
self.target.code.push(data);
|
||||||
}
|
}
|
||||||
|
Operator::MemoryCopy { src, dst } => {
|
||||||
|
let size = self.target.stack.pop().into();
|
||||||
|
|
||||||
|
let data = Statement::MemoryCopy(MemoryCopy {
|
||||||
|
dst,
|
||||||
|
src,
|
||||||
|
size,
|
||||||
|
});
|
||||||
|
|
||||||
|
self.target.code.push(data);
|
||||||
|
}
|
||||||
|
Operator::MemoryFill { mem } => {
|
||||||
|
let n = self.target.stack.pop().into();
|
||||||
|
let value = self.target.stack.pop().into();
|
||||||
|
|
||||||
|
let data = Statement::MemoryFill(MemoryFill {
|
||||||
|
mem,
|
||||||
|
n,
|
||||||
|
value,
|
||||||
|
});
|
||||||
|
|
||||||
|
self.target.code.push(data);
|
||||||
|
}
|
||||||
Operator::I32Const { value } => self.target.push_constant(value),
|
Operator::I32Const { value } => self.target.push_constant(value),
|
||||||
Operator::I64Const { value } => self.target.push_constant(value),
|
Operator::I64Const { value } => self.target.push_constant(value),
|
||||||
Operator::F32Const { value } => self.target.push_constant(value.bits()),
|
Operator::F32Const { value } => self.target.push_constant(value.bits()),
|
||||||
|
@ -1108,6 +1108,48 @@ impl MemoryGrow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct MemoryCopy {
|
||||||
|
pub(crate) dst: u32,
|
||||||
|
pub(crate) src: u32,
|
||||||
|
pub(crate) size: Box<Expression>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemoryCopy {
|
||||||
|
#[must_use]
|
||||||
|
pub fn dst(&self) -> u32 {
|
||||||
|
self.dst
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn src(&self) -> u32 {
|
||||||
|
self.src
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn size(&self) -> &Expression {
|
||||||
|
&self.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MemoryFill {
|
||||||
|
pub(crate) mem: u32,
|
||||||
|
pub(crate) value: Box<Expression>,
|
||||||
|
pub(crate) n: Box<Expression>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemoryFill {
|
||||||
|
#[must_use]
|
||||||
|
pub fn mem(&self) -> u32 {
|
||||||
|
self.mem
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn value(&self) -> &Expression {
|
||||||
|
&self.value
|
||||||
|
}
|
||||||
|
#[must_use]
|
||||||
|
pub fn n(&self) -> &Expression {
|
||||||
|
&self.n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub enum Statement {
|
pub enum Statement {
|
||||||
Block(Block),
|
Block(Block),
|
||||||
BrIf(BrIf),
|
BrIf(BrIf),
|
||||||
@ -1119,6 +1161,8 @@ pub enum Statement {
|
|||||||
SetGlobal(SetGlobal),
|
SetGlobal(SetGlobal),
|
||||||
StoreAt(StoreAt),
|
StoreAt(StoreAt),
|
||||||
MemoryGrow(MemoryGrow),
|
MemoryGrow(MemoryGrow),
|
||||||
|
MemoryCopy(MemoryCopy),
|
||||||
|
MemoryFill(MemoryFill)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FuncData {
|
pub struct FuncData {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::node::{
|
use crate::node::{
|
||||||
BinOp, Block, Br, BrIf, BrTable, Call, CallIndirect, CmpOp, Expression, FuncData, GetGlobal,
|
BinOp, Block, Br, BrIf, BrTable, Call, CallIndirect, CmpOp, Expression, FuncData, GetGlobal,
|
||||||
GetLocal, GetTemporary, If, LoadAt, MemoryGrow, MemorySize, Select, SetGlobal, SetLocal,
|
GetLocal, GetTemporary, If, LoadAt, MemoryGrow, MemorySize, MemoryCopy, MemoryFill, Select, SetGlobal, SetLocal,
|
||||||
SetTemporary, Statement, StoreAt, Terminator, UnOp, Value,
|
SetTemporary, Statement, StoreAt, Terminator, UnOp, Value,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -55,6 +55,10 @@ pub trait Visitor {
|
|||||||
|
|
||||||
fn visit_memory_grow(&mut self, _: &MemoryGrow) {}
|
fn visit_memory_grow(&mut self, _: &MemoryGrow) {}
|
||||||
|
|
||||||
|
fn visit_memory_copy(&mut self, _: &MemoryCopy) {}
|
||||||
|
|
||||||
|
fn visit_memory_fill(&mut self, _: &MemoryFill) {}
|
||||||
|
|
||||||
fn visit_statement(&mut self, _: &Statement) {}
|
fn visit_statement(&mut self, _: &Statement) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +108,23 @@ impl<T: Visitor> Driver<T> for MemorySize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Visitor> Driver<T> for MemoryCopy {
|
||||||
|
fn accept(&self, visitor: &mut T) {
|
||||||
|
self.size().accept(visitor);
|
||||||
|
|
||||||
|
visitor.visit_memory_copy(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Visitor> Driver<T> for MemoryFill {
|
||||||
|
fn accept(&self, visitor: &mut T) {
|
||||||
|
self.value().accept(visitor);
|
||||||
|
self.n().accept(visitor);
|
||||||
|
|
||||||
|
visitor.visit_memory_fill(self);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T: Visitor> Driver<T> for Value {
|
impl<T: Visitor> Driver<T> for Value {
|
||||||
fn accept(&self, visitor: &mut T) {
|
fn accept(&self, visitor: &mut T) {
|
||||||
visitor.visit_value(self);
|
visitor.visit_value(self);
|
||||||
@ -145,6 +166,8 @@ impl<T: Visitor> Driver<T> for Expression {
|
|||||||
Self::GetGlobal(v) => v.accept(visitor),
|
Self::GetGlobal(v) => v.accept(visitor),
|
||||||
Self::LoadAt(v) => v.accept(visitor),
|
Self::LoadAt(v) => v.accept(visitor),
|
||||||
Self::MemorySize(v) => v.accept(visitor),
|
Self::MemorySize(v) => v.accept(visitor),
|
||||||
|
Self::MemoryCopy(v) => v.accept(visitor),
|
||||||
|
Self::MemoryFill(v) => v.accept(visitor),
|
||||||
Self::Value(v) => v.accept(visitor),
|
Self::Value(v) => v.accept(visitor),
|
||||||
Self::UnOp(v) => v.accept(visitor),
|
Self::UnOp(v) => v.accept(visitor),
|
||||||
Self::BinOp(v) => v.accept(visitor),
|
Self::BinOp(v) => v.accept(visitor),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user