Skip to content

Commit baf442b

Browse files
Validation: Check table.init instruction
1 parent d452f05 commit baf442b

File tree

2 files changed

+33
-15
lines changed

2 files changed

+33
-15
lines changed

Sources/WasmKit/Translator.swift

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ protocol TranslatorContext {
4040
func globalType(_ index: GlobalIndex) throws -> ValueType
4141
func isMemory64(memoryIndex index: MemoryIndex) throws -> Bool
4242
func isMemory64(tableIndex index: TableIndex) throws -> Bool
43-
func elementType(_ index: TableIndex) throws -> ReferenceType
43+
func tableType(_ index: TableIndex) throws -> TableType
44+
func elementType(_ index: ElementIndex) throws -> ReferenceType
4445
func resolveCallee(_ index: FunctionIndex) -> InternalFunction?
4546
func isSameInstance(_ instance: InternalInstance) -> Bool
4647
func resolveGlobal(_ index: GlobalIndex) -> InternalGlobal?
4748
func validateDataSegment(_ index: DataIndex) throws
48-
func validateElementSegment(_ index: ElementIndex) throws
4949
func validateFunctionIndex(_ index: FunctionIndex) throws
5050
}
5151

@@ -56,6 +56,9 @@ extension TranslatorContext {
5656
func addressType(tableIndex: TableIndex) throws -> ValueType {
5757
return ValueType.addressType(isMemory64: try isMemory64(tableIndex: tableIndex))
5858
}
59+
func validateElementSegment(_ index: ElementIndex) throws {
60+
_ = try elementType(index)
61+
}
5962
}
6063

6164
extension InternalInstance: TranslatorContext {
@@ -92,11 +95,14 @@ extension InternalInstance: TranslatorContext {
9295
}
9396
return self.tables[Int(index)].limits.isMemory64
9497
}
95-
func elementType(_ index: TableIndex) throws -> ReferenceType {
98+
func tableType(_ index: TableIndex) throws -> TableType {
9699
guard Int(index) < self.tables.count else {
97100
throw TranslationError("Table index \(index) is out of range")
98101
}
99-
return self.tables[Int(index)].tableType.elementType
102+
return self.tables[Int(index)].tableType
103+
}
104+
func elementType(_ index: ElementIndex) throws -> ReferenceType {
105+
try self.elementSegments[validating: Int(index)].type
100106
}
101107

102108
func resolveCallee(_ index: FunctionIndex) -> InternalFunction? {
@@ -111,9 +117,6 @@ extension InternalInstance: TranslatorContext {
111117
func validateDataSegment(_ index: DataIndex) throws {
112118
_ = try self.dataSegments[validating: Int(index)]
113119
}
114-
func validateElementSegment(_ index: ElementIndex) throws {
115-
_ = try self.elementSegments[validating: Int(index)]
116-
}
117120
func validateFunctionIndex(_ index: FunctionIndex) throws {
118121
_ = try self.functions[validating: Int(index)]
119122
}
@@ -807,7 +810,7 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
807810
/// Whether a call to this function should be intercepted
808811
let intercepting: Bool
809812
var constantSlots: ConstSlots
810-
let validator: InstructionValidator
813+
let validator: InstructionValidator<Context>
811814

812815
init(
813816
allocator: ISeqAllocator,
@@ -836,7 +839,7 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
836839
self.functionIndex = functionIndex
837840
self.intercepting = intercepting
838841
self.constantSlots = ConstSlots(stackLayout: stackLayout)
839-
self.validator = InstructionValidator()
842+
self.validator = InstructionValidator(context: module)
840843

841844
do {
842845
let endLabel = self.iseqBuilder.allocLabel()
@@ -1958,7 +1961,8 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
19581961
}
19591962
}
19601963
mutating func visitTableInit(elemIndex: UInt32, table: UInt32) throws -> Output {
1961-
try self.module.validateElementSegment(elemIndex)
1964+
try validator.validateTableInit(elemIndex: elemIndex, table: table)
1965+
19621966
try pop3Emit((.i32, .i32, module.addressType(tableIndex: table))) { values, stack in
19631967
let (size, sourceOffset, destOffset) = values
19641968
return .tableInit(
@@ -2005,7 +2009,8 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
20052009
}
20062010
mutating func visitTableFill(table: UInt32) throws -> Output {
20072011
let address = try module.addressType(tableIndex: table)
2008-
try pop3Emit((address, .ref(module.elementType(table)), address)) { values, stack in
2012+
let type = try module.tableType(table)
2013+
try pop3Emit((address, .ref(type.elementType), address)) { values, stack in
20092014
let (size, value, destOffset) = values
20102015
return .tableFill(
20112016
Instruction.TableFillOperand(
@@ -2018,9 +2023,10 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
20182023
}
20192024
}
20202025
mutating func visitTableGet(table: UInt32) throws -> Output {
2026+
let type = try module.tableType(table)
20212027
try popPushEmit(
20222028
module.addressType(tableIndex: table),
2023-
.ref(module.elementType(table))
2029+
.ref(type.elementType)
20242030
) { index, result, stack in
20252031
return .tableGet(
20262032
Instruction.TableGetOperand(
@@ -2032,7 +2038,8 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
20322038
}
20332039
}
20342040
mutating func visitTableSet(table: UInt32) throws -> Output {
2035-
try pop2Emit((.ref(module.elementType(table)), module.addressType(tableIndex: table))) { values, stack in
2041+
let type = try module.tableType(table)
2042+
try pop2Emit((.ref(type.elementType), module.addressType(tableIndex: table))) { values, stack in
20362043
let (value, index) = values
20372044
return .tableSet(
20382045
Instruction.TableSetOperand(
@@ -2045,7 +2052,8 @@ struct InstructionTranslator<Context: TranslatorContext>: InstructionVisitor {
20452052
}
20462053
mutating func visitTableGrow(table: UInt32) throws -> Output {
20472054
let address = try module.addressType(tableIndex: table)
2048-
try pop2PushEmit((address, .ref(module.elementType(table))), address) { values, result in
2055+
let type = try module.tableType(table)
2056+
try pop2PushEmit((address, .ref(type.elementType)), address) { values, result in
20492057
let (delta, value) = values
20502058
return .tableGrow(
20512059
Instruction.TableGrowOperand(

Sources/WasmKit/Validator.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ struct ValidationError: Error, CustomStringConvertible {
1717
}
1818
}
1919

20-
struct InstructionValidator {
20+
struct InstructionValidator<Context: TranslatorContext> {
21+
let context: Context
22+
2123
func validateMemArg(_ memarg: MemArg, naturalAlignment: Int) throws {
2224
if memarg.align > naturalAlignment {
2325
throw ValidationError("Alignment 2**\(memarg.align) is out of limit \(naturalAlignment)")
@@ -32,6 +34,14 @@ struct InstructionValidator {
3234
break
3335
}
3436
}
37+
38+
func validateTableInit(elemIndex: UInt32, table: UInt32) throws {
39+
let tableType = try context.tableType(table)
40+
let elementType = try context.elementType(elemIndex)
41+
guard tableType.elementType == elementType else {
42+
throw ValidationError("Table element type mismatch in table.init: \(tableType.elementType) != \(elementType)")
43+
}
44+
}
3545
}
3646

3747
struct ModuleValidator {

0 commit comments

Comments
 (0)