@@ -9,6 +9,7 @@
import som.interpreter.Invokable;
import som.interpreter.Method;
import som.interpreter.nodes.nary.BinaryComplexOperation;
import som.interpreter.nodes.nary.UnaryBasicOperation;
import som.interpreter.nodes.nary.UnaryExpressionNode;
import som.vm.constants.Classes;
import som.vm.constants.Nil;
@@ -33,6 +34,8 @@ public final class SystemPrims {
@GenerateNodeFactory
@Primitive("systemModuleObject:")
public abstract static class SystemModuleObjectPrim extends UnaryExpressionNode {
public SystemModuleObjectPrim(final SourceSection source) { super(source); }

@Specialization
public final Object set(final SObjectWithClass system) {
SystemModule = system;
@@ -55,6 +58,8 @@ public static Object loadModule(final String path) {
@GenerateNodeFactory
@Primitive("load:")
public abstract static class LoadPrim extends UnaryExpressionNode {
public LoadPrim(final SourceSection source) { super(source); }

@Specialization
public final Object doSObject(final String moduleName) {
return loadModule(moduleName);
@@ -79,6 +84,8 @@ public final Object load(final String filename, final SObjectWithClass moduleObj
@GenerateNodeFactory
@Primitive("exit:")
public abstract static class ExitPrim extends UnaryExpressionNode {
public ExitPrim(final SourceSection source) { super(source); }

@Specialization
public final Object doSObject(final long error) {
VM.exit((int) error);
@@ -89,6 +96,8 @@ public final Object doSObject(final long error) {
@GenerateNodeFactory
@Primitive("printString:")
public abstract static class PrintStringPrim extends UnaryExpressionNode {
public PrintStringPrim(final SourceSection source) { super(source); }

@Specialization
public final Object doSObject(final String argument) {
VM.print(argument);
@@ -104,6 +113,8 @@ public final Object doSObject(final SSymbol argument) {
@GenerateNodeFactory
@Primitive("printNewline:")
public abstract static class PrintInclNewlinePrim extends UnaryExpressionNode {
public PrintInclNewlinePrim(final SourceSection source) { super(source); }

@Specialization
public final Object doSObject(final String argument) {
VM.println(argument);
@@ -114,6 +125,8 @@ public final Object doSObject(final String argument) {
@GenerateNodeFactory
@Primitive("printStackTrace:")
public abstract static class PrintStackTracePrim extends UnaryExpressionNode {
public PrintStackTracePrim(final SourceSection source) { super(source); }

@Specialization
public final Object doSObject(final Object receiver) {
printStackTrace();
@@ -168,6 +181,8 @@ public Method visitFrame(final FrameInstance frameInstance) {
@GenerateNodeFactory
@Primitive("vmArguments:")
public abstract static class VMArgumentsPrim extends UnaryExpressionNode {
public VMArgumentsPrim(final SourceSection source) { super(source); }

@Specialization
public final SImmutableArray getArguments(final Object receiver) {
return new SImmutableArray(VM.getArguments(), Classes.valueArrayClass);
@@ -177,6 +192,8 @@ public final SImmutableArray getArguments(final Object receiver) {
@GenerateNodeFactory
@Primitive("systemGC:")
public abstract static class FullGCPrim extends UnaryExpressionNode {
public FullGCPrim(final SourceSection source) { super(source); }

@Specialization
public final Object doSObject(final Object receiver) {
System.gc();
@@ -186,7 +203,9 @@ public final Object doSObject(final Object receiver) {

@GenerateNodeFactory
@Primitive("systemTime:")
public abstract static class TimePrim extends UnaryExpressionNode {
public abstract static class TimePrim extends UnaryBasicOperation {
public TimePrim(final SourceSection source) { super(source); }

@Specialization
public final long doSObject(final Object receiver) {
return System.currentTimeMillis() - startTime;
@@ -195,7 +214,9 @@ public final long doSObject(final Object receiver) {

@GenerateNodeFactory
@Primitive("systemTicks:")
public abstract static class TicksPrim extends UnaryExpressionNode {
public abstract static class TicksPrim extends UnaryBasicOperation {
public TicksPrim(final SourceSection source) { super(source); }

@Specialization
public final long doSObject(final Object receiver) {
return System.nanoTime() / 1000L - startMicroTime;
@@ -11,12 +11,15 @@
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.source.SourceSection;


public final class ActorClasses {
@GenerateNodeFactory
@Primitive("actorsFarReferenceClass:")
public abstract static class SetFarReferenceClassPrim extends UnaryExpressionNode {
public SetFarReferenceClassPrim(final SourceSection source) { super(source); }

@Specialization
public final SClass setClass(final SClass value) {
SFarReference.setSOMClass(value);
@@ -27,6 +30,8 @@ public final SClass setClass(final SClass value) {
@GenerateNodeFactory
@Primitive("actorsPromiseClass:")
public abstract static class SetPromiseClassPrim extends UnaryExpressionNode {
public SetPromiseClassPrim(final SourceSection source) { super(source); }

@Specialization
public final SClass setClass(final SClass value) {
SPromise.setSOMClass(value);
@@ -37,6 +42,8 @@ public final SClass setClass(final SClass value) {
@GenerateNodeFactory
@Primitive("actorsPairClass:")
public abstract static class SetPairClassPrim extends UnaryExpressionNode {
public SetPairClassPrim(final SourceSection source) { super(source); }

@Specialization
public final SClass setClass(final SClass value) {
SPromise.setPairClass(value);
@@ -47,6 +54,8 @@ public final SClass setClass(final SClass value) {
@GenerateNodeFactory
@Primitive("actorsResolverClass:")
public abstract static class SetResolverClassPrim extends UnaryExpressionNode {
public SetResolverClassPrim(final SourceSection source) { super(source); }

@Specialization
public final SClass setClass(final SClass value) {
SResolver.setSOMClass(value);
@@ -59,6 +68,8 @@ public final SClass setClass(final SClass value) {
@GenerateNodeFactory
@Primitive("actorsModule:")
public abstract static class SetModulePrim extends UnaryExpressionNode {
public SetModulePrim(final SourceSection source) { super(source); }

@Specialization
public final SImmutableObject setClass(final SImmutableObject value) {
ActorModule = value;
@@ -44,6 +44,8 @@ protected static final DirectCallNode create() {
return Truffle.getRuntime().createDirectCallNode(((SInvokable) disp).getCallTarget());
}

public CreatePromisePairPrim(final SourceSection source) { super(source); }

@Specialization
public final SImmutableObject createPromisePair(final VirtualFrame frame,
final Object nil, @Cached("create()") final DirectCallNode factory) {
@@ -5,11 +5,13 @@

import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.source.SourceSection;


@GenerateNodeFactory
@Primitive("doubleExp:")
public abstract class ExpPrim extends UnaryExpressionNode {
public ExpPrim(final SourceSection source) { super(source); }

@Specialization
public final double doExp(final double rcvr) {
@@ -1,15 +1,17 @@
package som.primitives.arithmetic;

import som.interpreter.nodes.nary.UnaryExpressionNode;
import som.interpreter.nodes.nary.UnaryBasicOperation;
import som.primitives.Primitive;

import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.source.SourceSection;


@GenerateNodeFactory
@Primitive("doubleLog:")
public abstract class LogPrim extends UnaryExpressionNode {
public abstract class LogPrim extends UnaryBasicOperation {
public LogPrim(final SourceSection source) { super(source); }

@Specialization
public final double doLog(final double rcvr) {
@@ -1,15 +1,17 @@
package som.primitives.arithmetic;

import som.interpreter.nodes.nary.UnaryExpressionNode;
import som.interpreter.nodes.nary.UnaryBasicOperation;
import som.primitives.Primitive;

import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.source.SourceSection;


@GenerateNodeFactory
@Primitive("doubleSin:")
public abstract class SinPrim extends UnaryExpressionNode {
public abstract class SinPrim extends UnaryBasicOperation {
public SinPrim(final SourceSection source) { super(source); }

@Specialization
public final double doSin(final double rcvr) {
@@ -2,19 +2,19 @@

import java.math.BigInteger;

import som.interpreter.nodes.nary.UnaryExpressionNode;
import som.interpreter.nodes.nary.UnaryBasicOperation;
import som.primitives.Primitive;

import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.source.SourceSection;


@GenerateNodeFactory
@Primitive({"intSqrt:", "doubleSqrt:"})
public abstract class SqrtPrim extends UnaryExpressionNode {

public SqrtPrim() { super(null); }
public abstract class SqrtPrim extends UnaryBasicOperation {
public SqrtPrim(final SourceSection source) { super(source); }

private final BranchProfile longReturn = BranchProfile.create();
private final BranchProfile doubleReturn = BranchProfile.create();
@@ -1,7 +1,6 @@
package som.primitives.arrays;

import som.compiler.Tags;
import som.interpreter.nodes.SOMNode;
import som.interpreter.nodes.nary.BinaryBasicOperation;
import som.primitives.Primitive;
import som.vm.constants.Nil;
@@ -12,6 +11,8 @@
import com.oracle.truffle.api.profiles.ValueProfile;
import com.oracle.truffle.api.source.SourceSection;

import dym.Tagging;


@GenerateNodeFactory
@Primitive("array:at:")
@@ -20,7 +21,7 @@ public abstract class AtPrim extends BinaryBasicOperation {
private final ValueProfile storageType = ValueProfile.createClassProfile();

protected AtPrim(final SourceSection source) {
super(SOMNode.cloneAndAddTags(source, Tags.ARRAY_READ));
super(Tagging.cloneAndAddTags(source, Tags.ARRAY_READ));
}

@Specialization(guards = "receiver.isEmptyType()")
@@ -3,7 +3,6 @@
import java.util.Arrays;

import som.compiler.Tags;
import som.interpreter.nodes.SOMNode;
import som.interpreter.nodes.nary.TernaryExpressionNode;
import som.primitives.Primitive;
import som.vm.constants.Nil;
@@ -16,6 +15,8 @@
import com.oracle.truffle.api.profiles.ValueProfile;
import com.oracle.truffle.api.source.SourceSection;

import dym.Tagging;


@GenerateNodeFactory
@ImportStatic(Nil.class)
@@ -25,7 +26,7 @@ public abstract class AtPutPrim extends TernaryExpressionNode {
private final ValueProfile storageType = ValueProfile.createClassProfile();

protected AtPutPrim(final SourceSection source) {
super(SOMNode.cloneAndAddTags(source, Tags.ARRAY_WRITE));
super(Tagging.cloneAndAddTags(source, Tags.ARRAY_WRITE));
}

protected static final boolean valueIsNotLong(final Object value) {
@@ -5,9 +5,11 @@

import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.profiles.ValueProfile;
import com.oracle.truffle.api.source.SourceSection;


public abstract class CopyPrim extends UnaryExpressionNode {
public CopyPrim(final SourceSection source) { super(source); }

private final ValueProfile storageType = ValueProfile.createClassProfile();

@@ -25,7 +25,7 @@ public abstract class DoIndexesPrim extends BinaryComplexOperation {
public DoIndexesPrim(final SourceSection source) {
super(source);
block = BlockDispatchNodeGen.create();
length = SizeAndLengthPrimFactory.create(null);
length = SizeAndLengthPrimFactory.create(null, null);
}

@Specialization
@@ -19,7 +19,7 @@
public abstract class NewImmutableArrayNode extends TernaryExpressionNode {

@Child protected BlockDispatchNode block = BlockDispatchNodeGen.create();
@Child protected IsValue isValue = IsValueFactory.create(null);
@Child protected IsValue isValue = IsValueFactory.create(null, null);

public static boolean isValueArrayClass(final SClass valueArrayClass) {
return Classes.valueArrayClass == valueArrayClass;
@@ -1,7 +1,6 @@
package som.primitives.arrays;

import som.compiler.Tags;
import som.interpreter.nodes.SOMNode;
import som.interpreter.nodes.nary.BinaryComplexOperation;
import som.primitives.Primitive;
import som.vm.constants.Classes;
@@ -14,13 +13,15 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.source.SourceSection;

import dym.Tagging;


@GenerateNodeFactory
@Primitive("array:new:")
public abstract class NewPrim extends BinaryComplexOperation {

public NewPrim(final SourceSection source) {
super(SOMNode.cloneAndAddTags(source, Tags.NEW_ARRAY));
super(Tagging.cloneAndAddTags(source, Tags.NEW_ARRAY));
}

protected static final boolean receiverIsArrayClass(final SClass receiver) {
@@ -11,6 +11,7 @@
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.profiles.ValueProfile;
import com.oracle.truffle.api.source.SourceSection;


@NodeChildren({
@@ -19,7 +20,7 @@
public abstract class ToArgumentsArrayNode extends ExpressionNode {
private final ValueProfile storageType = ValueProfile.createClassProfile();

public ToArgumentsArrayNode() { super(null); }
public ToArgumentsArrayNode() { super((SourceSection) null); }

public static final boolean isNull(final Object somArray) {
return somArray == null;
@@ -22,9 +22,17 @@
public abstract class AbstractSymbolDispatch extends Node {
public static final int INLINE_CACHE_SIZE = 6;

private final SourceSection sourceSection;

protected AbstractSymbolDispatch(final SourceSection source) {
super(source);
super();
assert source != null;
this.sourceSection = source;
}

@Override
public final SourceSection getSourceSection() {
return sourceSection;
}

// TODO: think about how we can add a specialization for slot accesses, especially Caching Class lost stuff. Slot access are very expensive when uncached, we should avoid that, because we create nodes, every single time
@@ -140,34 +140,33 @@ private static SInvokable constructVmMirrorPrimitive(
// ignore the implicit vmMirror argument
final int numArgs = signature.getNumberOfSignatureArguments() - 1;

Source s = Source.fromNamedText("primitive", factory.getClass().getSimpleName());
MethodBuilder prim = new MethodBuilder(true);
ExpressionNode[] args = new ExpressionNode[numArgs];

for (int i = 0; i < numArgs; i++) {
// we do not pass the vmMirror, makes it easier to use the same primitives
// as replacements on the node level
args[i] = new LocalArgumentReadNode(i + 1, null);
args[i] = new LocalArgumentReadNode(i + 1, s.createSection(factory.getClass().getSimpleName(), 1));
}

ExpressionNode primNode;
SourceSection source = Source.fromNamedText("primitive",
factory.getClass().getSimpleName()).
createSection(factory.getClass().getSimpleName(), 1);
SourceSection source = s.createSection(factory.getClass().getSimpleName(), 1);
switch (numArgs) {
case 1:
primNode = factory.createNode(args[0]);
primNode = factory.createNode(source, args[0]);
break;
case 2:
// HACK for node class where we use `executeWith`
if (factory == PutAllNodeFactory.getInstance()) {
primNode = factory.createNode(source, args[0], args[1],
SizeAndLengthPrimFactory.create(null));
SizeAndLengthPrimFactory.create(null, null));
// } else if (factory == SpawnWithArgsPrimFactory.getInstance()) {
// primNode = factory.createNode(args[0], args[1],
// ToArgumentsArrayNodeGen.create(null, null));
} else if (factory == CreateActorPrimFactory.getInstance()) {
primNode = factory.createNode(source, args[0], args[1],
IsValueFactory.create(null));
IsValueFactory.create(null, null));
} else {
primNode = factory.createNode(source, args[0], args[1]);
}