Skip to content

Commit e2cee5e

Browse files
committed
save
1 parent 1475942 commit e2cee5e

File tree

11 files changed

+2575
-1116
lines changed

11 files changed

+2575
-1116
lines changed

internal/vm/gen/main.go

Lines changed: 643 additions & 0 deletions
Large diffs are not rendered by default.

internal/vm/inst_arithmetic.go

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
// Arithmetic opcode handlers: ADD, MUL, SUB, DIV, SDIV, MOD, SMOD, ADDMOD, MULMOD, EXP, SIGNEXTEND, KECCAK256.
2+
package vm
3+
4+
import (
5+
"github.com/Giulio2002/gevm/internal/keccak"
6+
"github.com/Giulio2002/gevm/internal/primitives"
7+
)
8+
9+
// opAdd — BinaryOp body. s.top already decremented.
10+
func opAdd(interp *Interpreter) {
11+
s := interp.Stack
12+
primitives.AddTo(&s.data[s.top-1], &s.data[s.top], &s.data[s.top-1])
13+
}
14+
15+
// opMul — BinaryOp body.
16+
func opMul(interp *Interpreter) {
17+
s := interp.Stack
18+
a := s.data[s.top]
19+
top := &s.data[s.top-1]
20+
*top = a.Mul(*top)
21+
}
22+
23+
// opSub — BinaryOp body.
24+
func opSub(interp *Interpreter) {
25+
s := interp.Stack
26+
primitives.SubTo(&s.data[s.top-1], &s.data[s.top], &s.data[s.top-1])
27+
}
28+
29+
// opDiv — BinaryOp body.
30+
func opDiv(interp *Interpreter) {
31+
s := interp.Stack
32+
a := s.data[s.top]
33+
top := &s.data[s.top-1]
34+
if !primitives.IsZeroPtr(top) {
35+
*top = a.Div(*top)
36+
}
37+
}
38+
39+
// opSdiv — BinaryOp body.
40+
func opSdiv(interp *Interpreter) {
41+
s := interp.Stack
42+
a := s.data[s.top]
43+
top := &s.data[s.top-1]
44+
*top = primitives.SDiv(a, *top)
45+
}
46+
47+
// opMod — BinaryOp body.
48+
func opMod(interp *Interpreter) {
49+
s := interp.Stack
50+
a := s.data[s.top]
51+
top := &s.data[s.top-1]
52+
if !primitives.IsZeroPtr(top) {
53+
*top = a.Mod(*top)
54+
}
55+
}
56+
57+
// opSmod — BinaryOp body.
58+
func opSmod(interp *Interpreter) {
59+
s := interp.Stack
60+
a := s.data[s.top]
61+
top := &s.data[s.top-1]
62+
*top = primitives.SMod(a, *top)
63+
}
64+
65+
// opAddmod — TernaryOp body. s.top already decremented by 2.
66+
func opAddmod(interp *Interpreter) {
67+
s := interp.Stack
68+
a := s.data[s.top+1]
69+
b := s.data[s.top]
70+
top := &s.data[s.top-1]
71+
*top = a.AddMod(b, *top)
72+
}
73+
74+
// opMulmod — TernaryOp body. s.top already decremented by 2.
75+
func opMulmod(interp *Interpreter) {
76+
s := interp.Stack
77+
a := s.data[s.top+1]
78+
b := s.data[s.top]
79+
top := &s.data[s.top-1]
80+
*top = a.MulMod(b, *top)
81+
}
82+
83+
// opSignextend — BinaryOp body.
84+
func opSignextend(interp *Interpreter) {
85+
s := interp.Stack
86+
ext := s.data[s.top]
87+
top := &s.data[s.top-1]
88+
*top = primitives.SignExtend(ext, *top)
89+
}
90+
91+
// opExp — Custom flush handler. Full body after gas flush.
92+
// EXP has static gas (GasHigh) charged by generator. This handles stack + dynamic gas.
93+
func opExp(interp *Interpreter) {
94+
s := interp.Stack
95+
if s.top < 2 {
96+
interp.HaltUnderflow()
97+
return
98+
}
99+
s.top--
100+
base := s.data[s.top]
101+
top := &s.data[s.top-1]
102+
cost := interp.GasParams.ExpCost(*top)
103+
if !interp.Gas.RecordCost(cost) {
104+
interp.HaltOOG()
105+
return
106+
}
107+
*top = base.Exp(*top)
108+
}
109+
110+
// opKeccak256 — Custom flush handler. Full body after gas flush.
111+
func opKeccak256(interp *Interpreter) {
112+
s := interp.Stack
113+
if s.top < 2 {
114+
interp.HaltUnderflow()
115+
return
116+
}
117+
s.top -= 2
118+
offsetVal := s.data[s.top+1]
119+
lenVal := s.data[s.top]
120+
length, ok := interp.asUsizeOrFail(lenVal)
121+
if !ok {
122+
return
123+
}
124+
cost := interp.GasParams.Keccak256Cost(uint64(length))
125+
if !interp.Gas.RecordCost(cost) {
126+
interp.HaltOOG()
127+
return
128+
}
129+
var hash primitives.B256
130+
if length != 0 {
131+
offset, ok := interp.asUsizeOrFail(offsetVal)
132+
if !ok {
133+
return
134+
}
135+
if !interp.ResizeMemory(offset, length) {
136+
return
137+
}
138+
data := interp.Memory.Slice(offset, length)
139+
hash = primitives.B256(keccak.Sum256(data))
140+
} else {
141+
hash = primitives.KeccakEmpty
142+
}
143+
s.data[s.top] = hash.ToU256()
144+
s.top++
145+
}

