Skip to content

Commit

Permalink
Fixes to Table model class (#199)
Browse files Browse the repository at this point in the history
Make the limits immutable. Use the maximum limit constant `0x1_0000_0000` when the upper limit is unspecified, and simplify comparisons accordingly.
There is a class which represents limits; change `Table` to reuse it.
  • Loading branch information
dmlloyd authored Jan 26, 2024
1 parent 5a7d59f commit e1538d1
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 51 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static com.dylibso.chicory.wasm.types.Value.REF_NULL_VALUE;

import com.dylibso.chicory.wasm.types.ElementType;
import com.dylibso.chicory.wasm.types.Limits;
import com.dylibso.chicory.wasm.types.Table;
import java.util.Map;

Expand All @@ -28,14 +29,10 @@ public HostTable(String moduleName, String fieldName, Map<Integer, Integer> func
}
}

this.table = new Table(ElementType.FuncRef, maxFuncRef, maxFuncRef);
this.table = new Table(ElementType.FuncRef, new Limits(maxFuncRef, maxFuncRef));

for (int i = 0; i < maxFuncRef; i++) {
if (funcRefs.containsKey(i)) {
this.table.setRef(i, funcRefs.get(i));
} else {
this.table.setRef(i, REF_NULL_VALUE);
}
this.table.setRef(i, funcRefs.getOrDefault(i, REF_NULL_VALUE));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2146,7 +2146,7 @@ private static void TABLE_GET(MStack stack, Instance instance, long[] operands)
table = instance.imports().table(idx).table();
}
var i = stack.pop().asInt();
if (i < 0 || (table.limitMax() != 0 && i >= table.limitMax()) || i >= table.size()) {
if (i < 0 || i >= table.limits().max() || i >= table.size()) {
throw new WASMRuntimeException("out of bounds table access");
}
stack.push(table.ref(i));
Expand Down
25 changes: 10 additions & 15 deletions wasm/src/main/java/com/dylibso/chicory/wasm/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -359,11 +359,10 @@ private static ImportSection parseImportSection(ByteBuffer buffer, long sectionI
var limitType = (int) readVarUInt32(buffer);
assert limitType == 0x00 || limitType == 0x01;
var min = (int) readVarUInt32(buffer);
var max = -1;
if (limitType > 0) {
max = (int) readVarUInt32(buffer);
}
var limits = new Limits(min, max);
var limits =
limitType > 0
? new Limits(min, readVarUInt32(buffer))
: new Limits(min);

ImportDesc tableDesc = new ImportDesc(descType, limits, tableType);
imports[i] = new Import(moduleName, fieldName, tableDesc);
Expand All @@ -374,11 +373,10 @@ private static ImportSection parseImportSection(ByteBuffer buffer, long sectionI
var limitType = (int) readVarUInt32(buffer);
assert limitType == 0x00 || limitType == 0x01;
var min = (int) readVarUInt32(buffer);
var max = -1;
if (limitType > 0) {
max = (int) readVarUInt32(buffer);
}
var limits = new Limits(min, max);
var limits =
limitType > 0
? new Limits(min, readVarUInt32(buffer))
: new Limits(min);

ImportDesc memDesc = new ImportDesc(descType, limits);
imports[i] = new Import(moduleName, fieldName, memDesc);
Expand Down Expand Up @@ -421,11 +419,8 @@ private static TableSection parseTableSection(ByteBuffer buffer, long sectionId)
var limitType = readVarUInt32(buffer);
assert limitType == 0x00 || limitType == 0x01;
var min = readVarUInt32(buffer);
Long max = null;
if (limitType == 0x01) {
max = readVarUInt32(buffer);
}
tables[i] = new Table(tableType, min, max);
var limits = limitType > 0 ? new Limits(min, readVarUInt32(buffer)) : new Limits(min);
tables[i] = new Table(tableType, limits);
}

return new TableSection(sectionId, tables);
Expand Down
26 changes: 19 additions & 7 deletions wasm/src/main/java/com/dylibso/chicory/wasm/types/Limits.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
package com.dylibso.chicory.wasm.types;

public class Limits {
private final int min;
private final int max;
public static final long LIMIT_MAX = 0x1_0000_0000L;

public Limits(int min, int max) {
this.min = min;
this.max = max;
private static final Limits UNBOUNDED = new Limits(0);

private final long min;
private final long max;

public Limits(long min) {
this(min, LIMIT_MAX);
}

public Limits(long min, long max) {
this.min = Math.min(Math.max(0, min), LIMIT_MAX);
this.max = Math.min(Math.max(min, max), LIMIT_MAX);
}

public int min() {
public long min() {
return min;
}

public int max() {
public long max() {
return max;
}

public static Limits unbounded() {
return UNBOUNDED;
}
}
35 changes: 13 additions & 22 deletions wasm/src/main/java/com/dylibso/chicory/wasm/types/Table.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,37 @@

import com.dylibso.chicory.wasm.exceptions.ChicoryException;
import java.util.Arrays;
import java.util.Objects;

public class Table {
private final ElementType elementType;
private long limitMin;
private long limitMax;
private final Limits limits;

private int[] refs;

public Table(ElementType elementType, long limitMin, Long limitMax) {
this.elementType = elementType;
this.limitMin = limitMin;
if (limitMax != null) {
this.limitMax = limitMax;
}
refs = new int[(int) limitMin];
for (int i = 0; i < limitMin; i++) {
refs[i] = REF_NULL_VALUE;
}
public Table(final ElementType elementType, final Limits limits) {
this.elementType = Objects.requireNonNull(elementType, "elementType");
this.limits = Objects.requireNonNull(limits, "limits");
refs = new int[(int) limits.min()];
Arrays.fill(refs, REF_NULL_VALUE);
}

public ElementType elementType() {
return elementType;
}

public long limitMin() {
return limitMin;
}

public Long limitMax() {
return limitMax;
public Limits limits() {
return limits;
}

public int size() {
return refs.length;
}

public int grow(int size, Integer value) {
public int grow(int size, int value) {
var oldSize = refs.length;
var targetSize = oldSize + size;
if (size < 0 || (limitMax != 0 && targetSize > limitMax)) {
if (size < 0 || targetSize > limits().max()) {
return -1;
}
var newRefs = Arrays.copyOf(refs, targetSize);
Expand All @@ -53,7 +44,7 @@ public int grow(int size, Integer value) {
}

public Value ref(int index) {
int res = REF_NULL_VALUE;
int res;
try {
res = this.refs[index];
} catch (IndexOutOfBoundsException e) {
Expand All @@ -66,7 +57,7 @@ public Value ref(int index) {
}
}

public void setRef(int index, Integer value) {
public void setRef(int index, int value) {
try {
this.refs[index] = value;
} catch (IndexOutOfBoundsException e) {
Expand Down

0 comments on commit e1538d1

Please sign in to comment.