-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
176 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import Foundation | ||
|
||
public class Memory { | ||
public enum Error: Swift.Error { | ||
case pageFault | ||
case notWritable | ||
} | ||
|
||
private let pageMap: [(address: UInt32, length: UInt32, writable: Bool)] | ||
private var chunks: [(address: UInt32, data: Data)] | ||
|
||
public init(pageMap: [(address: UInt32, length: UInt32, writable: Bool)], chunks: [(address: UInt32, data: Data)]) { | ||
self.pageMap = pageMap | ||
self.chunks = chunks | ||
} | ||
|
||
public func read(_ address: UInt32) throws(Memory.Error) -> UInt8 { | ||
// TODO: optimize this | ||
// check for chunks | ||
for chunk in chunks { | ||
if chunk.address <= address, address < chunk.address + UInt32(chunk.data.count) { | ||
return chunk.data[Int(address - chunk.address)] | ||
} | ||
} | ||
// check for page map | ||
for page in pageMap { | ||
if page.address <= address, address < page.address + page.length { | ||
return 0 | ||
} | ||
} | ||
throw Error.pageFault | ||
} | ||
|
||
public func write(address: UInt32, value: UInt8) throws(Memory.Error) { | ||
// TODO: optimize this | ||
// check for chunks | ||
for i in 0 ..< chunks.count { | ||
var chunk = chunks[i] | ||
if chunk.address <= address, address < chunk.address + UInt32(chunk.data.count) { | ||
chunk.data[Int(address - chunk.address)] = value | ||
chunks[i] = chunk | ||
return | ||
} | ||
} | ||
// check for page map | ||
for page in pageMap { | ||
if page.address <= address, address < page.address + page.length { | ||
var newChunk = (address: address, data: Data(repeating: 0, count: Int(page.length))) | ||
newChunk.data[Int(address - page.address)] = value | ||
chunks.append(newChunk) | ||
return | ||
} | ||
} | ||
throw Error.notWritable | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import Foundation | ||
|
||
public class VMState { | ||
public let program: ProgramCode | ||
|
||
public private(set) var instructionCounter: UInt32 | ||
|
||
public private(set) var registers: ( | ||
UInt32, UInt32, UInt32, UInt32, UInt32, UInt32, UInt32, UInt32, UInt32, UInt32, UInt32, UInt32, UInt32 | ||
) // 13 registers | ||
public private(set) var gas: UInt64 | ||
public private(set) var memory: Data | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import Foundation | ||
import Testing | ||
import Utils | ||
|
||
@testable import PolkaVM | ||
|
||
struct ProgramTests { | ||
@Test func empty() { | ||
let blob = Data() | ||
#expect(throws: ProgramCode.Error.invalidJumpTableEntriesCount) { try ProgramCode(blob) } | ||
} | ||
|
||
@Test func invalidJumpTableEntriesCount() { | ||
let highValue = Data(UInt64(0x1000000).encode(method: .variableWidth)) | ||
let data = highValue + Data([0, 0]) | ||
#expect(throws: ProgramCode.Error.invalidJumpTableEntriesCount) { try ProgramCode(data) } | ||
} | ||
|
||
@Test func invalidJumpTableEncodeSize() { | ||
let data = Data([1, 0xFF, 0, 0]) | ||
#expect(throws: ProgramCode.Error.invalidJumpTableEncodeSize) { try ProgramCode(data) } | ||
} | ||
|
||
@Test func invalidCodeLength() { | ||
let highValue = Data(UInt64(0x1000000).encode(method: .variableWidth)) | ||
let data = Data([0, 0]) + highValue | ||
#expect(throws: ProgramCode.Error.invalidCodeLength) { try ProgramCode(data) } | ||
} | ||
|
||
@Test func tooMuchData() throws { | ||
let data = Data([0, 0, 2, 1, 2, 0, 0]) | ||
#expect(throws: ProgramCode.Error.invalidDataLength) { try ProgramCode(data) } | ||
} | ||
|
||
@Test func tooLittleData() throws { | ||
let data = Data([0, 0, 2, 1, 2]) | ||
#expect(throws: ProgramCode.Error.invalidDataLength) { try ProgramCode(data) } | ||
} | ||
|
||
@Test func minimal() throws { | ||
let data = Data([0, 0, 0]) | ||
_ = try ProgramCode(data) | ||
} | ||
|
||
@Test func simple() throws { | ||
let data = Data([0, 0, 2, 1, 2, 0]) | ||
_ = try ProgramCode(data) | ||
} | ||
|
||
// TODO: add more Program parsing tests | ||
|
||
@Test(arguments: [ | ||
(Data(), 0, nil), | ||
(Data([0]), 0, 24), | ||
(Data([0]), 8, nil), | ||
(Data([0b0010_0000]), 0, 4), | ||
(Data([0b0010_0000]), 3, 1), | ||
(Data([0b0010_0000]), 6, 24), | ||
(Data([0b0010_0000]), 7, nil), | ||
(Data([0, 0, 0b0010_0000, 0b0000_0010]), 0, 20), | ||
(Data([0, 0, 0b0010_0000, 0b0000_0010]), 2, 18), | ||
(Data([0, 0, 0b0010_0000, 0b0000_0010]), 10, 10), | ||
(Data([0, 0, 0b0010_0000, 0b0000_0010]), 22, 2), | ||
(Data([0, 0, 0, 0b0000_0010]), 5, 19), | ||
] as[(Data, UInt, UInt?)]) | ||
func skip(testCase: (Data, UInt, UInt?)) { | ||
#expect(ProgramCode.skipOffset(start: testCase.1, bitmask: testCase.0) == testCase.2) | ||
} | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
extension Collection { | ||
subscript(safe index: Index) -> Element? { | ||
public subscript(safe index: Index) -> Element? { | ||
indices.contains(index) ? self[index] : nil | ||
} | ||
} |