internal/vm/inst_bitwise.go

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
package vm
2+
3+
// Comparison and bitwise opcode handlers.
4+
5+
import "github.com/Giulio2002/gevm/internal/primitives"
6+
7+
// opLt — BinaryOp body.
8+
func opLt(interp *Interpreter) {
9+
s := interp.Stack
10+
if primitives.LtPtr(&s.data[s.top], &s.data[s.top-1]) {
11+
s.data[s.top-1] = primitives.U256One
12+
} else {
13+
s.data[s.top-1] = primitives.U256Zero
14+
}
15+
}
16+
17+
// opGt — BinaryOp body.
18+
func opGt(interp *Interpreter) {
19+
s := interp.Stack
20+
if primitives.GtPtr(&s.data[s.top], &s.data[s.top-1]) {
21+
s.data[s.top-1] = primitives.U256One
22+
} else {
23+
s.data[s.top-1] = primitives.U256Zero
24+
}
25+
}
26+
27+
// opSlt — BinaryOp body.
28+
func opSlt(interp *Interpreter) {
29+
s := interp.Stack
30+
a := &s.data[s.top]
31+
b := &s.data[s.top-1]
32+
aNeg := a[3] >> 63
33+
bNeg := b[3] >> 63
34+
var lt bool
35+
if aNeg != bNeg {
36+
lt = aNeg > bNeg
37+
} else {
38+
lt = primitives.LtPtr(a, b)
39+
}
40+
if lt {
41+
s.data[s.top-1] = primitives.U256One
42+
} else {
43+
s.data[s.top-1] = primitives.U256Zero
44+
}
45+
}
46+
47+
// opSgt — BinaryOp body.
48+
func opSgt(interp *Interpreter) {
49+
s := interp.Stack
50+
a := &s.data[s.top]
51+
b := &s.data[s.top-1]
52+
aNeg := a[3] >> 63
53+
bNeg := b[3] >> 63
54+
var gt bool
55+
if aNeg != bNeg {
56+
gt = bNeg > aNeg
57+
} else {
58+
gt = primitives.GtPtr(a, b)
59+
}
60+
if gt {
61+
s.data[s.top-1] = primitives.U256One
62+
} else {
63+
s.data[s.top-1] = primitives.U256Zero
64+
}
65+
}
66+
67+
// opEq — BinaryOp body.
68+
func opEq(interp *Interpreter) {
69+
s := interp.Stack
70+
if primitives.EqPtr(&s.data[s.top], &s.data[s.top-1]) {
71+
s.data[s.top-1] = primitives.U256One
72+
} else {
73+
s.data[s.top-1] = primitives.U256Zero
74+
}
75+
}
76+
77+
// opIszero — UnaryOp body.
78+
func opIszero(interp *Interpreter) {
79+
s := interp.Stack
80+
if primitives.IsZeroPtr(&s.data[s.top-1]) {
81+
s.data[s.top-1] = primitives.U256One
82+
} else {
83+
s.data[s.top-1] = primitives.U256Zero
84+
}
85+
}
86+
87+
// opAnd — BinaryOp body.
88+
func opAnd(interp *Interpreter) {
89+
s := interp.Stack
90+
primitives.AndTo(&s.data[s.top-1], &s.data[s.top], &s.data[s.top-1])
91+
}
92+
93+
// opOr — BinaryOp body.
94+
func opOr(interp *Interpreter) {
95+
s := interp.Stack
96+
primitives.OrTo(&s.data[s.top-1], &s.data[s.top], &s.data[s.top-1])
97+
}
98+
99+
// opXor — BinaryOp body.
100+
func opXor(interp *Interpreter) {
101+
s := interp.Stack
102+
primitives.XorTo(&s.data[s.top-1], &s.data[s.top], &s.data[s.top-1])
103+
}
104+
105+
// opNot — UnaryOp body.
106+
func opNot(interp *Interpreter) {
107+
s := interp.Stack
108+
primitives.NotTo(&s.data[s.top-1], &s.data[s.top-1])
109+
}
110+
111+
// opByte — BinaryOp body.
112+
func opByte(interp *Interpreter) {
113+
s := interp.Stack
114+
a := s.data[s.top]
115+
top := &s.data[s.top-1]
116+
idx := a.AsUsizeSaturated()
117+
if idx < 32 {
118+
*top = primitives.U256From(uint64(top.ByteBE(uint(idx))))
119+
} else {
120+
*top = primitives.U256Zero
121+
}
122+
}
123+
124+
// opShl — BinaryOp body. Fork gate (Constantinople) handled by generator.
125+
func opShl(interp *Interpreter) {
126+
s := interp.Stack
127+
shift := s.data[s.top]
128+
top := &s.data[s.top-1]
129+
sa := shift.AsUsizeSaturated()
130+
if sa < 256 {
131+
*top = top.Shl(uint(sa))
132+
} else {
133+
*top = primitives.U256Zero
134+
}
135+
}
136+
137+
// opShr — BinaryOp body. Fork gate (Constantinople) handled by generator.
138+
func opShr(interp *Interpreter) {
139+
s := interp.Stack
140+
shift := s.data[s.top]
141+
top := &s.data[s.top-1]
142+
sa := shift.AsUsizeSaturated()
143+
if sa < 256 {
144+
*top = top.Shr(uint(sa))
145+
} else {
146+
*top = primitives.U256Zero
147+
}
148+
}
149+
150+
// opSar — BinaryOp body. Fork gate (Constantinople) handled by generator.
151+
func opSar(interp *Interpreter) {
152+
s := interp.Stack
153+
shift := s.data[s.top]
154+
top := &s.data[s.top-1]
155+
sa := shift.AsUsizeSaturated()
156+
if sa < 256 {
157+
*top = top.Sar(uint(sa))
158+
} else if top.Bit(255) {
159+
*top = primitives.U256Max
160+
} else {
161+
*top = primitives.U256Zero
162+
}
163+
}
164+
165+
// opClz — UnaryOp body. Fork gate (Osaka) handled by generator.
166+
func opClz(interp *Interpreter) {
167+
s := interp.Stack
168+
top := &s.data[s.top-1]
169+
*top = primitives.U256From(uint64(top.LeadingZeros()))
170+
}

0 commit comments

Comments
 (0)