Skip to content

Commit

Permalink
refactor(gnovm): handle assignment operations in preprocess
Browse files Browse the repository at this point in the history
  • Loading branch information
thehowl committed Feb 2, 2024
1 parent 12b4b45 commit 4cf1e2e
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 343 deletions.
52 changes: 4 additions & 48 deletions gnovm/pkg/gnolang/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -915,21 +915,10 @@ const (
OpMaybeNativeType Op = 0x79 // maybenative{X}

/* Statement operators */
OpAssign Op = 0x80 // Lhs = Rhs
OpAddAssign Op = 0x81 // Lhs += Rhs
OpSubAssign Op = 0x82 // Lhs -= Rhs
OpMulAssign Op = 0x83 // Lhs *= Rhs
OpQuoAssign Op = 0x84 // Lhs /= Rhs
OpRemAssign Op = 0x85 // Lhs %= Rhs
OpBandAssign Op = 0x86 // Lhs &= Rhs
OpBandnAssign Op = 0x87 // Lhs &^= Rhs
OpBorAssign Op = 0x88 // Lhs |= Rhs
OpXorAssign Op = 0x89 // Lhs ^= Rhs
OpShlAssign Op = 0x8A // Lhs <<= Rhs
OpShrAssign Op = 0x8B // Lhs >>= Rhs
OpDefine Op = 0x8C // X... := Y...
OpInc Op = 0x8D // X++
OpDec Op = 0x8E // X--
OpAssign Op = 0x80 // Lhs = Rhs
OpDefine Op = 0x81 // X... := Y...
OpInc Op = 0x82 // X++
OpDec Op = 0x83 // X--

/* Decl operators */
OpValueDecl Op = 0x90 // var/const ...
Expand Down Expand Up @@ -1335,39 +1324,6 @@ func (m *Machine) Run() {
case OpAssign:
m.incrCPU(OpCPUAssign)
m.doOpAssign()
case OpAddAssign:
m.incrCPU(OpCPUAddAssign)
m.doOpAddAssign()
case OpSubAssign:
m.incrCPU(OpCPUSubAssign)
m.doOpSubAssign()
case OpMulAssign:
m.incrCPU(OpCPUMulAssign)
m.doOpMulAssign()
case OpQuoAssign:
m.incrCPU(OpCPUQuoAssign)
m.doOpQuoAssign()
case OpRemAssign:
m.incrCPU(OpCPURemAssign)
m.doOpRemAssign()
case OpBandAssign:
m.incrCPU(OpCPUBandAssign)
m.doOpBandAssign()
case OpBandnAssign:
m.incrCPU(OpCPUBandnAssign)
m.doOpBandnAssign()
case OpBorAssign:
m.incrCPU(OpCPUBorAssign)
m.doOpBorAssign()
case OpXorAssign:
m.incrCPU(OpCPUXorAssign)
m.doOpXorAssign()
case OpShlAssign:
m.incrCPU(OpCPUShlAssign)
m.doOpShlAssign()
case OpShrAssign:
m.incrCPU(OpCPUShrAssign)
m.doOpShrAssign()
case OpDefine:
m.incrCPU(OpCPUDefine)
m.doOpDefine()
Expand Down
47 changes: 47 additions & 0 deletions gnovm/pkg/gnolang/nodes.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ const (
SHR // >>
BAND_NOT // &^

// NOTE: keep following combined assignment operations in sync with
// min/maxAssignmentOperationed

ADD_ASSIGN // +=
SUB_ASSIGN // -=
MUL_ASSIGN // *=
Expand Down Expand Up @@ -108,6 +111,50 @@ const (
VAR
)

const (
minAssignmentOperation = ADD_ASSIGN
maxAssignmentOperation = BAND_NOT_ASSIGN
)

func (w Word) isAssignmentOperation() bool {
return w >= minAssignmentOperation && w <= maxAssignmentOperation
}

// convertAssignemntOperation converts w to its equivalent binary operation in
// the case of an assignemnt operation; for instance,
// ADD_ASSIGN.convertAssignmentOperation() returns ADD.
//
// If w is not an assignment operation, ILLEGAL is returned.
func (w Word) convertAssignmentOperation() Word {
// XXX: is this inlined? if not, would lookup table make it inlined / better?
switch w {
case ADD_ASSIGN:
return ADD
case SUB_ASSIGN:
return SUB
case MUL_ASSIGN:
return MUL
case QUO_ASSIGN:
return QUO
case REM_ASSIGN:
return REM
case BAND_ASSIGN:
return BAND
case BOR_ASSIGN:
return BOR
case XOR_ASSIGN:
return XOR
case SHL_ASSIGN:
return SHL
case SHR_ASSIGN:
return SHR
case BAND_NOT_ASSIGN:
return BAND_NOT
default:
return ILLEGAL
}
}

type Name string

// ----------------------------------------
Expand Down
247 changes: 0 additions & 247 deletions gnovm/pkg/gnolang/op_assign.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,250 +44,3 @@ func (m *Machine) doOpAssign() {
lv.Assign2(m.Alloc, m.Store, m.Realm, rvs[i], true)
}
}

func (m *Machine) doOpAddAssign() {
s := m.PopStmt().(*AssignStmt)
rv := m.PopValue() // only one.
lv := m.PopAsPointer(s.Lhs[0])
if debug {
assertSameTypes(lv.TV.T, rv.T)
}

// XXX HACK (until value persistence impl'd)
if m.ReadOnly {
if oo, ok := lv.Base.(Object); ok {
if oo.GetIsReal() {
panic("readonly violation")
}
}
}
// add rv to lv.
addAssign(m.Alloc, lv.TV, rv)
if lv.Base != nil {
m.Realm.DidUpdate(lv.Base.(Object), nil, nil)
}
}

func (m *Machine) doOpSubAssign() {
s := m.PopStmt().(*AssignStmt)
rv := m.PopValue() // only one.
lv := m.PopAsPointer(s.Lhs[0])
if debug {
assertSameTypes(lv.TV.T, rv.T)
}

// XXX HACK (until value persistence impl'd)
if m.ReadOnly {
if oo, ok := lv.Base.(Object); ok {
if oo.GetIsReal() {
panic("readonly violation")
}
}
}
// sub rv from lv.
subAssign(lv.TV, rv)
if lv.Base != nil {
m.Realm.DidUpdate(lv.Base.(Object), nil, nil)
}
}

func (m *Machine) doOpMulAssign() {
s := m.PopStmt().(*AssignStmt)
rv := m.PopValue() // only one.
lv := m.PopAsPointer(s.Lhs[0])
if debug {
assertSameTypes(lv.TV.T, rv.T)
}

// XXX HACK (until value persistence impl'd)
if m.ReadOnly {
if oo, ok := lv.Base.(Object); ok {
if oo.GetIsReal() {
panic("readonly violation")
}
}
}
// lv *= rv
mulAssign(lv.TV, rv)
if lv.Base != nil {
m.Realm.DidUpdate(lv.Base.(Object), nil, nil)
}
}

func (m *Machine) doOpQuoAssign() {
s := m.PopStmt().(*AssignStmt)
rv := m.PopValue() // only one.
lv := m.PopAsPointer(s.Lhs[0])
if debug {
assertSameTypes(lv.TV.T, rv.T)
}

// XXX HACK (until value persistence impl'd)
if m.ReadOnly {
if oo, ok := lv.Base.(Object); ok {
if oo.GetIsReal() {
panic("readonly violation")
}
}
}
// lv /= rv
quoAssign(lv.TV, rv)
if lv.Base != nil {
m.Realm.DidUpdate(lv.Base.(Object), nil, nil)
}
}

func (m *Machine) doOpRemAssign() {
s := m.PopStmt().(*AssignStmt)
rv := m.PopValue() // only one.
lv := m.PopAsPointer(s.Lhs[0])
if debug {
assertSameTypes(lv.TV.T, rv.T)
}

// XXX HACK (until value persistence impl'd)
if m.ReadOnly {
if oo, ok := lv.Base.(Object); ok {
if oo.GetIsReal() {
panic("readonly violation")
}
}
}
// lv %= rv
remAssign(lv.TV, rv)
if lv.Base != nil {
m.Realm.DidUpdate(lv.Base.(Object), nil, nil)
}
}

func (m *Machine) doOpBandAssign() {
s := m.PopStmt().(*AssignStmt)
rv := m.PopValue() // only one.
lv := m.PopAsPointer(s.Lhs[0])
if debug {
assertSameTypes(lv.TV.T, rv.T)
}

// XXX HACK (until value persistence impl'd)
if m.ReadOnly {
if oo, ok := lv.Base.(Object); ok {
if oo.GetIsReal() {
panic("readonly violation")
}
}
}
// lv &= rv
bandAssign(lv.TV, rv)
if lv.Base != nil {
m.Realm.DidUpdate(lv.Base.(Object), nil, nil)
}
}

func (m *Machine) doOpBandnAssign() {
s := m.PopStmt().(*AssignStmt)
rv := m.PopValue() // only one.
lv := m.PopAsPointer(s.Lhs[0])
if debug {
assertSameTypes(lv.TV.T, rv.T)
}

// XXX HACK (until value persistence impl'd)
if m.ReadOnly {
if oo, ok := lv.Base.(Object); ok {
if oo.GetIsReal() {
panic("readonly violation")
}
}
}
// lv &^= rv
bandnAssign(lv.TV, rv)
if lv.Base != nil {
m.Realm.DidUpdate(lv.Base.(Object), nil, nil)
}
}

func (m *Machine) doOpBorAssign() {
s := m.PopStmt().(*AssignStmt)
rv := m.PopValue() // only one.
lv := m.PopAsPointer(s.Lhs[0])
if debug {
assertSameTypes(lv.TV.T, rv.T)
}

// XXX HACK (until value persistence impl'd)
if m.ReadOnly {
if oo, ok := lv.Base.(Object); ok {
if oo.GetIsReal() {
panic("readonly violation")
}
}
}
// lv |= rv
borAssign(lv.TV, rv)
if lv.Base != nil {
m.Realm.DidUpdate(lv.Base.(Object), nil, nil)
}
}

func (m *Machine) doOpXorAssign() {
s := m.PopStmt().(*AssignStmt)
rv := m.PopValue() // only one.
lv := m.PopAsPointer(s.Lhs[0])
if debug {
assertSameTypes(lv.TV.T, rv.T)
}

// XXX HACK (until value persistence impl'd)
if m.ReadOnly {
if oo, ok := lv.Base.(Object); ok {
if oo.GetIsReal() {
panic("readonly violation")
}
}
}
// lv ^= rv
xorAssign(lv.TV, rv)
if lv.Base != nil {
m.Realm.DidUpdate(lv.Base.(Object), nil, nil)
}
}

func (m *Machine) doOpShlAssign() {
s := m.PopStmt().(*AssignStmt)
rv := m.PopValue() // only one.
lv := m.PopAsPointer(s.Lhs[0])

// XXX HACK (until value persistence impl'd)
if m.ReadOnly {
if oo, ok := lv.Base.(Object); ok {
if oo.GetIsReal() {
panic("readonly violation")
}
}
}
// lv <<= rv
shlAssign(lv.TV, rv)
if lv.Base != nil {
m.Realm.DidUpdate(lv.Base.(Object), nil, nil)
}
}

func (m *Machine) doOpShrAssign() {
s := m.PopStmt().(*AssignStmt)
rv := m.PopValue() // only one.
lv := m.PopAsPointer(s.Lhs[0])

// XXX HACK (until value persistence impl'd)
if m.ReadOnly {
if oo, ok := lv.Base.(Object); ok {
if oo.GetIsReal() {
panic("readonly violation")
}
}
}
// lv >>= rv
shrAssign(lv.TV, rv)
if lv.Base != nil {
m.Realm.DidUpdate(lv.Base.(Object), nil, nil)
}
}
Loading

0 comments on commit 4cf1e2e

Please sign in to comment.