Skip to content

Commit

Permalink
Introduce MiscUtils#toIntExact
Browse files Browse the repository at this point in the history
with an assertion to detect integer overflows.

Also, introduce AbstractPointersObjectReadNode#executeInt to simplify some code.
  • Loading branch information
fniephaus committed Jun 10, 2020
1 parent cc5c5d2 commit 505bf4e
Show file tree
Hide file tree
Showing 12 changed files with 50 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import de.hpi.swa.trufflesqueak.model.NativeObject;
import de.hpi.swa.trufflesqueak.model.PointersObject;
import de.hpi.swa.trufflesqueak.model.layout.ObjectLayouts.FORM;
import de.hpi.swa.trufflesqueak.nodes.accessing.AbstractPointersObjectNodes.AbstractPointersObjectReadNode;
import de.hpi.swa.trufflesqueak.util.OSDetector;

final class Target_de_hpi_swa_trufflesqueak_io_SqueakDisplay implements SqueakDisplayInterface {
Expand Down Expand Up @@ -143,18 +144,19 @@ public void close() {
@Override
@TruffleBoundary
public void open(final PointersObject sqDisplay) {
bitmap = (NativeObject) sqDisplay.instVarAt0Slow(FORM.BITS);
final AbstractPointersObjectReadNode readNode = AbstractPointersObjectReadNode.getUncached();
bitmap = readNode.executeNative(sqDisplay, FORM.BITS);
if (!bitmap.isIntType()) {
throw SqueakException.create("Display bitmap expected to be a words object");
}

final int depth = (int) (long) sqDisplay.instVarAt0Slow(FORM.DEPTH);
final int depth = readNode.executeInt(sqDisplay, FORM.DEPTH);
if (depth != 32) {
throw SqueakException.create("Expected 32bit display");
}
if (window.isNull()) {
width = (int) (long) sqDisplay.instVarAt0Slow(FORM.WIDTH);
height = (int) (long) sqDisplay.instVarAt0Slow(FORM.HEIGHT);
width = readNode.executeInt(sqDisplay, FORM.WIDTH);
height = readNode.executeInt(sqDisplay, FORM.HEIGHT);
try (CCharPointerHolder title = CTypeConversion.toCString(DEFAULT_WINDOW_TITLE)) {
window = SDL.createWindow(
title.get(),
Expand All @@ -172,7 +174,7 @@ public void open(final PointersObject sqDisplay) {
fullDamage();
getNextEvent(); // Poll and drop fix events for faster window initialization.
} else {
resizeTo((int) (long) sqDisplay.instVarAt0Slow(FORM.WIDTH), (int) (long) sqDisplay.instVarAt0Slow(FORM.HEIGHT));
resizeTo(readNode.executeInt(sqDisplay, FORM.WIDTH), readNode.executeInt(sqDisplay, FORM.HEIGHT));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ public NativeObject getSpecialSelector(final int index) {
}

public int getSpecialSelectorNumArgs(final int index) {
return (int) (long) getSpecialSelectors().getObjectStorage()[index * 2 + 1];
return MiscUtils.toIntExact((long) getSpecialSelectors().getObjectStorage()[index * 2 + 1]);
}

public void setSemaphore(final int index, final AbstractSqueakObject semaphore) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import de.hpi.swa.trufflesqueak.model.PointersObject;
import de.hpi.swa.trufflesqueak.model.layout.ObjectLayouts.FORM;
import de.hpi.swa.trufflesqueak.model.layout.ObjectLayouts.SPECIAL_OBJECT;
import de.hpi.swa.trufflesqueak.nodes.accessing.AbstractPointersObjectNodes.AbstractPointersObjectReadNode;
import de.hpi.swa.trufflesqueak.nodes.plugins.HostWindowPlugin;
import de.hpi.swa.trufflesqueak.shared.SqueakLanguageConfig;
import de.hpi.swa.trufflesqueak.util.MiscUtils;
Expand Down Expand Up @@ -147,12 +148,13 @@ public void paintComponent(final Graphics g) {

private void setSqDisplay(final PointersObject sqDisplay) {
CompilerDirectives.transferToInterpreterAndInvalidate();
final NativeObject bitmap = (NativeObject) sqDisplay.instVarAt0Slow(FORM.BITS);
final AbstractPointersObjectReadNode readNode = AbstractPointersObjectReadNode.getUncached();
final NativeObject bitmap = readNode.executeNative(sqDisplay, FORM.BITS);
if (!bitmap.isIntType()) {
throw SqueakException.create("Display bitmap expected to be a words object");
}
final int width = (int) (long) sqDisplay.instVarAt0Slow(FORM.WIDTH);
final int height = (int) (long) sqDisplay.instVarAt0Slow(FORM.HEIGHT);
final int width = readNode.executeInt(sqDisplay, FORM.WIDTH);
final int height = readNode.executeInt(sqDisplay, FORM.HEIGHT);
assert (long) sqDisplay.instVarAt0Slow(FORM.DEPTH) == 32 : "Unsupported display depth";
if (width > 0 && height > 0) {
bufferedImage = MiscUtils.new32BitBufferedImage(bitmap.getIntStorage(), width, height);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ public final void fillin(final SqueakImageChunk chunk) {
}

private int getHeader() {
return (int) (long) literals[0];
return MiscUtils.toIntExact((long) literals[0]);
}

protected final void decodeHeader() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import de.hpi.swa.trufflesqueak.nodes.accessing.AbstractPointersObjectNodes.AbstractPointersObjectWriteNode;
import de.hpi.swa.trufflesqueak.nodes.bytecodes.MiscellaneousBytecodes.CallPrimitiveNode;
import de.hpi.swa.trufflesqueak.util.FrameAccess;
import de.hpi.swa.trufflesqueak.util.MiscUtils;
import de.hpi.swa.trufflesqueak.util.ObjectGraphUtils.ObjectTracer;

public final class ContextObject extends AbstractSqueakObjectWithHash {
Expand Down Expand Up @@ -152,9 +153,9 @@ public void fillinContext(final SqueakImageChunk chunk) {
if (pc == NilObject.SINGLETON) {
removeInstructionPointer();
} else {
setInstructionPointer((int) (long) pc);
setInstructionPointer(MiscUtils.toIntExact((long) pc));
}
setStackPointer((int) (long) pointers[CONTEXT.STACKPOINTER]);
setStackPointer(MiscUtils.toIntExact((long) pointers[CONTEXT.STACKPOINTER]));
for (int i = CONTEXT.TEMP_FRAME_START; i < pointers.length; i++) {
atTempPut(i - CONTEXT.TEMP_FRAME_START, pointers[i]);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,19 +123,19 @@ public int[] getFormBits(final AbstractPointersObjectReadNode readNode) {
}

public int getFormDepth(final AbstractPointersObjectReadNode readNode) {
return (int) readNode.executeLong(this, FORM.DEPTH);
return readNode.executeInt(this, FORM.DEPTH);
}

public int getFormHeight(final AbstractPointersObjectReadNode readNode) {
return (int) readNode.executeLong(this, FORM.HEIGHT);
return readNode.executeInt(this, FORM.HEIGHT);
}

public PointersObject getFormOffset(final AbstractPointersObjectReadNode readNode) {
return readNode.executePointers(this, FORM.OFFSET);
}

public int getFormWidth(final AbstractPointersObjectReadNode readNode) {
return (int) readNode.executeLong(this, FORM.WIDTH);
return readNode.executeInt(this, FORM.WIDTH);
}

public PointersObject removeFirstLinkOfList(final AbstractPointersObjectReadNode readNode, final AbstractPointersObjectWriteNode writeNode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import de.hpi.swa.trufflesqueak.nodes.AbstractNode;
import de.hpi.swa.trufflesqueak.nodes.accessing.AbstractPointersObjectNodesFactory.AbstractPointersObjectReadNodeGen;
import de.hpi.swa.trufflesqueak.nodes.accessing.AbstractPointersObjectNodesFactory.AbstractPointersObjectWriteNodeGen;
import de.hpi.swa.trufflesqueak.util.MiscUtils;

public class AbstractPointersObjectNodes {
protected static final int CACHE_LIMIT = 6;
Expand Down Expand Up @@ -58,6 +59,10 @@ public static AbstractPointersObjectReadNode getUncached() {

public abstract PointersObject executePointers(AbstractPointersObject obj, int index);

public final int executeInt(final AbstractPointersObject obj, final int index) {
return MiscUtils.toIntExact(executeLong(obj, index));
}

@SuppressWarnings("unused")
@Specialization(guards = {"cachedIndex == index", "object.getLayout() == cachedLayout"}, //
assumptions = "cachedLayout.getValidAssumption()", limit = "CACHE_LIMIT")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import de.hpi.swa.trufflesqueak.exceptions.PrimitiveExceptions.PrimitiveFailed;
import de.hpi.swa.trufflesqueak.exceptions.SqueakExceptions.SqueakException;
import de.hpi.swa.trufflesqueak.image.SqueakImageContext;
import de.hpi.swa.trufflesqueak.model.AbstractPointersObject;
import de.hpi.swa.trufflesqueak.model.AbstractSqueakObject;
import de.hpi.swa.trufflesqueak.model.FloatObject;
import de.hpi.swa.trufflesqueak.model.NativeObject;
Expand All @@ -22,6 +23,7 @@
import de.hpi.swa.trufflesqueak.model.VariablePointersObject;
import de.hpi.swa.trufflesqueak.model.layout.ObjectLayouts.FORM;
import de.hpi.swa.trufflesqueak.nodes.SqueakGuards;
import de.hpi.swa.trufflesqueak.util.MiscUtils;
import de.hpi.swa.trufflesqueak.util.UnsafeUtils;

/* Automatically generated by
Expand Down Expand Up @@ -1556,10 +1558,11 @@ private static int fetchIntOrFloatofObjectifNil(final int fieldIndex, final Poin
final Object fieldOop = fetchPointerofObject(fieldIndex, objectPointer);
if (fieldOop instanceof Long) {
final long longValue = (long) fieldOop;
if (Integer.MIN_VALUE <= longValue && longValue <= Integer.MAX_VALUE) {
return (int) (long) fieldOop;
if ((int) longValue == longValue) {
return (int) longValue;
} else {
PrimitiveFailed.andTransferToInterpreter(); // Fail because longValue is too big.
}
PrimitiveFailed.andTransferToInterpreter(); // Fail because value is too big.
}
if (fieldOop == NilObject.SINGLETON) {
return (int) defaultValue;
Expand Down Expand Up @@ -4048,27 +4051,17 @@ private long warpPickSourcePixelsxDeltahyDeltahxDeltavyDeltavdstShiftIncflags(fi
* POLYFILLS
*/

private int fetchIntegerofObject(final int index, final VariablePointersObject object) {
final Object value = fetchPointerofObject(index, object);
if (value instanceof Long) {
return (int) (long) value;
} else {
successFlag = false;
return 0;
}
}

private int fetchIntegerofObject(final int index, final PointersObject object) {
private int fetchIntegerofObject(final int index, final AbstractPointersObject object) {
final Object value = fetchPointerofObject(index, object);
if (value instanceof Long) {
return (int) (long) value;
return MiscUtils.toIntExact((long) value);
} else {
successFlag = false;
return 0;
}
}

private static PointersObject fetchPointerofObjectOrNull(final int index, final PointersObject object) {
private static PointersObject fetchPointerofObjectOrNull(final int index, final AbstractPointersObject object) {
final Object value = fetchPointerofObject(index, object);
if (value == NilObject.SINGLETON) {
return null;
Expand All @@ -4077,7 +4070,7 @@ private static PointersObject fetchPointerofObjectOrNull(final int index, final
}
}

private static NativeObject fetchNativeofObjectOrNull(final int index, final VariablePointersObject object) {
private static NativeObject fetchNativeofObjectOrNull(final int index, final AbstractPointersObject object) {
final Object value = fetchPointerofObject(index, object);
if (value == NilObject.SINGLETON) {
return null;
Expand All @@ -4086,20 +4079,7 @@ private static NativeObject fetchNativeofObjectOrNull(final int index, final Var
}
}

private static NativeObject fetchNativeofObjectOrNull(final int index, final PointersObject object) {
final Object value = fetchPointerofObject(index, object);
if (value == NilObject.SINGLETON) {
return null;
} else {
return (NativeObject) value;
}
}

private static Object fetchPointerofObject(final int index, final VariablePointersObject object) {
return object.instVarAt0Slow(index);
}

private static Object fetchPointerofObject(final int index, final PointersObject object) {
private static Object fetchPointerofObject(final int index, final AbstractPointersObject object) {
return object.instVarAt0Slow(index);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ protected static final Object doFormToBufferedImage(@SuppressWarnings("unused")
try {
/* Extract information from form. */
final NativeObject bits = (NativeObject) readNode.execute(form, FORM.BITS);
final int width = (int) (long) readNode.execute(form, FORM.WIDTH);
final int height = (int) (long) readNode.execute(form, FORM.HEIGHT);
final int width = readNode.executeInt(form, FORM.WIDTH);
final int height = readNode.executeInt(form, FORM.HEIGHT);
final long depth = (long) readNode.execute(form, FORM.DEPTH);
if (!bits.isIntType() || depth != 32) {
CompilerDirectives.transferToInterpreter();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import de.hpi.swa.trufflesqueak.model.NativeObject;
import de.hpi.swa.trufflesqueak.model.PointersObject;
import de.hpi.swa.trufflesqueak.nodes.SqueakGuards;
import de.hpi.swa.trufflesqueak.util.MiscUtils;

/* Automatically generated by
VMPluginCodeGenerator * VMMaker.oscog-eem.2518 uuid: 33deb326-de86-45aa-be20-d64c10de4e70 from
Expand Down Expand Up @@ -926,7 +927,7 @@ private static int[] fetchNativePointerOfObjectWithExpectedLength(final Pointers
private static int fetchIntegerofObject(final int index, final PointersObject arrayOop) {
final Object value = fetchPointerofObject(index, arrayOop);
if (value instanceof Long) {
return (int) (long) value;
return MiscUtils.toIntExact((long) value);
} else {
throw PrimitiveFailed.GENERIC_ERROR;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,8 @@ protected final PointersObject doCursor(final PointersObject receiver, @Suppress
@CachedContext(SqueakLanguage.class) final SqueakImageContext image) {
if (image.hasDisplay()) {
final PointersObject offset = receiver.getFormOffset(cursorReadNode);
final int offsetX = Math.abs((int) offsetReadNode.executeLong(offset, POINT.X));
final int offsetY = Math.abs((int) offsetReadNode.executeLong(offset, POINT.Y));
final int offsetX = Math.abs(offsetReadNode.executeInt(offset, POINT.X));
final int offsetY = Math.abs(offsetReadNode.executeInt(offset, POINT.Y));
image.getDisplay().setCursor(receiver.getFormBits(cursorReadNode), null, receiver.getFormWidth(cursorReadNode), receiver.getFormHeight(cursorReadNode),
receiver.getFormDepth(cursorReadNode), offsetX, offsetY);
}
Expand All @@ -217,8 +217,8 @@ protected final PointersObject doCursor(final PointersObject receiver, final Poi
final int height = receiver.getFormHeight(cursorReadNode);
final int width = receiver.getFormWidth(cursorReadNode);
final PointersObject offset = receiver.getFormOffset(cursorReadNode);
final int offsetX = Math.abs((int) offsetReadNode.executeLong(offset, POINT.X));
final int offsetY = Math.abs((int) offsetReadNode.executeLong(offset, POINT.Y));
final int offsetX = Math.abs(offsetReadNode.executeInt(offset, POINT.X));
final int offsetY = Math.abs(offsetReadNode.executeInt(offset, POINT.Y));
if (depthProfile.profile(depth == 1)) {
final int[] mask = cursorReadNode.executeNative(maskObject, FORM.BITS).getIntStorage();
image.getDisplay().setCursor(words, mask, width, height, 2, offsetX, offsetY);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,12 @@ public static byte[] toBytes(final String value) {
return value.getBytes();
}

/** Similar to {@link Math#toIntExact(long)}, but uses an assertion. */
public static int toIntExact(final long value) {
assert (int) value == value;
return (int) value;
}

public static long toJavaMicrosecondsUTC(final long microseconds) {
return microseconds - EPOCH_DELTA_MICROSECONDS;
}
Expand Down

0 comments on commit 505bf4e

Please sign in to comment.