mirror of
https://github.com/voltrevo/ValueScript.git
synced 2026-04-18 03:00:27 -04:00
visit_registers_mut_rev
This commit is contained in:
@@ -2,7 +2,9 @@ use std::hash::{Hash as HashTrait, Hasher};
|
||||
|
||||
use num_bigint::BigInt;
|
||||
|
||||
use crate::{assembler::ValueType, expression_compiler::CompiledExpression};
|
||||
use crate::{
|
||||
assembler::ValueType, expression_compiler::CompiledExpression, instruction::RegisterVisitMut,
|
||||
};
|
||||
|
||||
pub use crate::instruction::{Instruction, InstructionFieldMut};
|
||||
|
||||
@@ -420,6 +422,37 @@ impl Value {
|
||||
Value::Builtin(..) => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_registers_mut_rev<F>(&mut self, visit: &mut F)
|
||||
where
|
||||
F: FnMut(RegisterVisitMut) -> (),
|
||||
{
|
||||
match self {
|
||||
Value::Array(array) => {
|
||||
for item in &mut array.values.iter_mut().rev() {
|
||||
item.visit_registers_mut_rev(visit);
|
||||
}
|
||||
}
|
||||
Value::Object(object) => {
|
||||
for (k, v) in &mut object.properties.iter_mut().rev() {
|
||||
v.visit_registers_mut_rev(visit);
|
||||
k.visit_registers_mut_rev(visit);
|
||||
}
|
||||
}
|
||||
Value::Void => {}
|
||||
Value::Undefined => {}
|
||||
Value::Null => {}
|
||||
Value::Bool(..) => {}
|
||||
Value::Number(..) => {}
|
||||
Value::BigInt(..) => {}
|
||||
Value::String(..) => {}
|
||||
Value::Register(register) => {
|
||||
visit(RegisterVisitMut::read(register));
|
||||
}
|
||||
Value::Pointer(..) => {}
|
||||
Value::Builtin(..) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Value {
|
||||
|
||||
@@ -69,6 +69,38 @@ pub enum InstructionFieldMut<'a> {
|
||||
LabelRef(&'a mut LabelRef),
|
||||
}
|
||||
|
||||
pub struct RegisterVisitMut<'a> {
|
||||
pub register: &'a mut Register,
|
||||
pub read: bool,
|
||||
pub write: bool,
|
||||
}
|
||||
|
||||
impl<'a> RegisterVisitMut<'a> {
|
||||
pub fn read(register: &'a mut Register) -> Self {
|
||||
RegisterVisitMut {
|
||||
register,
|
||||
read: true,
|
||||
write: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write(register: &'a mut Register) -> Self {
|
||||
RegisterVisitMut {
|
||||
register,
|
||||
read: false,
|
||||
write: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_and_write(register: &'a mut Register) -> Self {
|
||||
RegisterVisitMut {
|
||||
register,
|
||||
read: true,
|
||||
write: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Instruction {
|
||||
pub fn visit_fields_mut<F>(&mut self, visit: &mut F)
|
||||
where
|
||||
@@ -187,6 +219,120 @@ impl Instruction {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_registers_mut_rev<F>(&mut self, visit: &mut F)
|
||||
where
|
||||
F: FnMut(RegisterVisitMut) -> (),
|
||||
{
|
||||
use Instruction::*;
|
||||
|
||||
match self {
|
||||
End => {}
|
||||
Mov(arg, dst)
|
||||
| OpNot(arg, dst)
|
||||
| OpBitNot(arg, dst)
|
||||
| TypeOf(arg, dst)
|
||||
| UnaryPlus(arg, dst)
|
||||
| UnaryMinus(arg, dst)
|
||||
| Import(arg, dst)
|
||||
| ImportStar(arg, dst)
|
||||
| Cat(arg, dst)
|
||||
| Yield(arg, dst)
|
||||
| YieldStar(arg, dst) => {
|
||||
visit(RegisterVisitMut::write(dst));
|
||||
arg.visit_registers_mut_rev(visit);
|
||||
}
|
||||
|
||||
OpInc(arg) | OpDec(arg) => {
|
||||
visit(RegisterVisitMut::read_and_write(arg));
|
||||
}
|
||||
|
||||
OpPlus(left, right, dst)
|
||||
| OpMinus(left, right, dst)
|
||||
| OpMul(left, right, dst)
|
||||
| OpDiv(left, right, dst)
|
||||
| OpMod(left, right, dst)
|
||||
| OpExp(left, right, dst)
|
||||
| OpEq(left, right, dst)
|
||||
| OpNe(left, right, dst)
|
||||
| OpTripleEq(left, right, dst)
|
||||
| OpTripleNe(left, right, dst)
|
||||
| OpAnd(left, right, dst)
|
||||
| OpOr(left, right, dst)
|
||||
| OpLess(left, right, dst)
|
||||
| OpLessEq(left, right, dst)
|
||||
| OpGreater(left, right, dst)
|
||||
| OpGreaterEq(left, right, dst)
|
||||
| OpNullishCoalesce(left, right, dst)
|
||||
| OpOptionalChain(left, right, dst)
|
||||
| OpBitAnd(left, right, dst)
|
||||
| OpBitOr(left, right, dst)
|
||||
| OpBitXor(left, right, dst)
|
||||
| OpLeftShift(left, right, dst)
|
||||
| OpRightShift(left, right, dst)
|
||||
| OpRightShiftUnsigned(left, right, dst)
|
||||
| InstanceOf(left, right, dst)
|
||||
| In(left, right, dst)
|
||||
| Call(left, right, dst)
|
||||
| Bind(left, right, dst)
|
||||
| Sub(left, right, dst)
|
||||
| SubMov(left, right, dst)
|
||||
| New(left, right, dst) => {
|
||||
visit(RegisterVisitMut::write(dst));
|
||||
right.visit_registers_mut_rev(visit);
|
||||
left.visit_registers_mut_rev(visit);
|
||||
}
|
||||
|
||||
Apply(fn_, this, args, dst) => {
|
||||
visit(RegisterVisitMut::write(dst));
|
||||
args.visit_registers_mut_rev(visit);
|
||||
visit(RegisterVisitMut::read_and_write(this));
|
||||
fn_.visit_registers_mut_rev(visit);
|
||||
}
|
||||
|
||||
ConstSubCall(a1, a2, a3, dst) => {
|
||||
visit(RegisterVisitMut::write(dst));
|
||||
a3.visit_registers_mut_rev(visit);
|
||||
a2.visit_registers_mut_rev(visit);
|
||||
a1.visit_registers_mut_rev(visit);
|
||||
}
|
||||
|
||||
SubCall(this, key, args, dst) | ThisSubCall(this, key, args, dst) => {
|
||||
visit(RegisterVisitMut::write(dst));
|
||||
args.visit_registers_mut_rev(visit);
|
||||
key.visit_registers_mut_rev(visit);
|
||||
visit(RegisterVisitMut::read_and_write(this));
|
||||
}
|
||||
|
||||
Jmp(_label_ref) => {}
|
||||
|
||||
JmpIf(cond, _label_ref) => {
|
||||
cond.visit_registers_mut_rev(visit);
|
||||
}
|
||||
|
||||
Throw(ex) => {
|
||||
ex.visit_registers_mut_rev(visit);
|
||||
}
|
||||
|
||||
SetCatch(_label_ref, _dst) => {
|
||||
// TODO: Does the write to dst need to be accounted for?
|
||||
// (It doesn't occur 'here')
|
||||
}
|
||||
|
||||
Next(iterable, dst) => {
|
||||
visit(RegisterVisitMut::write(dst));
|
||||
visit(RegisterVisitMut::read_and_write(iterable));
|
||||
}
|
||||
|
||||
UnpackIterRes(iter_res, value_dst, done_dst) => {
|
||||
visit(RegisterVisitMut::write(done_dst));
|
||||
visit(RegisterVisitMut::write(value_dst));
|
||||
visit(RegisterVisitMut::read_and_write(iter_res));
|
||||
}
|
||||
|
||||
UnsetCatch | RequireMutableThis => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn byte(&self) -> InstructionByte {
|
||||
use Instruction::*;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user