diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/ControlTree.java b/wasm/src/main/java/com/dylibso/chicory/wasm/ControlTree.java index 94adf5a0e..f5ffa7951 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/ControlTree.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/ControlTree.java @@ -50,7 +50,7 @@ * 19 local.get 1) * */ -public class ControlTree { +final class ControlTree { private final Instruction instruction; private final int initialInstructionNumber; private int finalInstructionNumber = -1; // to be set when END is reached diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/Encoding.java b/wasm/src/main/java/com/dylibso/chicory/wasm/Encoding.java index e38609c5e..47aafde21 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/Encoding.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/Encoding.java @@ -9,6 +9,8 @@ public final class Encoding { public static final int MAX_VARINT_LEN_32 = 5; // ceil(32/7) public static final int MAX_VARINT_LEN_64 = 10; // ceil(64/7) + private Encoding() {} + /** * Reads an unsigned integer from {@code byteBuffer}. */ diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/Module.java b/wasm/src/main/java/com/dylibso/chicory/wasm/Module.java index e852d8550..4c3c1162f 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/Module.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/Module.java @@ -151,8 +151,8 @@ public static class Builder { private CodeSection codeSection = CodeSection.builder().build(); private DataSection dataSection = DataSection.builder().build(); private Optional dataCountSection = Optional.empty(); - private HashMap customSections = new HashMap<>(); - private List ignoredSections = new ArrayList<>(); + private final HashMap customSections = new HashMap<>(); + private final List ignoredSections = new ArrayList<>(); private boolean validate = true; private Builder() {} diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/Parser.java b/wasm/src/main/java/com/dylibso/chicory/wasm/Parser.java index fc45354cc..6b1c20695 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/Parser.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/Parser.java @@ -1,6 +1,9 @@ package com.dylibso.chicory.wasm; import static com.dylibso.chicory.wasm.Encoding.MAX_VARINT_LEN_32; +import static com.dylibso.chicory.wasm.Encoding.readSigned32Leb128; +import static com.dylibso.chicory.wasm.Encoding.readSigned64Leb128; +import static com.dylibso.chicory.wasm.Encoding.readUnsignedLeb128; import static com.dylibso.chicory.wasm.WasmLimits.MAX_FUNCTION_LOCALS; import static java.util.Objects.requireNonNull; @@ -68,6 +71,7 @@ /** * Parser for Web Assembly binaries. */ +@SuppressWarnings("UnnecessaryCodeBlock") public final class Parser { private static final int MAGIC_BYTES = 1836278016; // Magic prefix \0asm @@ -89,7 +93,7 @@ public Parser( this.customParsers = Map.copyOf(customParsers); } - private ByteBuffer readByteBuffer(InputStream is) { + private static ByteBuffer readByteBuffer(InputStream is) { try { var buffer = ByteBuffer.wrap(is.readAllBytes()); buffer.order(ByteOrder.LITTLE_ENDIAN); @@ -152,7 +156,7 @@ public static Module parse(InputStream input) { } public static Module parse(ByteBuffer buffer) { - return new Parser().parse(buffer.array()); + return parse(buffer.array()); } public static Module parse(byte[] buffer) { @@ -160,7 +164,7 @@ public static Module parse(byte[] buffer) { } public static Module parse(File file) { - return new Parser().parse(file.toPath()); + return parse(file.toPath()); } public static Module parse(Path path) { @@ -178,7 +182,7 @@ public static Module parse(Path path) { public Module parse(Supplier inputStreamSupplier) { Module.Builder moduleBuilder = Module.builder(); - try (final InputStream is = inputStreamSupplier.get()) { + try (InputStream is = inputStreamSupplier.get()) { parse(is, (s) -> onSection(moduleBuilder, s)); } catch (IOException e) { throw new ChicoryException(e); @@ -214,7 +218,7 @@ private static void readBytes(ByteBuffer buffer, byte[] dest) { // https://webassembly.github.io/spec/core/binary/modules.html#binary-module private static class SectionsValidator { - private boolean hasStart = false; + private boolean hasStart; SectionsValidator() {} @@ -657,16 +661,10 @@ private static Element parseSingleElement(ByteBuffer buffer) { type = ValueType.FuncRef; } else if (hasElemKind) { int ek = (int) readVarUInt32(buffer); - switch (ek) { - case 0x00: - { - type = ValueType.FuncRef; - break; - } - default: - { - throw new ChicoryException("Invalid element kind"); - } + if (ek == 0x00) { + type = ValueType.FuncRef; + } else { + throw new ChicoryException("Invalid element kind"); } } else { assert hasRefType; @@ -691,12 +689,12 @@ private static Element parseSingleElement(ByteBuffer buffer) { } if (declarative) { return new DeclarativeElement(type, inits); - } else if (passive) { + } + if (passive) { return new PassiveElement(type, inits); - } else { - assert active; - return new ActiveElement(type, inits, tableIdx, offset); } + assert active; + return new ActiveElement(type, inits, tableIdx, offset); } private static List parseCodeSectionLocalTypes(ByteBuffer buffer) { @@ -753,14 +751,16 @@ private static CodeSection parseCodeSection(ByteBuffer buffer) { case LOOP: case IF: { - instruction.setDepth(++depth); + depth++; + instruction.setDepth(depth); blockScope.push(instruction); instruction.setScope(blockScope.peek()); break; } case END: { - instruction.setDepth(depth--); + instruction.setDepth(depth); + depth--; instruction.setScope( blockScope.isEmpty() ? instruction : blockScope.pop()); break; @@ -813,6 +813,7 @@ private static CodeSection parseCodeSection(ByteBuffer buffer) { { instruction.setLabelFalse(instructions.size() + 1); } + // fallthrough case BR: { var offset = (int) instruction.operands()[0]; @@ -970,7 +971,9 @@ private static Instruction parseInstruction(ByteBuffer buffer) { } } var operandsArray = new long[operands.size()]; - for (var i = 0; i < operands.size(); i++) operandsArray[i] = operands.get(i); + for (var i = 0; i < operands.size(); i++) { + operandsArray[i] = operands.get(i); + } verifyAlignment(op, operandsArray); return new Instruction(address, op, operandsArray); } @@ -1010,7 +1013,7 @@ private static void verifyAlignment(OpCode op, long[] operands) { align = 64; break; } - if (align > 0 && !(Math.pow(2, operands[0]) <= align / 8)) { + if ((align > 0) && ((1 << operands[0]) > (align >> 3))) { throw new InvalidException( "alignment must not be larger than natural alignment (" + operands[0] + ")"); } @@ -1030,12 +1033,9 @@ private static Instruction[] parseExpression(ByteBuffer buffer) { } // https://webassembly.github.io/spec/core/syntax/values.html#integers - public static final long MIN_SIGNED_INT = -2147483648l; // -2^(32-1) - public static final long MAX_SIGNED_INT = 2147483647l; // 2^(32-1)-1 - public static final long MIN_UNSIGNED_INT = 0l; - public static final long MAX_UNSIGNED_INT = 0xFFFFFFFFl; // 2^(32)-1 - public static final long MIN_SIGNED_LONG = -0x8000000000000000l; // -2^(64-1) - public static final long MAX_SIGNED_LONG = 0x7FFFFFFFFFFFFFFFl; // 2^(64-1)-1 + public static final long MIN_SIGNED_INT = Integer.MIN_VALUE; // -2^(32-1) + public static final long MAX_SIGNED_INT = Integer.MAX_VALUE; // 2^(32-1)-1 + public static final long MAX_UNSIGNED_INT = 0xFFFFFFFFL; // 2^(32)-1 /** * Read an unsigned I32 from the buffer. We can't fit an unsigned 32bit int @@ -1046,8 +1046,8 @@ private static Instruction[] parseExpression(ByteBuffer buffer) { * @return the resulting long */ public static long readVarUInt32(ByteBuffer buffer) { - var value = Encoding.readUnsignedLeb128(buffer, MAX_VARINT_LEN_32); - if (value < MIN_UNSIGNED_INT || value > MAX_UNSIGNED_INT) { + var value = readUnsignedLeb128(buffer, MAX_VARINT_LEN_32); + if (value < 0 || value > MAX_UNSIGNED_INT) { throw new MalformedException("integer too large"); } return value; @@ -1061,8 +1061,8 @@ public static long readVarUInt32(ByteBuffer buffer) { * @return the resulting long */ public static long readVarSInt32(ByteBuffer buffer) { - var value = Encoding.readSigned32Leb128(buffer); - if (value > MAX_SIGNED_INT || value < MIN_SIGNED_INT) { + var value = readSigned32Leb128(buffer); + if (value < MIN_SIGNED_INT || value > MAX_SIGNED_INT) { throw new MalformedException("integer too large"); } return value; @@ -1076,11 +1076,7 @@ public static long readVarSInt32(ByteBuffer buffer) { * @return the resulting long */ public static long readVarSInt64(ByteBuffer buffer) { - var value = Encoding.readSigned64Leb128(buffer); - if (value > MAX_SIGNED_LONG || value < MIN_SIGNED_LONG) { - throw new MalformedException("integer too large"); - } - return value; + return readSigned64Leb128(buffer); } /** diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/Validator.java b/wasm/src/main/java/com/dylibso/chicory/wasm/Validator.java index fb485d2ab..463903eea 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/Validator.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/Validator.java @@ -1,6 +1,7 @@ package com.dylibso.chicory.wasm; import static java.util.Objects.requireNonNull; +import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toSet; @@ -24,7 +25,6 @@ import java.util.Collections; import java.util.List; import java.util.Set; -import java.util.stream.Collectors; import java.util.stream.Stream; // Heavily inspired by wazero @@ -33,27 +33,28 @@ // https://webassembly.github.io/spec/core/appendix/algorithm.html final class Validator { - private boolean isNum(ValueType t) { + private static boolean isNum(ValueType t) { return t.isNumeric() || t == ValueType.UNKNOWN; } - private boolean isRef(ValueType t) { + private static boolean isRef(ValueType t) { return t.isReference() || t == ValueType.UNKNOWN; } + @SuppressWarnings("PublicField") private static class CtrlFrame { // OpCode of the current Control Flow instruction - private final OpCode opCode; + public final OpCode opCode; // params or inputs - private final List startTypes; + public final List startTypes; // returns or outputs - private final List endTypes; + public final List endTypes; // the height of the stack before entering the current Control Flow instruction - private final int height; + public final int height; // set after uncoditional jumps - private boolean unreachable; + public boolean unreachable; // if there is no else, we explicit check that the enclosing IF is not returning values - private boolean hasElse; + public boolean hasElse; public CtrlFrame( OpCode opCode, @@ -206,12 +207,8 @@ private CtrlFrame getCtrl(int n) { return ctrlFrameStack.get(ctrlFrameStack.size() - 1 - n); } - private List labelTypes(CtrlFrame frame) { - if (frame.opCode == OpCode.LOOP) { - return frame.startTypes; - } else { - return frame.endTypes; - } + private static List labelTypes(CtrlFrame frame) { + return (frame.opCode == OpCode.LOOP) ? frame.startTypes : frame.endTypes; } private void resetAtStackLimit() { @@ -243,25 +240,25 @@ private List getReturns(Instruction op) { var typeId = (int) op.operands()[0]; if (typeId == 0x40) { // epsilon return List.of(); - } else if (ValueType.isValid(typeId)) { + } + if (ValueType.isValid(typeId)) { return List.of(ValueType.forId(typeId)); - } else { - return getType(typeId).returns(); } + return getType(typeId).returns(); } private List getParams(Instruction op) { var typeId = (int) op.operands()[0]; if (typeId == 0x40) { // epsilon return List.of(); - } else if (ValueType.isValid(typeId)) { + } + if (ValueType.isValid(typeId)) { return List.of(); - } else { - if (typeId >= module.typeSection().typeCount()) { - throw new MalformedException("unexpected end"); - } - return getType(typeId).params(); } + if (typeId >= module.typeSection().typeCount()) { + throw new MalformedException("unexpected end"); + } + return getType(typeId).params(); } private static ValueType getLocalType(List localTypes, int idx) { @@ -348,6 +345,7 @@ public void validateFunctions() { } } + @SuppressWarnings("UnnecessaryCodeBlock") public void validateFunction(int funcIdx, FunctionBody body, FunctionType functionType) { var localTypes = body.localTypes(); var inputLen = functionType.params().size(); @@ -359,16 +357,13 @@ public void validateFunction(int funcIdx, FunctionBody body, FunctionType functi // control flow instructions handling switch (op.opcode()) { case UNREACHABLE: - { - unreachable(); - break; - } + unreachable(); + break; case IF: - { - popVal(ValueType.I32); - // fallthrough - } - case LOOP: // t1* -> t2* + popVal(ValueType.I32); + // fallthrough + case LOOP: + // t1* -> t2* // fallthrough case BLOCK: { @@ -432,7 +427,7 @@ public void validateFunction(int funcIdx, FunctionBody body, FunctionType functi var arity = defaultBranchLabelTypes.size(); for (var idx = 0; idx < op.operands().length - 1; idx++) { var n = (int) op.operands()[idx]; - CtrlFrame ctrlFrame = null; + CtrlFrame ctrlFrame; try { ctrlFrame = getCtrl(n); } catch (IndexOutOfBoundsException e) { @@ -1072,7 +1067,7 @@ public void validateFunction(int funcIdx, FunctionBody body, FunctionType functi if (!errors.isEmpty()) { throw new InvalidException( - errors.stream().map(e -> e.getMessage()).collect(Collectors.joining(" - "))); + errors.stream().map(Throwable::getMessage).collect(joining(" - "))); } // to satisfy the check mentioned in the NOTE diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/WasmLimits.java b/wasm/src/main/java/com/dylibso/chicory/wasm/WasmLimits.java index 3f885425a..7612cb7a6 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/WasmLimits.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/WasmLimits.java @@ -2,7 +2,7 @@ // Spec: https://webassembly.github.io/spec/core/appendix/implementation.html#syntactic-limits // From: https://github.com/WebKit/webkit/blob/main/Source/JavaScriptCore/wasm/WasmLimits.h -public class WasmLimits { +public final class WasmLimits { public static final int MAX_TYPES = 1000000; public static final int MAX_FUNCTIONS = 1000000; @@ -27,4 +27,6 @@ public class WasmLimits { public static final int MAX_TABLE_ENTRIES = 10000000; public static final int MAX_TABLES = 1000000; + + private WasmLimits() {} } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/ActiveDataSegment.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/ActiveDataSegment.java index 1de267687..99e800d85 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/ActiveDataSegment.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/ActiveDataSegment.java @@ -6,10 +6,6 @@ public final class ActiveDataSegment extends DataSegment { private final long idx; private final List offsetInstructions; - public ActiveDataSegment(List offsetInstructions, byte[] data) { - this(0, offsetInstructions, data); - } - public ActiveDataSegment(long idx, List offsetInstructions, byte[] data) { super(data); this.idx = idx; diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/ActiveElement.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/ActiveElement.java index 58fd3fe85..2a66e5692 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/ActiveElement.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/ActiveElement.java @@ -19,10 +19,10 @@ public final class ActiveElement extends Element { * @param offset the list of instructions which give the offset into the table (must not be {@code null}) */ public ActiveElement( - final ValueType type, - final List> initializers, - final int tableIndex, - final List offset) { + ValueType type, + List> initializers, + int tableIndex, + List offset) { super(type, initializers); this.tableIndex = tableIndex; this.offset = List.copyOf(offset); diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/BlockKind.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/BlockKind.java deleted file mode 100644 index af73596e1..000000000 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/BlockKind.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.dylibso.chicory.wasm.types; - -public enum BlockKind { - BLOCK, - LOOP, -} diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/CodeSection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/CodeSection.java index 93406a4d4..a4d9e172f 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/CodeSection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/CodeSection.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Objects; -public class CodeSection extends Section { +public final class CodeSection extends Section { private final List functionBodies; private final boolean requiresDataCount; @@ -35,8 +35,8 @@ public static Builder builder() { } public static class Builder { - private List functionBodies = new ArrayList<>(); - private boolean requiresDataCount = false; + private final List functionBodies = new ArrayList<>(); + private boolean requiresDataCount; private Builder() {} diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/CustomSection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/CustomSection.java index 9b81ecdd6..35c05a389 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/CustomSection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/CustomSection.java @@ -5,7 +5,7 @@ */ public abstract class CustomSection extends Section { - protected CustomSection() { + CustomSection() { super(SectionId.CUSTOM); } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/DataCountSection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/DataCountSection.java index 292873946..cbf971485 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/DataCountSection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/DataCountSection.java @@ -1,6 +1,6 @@ package com.dylibso.chicory.wasm.types; -public class DataCountSection extends Section { +public final class DataCountSection extends Section { private final int dataCount; private DataCountSection(int dataCount) { diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/DataSection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/DataSection.java index 75b7ca512..7623f4b75 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/DataSection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/DataSection.java @@ -4,7 +4,7 @@ import java.util.List; import java.util.Objects; -public class DataSection extends Section { +public final class DataSection extends Section { private final List dataSegments; private DataSection(List dataSegments) { @@ -29,7 +29,7 @@ public static Builder builder() { } public static class Builder { - private List dataSegments = new ArrayList<>(); + private final List dataSegments = new ArrayList<>(); private Builder() {} diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/DataSegment.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/DataSegment.java index 6af867cfb..9b3482eb3 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/DataSegment.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/DataSegment.java @@ -1,15 +1,13 @@ package com.dylibso.chicory.wasm.types; -import java.util.Objects; - public abstract class DataSegment { private final byte[] data; - public DataSegment(byte[] data) { - this.data = Objects.requireNonNull(data); + DataSegment(byte[] data) { + this.data = data.clone(); } public byte[] data() { - return data; + return data.clone(); } } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/DeclarativeElement.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/DeclarativeElement.java index e46363ed5..e0c766518 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/DeclarativeElement.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/DeclarativeElement.java @@ -14,7 +14,7 @@ public final class DeclarativeElement extends Element { * @param type the type of the element values (must not be {@code null}) * @param initializers the list of instruction lists which are used to initialize each element in the range (must not be {@code null}) */ - public DeclarativeElement(final ValueType type, final List> initializers) { + public DeclarativeElement(ValueType type, List> initializers) { super(type, initializers); } } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Element.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Element.java index c4ece86f9..f79493c0e 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Element.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Element.java @@ -1,7 +1,8 @@ package com.dylibso.chicory.wasm.types; +import static java.util.Objects.requireNonNull; + import java.util.List; -import java.util.Objects; /** * An element, used to initialize table ranges. @@ -16,8 +17,8 @@ public abstract class Element { * @param type the type of the element values (must not be {@code null}) * @param initializers the list of instruction lists which are used to initialize each element in the range (must not be {@code null}) */ - public Element(final ValueType type, final List> initializers) { - this.type = Objects.requireNonNull(type, "type"); + Element(ValueType type, List> initializers) { + this.type = requireNonNull(type, "type"); this.initializers = List.copyOf(initializers); } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/ElementSection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/ElementSection.java index 09cec9133..abdd959b9 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/ElementSection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/ElementSection.java @@ -34,7 +34,7 @@ public static Builder builder() { } public static class Builder { - private List elements = new ArrayList<>(); + private final List elements = new ArrayList<>(); /** * Add an element definition to this section. diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Export.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Export.java index 5643f686a..b625170c0 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Export.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Export.java @@ -21,7 +21,7 @@ public class Export { * @param index the index of the definition to export * @param exportType the export type (must not be {@code null}) */ - public Export(final String name, final int index, final ExternalType exportType) { + public Export(String name, int index, ExternalType exportType) { this.name = Objects.requireNonNull(name, "name"); this.index = index; this.exportType = Objects.requireNonNull(exportType, "type"); @@ -48,15 +48,17 @@ public ExternalType exportType() { return exportType; } + @Override public int hashCode() { return (name.hashCode() * 31 + index) * 31 + exportType.hashCode(); } - public boolean equals(final Object obj) { + @Override + public boolean equals(Object obj) { return obj instanceof Export && equals((Export) obj); } - public boolean equals(final Export other) { + public boolean equals(Export other) { return this == other || other != null && index == other.index diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/ExportSection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/ExportSection.java index 08b3969e1..db881ece2 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/ExportSection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/ExportSection.java @@ -25,7 +25,7 @@ public static Builder builder() { } public static class Builder { - private List exports = new ArrayList<>(); + private final List exports = new ArrayList<>(); private Builder() {} diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/ExternalType.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/ExternalType.java index 3e1a908ea..27b5bc2f6 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/ExternalType.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/ExternalType.java @@ -20,7 +20,7 @@ public enum ExternalType { private final int id; - ExternalType(final int id) { + ExternalType(int id) { this.id = id; } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionBody.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionBody.java index 78c088c19..6c784581f 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionBody.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionBody.java @@ -2,7 +2,7 @@ import java.util.List; -public class FunctionBody { +public final class FunctionBody { private final List locals; private final List instructions; diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionImport.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionImport.java index 93b608abb..e7192f480 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionImport.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionImport.java @@ -13,7 +13,7 @@ public final class FunctionImport extends Import { * @param name the imported function name (must not be {@code null}) * @param typeIndex the type index of the function (should correspond to a valid index in the type section) */ - public FunctionImport(final String moduleName, final String name, final int typeIndex) { + public FunctionImport(String moduleName, String name, int typeIndex) { super(moduleName, name); this.typeIndex = typeIndex; } @@ -25,23 +25,27 @@ public int typeIndex() { return typeIndex; } + @Override public ExternalType importType() { return ExternalType.FUNCTION; } - public boolean equals(final Import other) { + @Override + public boolean equals(Import other) { return other instanceof FunctionImport && equals((FunctionImport) other); } - public boolean equals(final FunctionImport other) { + public boolean equals(FunctionImport other) { return this == other || super.equals(other) && typeIndex == other.typeIndex; } + @Override public int hashCode() { return super.hashCode() * 19 + typeIndex; } - public StringBuilder toString(final StringBuilder b) { + @Override + public StringBuilder toString(StringBuilder b) { b.append("func (type=").append(typeIndex).append(')'); return super.toString(b); } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionSection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionSection.java index ca4e1f629..e1c95f506 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionSection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionSection.java @@ -28,7 +28,7 @@ public static Builder builder() { } public static class Builder { - private List typeIndices = new ArrayList<>(); + private final List typeIndices = new ArrayList<>(); private Builder() {} diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionType.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionType.java index 3f77e01fb..afb970202 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionType.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/FunctionType.java @@ -31,7 +31,8 @@ public boolean returnsMatch(FunctionType other) { return returns.equals(other.returns); } - public boolean equals(final Object obj) { + @Override + public boolean equals(Object obj) { return obj instanceof FunctionType && equals((FunctionType) obj); } @@ -39,6 +40,7 @@ public boolean equals(FunctionType other) { return hashCode == other.hashCode && paramsMatch(other) && returnsMatch(other); } + @Override public int hashCode() { return hashCode; } @@ -81,7 +83,8 @@ public static FunctionType of(List params, List returns) { if (params.isEmpty()) { if (returns.isEmpty()) { return empty; - } else if (returns.size() == 1) { + } + if (returns.size() == 1) { return returning(returns.get(0)); } } else if (returns.isEmpty()) { @@ -104,6 +107,7 @@ public static FunctionType empty() { return empty; } + @Override public String toString() { var builder = new StringBuilder(); builder.append('('); diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/GlobalImport.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/GlobalImport.java index 74df581d7..958f5328c 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/GlobalImport.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/GlobalImport.java @@ -18,10 +18,7 @@ public final class GlobalImport extends Import { * @param type the type of the value stored in the global (must not be {@code null}) */ public GlobalImport( - final String moduleName, - final String name, - final MutabilityType mutabilityType, - final ValueType type) { + String moduleName, String name, MutabilityType mutabilityType, ValueType type) { super(moduleName, name); this.mutabilityType = Objects.requireNonNull(mutabilityType, "mutabilityType"); this.type = Objects.requireNonNull(type, "type"); @@ -41,26 +38,30 @@ public ValueType type() { return type; } + @Override public ExternalType importType() { return ExternalType.GLOBAL; } - public boolean equals(final Import other) { + @Override + public boolean equals(Import other) { return other instanceof GlobalImport && equals((GlobalImport) other); } - public boolean equals(final GlobalImport other) { + public boolean equals(GlobalImport other) { return this == other || super.equals(other) && mutabilityType == other.mutabilityType && type == other.type; } + @Override public int hashCode() { return (super.hashCode() * 19 + mutabilityType.hashCode()) * 19 + type.hashCode(); } - public StringBuilder toString(final StringBuilder b) { + @Override + public StringBuilder toString(StringBuilder b) { b.append("global (type=").append(type).append(",mut=").append(mutabilityType).append(')'); return super.toString(b); } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/GlobalSection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/GlobalSection.java index d4f992b97..7bbac7e21 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/GlobalSection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/GlobalSection.java @@ -29,7 +29,7 @@ public static Builder builder() { } public static class Builder { - private List globals = new ArrayList<>(); + private final List globals = new ArrayList<>(); private Builder() {} diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Import.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Import.java index 99f16278a..1e5086220 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Import.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Import.java @@ -1,11 +1,13 @@ package com.dylibso.chicory.wasm.types; +import static java.util.Objects.requireNonNull; + import java.util.Objects; /** * Some imported entity. *

- * See <a href=https://webassembly.github.io/spec/core/syntax/modules.html#syntax-import">Imports</a> for + * See Imports for * reference. */ public abstract class Import { @@ -13,8 +15,8 @@ public abstract class Import { private final String name; Import(String moduleName, String name) { - this.moduleName = Objects.requireNonNull(moduleName, "moduleName"); - this.name = Objects.requireNonNull(name, "name"); + this.moduleName = requireNonNull(moduleName, "moduleName"); + this.name = requireNonNull(name, "name"); } /** @@ -36,6 +38,7 @@ public String name() { */ public abstract ExternalType importType(); + @Override public boolean equals(Object obj) { return obj instanceof Import && equals((Import) obj); } @@ -44,6 +47,7 @@ public boolean equals(Import other) { return other != null && moduleName.equals(other.moduleName) && name.equals(other.name); } + @Override public int hashCode() { return Objects.hash(moduleName, name); } @@ -52,6 +56,7 @@ public StringBuilder toString(StringBuilder b) { return b.append('<').append(moduleName).append('.').append(name).append('>'); } + @Override public String toString() { return toString(new StringBuilder()).toString(); } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/ImportSection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/ImportSection.java index df4f7398b..a486ee264 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/ImportSection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/ImportSection.java @@ -34,7 +34,7 @@ public static Builder builder() { } public static class Builder { - private List imports = new ArrayList<>(); + private final List imports = new ArrayList<>(); private Builder() {} diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Instruction.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Instruction.java index d56133ce5..b2aac94d8 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Instruction.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Instruction.java @@ -27,6 +27,7 @@ public long[] operands() { return operands; } + @Override public String toString() { var result = String.format("0x%08X", address) + ": "; if (operands.length > 0) { diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Limits.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Limits.java index 1c597d434..35960c2d7 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Limits.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Limits.java @@ -30,18 +30,21 @@ public long max() { return max; } - public boolean equals(final Object obj) { + @Override + public boolean equals(Object obj) { return obj instanceof Limits && equals((Limits) obj); } - public boolean equals(final Limits other) { + public boolean equals(Limits other) { return this == other || other != null && min == other.min && max == other.max; } + @Override public int hashCode() { return Long.hashCode(min) * 19 + Long.hashCode(max); } + @Override public String toString() { return toString(new StringBuilder()).toString(); } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/MemoryImport.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/MemoryImport.java index 5e0622edb..e70106965 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/MemoryImport.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/MemoryImport.java @@ -13,7 +13,7 @@ public final class MemoryImport extends Import { * @param name the imported memory name (must not be {@code null}) * @param limits the memory size limits (must not be {@code null}) */ - public MemoryImport(final String moduleName, final String name, final MemoryLimits limits) { + public MemoryImport(String moduleName, String name, MemoryLimits limits) { super(moduleName, name); this.limits = limits; } @@ -25,23 +25,27 @@ public MemoryLimits limits() { return limits; } + @Override public ExternalType importType() { return ExternalType.MEMORY; } - public boolean equals(final Import other) { + @Override + public boolean equals(Import other) { return other instanceof MemoryImport && equals((MemoryImport) other); } - public boolean equals(final MemoryImport other) { + public boolean equals(MemoryImport other) { return this == other || super.equals(other) && limits.equals(other.limits); } + @Override public int hashCode() { return super.hashCode() * 19 + limits.hashCode(); } - public StringBuilder toString(final StringBuilder b) { + @Override + public StringBuilder toString(StringBuilder b) { b.append("memory (limits="); limits.toString(b); b.append(')'); diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/MemoryLimits.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/MemoryLimits.java index 9737e2241..4f54bdd9a 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/MemoryLimits.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/MemoryLimits.java @@ -67,7 +67,8 @@ public MemoryLimits(int initial, int maximum) { public MemoryLimits(int initial, int maximum, boolean shared) { if (initial > MAX_PAGES || maximum > MAX_PAGES || initial < 0 || maximum < 0) { throw new InvalidException("memory size must be at most 65536 pages (4GiB)"); - } else if (initial > maximum) { + } + if (initial > maximum) { throw new InvalidException("size minimum must not be greater than maximum"); } @@ -98,25 +99,28 @@ public int maximumPages() { } /** - * @return true if the limits apply to a shared memory segment, or false otherwise + * @return {@code true} if the limits apply to a shared memory segment, or {@code false} otherwise */ public boolean shared() { return shared; } - public boolean equals(final Object obj) { + @Override + public boolean equals(Object obj) { return obj instanceof MemoryLimits && equals((MemoryLimits) obj); } - public boolean equals(final MemoryLimits other) { + public boolean equals(MemoryLimits other) { return this == other || other != null && initial == other.initial && maximum == other.maximum; } + @Override public int hashCode() { return maximum * 19 + initial; } + @Override public String toString() { return toString(new StringBuilder()).toString(); } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/MemorySection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/MemorySection.java index 7683c3379..86f93c714 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/MemorySection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/MemorySection.java @@ -25,7 +25,7 @@ public static Builder builder() { } public static class Builder { - private List memories = new ArrayList<>(); + private final List memories = new ArrayList<>(); private Builder() {} diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/MutabilityType.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/MutabilityType.java index 5e92b1f90..674671631 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/MutabilityType.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/MutabilityType.java @@ -23,7 +23,7 @@ public int id() { } /** - * @return the MutabilityType for the given ID value + * @return the {@code MutabilityType} for the given ID value * * @throws IllegalArgumentException if the ID value does not correspond to a valid mutability type */ diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/NameCustomSection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/NameCustomSection.java index 95b9124ed..810964d39 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/NameCustomSection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/NameCustomSection.java @@ -25,9 +25,6 @@ public class NameCustomSection extends CustomSection { private final List dataNames; private final List tagNames; - /** - * Construct a section instance from the specified contents. - */ private NameCustomSection( Optional moduleName, List funcNames, @@ -39,7 +36,7 @@ private NameCustomSection( List elementNames, List dataNames, List tagNames) { - this.moduleName = moduleName; + this.moduleName = requireNonNull(moduleName); this.funcNames = List.copyOf(requireNonNull(funcNames)); this.localNames = List.copyOf(requireNonNull(localNames)); this.labelNames = List.copyOf(requireNonNull(labelNames)); @@ -76,56 +73,36 @@ public static NameCustomSection parse(byte[] bytes) { // todo: IDs 4 and 10 are reserved for the Host GC spec switch (id) { case 0: - { - assert (moduleName == null); - moduleName = Parser.readName(slice); - break; - } + assert (moduleName == null); + moduleName = Parser.readName(slice); + break; case 1: - { - oneLevelParse(slice, funcNames); - break; - } + oneLevelParse(slice, funcNames); + break; case 2: - { - twoLevelParse(slice, localNames); - break; - } + twoLevelParse(slice, localNames); + break; case 3: - { - twoLevelParse(slice, labelNames); - break; - } + twoLevelParse(slice, labelNames); + break; case 5: - { - oneLevelParse(slice, tableNames); - break; - } + oneLevelParse(slice, tableNames); + break; case 6: - { - oneLevelParse(slice, memoryNames); - break; - } + oneLevelParse(slice, memoryNames); + break; case 7: - { - oneLevelParse(slice, globalNames); - break; - } + oneLevelParse(slice, globalNames); + break; case 8: - { - oneLevelParse(slice, elementNames); - break; - } + oneLevelParse(slice, elementNames); + break; case 9: - { - oneLevelParse(slice, dataNames); - break; - } + oneLevelParse(slice, dataNames); + break; case 11: - { - oneLevelParse(slice, tagNames); - break; - } + oneLevelParse(slice, tagNames); + break; default: // ignore unknown subsection for forwards-compatibility } @@ -144,6 +121,7 @@ public static NameCustomSection parse(byte[] bytes) { tagNames); } + @Override public String name() { return "name"; } @@ -156,7 +134,7 @@ public Optional moduleName() { } /** - * @return the name of the function with the given index, or null if none is set + * @return the name of the function with the given index, or {@code null} if none is set */ public String nameOfFunction(int functionIdx) { return oneLevelSearch(funcNames, functionIdx); @@ -173,56 +151,56 @@ public int functionNameCount() { } /** - * @return the name of the local with the given index within the function with the given index, or null if none is set + * @return the name of the local with the given index within the function with the given index, or {@code null} if none is set */ public String nameOfLocal(int functionIdx, int localIdx) { return twoLevelSearch(localNames, functionIdx, localIdx); } /** - * @return the name of the local with the given index within the function with the given index, or null if none is set + * @return the name of the local with the given index within the function with the given index, or {@code null} if none is set */ public String nameOfLabel(int functionIdx, int labelIdx) { return twoLevelSearch(labelNames, functionIdx, labelIdx); } /** - * @return the name of the table with the given index, or null if none is set + * @return the name of the table with the given index, or {@code null} if none is set */ public String nameOfTable(int tableIdx) { return oneLevelSearch(tableNames, tableIdx); } /** - * @return the name of the memory with the given index, or null if none is set + * @return the name of the memory with the given index, or {@code null} if none is set */ public String nameOfMemory(int memoryIdx) { return oneLevelSearch(memoryNames, memoryIdx); } /** - * @return the name of the global with the given index, or null if none is set + * @return the name of the global with the given index, or {@code null} if none is set */ public String nameOfGlobal(int globalIdx) { return oneLevelSearch(globalNames, globalIdx); } /** - * @return the name of the element with the given index, or null if none is set + * @return the name of the element with the given index, or {@code null} if none is set */ public String nameOfElement(int elementIdx) { return oneLevelSearch(elementNames, elementIdx); } /** - * @return the name of the data segment with the given index, or null if none is set + * @return the name of the data segment with the given index, or {@code null} if none is set */ public String nameOfData(int dataIdx) { return oneLevelSearch(dataNames, dataIdx); } /** - * @return the name of the tag with the given index, or null if none is set + * @return the name of the tag with the given index, or {@code null} if none is set */ public String nameOfTag(int tagIdx) { return oneLevelSearch(tagNames, tagIdx); @@ -230,15 +208,14 @@ public String nameOfTag(int tagIdx) { // parsing helpers - private static void oneLevelParse(final ByteBuffer slice, final List list) { + private static void oneLevelParse(ByteBuffer slice, List list) { int cnt = (int) Parser.readVarUInt32(slice); for (int i = 0; i < cnt; i++) { oneLevelStore(list, (int) Parser.readVarUInt32(slice), Parser.readName(slice)); } } - private static void twoLevelParse( - final ByteBuffer slice, final List> list) { + private static void twoLevelParse(ByteBuffer slice, List> list) { int listCnt = (int) Parser.readVarUInt32(slice); for (int i = 0; i < listCnt; i++) { int groupIdx = (int) Parser.readVarUInt32(slice); @@ -250,7 +227,7 @@ private static void twoLevelParse( } } - private static ByteBuffer slice(final ByteBuffer buf, final int size) { + private static ByteBuffer slice(ByteBuffer buf, int size) { int pos = buf.position(); int lim = buf.limit(); try { @@ -287,10 +264,9 @@ private static String oneLevelStore(List list, int storeIdx, String n // insert list.add(-idx - 1, new NameEntry(storeIdx, name)); return null; - } else { - // replace - return list.set(idx, new NameEntry(storeIdx, name)).name(); } + // replace + return list.set(idx, new NameEntry(storeIdx, name)).name(); } private static String twoLevelStore( @@ -309,10 +285,9 @@ private static String twoLevelStore( // insert subList.add(-li - 1, new NameEntry(subIdx, name)); return null; - } else { - // replace - return subList.set(li, new NameEntry(subIdx, name)).name(); } + // replace + return subList.set(li, new NameEntry(subIdx, name)).name(); } private static int binarySearch(List list, int idx, ToIntFunction indexExtractor) { @@ -342,7 +317,7 @@ static final class NameEntry { private final int index; private final String name; - NameEntry(final int index, final String name) { + NameEntry(int index, String name) { this.index = index; this.name = name; } @@ -355,6 +330,7 @@ String name() { return name; } + @Override public String toString() { return "[" + index + "] -> " + name; } @@ -365,7 +341,7 @@ public String toString() { static final class ListEntry extends ArrayList { private final int index; - ListEntry(final int index) { + ListEntry(int index) { this.index = index; } @@ -373,6 +349,7 @@ int index() { return index; } + @Override public String toString() { return "[" + index + "] -> " + super.toString(); } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/PassiveElement.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/PassiveElement.java index 4a0fa03e5..387e0df11 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/PassiveElement.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/PassiveElement.java @@ -14,7 +14,7 @@ public final class PassiveElement extends Element { * @param type the type of the element values (must not be {@code null}) * @param initializers the list of instruction lists which are used to initialize each element in the range (must not be {@code null}) */ - public PassiveElement(final ValueType type, final List> initializers) { + public PassiveElement(ValueType type, List> initializers) { super(type, initializers); } } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Section.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Section.java index 71850e4c3..b09c6ce19 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Section.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Section.java @@ -1,9 +1,9 @@ package com.dylibso.chicory.wasm.types; -public class Section { +public abstract class Section { private final int id; - public Section(long id) { + Section(long id) { this.id = (int) id; } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/SectionId.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/SectionId.java index 509bc32b5..12007a517 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/SectionId.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/SectionId.java @@ -1,6 +1,6 @@ package com.dylibso.chicory.wasm.types; -public class SectionId { +public final class SectionId { public static final int CUSTOM = 0; public static final int TYPE = 1; public static final int IMPORT = 2; @@ -14,4 +14,6 @@ public class SectionId { public static final int CODE = 10; public static final int DATA = 11; public static final int DATA_COUNT = 12; + + private SectionId() {} } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/StartSection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/StartSection.java index fa1213c7d..df8169429 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/StartSection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/StartSection.java @@ -1,6 +1,6 @@ package com.dylibso.chicory.wasm.types; -public class StartSection extends Section { +public final class StartSection extends Section { private final long startIndex; private StartSection(long startIndex) { diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Table.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Table.java index c95bf0704..59c80c292 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Table.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Table.java @@ -6,7 +6,7 @@ public class Table { private final ValueType elementType; private final Limits limits; - public Table(final ValueType elementType, final Limits limits) { + public Table(ValueType elementType, Limits limits) { this.elementType = Objects.requireNonNull(elementType, "elementType"); if (!elementType.isReference()) { throw new IllegalArgumentException("Table element type must be a reference type"); diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/TableImport.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/TableImport.java index 88f85657a..240532f3f 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/TableImport.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/TableImport.java @@ -17,11 +17,7 @@ public final class TableImport extends Import { * @param entryType the table entry type (must not be {@code null}) * @param limits the table limits (must not be {@code null}) */ - public TableImport( - final String moduleName, - final String name, - final ValueType entryType, - final Limits limits) { + public TableImport(String moduleName, String name, ValueType entryType, Limits limits) { super(moduleName, name); this.entryType = Objects.requireNonNull(entryType, "entryType"); this.limits = Objects.requireNonNull(limits, "limits"); @@ -41,26 +37,30 @@ public Limits limits() { return limits; } + @Override public ExternalType importType() { return ExternalType.TABLE; } - public boolean equals(final Import other) { + @Override + public boolean equals(Import other) { return other instanceof TableImport && equals((TableImport) other); } - public boolean equals(final TableImport other) { + public boolean equals(TableImport other) { return this == other || super.equals(other) && entryType == other.entryType && limits.equals(other.limits); } + @Override public int hashCode() { return (super.hashCode() * 19 + entryType.hashCode()) * 19 + limits.hashCode(); } - public StringBuilder toString(final StringBuilder b) { + @Override + public StringBuilder toString(StringBuilder b) { b.append("table (type=").append(entryType).append(",limits="); limits.toString(b); b.append(')'); diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/TableSection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/TableSection.java index 1c1f5e9a1..9bfff3259 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/TableSection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/TableSection.java @@ -25,7 +25,7 @@ public static Builder builder() { } public static class Builder { - private List tables = new ArrayList<>(); + private final List
tables = new ArrayList<>(); private Builder() {} diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/TypeSection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/TypeSection.java index 2d9de4ba5..9bb71c154 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/TypeSection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/TypeSection.java @@ -29,7 +29,7 @@ public static Builder builder() { } public static class Builder { - private List types = new ArrayList<>(); + private final List types = new ArrayList<>(); private Builder() {} diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/UnknownCustomSection.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/UnknownCustomSection.java index 42ab8987e..cc0dabb46 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/UnknownCustomSection.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/UnknownCustomSection.java @@ -1,6 +1,6 @@ package com.dylibso.chicory.wasm.types; -import java.util.Objects; +import static java.util.Objects.requireNonNull; /** * A custom section which is unknown to the parser. @@ -9,24 +9,18 @@ public final class UnknownCustomSection extends CustomSection { private final String name; private final byte[] bytes; - /** - * Construct a new instance. - * - * @param name the name of the section (must not be {@code null}) - * @param bytes the section contents (must not be {@code null}) - */ - private UnknownCustomSection(final String name, final byte[] bytes) { - super(); - this.name = Objects.requireNonNull(name, "name"); + private UnknownCustomSection(String name, byte[] bytes) { + this.name = requireNonNull(name, "name"); this.bytes = bytes.clone(); } + @Override public String name() { return name; } public byte[] bytes() { - return bytes; + return bytes.clone(); } public static Builder builder() { @@ -40,12 +34,12 @@ public static class Builder { private Builder() {} public Builder withName(String name) { - this.name = name; + this.name = requireNonNull(name); return this; } public Builder withBytes(byte[] bytes) { - this.bytes = bytes; + this.bytes = requireNonNull(bytes); return this; } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Value.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Value.java index 2faa60ad0..d1688b8ea 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/Value.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/Value.java @@ -189,11 +189,11 @@ public double asDouble() { } public ValueType type() { - return this.type; + return type; } public byte[] data() { - switch (this.type) { + switch (type) { case I64: case F64: ByteBuffer buffer = ByteBuffer.allocate(8); @@ -208,22 +208,23 @@ public byte[] data() { } } + @Override public String toString() { - switch (this.type) { + switch (type) { case I32: - return this.asInt() + "@i32"; + return asInt() + "@i32"; case I64: - return this.asLong() + "@i64"; + return asLong() + "@i64"; case F32: - return this.asFloat() + "@f32"; + return asFloat() + "@f32"; case F64: - return this.asDouble() + "@f64"; + return asDouble() + "@f64"; case FuncRef: return "func[" + (int) data + "]"; case ExternRef: return "ext[" + (int) data + "]"; default: - throw new RuntimeException("TODO handle missing types"); + throw new AssertionError("Unhandled type: " + type); } } diff --git a/wasm/src/main/java/com/dylibso/chicory/wasm/types/ValueType.java b/wasm/src/main/java/com/dylibso/chicory/wasm/types/ValueType.java index 44a40f5d6..80d12981a 100644 --- a/wasm/src/main/java/com/dylibso/chicory/wasm/types/ValueType.java +++ b/wasm/src/main/java/com/dylibso/chicory/wasm/types/ValueType.java @@ -29,7 +29,7 @@ public int id() { } /** - * @return true if the type can be stored in memory, and thus has a size, or false otherwise + * @return {@code true} if the type can be stored in memory, and thus has a size, or {@code false} otherwise */ public boolean hasSize() { switch (this) { @@ -65,7 +65,7 @@ public int size() { } /** - * @return true if the type is a numeric type, or false otherwise + * @return {@code true} if the type is a numeric type, or {@code false} otherwise */ public boolean isNumeric() { switch (this) { @@ -80,7 +80,7 @@ public boolean isNumeric() { } /** - * @return true if the type is an integer type, or false otherwise + * @return {@code true} if the type is an integer type, or {@code false} otherwise */ public boolean isInteger() { switch (this) { @@ -93,7 +93,7 @@ public boolean isInteger() { } /** - * @return true if the type is a floating-point type, or false otherwise + * @return {@code true} if the type is a floating-point type, or {@code false} otherwise */ public boolean isFloatingPoint() { switch (this) { @@ -106,7 +106,7 @@ public boolean isFloatingPoint() { } /** - * @return true if the type is a reference type, or false otherwise + * @return {@code true} if the type is a reference type, or {@code false} otherwise */ public boolean isReference() { switch (this) { @@ -119,9 +119,9 @@ public boolean isReference() { } /** - * @return true if the given type ID is a valid value type ID, or false if it is not + * @return {@code true} if the given type ID is a valid value type ID, or {@code false} if it is not */ - public static boolean isValid(final int typeId) { + public static boolean isValid(int typeId) { switch (typeId) { case ID.F64: case ID.ExternRef: @@ -137,7 +137,7 @@ public static boolean isValid(final int typeId) { } /** - * @return the ValueType for the given ID value + * @return the {@code ValueType} for the given ID value * * @throws IllegalArgumentException if the ID value does not correspond to a valid value type */ @@ -163,7 +163,7 @@ public static ValueType forId(int id) { } /** - * @return the reference-typed ValueType for the given ID value + * @return the reference-typed {@code ValueType} for the given ID value * * @throws IllegalArgumentException if the ID value does not correspond to a valid reference type */ diff --git a/wasm/src/test/java/com/dylibso/chicory/wasm/ParserTest.java b/wasm/src/test/java/com/dylibso/chicory/wasm/ParserTest.java index dddb692bc..b5ea668f7 100644 --- a/wasm/src/test/java/com/dylibso/chicory/wasm/ParserTest.java +++ b/wasm/src/test/java/com/dylibso/chicory/wasm/ParserTest.java @@ -15,9 +15,11 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; -import java.util.ArrayList; -import java.util.Arrays; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; @@ -81,9 +83,9 @@ public void shouldParseFile() throws IOException { assertEquals("0x00000032: I32_CONST [42]", instructions.get(0).toString()); assertEquals(OpCode.I32_CONST, instructions.get(0).opcode()); - assertEquals(42L, (long) instructions.get(0).operands()[0]); + assertEquals(42L, instructions.get(0).operands()[0]); assertEquals(OpCode.CALL, instructions.get(1).opcode()); - assertEquals(0L, (long) instructions.get(1).operands()[0]); + assertEquals(0L, instructions.get(1).operands()[0]); assertEquals(OpCode.END, instructions.get(2).opcode()); } } @@ -116,14 +118,16 @@ public void shouldParseIterfact() throws IOException { } @Test - public void shouldParseAllFiles() { + public void shouldParseAllFiles() throws IOException { File compiledDir = new File("../wasm-corpus/src/main/resources/compiled/"); - List files = new ArrayList<>(); - files.addAll( - Arrays.asList( - compiledDir.listFiles( - (ignored, name) -> name.toLowerCase().endsWith(".wasm")))); + List files; + try (Stream stream = Files.list(compiledDir.toPath())) { + files = + stream.map(Path::toFile) + .filter(f -> f.getName().toLowerCase().endsWith(".wasm")) + .collect(Collectors.toList()); + } if (files.isEmpty()) { throw new RuntimeException("Could not find files"); @@ -132,7 +136,7 @@ public void shouldParseAllFiles() { for (var f : files) { try (InputStream is = new FileInputStream(f)) { Parser.parse(is); - } catch (Exception e) { + } catch (IOException | RuntimeException e) { throw new RuntimeException(String.format("Failed to parse file %s", f), e); } } diff --git a/wasm/src/test/java/com/dylibso/chicory/wasm/types/ValueTest.java b/wasm/src/test/java/com/dylibso/chicory/wasm/types/ValueTest.java index 618722d64..52fc6fb68 100644 --- a/wasm/src/test/java/com/dylibso/chicory/wasm/types/ValueTest.java +++ b/wasm/src/test/java/com/dylibso/chicory/wasm/types/ValueTest.java @@ -53,7 +53,7 @@ public void equalsContract() { var i32FortyTwo = Value.i32(42); var i64FortyTwo = Value.i64(42L); var i32TwentyOne = Value.i32(21); - var f32TwentyOne = Value.f32(Float.floatToIntBits(21.f)); + var f32TwentyOne = Value.f32(Float.floatToIntBits(21.0f)); assertEquals(i32FortyTwo, i32FortyTwo); assertEquals(i32FortyTwo, Value.i32(42));