Skip to content

Commit

Permalink
more PVM instructions (#47)
Browse files Browse the repository at this point in the history
* jump

* more instructions

* fix lint
  • Loading branch information
xlc authored Jul 30, 2024
1 parent 52ca58a commit cf9bab1
Show file tree
Hide file tree
Showing 12 changed files with 555 additions and 63 deletions.
1 change: 1 addition & 0 deletions .swiftlint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ disabled_rules:
- opening_brace
- cyclomatic_complexity
- blanket_disable_command
- type_body_length

excluded:
- "**/.build"
Expand Down
6 changes: 3 additions & 3 deletions JAMTests/Tests/JAMTests/PVMTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,15 +96,15 @@ struct PVMTests {

withKnownIssue("not yet implemented", isIntermittent: true) {
#expect(exitReason2 == testCase.expectedStatus)
#expect(vmState.registers == Registers(testCase.expectedRegs))
#expect(vmState.getRegisters() == Registers(testCase.expectedRegs))
#expect(vmState.pc == testCase.expectedPC)
for chunk in testCase.expectedMemory {
for (offset, byte) in chunk.contents.enumerated() {
let value = try vmState.memory.read(chunk.address + UInt32(offset))
let value = try vmState.getMemory().read(address: chunk.address + UInt32(offset))
#expect(value == byte)
}
}
#expect(vmState.gas == testCase.expectedGas)
#expect(vmState.getGas() == testCase.expectedGas)
}
}
}
16 changes: 14 additions & 2 deletions PolkaVM/Sources/PolkaVM/Engine.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import Foundation

public class Engine {
public enum Constants {
public static let exitAddress: UInt32 = 0xFFFF_0000
}

public init() {}

public func execute(program: ProgramCode, state: VMState) -> ExitReason {
while true {
guard state.gas > 0 else {
guard state.getGas() > 0 else {
return .outOfGas
}
if let exitReason = step(program: program, state: state) {
Expand All @@ -30,6 +34,14 @@ public class Engine {
return .panic(.invalidInstruction)
}

return inst.execute(state: state, skip: skip)
let res = inst.execute(state: state, skip: skip)

if state.pc == Constants.exitAddress {
// TODO: GP only defined this for `djump` but not `branch`
// so need to confirm this is correct
return .halt
}

return res
}
}
20 changes: 14 additions & 6 deletions PolkaVM/Sources/PolkaVM/Instruction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import Foundation
public protocol Instruction {
static var opcode: UInt8 { get }

init?(data: Data)
init(data: Data) throws

func execute(state: VMState, skip: UInt32) -> ExitReason?
func executeImpl(state: VMState) -> ExitReason?
func executeImpl(state: VMState) throws -> ExitReason?

func gasCost() -> UInt64
func updatePC(state: VMState, skip: UInt32)
Expand All @@ -15,11 +15,19 @@ public protocol Instruction {
extension Instruction {
public func execute(state: VMState, skip: UInt32) -> ExitReason? {
state.consumeGas(gasCost())
let res = executeImpl(state: state)
if res == nil {
state.updatePC(state.pc + skip + 1)
do {
let res = try executeImpl(state: state)
if res == nil {
updatePC(state: state, skip: skip)
}
return res
} catch let e as Memory.Error {
return .pageFault(e.address)
} catch {
// other unknown errors
// TODO: log details
return .panic(.trap)
}
return res
}

public func gasCost() -> UInt64 {
Expand Down
14 changes: 13 additions & 1 deletion PolkaVM/Sources/PolkaVM/InstructionTable.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Foundation
import Utils

public class InstructionTable {
public static let table: [Instruction.Type?] = {
Expand All @@ -9,6 +10,16 @@ public class InstructionTable {
Instructions.StoreImmU8.self,
Instructions.StoreImmU16.self,
Instructions.StoreImmU32.self,
Instructions.JumpInd.self,
Instructions.LoadImm.self,
Instructions.LoadU8.self,
Instructions.LoadI8.self,
Instructions.LoadU16.self,
Instructions.LoadI16.self,
Instructions.LoadU32.self,
Instructions.StoreU8.self,
Instructions.StoreU16.self,
Instructions.StoreU32.self,
]
var table: [Instruction.Type?] = Array(repeating: nil, count: 256)
for i in 0 ..< insts.count {
Expand All @@ -25,6 +36,7 @@ public class InstructionTable {
guard let instType = table[Int(opcode)] else {
return nil
}
return instType.init(data: data)
// TODO: log errors
return try? instType.init(data: data[relative: 1...])
}
}
Loading

0 comments on commit cf9bab1

Please sign in to comment.