sevm
Version:
A Symbolic Ethereum Virtual Machine (EVM) bytecode decompiler & analyzer library & CLI
89 lines (73 loc) • 2.04 kB
text/typescript
import type { State } from '../state';
import { type Inst, type Expr, type IInst, Tag } from '.';
/**
* Represents a jump from one `State` to another from the given `pc`.
*/
export class Branch {
constructor(readonly pc: number, public state: State<Inst, Expr>) { }
static make(pc: number, state: State<Inst, Expr>) {
return new Branch(pc, state.clone());
}
}
export class Jump implements IInst {
readonly name = 'Jump';
constructor(readonly offset: Expr, readonly destBranch: Branch, readonly pushStateId: number) { }
eval() {
return this;
}
next() {
return [this.destBranch];
}
}
export class Jumpi implements IInst {
readonly name = 'Jumpi';
readonly evalCond: Expr;
constructor(
readonly cond: Expr,
readonly offset: Expr,
readonly fallBranch: Branch,
readonly destBranch: Branch,
readonly pushStateId: number,
) {
this.evalCond = cond.eval();
}
eval() {
return new Jumpi(this.cond.eval(), this.offset, this.fallBranch, this.destBranch, this.pushStateId);
}
next() {
return this.evalCond.isVal()
? this.evalCond.val === 0n
? [this.fallBranch]
: [this.destBranch]
: [this.destBranch, this.fallBranch];
}
}
export class JumpDest implements IInst {
readonly name = 'JumpDest';
constructor(readonly fallBranch: Branch) { }
eval() {
return this;
}
next() {
return [this.fallBranch];
}
}
export class Sig extends Tag {
readonly tag = 'Sig';
constructor(readonly selector: string, readonly positive = true) {
super(0, 1);
}
eval(): Expr {
return this;
}
}
export class SigCase implements IInst {
readonly name = 'SigCase';
constructor(readonly condition: Sig, readonly offset: Expr, readonly fallBranch: Branch) { }
eval() {
return this;
}
next(): Branch[] {
return [this.fallBranch];
}
}