├── debug ├── fast ├── docs ├── AUTHORS.md ├── LICENSE.md ├── README.md ├── CHANGELOG.md ├── codespeed.png ├── eclipse-project-outline.png ├── conf.py ├── index.md ├── release-checklist.md └── vs-code.md ├── tests ├── files │ └── data │ │ ├── C │ │ └── B ├── streams │ ├── Text.t │ └── Binary.blob ├── dym │ └── expected-results.tar.bz2 ├── superinstructions │ └── expected-results.tar.bz2 ├── java │ └── debugger │ │ └── ReflectionRegistrationTests.java └── snapshot │ └── test.sh ├── .gitattributes ├── core-lib ├── TestSuite │ ├── extension │ │ ├── .gitignore │ │ ├── src-cp-dep │ │ │ └── dep │ │ │ │ └── SomeDependency.java │ │ ├── .settings │ │ │ └── org.eclipse.jdt.apt.core.prefs │ │ ├── .checkstyle_suppressions.xml │ │ ├── README.md │ │ ├── .checkstyle │ │ ├── .factorypath │ │ ├── .project │ │ ├── src │ │ │ └── ext │ │ │ │ ├── Extension.java │ │ │ │ └── ExtensionPrims.java │ │ └── .classpath │ ├── BasicInterpreterTests │ │ ├── DoesNotUnderstand.ns │ │ ├── BlockInlining4.ns │ │ ├── BlockInlining5.ns │ │ ├── BlockInlining3.ns │ │ ├── Initializers.ns │ │ ├── BlockInlining2.ns │ │ ├── Parser.ns │ │ ├── MethodCall.ns │ │ ├── Exceptions.ns │ │ ├── ObjectCreation.ns │ │ ├── Return.ns │ │ └── Blocks.ns │ ├── SystemTests.ns │ └── BenchmarkHarnessTests.ns ├── Hello.ns ├── Benchmarks │ ├── LanguageFeatures │ │ └── DoesNotUnderstand │ │ │ ├── CalculatorDelegate.ns │ │ │ ├── Proxy.ns │ │ │ ├── DnuAdd.ns │ │ │ ├── DirectAdd.ns │ │ │ ├── PerformAdd.ns │ │ │ ├── Calculator.ns │ │ │ ├── DnuPerformAdd.ns │ │ │ ├── ProxyAdd.ns │ │ │ ├── CalculatorDnuPerform.ns │ │ │ └── IndirectAdd.ns │ ├── ForkJoin │ │ ├── FibSeq.ns │ │ ├── FibOpt.ns │ │ ├── FibNai.ns │ │ └── FibOne.ns │ └── ForkJoin.ns ├── demos │ ├── ForkJoinDemo.ns │ ├── ActorDemo.ns │ └── STMDemo.ns └── Transactions.ns ├── src ├── META-INF │ └── services │ │ └── java.nio.file.spi.FileTypeDetector ├── tools │ ├── replay │ │ ├── actors │ │ │ └── ExternalMessage.java │ │ ├── StringWrapper.java │ │ ├── ExternalDataSource.java │ │ ├── nodes │ │ │ ├── TraceNode.java │ │ │ ├── TraceActorContextNode.java │ │ │ └── TraceActorCreationNode.java │ │ └── TwoDArrayWrapper.java │ ├── dym │ │ ├── JsonSerializable.java │ │ ├── profiles │ │ │ ├── CreateCounter.java │ │ │ ├── ArrayCreationProfile.java │ │ │ ├── Counter.java │ │ │ ├── BranchProfile.java │ │ │ ├── ClosureApplicationProfile.java │ │ │ └── LoopProfile.java │ │ ├── nodes │ │ │ ├── ControlFlowProfileNode.java │ │ │ ├── LoopProfilingNode.java │ │ │ ├── LoopIterationReportNode.java │ │ │ ├── CountingNode.java │ │ │ ├── ReadProfilingNode.java │ │ │ ├── AllocationProfilingNode.java │ │ │ ├── ArrayAllocationProfilingNode.java │ │ │ ├── ReportReceiverNode.java │ │ │ ├── CallTargetNode.java │ │ │ ├── ReportResultNode.java │ │ │ ├── ClosureTargetNode.java │ │ │ └── InvocationProfilingNode.java │ │ └── CsvWriter.java │ ├── debugger │ │ ├── nodes │ │ │ ├── DisabledBreakpointNode.java │ │ │ ├── AbstractBreakpointNode.java │ │ │ └── BreakpointNode.java │ │ ├── message │ │ │ ├── TraceDataRequest.java │ │ │ ├── ProgramInfoRequest.java │ │ │ ├── ProgramInfoResponse.java │ │ │ ├── SymbolMessage.java │ │ │ ├── ScopesRequest.java │ │ │ ├── UpdateBreakpoint.java │ │ │ ├── StepMessage.java │ │ │ ├── InitializeConnection.java │ │ │ ├── Message.java │ │ │ ├── UpdateSourceSections.java │ │ │ ├── StackTraceRequest.java │ │ │ ├── VariablesRequest.java │ │ │ └── StoppedMessage.java │ │ ├── SteppingStrategy.java │ │ ├── entities │ │ │ ├── ReceiveOp.java │ │ │ ├── Implementation.java │ │ │ ├── SendOp.java │ │ │ ├── PassiveEntityType.java │ │ │ ├── DynamicScopeType.java │ │ │ ├── EntityType.java │ │ │ └── Marker.java │ │ ├── frontend │ │ │ ├── RuntimeScope.java │ │ │ └── ApplicationThreadTask.java │ │ ├── session │ │ │ ├── BreakpointInfo.java │ │ │ └── LineBreakpoint.java │ │ └── PrimitiveCallOrigin.java │ ├── snapshot │ │ ├── nodes │ │ │ ├── AbstractSerializationNode.java │ │ │ └── SerializerRootNode.java │ │ └── deserialization │ │ │ └── FixupInformation.java │ ├── superinstructions │ │ ├── TypeCounter.java │ │ └── TypeCountingNode.java │ └── Tagging.java └── som │ ├── vm │ ├── NotYetImplementedException.java │ ├── constants │ │ ├── KernelObj.java │ │ └── Nil.java │ ├── NotAFileException.java │ ├── SomFileDetector.java │ ├── Extension.java │ └── Activity.java │ ├── interpreter │ ├── nodes │ │ ├── ISpecialSend.java │ │ ├── literals │ │ │ ├── NilLiteralNode.java │ │ │ ├── DoubleLiteralNode.java │ │ │ ├── IntegerLiteralNode.java │ │ │ ├── StringLiteralNode.java │ │ │ ├── SymbolLiteralNode.java │ │ │ ├── BigIntegerLiteralNode.java │ │ │ └── BooleanLiteralNode.java │ │ ├── nary │ │ │ ├── EagerPrimitiveNode.java │ │ │ ├── BinaryBasicOperation.java │ │ │ ├── UnaryBasicOperation.java │ │ │ ├── BinaryComplexOperation.java │ │ │ ├── QuaternaryExpressionNode.java │ │ │ └── BinaryExpressionNode.java │ │ ├── dispatch │ │ │ ├── Dispatchable.java │ │ │ ├── DispatchChain.java │ │ │ ├── GenericDispatchNode.java │ │ │ ├── TypeConditionExactProfile.java │ │ │ ├── LexicallyBoundDispatchNode.java │ │ │ └── AbstractDispatchNode.java │ │ ├── specialized │ │ │ ├── SomLoop.java │ │ │ ├── whileloops │ │ │ │ ├── WhileFalsePrimitiveNode.java │ │ │ │ ├── WhileTruePrimitiveNode.java │ │ │ │ ├── WhileWithDynamicBlocksNode.java │ │ │ │ └── WhilePrimitiveNode.java │ │ │ ├── NotMessageNode.java │ │ │ ├── OrBoolMessageNode.java │ │ │ ├── AndBoolMessageNode.java │ │ │ └── IntDownToDoMessageNode.java │ │ ├── InternalObjectArrayNode.java │ │ └── ISuperReadNode.java │ ├── TruffleCompiler.java │ ├── SomException.java │ ├── transactions │ │ ├── CachedTxSlotWrite.java │ │ └── CachedTxSlotRead.java │ └── actors │ │ ├── SuspendExecutionNode.java │ │ ├── ErrorPromiseNode.java │ │ └── ResolvePromiseNode.java │ ├── interop │ └── SomInteropObject.java │ ├── compiler │ ├── AccessModifier.java │ ├── SemanticDefinitionError.java │ └── ScopeBuilder.java │ ├── primitives │ ├── ComparisonPrim.java │ ├── bitops │ │ ├── BitOrPrim.java │ │ ├── BitXorPrim.java │ │ └── BitAndPrim.java │ ├── arithmetic │ │ ├── ExpPrim.java │ │ ├── LogPrim.java │ │ ├── PowPrim.java │ │ ├── ArithmeticPrim.java │ │ ├── SinPrim.java │ │ ├── DividePrim.java │ │ ├── SqrtPrim.java │ │ ├── DoubleDivPrim.java │ │ ├── GreaterThanPrim.java │ │ ├── LessThanOrEqualPrim.java │ │ └── GreaterThanOrEqualPrim.java │ ├── ObjectSystemPrims.java │ ├── CosPrim.java │ ├── HashPrim.java │ ├── threading │ │ └── DelayPrimitives.java │ ├── reflection │ │ └── PerformInSuperclassPrim.java │ ├── AsStringPrim.java │ ├── arrays │ │ └── ToArgumentsArrayFactory.java │ └── ClassPrims.java │ ├── vmobjects │ ├── SAbstractObject.java │ └── SObjectWithContext.java │ └── UncaughtExceptions.java ├── tools └── kompos │ ├── src │ ├── ws-shim.js │ ├── logo │ │ ├── kompos-name.png │ │ └── tangled-string.png │ ├── source.ts │ ├── launch-connector.ts │ ├── main.js │ └── controller.ts │ ├── tsconfig.json │ ├── tests │ ├── forkjoin.ns │ ├── pingpong-csp.ns │ ├── stm.ns │ └── actor.ns │ ├── tsfmt.json │ ├── .vscode │ ├── tasks.json │ ├── launch.json │ └── settings.json │ └── tslint.json ├── .settings ├── org.eclipse.jdt.launching.prefs ├── org.eclipse.jdt.apt.core.prefs └── SOMns-tests.launch ├── artifact ├── config.inc ├── provision.sh ├── customize.sh ├── build.sh ├── virtualbox.sh └── clean.sh ├── .gitloadmodules ├── .gitmodules ├── .checkstyle_suppressions.xml ├── .checkstyle ├── .gitignore ├── .factorypath ├── mkdocs.yml ├── libs └── java8 │ └── Unsafe.java ├── LICENSE └── AUTHORS /debug: -------------------------------------------------------------------------------- 1 | som -------------------------------------------------------------------------------- /fast: -------------------------------------------------------------------------------- 1 | som -------------------------------------------------------------------------------- /docs/AUTHORS.md: -------------------------------------------------------------------------------- 1 | ../AUTHORS -------------------------------------------------------------------------------- /docs/LICENSE.md: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /docs/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ../CHANGELOG.md -------------------------------------------------------------------------------- /tests/files/data/C: -------------------------------------------------------------------------------- 1 | Test1234567890ß 2 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.som linguist-language=Smalltalk 2 | -------------------------------------------------------------------------------- /tests/streams/Text.t: -------------------------------------------------------------------------------- 1 | ABCDEFGHIJKLMNOPQRSTUVW1234567890 -------------------------------------------------------------------------------- /core-lib/TestSuite/extension/.gitignore: -------------------------------------------------------------------------------- 1 | /src_gen/ 2 | /bin/ 3 | -------------------------------------------------------------------------------- /tests/streams/Binary.blob: -------------------------------------------------------------------------------- 1 |  2 |  -------------------------------------------------------------------------------- /docs/codespeed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smarr/SOMns/HEAD/docs/codespeed.png -------------------------------------------------------------------------------- /src/META-INF/services/java.nio.file.spi.FileTypeDetector: -------------------------------------------------------------------------------- 1 | som.vm.SomFileDetector 2 | -------------------------------------------------------------------------------- /tools/kompos/src/ws-shim.js: -------------------------------------------------------------------------------- 1 | define("ws", function() { 2 | return WebSocket; 3 | }); 4 | -------------------------------------------------------------------------------- /docs/eclipse-project-outline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smarr/SOMns/HEAD/docs/eclipse-project-outline.png -------------------------------------------------------------------------------- /tests/dym/expected-results.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smarr/SOMns/HEAD/tests/dym/expected-results.tar.bz2 -------------------------------------------------------------------------------- /tools/kompos/src/logo/kompos-name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smarr/SOMns/HEAD/tools/kompos/src/logo/kompos-name.png -------------------------------------------------------------------------------- /tools/kompos/src/logo/tangled-string.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smarr/SOMns/HEAD/tools/kompos/src/logo/tangled-string.png -------------------------------------------------------------------------------- /tests/superinstructions/expected-results.tar.bz2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smarr/SOMns/HEAD/tests/superinstructions/expected-results.tar.bz2 -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.launching.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning 3 | -------------------------------------------------------------------------------- /src/tools/replay/actors/ExternalMessage.java: -------------------------------------------------------------------------------- 1 | package tools.replay.actors; 2 | 3 | public interface ExternalMessage { 4 | short getMethod(); 5 | 6 | int getDataId(); 7 | } 8 | -------------------------------------------------------------------------------- /core-lib/TestSuite/extension/src-cp-dep/dep/SomeDependency.java: -------------------------------------------------------------------------------- 1 | package dep; 2 | 3 | public class SomeDependency { 4 | public static long getValue() { 5 | return 42L; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.apt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.apt.aptEnabled=true 3 | org.eclipse.jdt.apt.genSrcDir=src_gen 4 | org.eclipse.jdt.apt.reconcileEnabled=true 5 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | from recommonmark.parser import CommonMarkParser 2 | 3 | source_parsers = { 4 | '.md': CommonMarkParser, 5 | } 6 | 7 | source_suffix = ['.md'] 8 | html_theme = 'sphinx_rtd_theme' 9 | -------------------------------------------------------------------------------- /src/som/vm/NotYetImplementedException.java: -------------------------------------------------------------------------------- 1 | package som.vm; 2 | 3 | public final class NotYetImplementedException extends RuntimeException { 4 | private static final long serialVersionUID = -1862914873966278087L; 5 | } 6 | -------------------------------------------------------------------------------- /src/tools/dym/JsonSerializable.java: -------------------------------------------------------------------------------- 1 | package tools.dym; 2 | 3 | import com.oracle.truffle.api.utilities.JSONHelper.JSONStringBuilder; 4 | 5 | 6 | public interface JsonSerializable { 7 | JSONStringBuilder toJson(); 8 | } 9 | -------------------------------------------------------------------------------- /artifact/config.inc: -------------------------------------------------------------------------------- 1 | ## Config 2 | export BOX_NAME=somns-dev 3 | export REBENCH_CONF=codespeed.conf 4 | export COMMIT_SHA=`git rev-parse HEAD` 5 | export GIT_REPO="https://github.com/smarr/SOMns.git" 6 | export REPO_NAME=SOMns 7 | -------------------------------------------------------------------------------- /core-lib/TestSuite/extension/.settings/org.eclipse.jdt.apt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.apt.aptEnabled=true 3 | org.eclipse.jdt.apt.genSrcDir=src_gen 4 | org.eclipse.jdt.apt.reconcileEnabled=true 5 | -------------------------------------------------------------------------------- /core-lib/Hello.ns: -------------------------------------------------------------------------------- 1 | class Hello usingPlatform: platform = Value ()( 2 | public main: args = ( 3 | 'Hello World!' println. 4 | args from: 2 to: args size do: [ :arg | arg print. ' ' print ]. 5 | '' println. 6 | ^ 0 7 | ) 8 | ) 9 | -------------------------------------------------------------------------------- /core-lib/TestSuite/BasicInterpreterTests/DoesNotUnderstand.ns: -------------------------------------------------------------------------------- 1 | class DoesNotUnderstand = ()( 2 | protected doesNotUnderstand: selector arguments: arguments = ( 3 | ^ selector 4 | ) 5 | ):( 6 | public test = ( 7 | ^ self new Foo 8 | ) 9 | ) 10 | -------------------------------------------------------------------------------- /core-lib/TestSuite/BasicInterpreterTests/BlockInlining4.ns: -------------------------------------------------------------------------------- 1 | class BlockInlining4 = () () : ( 2 | private method: arg = ( 3 | false whileFalse: [ 4 | | resrv | 5 | [ [ [ ^ resrv:: arg ] value ] value ] value ]. 6 | ) 7 | public test = ( ^ method: 33 ) 8 | ) 9 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/ISpecialSend.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes; 2 | 3 | import som.compiler.MixinBuilder.MixinDefinitionId; 4 | 5 | 6 | public interface ISpecialSend { 7 | boolean isSuperSend(); 8 | 9 | MixinDefinitionId getEnclosingMixinId(); 10 | } 11 | -------------------------------------------------------------------------------- /src/som/vm/constants/KernelObj.java: -------------------------------------------------------------------------------- 1 | package som.vm.constants; 2 | 3 | import som.vmobjects.SObject.SImmutableObject; 4 | 5 | 6 | public final class KernelObj { 7 | private KernelObj() {} 8 | 9 | public static final SImmutableObject kernel = new SImmutableObject(true, true); 10 | } 11 | -------------------------------------------------------------------------------- /core-lib/TestSuite/BasicInterpreterTests/BlockInlining5.ns: -------------------------------------------------------------------------------- 1 | class BlockInlining5 = () () : ( 2 | private method = ( 3 | false whileFalse: [ 4 | [ | resrv | 5 | resrv:: 33. 6 | [ [ ^ resrv ] value ] value ] value ]. 7 | ) 8 | 9 | public test = ( ^ method ) 10 | ) 11 | -------------------------------------------------------------------------------- /core-lib/TestSuite/BasicInterpreterTests/BlockInlining3.ns: -------------------------------------------------------------------------------- 1 | class BlockInlining3 = () ( 2 | private class SomeClass = ()( 3 | public method: arg = ( 4 | false whileFalse: [ 5 | | resrv | 6 | [ resrv ] ]. 7 | ) 8 | ) 9 | ) : ( 10 | public test = ( ^ 33 ) 11 | ) 12 | -------------------------------------------------------------------------------- /src/tools/dym/profiles/CreateCounter.java: -------------------------------------------------------------------------------- 1 | package tools.dym.profiles; 2 | 3 | import som.interpreter.objectstorage.ClassFactory; 4 | import tools.dym.profiles.ReadValueProfile.ProfileCounter; 5 | 6 | 7 | public interface CreateCounter { 8 | ProfileCounter createCounter(ClassFactory factory); 9 | } 10 | -------------------------------------------------------------------------------- /src/som/vm/NotAFileException.java: -------------------------------------------------------------------------------- 1 | package som.vm; 2 | 3 | import java.io.IOException; 4 | 5 | 6 | public final class NotAFileException extends IOException { 7 | private static final long serialVersionUID = -8754495184109566069L; 8 | 9 | public NotAFileException(final String path) { 10 | super(path); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.gitloadmodules: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | git submodule update --init libs/mx || git submodule update --init --depth 100 libs/mx 3 | git submodule update --init libs/truffle || git submodule update --init --no-recommend-shallow libs/truffle 4 | git submodule update --init libs/black-diamonds || git submodule update --init --depth 100 libs/black-diamonds 5 | -------------------------------------------------------------------------------- /core-lib/TestSuite/BasicInterpreterTests/Initializers.ns: -------------------------------------------------------------------------------- 1 | class Initializers = ()( 2 | public class OneParam new: x = ( | public x = x. |)() 3 | public class OneSub new: x = OneParam new: x ()() 4 | ):( 5 | public testInit1 = ( 6 | ^ (self new OneParam new: 42) x 7 | ) 8 | public testInit2 = ( 9 | ^ (self new OneSub new: 42) x 10 | ) 11 | ) 12 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "libs/truffle"] 2 | path = libs/truffle 3 | url = https://github.com/smarr/Truffle.git 4 | shallow = false 5 | [submodule "libs/mx"] 6 | path = libs/mx 7 | url = https://github.com/smarr/mx.git 8 | shallow = false 9 | [submodule "libs/black-diamonds"] 10 | path = libs/black-diamonds 11 | url = https://github.com/SOM-st/black-diamonds.git 12 | -------------------------------------------------------------------------------- /artifact/provision.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | wget -O- https://deb.nodesource.com/setup_8.x | bash - 4 | 5 | apt-get update 6 | apt-get install -y openjdk-8-jdk openjdk-8-source python-pip ant nodejs 7 | 8 | pip install git+https://github.com/smarr/ReBench 9 | 10 | # enable nice without sudo 11 | echo "artifact - nice -20" >> /etc/security/limits.conf 12 | -------------------------------------------------------------------------------- /.checkstyle_suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /artifact/customize.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | echo "" 4 | echo "Customize Image" 5 | echo "" 6 | 7 | cd ~/ 8 | ## Create Links on Desktop 9 | mkdir -p ~/Desktop 10 | ln -s ~/eclipse/eclipse ~/Desktop/eclipse 11 | 12 | ln -s ~/${REPO_NAME} ~/Desktop/${REPO_NAME} 13 | ln -s ~/${REPO_NAME}/README.md ~/Desktop/README.md 14 | 15 | echo "" 16 | echo "Customization Done" 17 | echo "" 18 | -------------------------------------------------------------------------------- /src/som/interop/SomInteropObject.java: -------------------------------------------------------------------------------- 1 | package som.interop; 2 | 3 | import com.oracle.truffle.api.interop.TruffleObject; 4 | 5 | 6 | /** 7 | * This is a marker interface, which identifies {@link TruffleObject}s, 8 | * which are also SOMns objects, and thus, do not need to be handled as foreign ones. 9 | */ 10 | public interface SomInteropObject extends TruffleObject { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /tools/kompos/src/source.ts: -------------------------------------------------------------------------------- 1 | /* jshint -W097 */ 2 | "use strict"; 3 | 4 | export function dbgLog(msg) { 5 | const tzOffset = (new Date()).getTimezoneOffset() * 60000; // offset in milliseconds 6 | const localISOTime = (new Date(Date.now() - tzOffset)).toISOString().slice(0, -1); 7 | 8 | $("#debugger-log").html(localISOTime + ": " + msg + "
" + $("#debugger-log").html()); 9 | } 10 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/literals/NilLiteralNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.literals; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | import som.vm.constants.Nil; 6 | 7 | 8 | public final class NilLiteralNode extends LiteralNode { 9 | 10 | @Override 11 | public Object executeGeneric(final VirtualFrame frame) { 12 | return Nil.nilObject; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/tools/replay/StringWrapper.java: -------------------------------------------------------------------------------- 1 | package tools.replay; 2 | 3 | public class StringWrapper { 4 | public final String s; 5 | public final int actorId; 6 | public final int dataId; 7 | 8 | public StringWrapper(final String s, final int actorId, final int dataId) { 9 | super(); 10 | this.s = s; 11 | this.actorId = actorId; 12 | this.dataId = dataId; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/tools/debugger/nodes/DisabledBreakpointNode.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.nodes; 2 | 3 | /** 4 | * Disabled breakpoint node that returns false all the time. 5 | * (use mainly when the Truffle debugger is not enabled) 6 | */ 7 | public final class DisabledBreakpointNode extends AbstractBreakpointNode { 8 | @Override 9 | public boolean executeShouldHalt() { 10 | return false; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /core-lib/TestSuite/extension/.checkstyle_suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /tools/kompos/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "outDir": "out", 5 | "module": "amd", 6 | "moduleResolution": "node", 7 | "inlineSourceMap": true, 8 | "allowJs": true, 9 | "noUnusedLocals" : true, 10 | "noUnusedParameters": true 11 | }, 12 | "include": [ 13 | "tests/**/*", 14 | "src/**/*" 15 | ], 16 | "exclude": [ 17 | "src/libs/**" 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /src/tools/debugger/nodes/AbstractBreakpointNode.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.nodes; 2 | 3 | import com.oracle.truffle.api.nodes.Node; 4 | 5 | 6 | /** 7 | * Abstract node for controlling states (enable or disable) of breakpoints. 8 | * Implementation of executeCheckIsSetAndEnabled method is generated by Truffle DSL. 9 | * 10 | */ 11 | public abstract class AbstractBreakpointNode extends Node { 12 | public abstract boolean executeShouldHalt(); 13 | } 14 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/LanguageFeatures/DoesNotUnderstand/CalculatorDelegate.ns: -------------------------------------------------------------------------------- 1 | CalculatorDelegate = ( 2 | | target | 3 | 4 | initializeWith: aCalculator = ( 5 | target:: aCalculator 6 | ) 7 | 8 | inc: aSymbol = ( 9 | target inc: aSymbol 10 | ) 11 | 12 | ---- 13 | 14 | new: a = ( 15 | | calc | 16 | calc:: self new. 17 | calc initializeWith: a. 18 | ^ calc 19 | ) 20 | ) 21 | -------------------------------------------------------------------------------- /src/som/compiler/AccessModifier.java: -------------------------------------------------------------------------------- 1 | package som.compiler; 2 | 3 | public enum AccessModifier { 4 | // Those things also get Access Modifiers, and not yet sure how to handle them 5 | // so, keep them distinct. 6 | CLASS_CACHE_SLOT, OBJECT_INSTANTIATION_METHOD, BLOCK_METHOD, 7 | 8 | // NOTE: Order is important, for the lookup in SClass, we rely on it to 9 | // define the sets of protected+public vs. public methods 10 | PRIVATE, PROTECTED, PUBLIC 11 | } 12 | -------------------------------------------------------------------------------- /src/tools/debugger/message/TraceDataRequest.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.message; 2 | 3 | import org.java_websocket.WebSocket; 4 | 5 | import tools.debugger.FrontendConnector; 6 | import tools.debugger.message.Message.IncommingMessage; 7 | 8 | 9 | public class TraceDataRequest extends IncommingMessage { 10 | 11 | @Override 12 | public void process(final FrontendConnector connector, final WebSocket conn) { 13 | connector.sendTracingData(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/tools/debugger/message/ProgramInfoRequest.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.message; 2 | 3 | import org.java_websocket.WebSocket; 4 | 5 | import tools.debugger.FrontendConnector; 6 | import tools.debugger.message.Message.IncommingMessage; 7 | 8 | 9 | public final class ProgramInfoRequest extends IncommingMessage { 10 | 11 | @Override 12 | public void process(final FrontendConnector connector, final WebSocket conn) { 13 | connector.sendProgramInfo(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /core-lib/TestSuite/BasicInterpreterTests/BlockInlining2.ns: -------------------------------------------------------------------------------- 1 | class BlockInlining2 = () ( 2 | public class SomeClass = ()( 3 | public method: arg = ( 4 | critical: [ 5 | false whileFalse: [ 6 | | resrv | 7 | critical: [ 8 | resrv:: arg. 9 | ^ resrv ] ] ]. 10 | ) 11 | 12 | private critical: block = ( 13 | ^ block value 14 | ) 15 | ) 16 | ) : ( 17 | public test = ( ^ new SomeClass new method: 33 ) 18 | ) 19 | -------------------------------------------------------------------------------- /src/som/interpreter/TruffleCompiler.java: -------------------------------------------------------------------------------- 1 | package som.interpreter; 2 | 3 | import com.oracle.truffle.api.CompilerDirectives; 4 | 5 | 6 | public final class TruffleCompiler { 7 | public static void transferToInterpreter(final String reason) { 8 | CompilerDirectives.transferToInterpreterAndInvalidate(); 9 | } 10 | 11 | public static void transferToInterpreterAndInvalidate(final String reason) { 12 | CompilerDirectives.transferToInterpreterAndInvalidate(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/tools/replay/ExternalDataSource.java: -------------------------------------------------------------------------------- 1 | package tools.replay; 2 | 3 | public interface ExternalDataSource { 4 | 5 | /** 6 | * This is the method that is called in replay when an actor expects an external message. 7 | * The actor looks up the datasource through the id of its actor, and then calls this method 8 | * on it with the needed data. This method will then cause the message to be created and 9 | * sent. 10 | */ 11 | void requestExternalMessage(short method, int dataId); 12 | } 13 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/LanguageFeatures/DoesNotUnderstand/Proxy.ns: -------------------------------------------------------------------------------- 1 | Proxy = ( 2 | | target | 3 | 4 | initializeWith: anObj = ( 5 | target:: anObj 6 | ) 7 | 8 | doesNotUnderstand: selector arguments: arguments = ( 9 | ^ target perform: selector withArguments: arguments 10 | ) 11 | 12 | ---- 13 | 14 | new: target = ( 15 | | proxy | 16 | proxy:: self new. 17 | proxy initializeWith: target. 18 | ^ proxy 19 | ) 20 | ) 21 | -------------------------------------------------------------------------------- /src/tools/replay/nodes/TraceNode.java: -------------------------------------------------------------------------------- 1 | package tools.replay.nodes; 2 | 3 | import com.oracle.truffle.api.nodes.Node; 4 | 5 | import tools.concurrency.TracingActivityThread; 6 | import tools.replay.actors.ActorExecutionTrace.ActorTraceBuffer; 7 | 8 | 9 | public abstract class TraceNode extends Node { 10 | 11 | protected static ActorTraceBuffer getCurrentBuffer() { 12 | TracingActivityThread t = TracingActivityThread.currentThread(); 13 | return (ActorTraceBuffer) t.getBuffer(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/tools/replay/TwoDArrayWrapper.java: -------------------------------------------------------------------------------- 1 | package tools.replay; 2 | 3 | import som.vmobjects.SArray.SImmutableArray; 4 | 5 | 6 | public class TwoDArrayWrapper { 7 | public final SImmutableArray immArray; 8 | public final int actorId; 9 | public final int dataId; 10 | 11 | public TwoDArrayWrapper(final SImmutableArray ia, final int actorId, final int dataId) { 12 | super(); 13 | this.immArray = ia; 14 | this.actorId = actorId; 15 | this.dataId = dataId; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /core-lib/TestSuite/extension/README.md: -------------------------------------------------------------------------------- 1 | # SOMns Extension for Testing 2 | 3 | This is a SOMns extension module, which is used to test the SOMns functionality. 4 | 5 | Similar to SOMns, the extension uses `ant` as build systems. 6 | 7 | The `build.xml` file defines the various build tasks. It contains examples of 8 | how to create the `somns.properties` file (see the `compile` task) as well as 9 | an example for adding a JAR dependency to the module's own `Class-Path` 10 | property in its manifest file (see the `jar` task). 11 | -------------------------------------------------------------------------------- /src/tools/debugger/message/ProgramInfoResponse.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.message; 2 | 3 | import tools.debugger.message.Message.OutgoingMessage; 4 | 5 | 6 | @SuppressWarnings("unused") 7 | public final class ProgramInfoResponse extends OutgoingMessage { 8 | private final Object[] args; 9 | 10 | private ProgramInfoResponse(final Object[] args) { 11 | this.args = args; 12 | } 13 | 14 | public static ProgramInfoResponse create(final Object[] args) { 15 | return new ProgramInfoResponse(args); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/tools/dym/nodes/ControlFlowProfileNode.java: -------------------------------------------------------------------------------- 1 | package tools.dym.nodes; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | import tools.dym.profiles.BranchProfile; 6 | 7 | 8 | public class ControlFlowProfileNode extends CountingNode { 9 | 10 | public ControlFlowProfileNode(final BranchProfile profile) { 11 | super(profile); 12 | } 13 | 14 | @Override 15 | protected void onReturnValue(final VirtualFrame frame, final Object result) { 16 | counter.profile((boolean) result); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tests/files/data/B: -------------------------------------------------------------------------------- 1 | Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque magna dolor, elementum et semper eu, semper vel ante. Phasellus ut euismod dui. Nulla sit amet nunc fringilla, lacinia erat sodales, suscipit augue. Maecenas sed dolor sed diam ullamcorper dictum. Cras sodales tincidunt tortor in scelerisque. Donec convallis, risus quis varius lacinia, lorem leo aliquet orci, vitae aliquam mauris erat sed ipsum. Sed pretium, lorem ut placerat interdum, ex tortor imperdiet mauris, fringilla pretium odio velit non nisi. Vestibulum amet. -------------------------------------------------------------------------------- /tools/kompos/tests/forkjoin.ns: -------------------------------------------------------------------------------- 1 | class ForkJoin usingPlatform: platform = Value ( 2 | | private Task = platform threading Task. 3 | |)( 4 | 5 | public cnt: n = ( 6 | | result task | 7 | n < 1 ifTrue: [ ^ 0 ]. 8 | 9 | task:: Task spawn: [ 10 | 'cnt: ' print. n println. 11 | cnt: n - 1 ]. 12 | 13 | result:: task join. 14 | 15 | ^ result 16 | ) 17 | 18 | 19 | public main: args = ( 20 | 'Count down example\n' println. 21 | 22 | cnt: 2. 23 | 24 | ^ 0 25 | ) 26 | ) 27 | -------------------------------------------------------------------------------- /core-lib/TestSuite/SystemTests.ns: -------------------------------------------------------------------------------- 1 | class SystemTests usingPlatform: platform testFramework: minitest = ( 2 | | private TestContext = minitest TestContext. 3 | private system = platform system. | 4 | )( 5 | public class SystemTest = TestContext ()( 6 | 7 | public testFullGCSupport = ( 8 | (* Test whether #fullGC is support. We expect the VM now to return true, 9 | to indicate the a GC was done. *) 10 | self assert: system fullGC description: 'VM does not support #fullGC.' 11 | ) 12 | ) : ( TEST_CONTEXT = () ) 13 | ) 14 | -------------------------------------------------------------------------------- /src/som/vm/SomFileDetector.java: -------------------------------------------------------------------------------- 1 | package som.vm; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Path; 5 | import java.nio.file.spi.FileTypeDetector; 6 | 7 | import som.interpreter.SomLanguage; 8 | 9 | 10 | public final class SomFileDetector extends FileTypeDetector { 11 | 12 | @Override 13 | public String probeContentType(final Path path) throws IOException { 14 | if (path.getFileName().toString().endsWith(SomLanguage.DOT_FILE_EXTENSION)) { 15 | return SomLanguage.MIME_TYPE; 16 | } 17 | return null; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /core-lib/demos/ForkJoinDemo.ns: -------------------------------------------------------------------------------- 1 | class ForkJoinDemo usingPlatform: platform = Value ( 2 | | private Task = platform threading Task. 3 | |)( 4 | 5 | public cnt: n = ( 6 | | result task | 7 | n < 1 ifTrue: [ ^ 0 ]. 8 | 9 | task:: Task spawn: [ 10 | 'cnt: ' print. n println. 11 | cnt: n - 1 ]. 12 | 13 | result:: task join. 14 | 15 | ^ result 16 | ) 17 | 18 | 19 | public main: args = ( 20 | 'Count down example\n' println. 21 | 22 | 1 halt. 23 | 24 | cnt: 2. 25 | 26 | ^ 0 27 | ) 28 | ) 29 | -------------------------------------------------------------------------------- /src/som/primitives/ComparisonPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives; 2 | 3 | import com.oracle.truffle.api.instrumentation.Tag; 4 | 5 | import som.interpreter.nodes.nary.BinaryBasicOperation; 6 | import tools.dym.Tags.OpComparison; 7 | 8 | 9 | public abstract class ComparisonPrim extends BinaryBasicOperation { 10 | @Override 11 | protected boolean hasTagIgnoringEagerness(final Class tag) { 12 | if (tag == OpComparison.class) { 13 | return true; 14 | } else { 15 | return super.hasTagIgnoringEagerness(tag); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/som/vm/constants/Nil.java: -------------------------------------------------------------------------------- 1 | package som.vm.constants; 2 | 3 | import som.vmobjects.SObjectWithClass.SObjectWithoutFields; 4 | 5 | 6 | public final class Nil { 7 | private Nil() {} 8 | 9 | public static final SObjectWithoutFields nilObject; 10 | 11 | static { 12 | nilObject = new SObjectWithoutFields(); 13 | } 14 | 15 | public static boolean valueIsNil(final Object value) { 16 | return value == Nil.nilObject; 17 | } 18 | 19 | public static boolean valueIsNotNil(final Object value) { 20 | return value != Nil.nilObject; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/LanguageFeatures/DoesNotUnderstand/DnuAdd.ns: -------------------------------------------------------------------------------- 1 | DnuAdd = Benchmark ( 2 | | calc | 3 | 4 | initialize = ( 5 | calc:: Calculator new. 6 | ) 7 | 8 | benchmark = ( 9 | calc initializeWith: 5. 10 | 11 | 1 to: 20000 do: [ :i | 12 | calc incDNU: #once 13 | ]. 14 | 15 | calc a = 20005 ifFalse: [ 'Benchmark failed with wrong result' println. calc a println. ] 16 | ) 17 | 18 | ---- 19 | 20 | new = ( 21 | ^ super new initialize 22 | ) 23 | ) 24 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/LanguageFeatures/DoesNotUnderstand/DirectAdd.ns: -------------------------------------------------------------------------------- 1 | DirectAdd = Benchmark ( 2 | | calc | 3 | 4 | initialize = ( 5 | calc:: Calculator new. 6 | ) 7 | 8 | benchmark = ( 9 | calc initializeWith: 5. 10 | 11 | 1 to: 20000 do: [ :i | 12 | calc inc: #once 13 | ]. 14 | 15 | calc a = 20005 ifFalse: [ 'Benchmark failed with wrong result' println. calc a println. ] 16 | ) 17 | 18 | ---- 19 | 20 | new = ( 21 | ^ super new initialize 22 | ) 23 | ) 24 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/LanguageFeatures/DoesNotUnderstand/PerformAdd.ns: -------------------------------------------------------------------------------- 1 | PerformAdd = Benchmark ( 2 | | calc | 3 | 4 | initialize = ( 5 | calc:: Calculator new. 6 | ) 7 | 8 | benchmark = ( 9 | calc initializeWith: 5. 10 | 11 | 1 to: 20000 do: [ :i | 12 | calc perform: #inc: withArguments: { #once } 13 | ]. 14 | 15 | calc a = 20005 ifFalse: [ 'Benchmark failed with wrong result' println. calc a println. ] 16 | ) 17 | 18 | ---- 19 | 20 | new = ( 21 | ^ super new initialize 22 | ) 23 | ) 24 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/LanguageFeatures/DoesNotUnderstand/Calculator.ns: -------------------------------------------------------------------------------- 1 | Calculator = ( 2 | | a | 3 | 4 | initializeWith: anInt = ( 5 | a:: anInt 6 | ) 7 | 8 | inc: aSymbol = ( 9 | aSymbol = #once ifTrue: [ a:: a + 1 ] 10 | ) 11 | 12 | a = ( ^ a ) 13 | 14 | doesNotUnderstand: selector arguments: arguments = ( 15 | ^ self inc: #once 16 | ) 17 | 18 | ---- 19 | 20 | new: a = ( 21 | | calc | 22 | calc:: self new. 23 | calc initializeWith: a. 24 | ^ calc 25 | ) 26 | ) 27 | -------------------------------------------------------------------------------- /.checkstyle: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/som/primitives/bitops/BitOrPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.bitops; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | 6 | import bd.primitives.Primitive; 7 | import som.primitives.arithmetic.ArithmeticPrim; 8 | 9 | 10 | @GenerateNodeFactory 11 | @Primitive(primitive = "int:bitOr:", selector = "bitOr:") 12 | public abstract class BitOrPrim extends ArithmeticPrim { 13 | @Specialization 14 | public final long doLong(final long receiver, final long right) { 15 | return receiver | right; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/som/primitives/bitops/BitXorPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.bitops; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | 6 | import bd.primitives.Primitive; 7 | import som.primitives.arithmetic.ArithmeticPrim; 8 | 9 | 10 | @GenerateNodeFactory 11 | @Primitive(primitive = "int:bitXor:", selector = "bitXor:") 12 | public abstract class BitXorPrim extends ArithmeticPrim { 13 | @Specialization 14 | public final long doLong(final long receiver, final long right) { 15 | return receiver ^ right; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | src_gen 3 | mini-som.sh 4 | mini.sh 5 | rebench.conf 6 | user-dict.txt 7 | /libs/*.jar 8 | /libs/*.zip 9 | /libs/jacoco 10 | jacoco.exec 11 | jacoco.xml 12 | /report 13 | *.json 14 | nbproject 15 | .idea 16 | .pmd 17 | newspeak 18 | *.ns3 19 | tools/kompos/node_modules 20 | tools/kompos/out 21 | traces 22 | /tests/dym/old-results 23 | /tests/dym/results 24 | /tests/dym/expected-results 25 | /tests/superinstructions/old-results 26 | /tests/superinstructions/results 27 | /tests/superinstructions/expected-results 28 | /tests/streams/*.txt 29 | npm-debug.log* 30 | /.metadata 31 | -------------------------------------------------------------------------------- /src/tools/dym/nodes/LoopProfilingNode.java: -------------------------------------------------------------------------------- 1 | package tools.dym.nodes; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | import tools.dym.profiles.LoopProfile; 6 | 7 | 8 | public class LoopProfilingNode extends CountingNode { 9 | 10 | public LoopProfilingNode(final LoopProfile profile) { 11 | super(profile); 12 | } 13 | 14 | @Override 15 | protected void onReturnValue(final VirtualFrame frame, final Object result) { 16 | counter.recordLoopExit(); 17 | } 18 | 19 | public LoopProfile getProfile() { 20 | return counter; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/LanguageFeatures/DoesNotUnderstand/DnuPerformAdd.ns: -------------------------------------------------------------------------------- 1 | DnuPerformAdd = Benchmark ( 2 | | calc | 3 | 4 | initialize = ( 5 | calc:: CalculatorDnuPerform new. 6 | ) 7 | 8 | benchmark = ( 9 | calc initializeWith: 5. 10 | 11 | 1 to: 20000 do: [ :i | 12 | calc incDNU: #once 13 | ]. 14 | 15 | calc a = 20005 ifFalse: [ 'Benchmark failed with wrong result' println. calc a println. ] 16 | ) 17 | 18 | ---- 19 | 20 | new = ( 21 | ^ super new initialize 22 | ) 23 | ) 24 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/literals/DoubleLiteralNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.literals; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | 6 | public final class DoubleLiteralNode extends LiteralNode { 7 | private final double value; 8 | 9 | public DoubleLiteralNode(final double value) { 10 | this.value = value; 11 | } 12 | 13 | @Override 14 | public double executeDouble(final VirtualFrame frame) { 15 | return value; 16 | } 17 | 18 | @Override 19 | public Object executeGeneric(final VirtualFrame frame) { 20 | return value; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/literals/IntegerLiteralNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.literals; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | 6 | public final class IntegerLiteralNode extends LiteralNode { 7 | 8 | private final long value; 9 | 10 | public IntegerLiteralNode(final long value) { 11 | this.value = value; 12 | } 13 | 14 | @Override 15 | public long executeLong(final VirtualFrame frame) { 16 | return value; 17 | } 18 | 19 | @Override 20 | public Object executeGeneric(final VirtualFrame frame) { 21 | return value; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/literals/StringLiteralNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.literals; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | 6 | public final class StringLiteralNode extends LiteralNode { 7 | 8 | private final String value; 9 | 10 | public StringLiteralNode(final String value) { 11 | this.value = value; 12 | } 13 | 14 | @Override 15 | public String executeString(final VirtualFrame frame) { 16 | return value; 17 | } 18 | 19 | @Override 20 | public Object executeGeneric(final VirtualFrame frame) { 21 | return value; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/som/vm/Extension.java: -------------------------------------------------------------------------------- 1 | package som.vm; 2 | 3 | import java.util.List; 4 | 5 | import bd.primitives.Specializer; 6 | import som.VM; 7 | import som.interpreter.nodes.ExpressionNode; 8 | import som.vmobjects.SSymbol; 9 | 10 | 11 | /** 12 | * Interface for extension jars to implement. 13 | * 14 | * The {@code Extension#getFactories()} method returns all primitives provided by the 15 | * extension. These are then used to create a Newspeak class, similar to {@code vmMirror}. 16 | */ 17 | public interface Extension { 18 | List> getSpecializers(); 19 | } 20 | -------------------------------------------------------------------------------- /src/som/primitives/arithmetic/ExpPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.arithmetic; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | 6 | import bd.primitives.Primitive; 7 | import som.interpreter.nodes.nary.UnaryExpressionNode; 8 | 9 | 10 | @GenerateNodeFactory 11 | @Primitive(primitive = "doubleExp:", selector = "exp", receiverType = Double.class) 12 | public abstract class ExpPrim extends UnaryExpressionNode { 13 | @Specialization 14 | public final double doExp(final double rcvr) { 15 | return Math.exp(rcvr); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tools/kompos/src/launch-connector.ts: -------------------------------------------------------------------------------- 1 | const msgPortRe = /.*Message Handler:\s+(\d+)/m; 2 | const tracePortRe = /.*Trace Handler:\s+(\d+)/m; 3 | 4 | /** Parse the data string and retrieve message and trace ports. */ 5 | export function determinePorts(data: string, ports: { msg: number, trace: number }) { 6 | const m1 = data.match(msgPortRe); 7 | if (m1) { 8 | if (ports.msg === 0) { 9 | ports.msg = parseInt(m1[1]); 10 | } 11 | } 12 | const m2 = data.match(tracePortRe); 13 | if (m2) { 14 | if (ports.trace === 0) { 15 | ports.trace = parseInt(m2[1]); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/LanguageFeatures/DoesNotUnderstand/ProxyAdd.ns: -------------------------------------------------------------------------------- 1 | ProxyAdd = Benchmark ( 2 | | proxy calc | 3 | 4 | initialize = ( 5 | calc:: Calculator new. 6 | proxy:: Proxy new: calc 7 | ) 8 | 9 | benchmark = ( 10 | calc initializeWith: 5. 11 | 12 | 1 to: 20000 do: [ :i | 13 | proxy inc: #once 14 | ]. 15 | 16 | ^ calc a 17 | ) 18 | 19 | verifyResult: result = ( 20 | ^ 20005 = result 21 | ) 22 | 23 | ---- 24 | 25 | new = ( 26 | ^ super new initialize 27 | ) 28 | ) 29 | -------------------------------------------------------------------------------- /src/tools/debugger/SteppingStrategy.java: -------------------------------------------------------------------------------- 1 | package tools.debugger; 2 | 3 | import tools.debugger.entities.SteppingType; 4 | 5 | 6 | public final class SteppingStrategy { 7 | 8 | private final SteppingType type; 9 | private boolean consumed; 10 | 11 | public SteppingStrategy(final SteppingType type) { 12 | this.type = type; 13 | this.consumed = false; 14 | } 15 | 16 | public boolean is(final SteppingType type) { 17 | if (!consumed && this.type == type) { 18 | consumed = true; 19 | return true; 20 | } else { 21 | return false; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /core-lib/TestSuite/extension/.checkstyle: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/tools/dym/nodes/LoopIterationReportNode.java: -------------------------------------------------------------------------------- 1 | package tools.dym.nodes; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.instrumentation.ExecutionEventNode; 5 | 6 | import tools.dym.profiles.LoopProfile; 7 | 8 | 9 | public class LoopIterationReportNode extends ExecutionEventNode { 10 | protected final LoopProfile profile; 11 | 12 | public LoopIterationReportNode(final LoopProfile profile) { 13 | this.profile = profile; 14 | } 15 | 16 | @Override 17 | protected void onEnter(final VirtualFrame frame) { 18 | profile.recordLoopIteration(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/LanguageFeatures/DoesNotUnderstand/CalculatorDnuPerform.ns: -------------------------------------------------------------------------------- 1 | CalculatorDnuPerform = ( 2 | | a | 3 | 4 | initializeWith: anInt = ( 5 | a:: anInt 6 | ) 7 | 8 | inc: aSymbol = ( 9 | aSymbol = #once ifTrue: [ a:: a + 1 ] 10 | ) 11 | 12 | a = ( ^ a ) 13 | 14 | doesNotUnderstand: selector arguments: arguments = ( 15 | ^ self perform: #inc: withArguments: arguments 16 | ) 17 | 18 | ---- 19 | 20 | new: a = ( 21 | | calc | 22 | calc:: self new. 23 | calc initializeWith: a. 24 | ^ calc 25 | ) 26 | ) 27 | -------------------------------------------------------------------------------- /core-lib/TestSuite/extension/.factorypath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/LanguageFeatures/DoesNotUnderstand/IndirectAdd.ns: -------------------------------------------------------------------------------- 1 | IndirectAdd = Benchmark ( 2 | | delegate calc | 3 | 4 | initialize = ( 5 | calc:: Calculator new. 6 | delegate:: CalculatorDelegate new: calc 7 | ) 8 | 9 | benchmark = ( 10 | calc initializeWith: 5. 11 | 12 | 1 to: 20000 do: [ :i | 13 | delegate inc: #once 14 | ]. 15 | 16 | ^ calc a 17 | ) 18 | 19 | verifyResult: result = ( 20 | ^ 20005 = result 21 | ) 22 | 23 | ---- 24 | 25 | new = ( 26 | ^ super new initialize 27 | ) 28 | ) 29 | -------------------------------------------------------------------------------- /tests/java/debugger/ReflectionRegistrationTests.java: -------------------------------------------------------------------------------- 1 | package debugger; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.util.HashSet; 6 | 7 | import org.junit.Test; 8 | 9 | import tools.debugger.RuntimeReflectionRegistration; 10 | 11 | 12 | public class ReflectionRegistrationTests { 13 | 14 | @Test 15 | public void runtimeRegistration() { 16 | RuntimeReflectionRegistration rrr = new RuntimeReflectionRegistration(); 17 | rrr.beforeAnalysis(null); 18 | 19 | HashSet> registeredClasses = rrr.getRegisteredClasses(); 20 | assertEquals(56, registeredClasses.size()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/tools/dym/nodes/CountingNode.java: -------------------------------------------------------------------------------- 1 | package tools.dym.nodes; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.instrumentation.ExecutionEventNode; 5 | 6 | import tools.dym.profiles.Counter; 7 | 8 | 9 | public class CountingNode extends ExecutionEventNode { 10 | 11 | protected final T counter; 12 | 13 | public CountingNode(final T counter) { 14 | this.counter = counter; 15 | } 16 | 17 | @Override 18 | protected void onEnter(final VirtualFrame frame) { 19 | counter.inc(); 20 | } 21 | 22 | public T getProfile() { 23 | return counter; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/literals/SymbolLiteralNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.literals; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | import som.vmobjects.SSymbol; 6 | 7 | 8 | public final class SymbolLiteralNode extends LiteralNode { 9 | 10 | private final SSymbol value; 11 | 12 | public SymbolLiteralNode(final SSymbol value) { 13 | this.value = value; 14 | } 15 | 16 | @Override 17 | public SSymbol executeSSymbol(final VirtualFrame frame) { 18 | return value; 19 | } 20 | 21 | @Override 22 | public Object executeGeneric(final VirtualFrame frame) { 23 | return value; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/som/primitives/arithmetic/LogPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.arithmetic; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | 6 | import bd.primitives.Primitive; 7 | import som.interpreter.nodes.nary.UnaryBasicOperation; 8 | 9 | 10 | @GenerateNodeFactory 11 | @Primitive(primitive = "doubleLog:", selector = "log", receiverType = Double.class) 12 | public abstract class LogPrim extends UnaryBasicOperation { 13 | // TODO: assign some specific tag 14 | @Specialization 15 | public final double doLog(final double rcvr) { 16 | return Math.log(rcvr); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/som/primitives/arithmetic/PowPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.arithmetic; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | 6 | import bd.primitives.Primitive; 7 | import som.interpreter.nodes.nary.BinaryExpressionNode; 8 | 9 | 10 | @GenerateNodeFactory 11 | @Primitive(primitive = "doublePow:exp:", selector = "pow:", receiverType = Double.class) 12 | public abstract class PowPrim extends BinaryExpressionNode { 13 | 14 | @Specialization 15 | public final double doPow(final double base, final double exponent) { 16 | return Math.pow(base, exponent); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /core-lib/Transactions.ns: -------------------------------------------------------------------------------- 1 | class Transactions usingVmMirror: vmMirror usingKernel: kernel = Value ( 2 | | private vmMirror = vmMirror. 3 | private Exception = kernel Exception. 4 | | 5 | (* vmMirror txRegisterTransaction: Transaction *) 6 | )( 7 | public class Transaction = ( 8 | (* Can't be instantiated directly. *) 9 | Exception signal 10 | )() : ( 11 | (* Executes the given block atomically. 12 | The execution of the block is retried until it succeeds without conflicts. 13 | The result of the block is returned. *) 14 | public atomic: block = ( 15 | ^ vmMirror tx: self atomic: block 16 | ) 17 | ) 18 | ) 19 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/nary/EagerPrimitiveNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.nary; 2 | 3 | import bd.primitives.nodes.EagerPrimitive; 4 | import bd.tools.nodes.Invocation; 5 | import som.interpreter.nodes.ExpressionNode; 6 | import som.vmobjects.SSymbol; 7 | 8 | 9 | public abstract class EagerPrimitiveNode extends ExpressionNode 10 | implements EagerPrimitive, Invocation { 11 | protected final SSymbol selector; 12 | 13 | protected EagerPrimitiveNode(final SSymbol selector) { 14 | this.selector = selector; 15 | } 16 | 17 | @Override 18 | public SSymbol getInvocationIdentifier() { 19 | return selector; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/tools/dym/nodes/ReadProfilingNode.java: -------------------------------------------------------------------------------- 1 | package tools.dym.nodes; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | import tools.dym.profiles.ReadValueProfile; 6 | 7 | 8 | public final class ReadProfilingNode extends CountingNode { 9 | 10 | @Child protected TypeProfileNode typeProfile; 11 | 12 | public ReadProfilingNode(final ReadValueProfile profile) { 13 | super(profile); 14 | typeProfile = TypeProfileNodeGen.create(profile); 15 | } 16 | 17 | @Override 18 | protected void onReturnValue(final VirtualFrame frame, final Object result) { 19 | typeProfile.executeProfiling(result); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/literals/BigIntegerLiteralNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.literals; 2 | 3 | import java.math.BigInteger; 4 | 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | 8 | public final class BigIntegerLiteralNode extends LiteralNode { 9 | 10 | private final BigInteger value; 11 | 12 | public BigIntegerLiteralNode(final BigInteger value) { 13 | this.value = value; 14 | } 15 | 16 | @Override 17 | public BigInteger executeBigInteger(final VirtualFrame frame) { 18 | return value; 19 | } 20 | 21 | @Override 22 | public Object executeGeneric(final VirtualFrame frame) { 23 | return value; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tools/kompos/src/main.js: -------------------------------------------------------------------------------- 1 | requirejs.config({ 2 | paths: { 3 | 'd3': ['/node_modules/d3/d3'], 4 | 'ws': ['ws-shim'] 5 | }, 6 | shim: { 7 | 'd3': { exports: 'd3' }, 8 | 'ws': { exports: 'ws' } 9 | } 10 | }); 11 | 12 | var ctrl; 13 | 14 | requirejs( 15 | ['vm-connection', 'controller', 'ui-controller', 'debugger', 'view', 16 | 'breakpoints'], 17 | function(vmConn, cont, uiCont, d, vw, bps) { 18 | $("#graph-canvas").resizable({ handleSelector: '#split-system-code', resizeWidth: false }); 19 | 20 | var vmConnection = new vmConn.VmConnection(true); 21 | ctrl = new uiCont.UiController(vmConnection); 22 | ctrl.toggleConnection(); 23 | }); 24 | -------------------------------------------------------------------------------- /core-lib/TestSuite/extension/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | SOMns-ExtensionTests 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | net.sf.eclipsecs.core.CheckstyleBuilder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | net.sf.eclipsecs.core.CheckstyleNature 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/som/interpreter/SomException.java: -------------------------------------------------------------------------------- 1 | package som.interpreter; 2 | 3 | import com.oracle.truffle.api.nodes.ControlFlowException; 4 | 5 | import som.vmobjects.SAbstractObject; 6 | 7 | 8 | public final class SomException extends ControlFlowException { 9 | 10 | private static final long serialVersionUID = -639789248178270606L; 11 | private final SAbstractObject somObj; 12 | 13 | public SomException(final SAbstractObject somObj) { 14 | this.somObj = somObj; 15 | } 16 | 17 | public SAbstractObject getSomObject() { 18 | return somObj; 19 | } 20 | 21 | @Override 22 | public String toString() { 23 | return "SomException[" + somObj.toString() + "]"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/tools/debugger/entities/ReceiveOp.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.entities; 2 | 3 | public enum ReceiveOp { 4 | CHANNEL_RCV(Marker.CHANNEL_MSG_RCV, EntityType.CHANNEL), 5 | TASK_JOIN(Marker.TASK_JOIN, EntityType.TASK), 6 | THREAD_JOIN(Marker.THREAD_JOIN, EntityType.THREAD); 7 | 8 | private final byte id; 9 | private final EntityType source; 10 | 11 | ReceiveOp(final byte id, final EntityType source) { 12 | this.id = id; 13 | this.source = source; 14 | } 15 | 16 | public byte getId() { 17 | return id; 18 | } 19 | 20 | public EntityType getSource() { 21 | return source; 22 | } 23 | 24 | public int getSize() { 25 | return 9; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/dispatch/Dispatchable.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.dispatch; 2 | 3 | import com.oracle.truffle.api.nodes.IndirectCallNode; 4 | 5 | import som.compiler.AccessModifier; 6 | 7 | 8 | /** 9 | * Something that can create a dispatch node. 10 | * Used for slots, and methods currently. 11 | */ 12 | public interface Dispatchable { 13 | 14 | AbstractDispatchNode getDispatchNode( 15 | Object rcvr, Object firstArg, AbstractDispatchNode newChainEnd, boolean forAtomic); 16 | 17 | AccessModifier getAccessModifier(); 18 | 19 | Object invoke(IndirectCallNode node, Object[] arguments); 20 | 21 | String typeForErrors(); 22 | 23 | boolean isInitializer(); 24 | } 25 | -------------------------------------------------------------------------------- /.factorypath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /core-lib/TestSuite/extension/src/ext/Extension.java: -------------------------------------------------------------------------------- 1 | package ext; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | import bd.primitives.PrimitiveLoader; 7 | import bd.primitives.Specializer; 8 | import som.VM; 9 | import som.interpreter.nodes.ExpressionNode; 10 | import som.vmobjects.SSymbol; 11 | 12 | 13 | public class Extension implements som.vm.Extension { 14 | 15 | @Override 16 | public List> getSpecializers() { 17 | List> specializers = new ArrayList<>(); 18 | 19 | PrimitiveLoader.addAll(specializers, ExtensionPrimsFactory.getFactories()); 20 | 21 | return specializers; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/som/primitives/ObjectSystemPrims.java: -------------------------------------------------------------------------------- 1 | package som.primitives; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | 6 | import bd.primitives.Primitive; 7 | import som.interpreter.nodes.nary.UnaryExpressionNode; 8 | import som.vm.constants.KernelObj; 9 | import som.vmobjects.SObject; 10 | 11 | 12 | public abstract class ObjectSystemPrims { 13 | 14 | @GenerateNodeFactory 15 | @Primitive(primitive = "kernelObject:") 16 | public abstract static class KernelObjectPrim extends UnaryExpressionNode { 17 | @Specialization 18 | public final SObject getKernel(final Object self) { 19 | return KernelObj.kernel; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/tools/dym/nodes/AllocationProfilingNode.java: -------------------------------------------------------------------------------- 1 | package tools.dym.nodes; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | import tools.dym.profiles.AllocationProfile; 6 | import tools.dym.profiles.AllocationProfile.AllocProfileNode; 7 | 8 | 9 | public final class AllocationProfilingNode extends CountingNode { 10 | @Child private AllocProfileNode profile; 11 | 12 | public AllocationProfilingNode(final AllocationProfile profile) { 13 | super(profile); 14 | this.profile = profile.getProfile(); 15 | } 16 | 17 | @Override 18 | protected void onReturnValue(final VirtualFrame frame, final Object result) { 19 | profile.executeProfiling(result); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/tools/debugger/entities/Implementation.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.entities; 2 | 3 | /** 4 | * Trace events that encode implementation-specific information that is used 5 | * to interpret trace buffers, which represent only a chunk of the overall data. 6 | */ 7 | public enum Implementation { 8 | IMPL_THREAD(Marker.IMPL_THREAD, 9), 9 | IMPL_CURRENT_ACTIVITY(Marker.IMPL_THREAD_CURRENT_ACTIVITY, 13); 10 | 11 | private final byte id; 12 | private final int size; 13 | 14 | Implementation(final byte id, final int size) { 15 | this.id = id; 16 | this.size = size; 17 | } 18 | 19 | public byte getId() { 20 | return id; 21 | } 22 | 23 | public int getSize() { 24 | return size; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /artifact/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | echo "" 3 | echo "Get Eclipse" 4 | echo "" 5 | wget http://ftp.halifax.rwth-aachen.de/eclipse//technology/epp/downloads/release/2019-03/R/eclipse-java-2019-03-R-linux-gtk-x86_64.tar.gz 6 | tar xf eclipse-java-2019-03-R-linux-gtk-x86_64.tar.gz 7 | 8 | export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 9 | export JVMCI_VERSION_CHECK=ignore 10 | 11 | echo "" >> ~/.profile 12 | echo "# Export JVMCI_HOME for SOMns" >> ~/.profile 13 | echo "export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64" 14 | 15 | git clone ${GIT_REPO} ${REPO_NAME} 16 | 17 | cd ${REPO_NAME} 18 | git checkout ${COMMIT_SHA} 19 | git submodule update --init --recursive 20 | ant 21 | rebench -S -B --faulty --setup-only ${REBENCH_CONF} SOMns 22 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/dispatch/DispatchChain.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.dispatch; 2 | 3 | import com.oracle.truffle.api.nodes.NodeCost; 4 | 5 | 6 | public interface DispatchChain { 7 | int lengthOfDispatchChain(); 8 | 9 | class Cost { 10 | public static NodeCost getCost(final DispatchChain chain) { 11 | int dispatchChain = chain.lengthOfDispatchChain(); 12 | if (dispatchChain == 0) { 13 | return NodeCost.UNINITIALIZED; 14 | } else if (dispatchChain == 1) { 15 | return NodeCost.MONOMORPHIC; 16 | } else if (dispatchChain <= AbstractDispatchNode.INLINE_CACHE_SIZE) { 17 | return NodeCost.POLYMORPHIC; 18 | } else { 19 | return NodeCost.MEGAMORPHIC; 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/tools/dym/profiles/ArrayCreationProfile.java: -------------------------------------------------------------------------------- 1 | package tools.dym.profiles; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 7 | import com.oracle.truffle.api.source.SourceSection; 8 | 9 | 10 | public class ArrayCreationProfile extends Counter { 11 | 12 | private final Map arraySizes; 13 | 14 | public ArrayCreationProfile(final SourceSection source) { 15 | super(source); 16 | arraySizes = new HashMap<>(); 17 | } 18 | 19 | @TruffleBoundary 20 | public void profileArraySize(final int size) { 21 | arraySizes.merge(size, 1, Integer::sum); 22 | } 23 | 24 | public Map getSizes() { 25 | return arraySizes; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/tools/snapshot/nodes/AbstractSerializationNode.java: -------------------------------------------------------------------------------- 1 | package tools.snapshot.nodes; 2 | 3 | import com.oracle.truffle.api.nodes.Node; 4 | 5 | import som.interpreter.objectstorage.ClassFactory; 6 | import som.vm.VmSettings; 7 | import tools.snapshot.SnapshotBuffer; 8 | import tools.snapshot.deserialization.DeserializationBuffer; 9 | 10 | 11 | public abstract class AbstractSerializationNode extends Node { 12 | public final ClassFactory classFact; 13 | 14 | public AbstractSerializationNode(final ClassFactory classFact) { 15 | assert VmSettings.SNAPSHOTS_ENABLED; 16 | this.classFact = classFact; 17 | } 18 | 19 | public abstract void execute(Object o, SnapshotBuffer sb); 20 | 21 | public abstract Object deserialize(DeserializationBuffer bb); 22 | } 23 | -------------------------------------------------------------------------------- /src/tools/debugger/message/SymbolMessage.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.message; 2 | 3 | import java.util.ArrayList; 4 | 5 | import som.vmobjects.SSymbol; 6 | import tools.debugger.message.Message.OutgoingMessage; 7 | 8 | 9 | /** 10 | * Message with a map to resolve symbol ids to their name. 11 | */ 12 | public class SymbolMessage extends OutgoingMessage { 13 | private final String[] symbols; 14 | private final int[] ids; 15 | 16 | public SymbolMessage(final ArrayList symbols) { 17 | this.symbols = new String[symbols.size()]; 18 | this.ids = new int[symbols.size()]; 19 | int i = 0; 20 | 21 | for (SSymbol s : symbols) { 22 | this.symbols[i] = s.getString(); 23 | ids[i] = s.getSymbolId(); 24 | i++; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /tools/kompos/tests/pingpong-csp.ns: -------------------------------------------------------------------------------- 1 | class PingPongCSP usingPlatform: platform = Value ( 2 | | Channel = platform processes Channel. 3 | Process = platform processes Process. 4 | processes = platform processes. 5 | Array = platform kernel Array. 6 | |)( 7 | class Ping new: out and: in = Process ( 8 | | private out = out. 9 | private in = in. 10 | |)( 11 | public run = ( 12 | out write: #ping. 13 | in read. 14 | ) 15 | ) 16 | 17 | public main: args = ( 18 | | ch1 ch2 | 19 | ch1:: Channel new. 20 | ch2:: Channel new. 21 | 22 | processes spawn: Ping with: (Array with: ch1 out with: ch2 in). 23 | ch1 in read. 24 | ch2 out write: #done. 25 | 26 | ^ 0 27 | ) 28 | ) 29 | ) 30 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/nary/BinaryBasicOperation.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.nary; 2 | 3 | import com.oracle.truffle.api.instrumentation.Tag; 4 | 5 | import tools.dym.Tags.BasicPrimitiveOperation; 6 | 7 | 8 | /** 9 | * Nodes of this type represent basic operations such as arithmetics and 10 | * comparisons. Basic means here, that these nodes are mapping to one or only 11 | * a few basic operations in an ideal native code mapping. 12 | */ 13 | public abstract class BinaryBasicOperation extends BinaryExpressionNode { 14 | @Override 15 | protected boolean hasTagIgnoringEagerness(final Class tag) { 16 | if (tag == BasicPrimitiveOperation.class) { 17 | return true; 18 | } else { 19 | return super.hasTagIgnoringEagerness(tag); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/nary/UnaryBasicOperation.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.nary; 2 | 3 | import com.oracle.truffle.api.instrumentation.Tag; 4 | 5 | import tools.dym.Tags.BasicPrimitiveOperation; 6 | 7 | 8 | /** 9 | * Nodes of this type represent basic operations such as arithmetics and 10 | * comparisons. Basic means here, that these nodes are mapping to one or only 11 | * a few basic operations in an ideal native code mapping. 12 | */ 13 | public abstract class UnaryBasicOperation extends UnaryExpressionNode { 14 | @Override 15 | protected boolean hasTagIgnoringEagerness(final Class tag) { 16 | if (tag == BasicPrimitiveOperation.class) { 17 | return true; 18 | } else { 19 | return super.hasTagIgnoringEagerness(tag); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/tools/dym/nodes/ArrayAllocationProfilingNode.java: -------------------------------------------------------------------------------- 1 | package tools.dym.nodes; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | import som.primitives.SizeAndLengthPrim; 6 | import som.primitives.SizeAndLengthPrimFactory; 7 | import tools.dym.profiles.ArrayCreationProfile; 8 | 9 | 10 | public class ArrayAllocationProfilingNode extends CountingNode { 11 | 12 | @Child protected SizeAndLengthPrim size; 13 | 14 | public ArrayAllocationProfilingNode(final ArrayCreationProfile counter) { 15 | super(counter); 16 | size = SizeAndLengthPrimFactory.create(null); 17 | } 18 | 19 | @Override 20 | protected void onReturnValue(final VirtualFrame frame, final Object result) { 21 | counter.profileArraySize((int) size.executeEvaluated(result)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /core-lib/demos/ActorDemo.ns: -------------------------------------------------------------------------------- 1 | class ActorDemo usingPlatform: platform = Value ( 2 | | private actors = platform actors. | 3 | )( 4 | 5 | class Result = ()( 6 | public get = ( 7 | 'get' println. 8 | ^ 42 9 | ) 10 | ) 11 | 12 | public createActorSendMessageAndProcessResult = ( 13 | | p p2 | 14 | p:: (actors createActorFromValue: Result) <-: new. 15 | p2:: p <-: get. 16 | p2 whenResolved: [:r | 17 | 'after get async' println. 18 | r println. 19 | 5 20 | ]. 21 | 'after get send, sequential' println. 22 | ^ 0 23 | ) 24 | 25 | public main: args = ( 26 | | completionPP | 27 | completionPP:: actors createPromisePair. 28 | 29 | 1 halt. 30 | 31 | createActorSendMessageAndProcessResult. 32 | 33 | ^ completionPP promise 34 | ) 35 | ) 36 | -------------------------------------------------------------------------------- /core-lib/TestSuite/extension/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/tools/debugger/message/ScopesRequest.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.message; 2 | 3 | import org.java_websocket.WebSocket; 4 | 5 | import tools.debugger.FrontendConnector; 6 | import tools.debugger.frontend.Suspension; 7 | import tools.debugger.message.Message.Request; 8 | 9 | 10 | public final class ScopesRequest extends Request { 11 | private final long frameId; 12 | 13 | ScopesRequest(final int requestId, final int frameId) { 14 | super(requestId); 15 | this.frameId = frameId; 16 | } 17 | 18 | ScopesRequest() { 19 | frameId = 0; 20 | } 21 | 22 | @Override 23 | public void process(final FrontendConnector connector, final WebSocket conn) { 24 | Suspension suspension = connector.getSuspensionForGlobalId(frameId); 25 | suspension.sendScopes(frameId, connector, requestId); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/tools/debugger/frontend/RuntimeScope.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.frontend; 2 | 3 | import com.oracle.truffle.api.frame.MaterializedFrame; 4 | 5 | import som.compiler.Variable; 6 | import som.interpreter.LexicalScope.MethodScope; 7 | 8 | 9 | public class RuntimeScope { 10 | private final MaterializedFrame frame; 11 | private final MethodScope lexicalScope; 12 | 13 | public RuntimeScope(final MaterializedFrame frame, final MethodScope lexcialScope) { 14 | this.frame = frame; 15 | this.lexicalScope = lexcialScope; 16 | assert frame.getFrameDescriptor() == lexcialScope.getFrameDescriptor(); 17 | } 18 | 19 | public Variable[] getVariables() { 20 | return lexicalScope.getVariables(); 21 | } 22 | 23 | public Object read(final Variable var) { 24 | return var.read(frame); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/specialized/SomLoop.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.specialized; 2 | 3 | import som.interpreter.Invokable; 4 | 5 | import com.oracle.truffle.api.CompilerAsserts; 6 | import com.oracle.truffle.api.nodes.Node; 7 | import com.oracle.truffle.api.nodes.RootNode; 8 | 9 | 10 | public abstract class SomLoop { 11 | 12 | public static void reportLoopCount(final long count, final Node loopNode) { 13 | if (count < 1) { 14 | return; 15 | } 16 | 17 | CompilerAsserts.neverPartOfCompilation("reportLoopCount"); 18 | Node current = loopNode.getParent(); 19 | while (current != null && !(current instanceof RootNode)) { 20 | current = current.getParent(); 21 | } 22 | if (current != null) { 23 | ((Invokable) current).propagateLoopCountThroughoutMethodScope(count); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /core-lib/TestSuite/BasicInterpreterTests/Parser.ns: -------------------------------------------------------------------------------- 1 | class Parser = ()( 2 | public class R a: a b: b c: c = ( 3 | | public a = a. 4 | public b = b. 5 | public c = c. 6 | |)() 7 | 8 | public class A = ()( 9 | public foo = ( ^ R a: outer Parser baz b: outer Parser baz c: outer Parser baz ) 10 | public bar = ( ^ outer Parser a: 3 b: 4 ) 11 | public thirtyTwo = ( ^ 32 ) 12 | ) 13 | 14 | public class B = outer Parser A ()() 15 | 16 | public baz = ( ^ 32 ) 17 | public a: a b: b = ( ^ a * b ) 18 | ) : ( 19 | public testOuterInKeyword = ( 20 | | r | 21 | r:: self new A new foo. 22 | ^ r a * r b * r c 23 | ) 24 | 25 | public testOuterWithKeyword = ( 26 | ^ self new A new bar 27 | ) 28 | 29 | public testOuterInheritancePrefix = ( 30 | ^ self new B new thirtyTwo 31 | ) 32 | ) 33 | -------------------------------------------------------------------------------- /src/tools/debugger/message/UpdateBreakpoint.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.message; 2 | 3 | import org.java_websocket.WebSocket; 4 | 5 | import tools.debugger.FrontendConnector; 6 | import tools.debugger.message.Message.IncommingMessage; 7 | import tools.debugger.session.BreakpointInfo; 8 | 9 | 10 | public class UpdateBreakpoint extends IncommingMessage { 11 | private final BreakpointInfo breakpoint; 12 | 13 | public UpdateBreakpoint(final BreakpointInfo breakpoint) { 14 | this.breakpoint = breakpoint; 15 | } 16 | 17 | UpdateBreakpoint() { 18 | this.breakpoint = null; 19 | } 20 | 21 | public BreakpointInfo getBreakpoint() { 22 | return breakpoint; 23 | } 24 | 25 | @Override 26 | public void process(final FrontendConnector connector, final WebSocket conn) { 27 | breakpoint.registerOrUpdate(connector); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # SOMns: A Simple Newspeak Implementation focusing on Concurrency Features 2 | 3 | This documentation is split in multiple parts. 4 | Please see the navigation on the left to find links to: 5 | 6 | Documentation for users: 7 | 8 | - [Basic User Setup](basic-setup) with installation instructions 9 | - [IDE Setup](vs-code) of VS Code for writing SOMns code 10 | - [`som` Launcher](launcher) overview 11 | 12 | Documentation for developers: 13 | 14 | - [Development Setup](dev-setup) to use Eclipse for working 15 | on the SOMns interpreter 16 | - [Repository and Code Layout](repo-layout) 17 | - [Infrastructure](infrastructure) for day-to-day development 18 | 19 | An overview of SOMns' design decisions: 20 | 21 | - [Naming Conventions](naming) 22 | - [Connection between SOMns and Kompos](kompos-connection) 23 | - [CSP Design](csp-design) 24 | -------------------------------------------------------------------------------- /src/som/compiler/SemanticDefinitionError.java: -------------------------------------------------------------------------------- 1 | package som.compiler; 2 | 3 | import com.oracle.truffle.api.source.SourceSection; 4 | 5 | import bd.basic.ProgramDefinitionError; 6 | import bd.source.SourceCoordinate; 7 | 8 | 9 | public abstract class SemanticDefinitionError extends ProgramDefinitionError { 10 | private static final long serialVersionUID = -3374814429682547685L; 11 | private final SourceSection source; 12 | 13 | protected SemanticDefinitionError(final String message, final SourceSection source) { 14 | super(message); 15 | this.source = source; 16 | } 17 | 18 | public SourceSection getSourceSection() { 19 | return source; 20 | } 21 | 22 | @Override 23 | public String toString() { 24 | return source.getSource().getName() + 25 | SourceCoordinate.getLocationQualifier(source) + ":error: " + getMessage(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/tools/replay/nodes/TraceActorContextNode.java: -------------------------------------------------------------------------------- 1 | package tools.replay.nodes; 2 | 3 | import tools.concurrency.TracingActors.TracingActor; 4 | import tools.replay.actors.ActorExecutionTrace; 5 | import tools.replay.actors.ActorExecutionTrace.ActorTraceBuffer; 6 | 7 | 8 | public final class TraceActorContextNode extends TraceNode { 9 | 10 | @Child protected RecordIdNode id = RecordIdNodeGen.create(); 11 | 12 | public void trace(final TracingActor actor) { 13 | ActorTraceBuffer buffer = getCurrentBuffer(); 14 | int pos = buffer.position(); 15 | 16 | int idLen = id.execute(buffer, pos + 3, actor.getActorId()); 17 | int idBit = (idLen - 1) << 4; 18 | 19 | buffer.putByteAt(pos, (byte) (ActorExecutionTrace.ACTOR_CONTEXT | idBit)); 20 | buffer.putShortAt(pos + 1, actor.getOrdering()); 21 | 22 | buffer.position(pos + idLen + 1 + 2); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /artifact/virtualbox.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e # make script fail on first error 3 | 4 | # make SCRIPT_PATH absolute 5 | pushd `dirname $0` > /dev/null 6 | SCRIPT_PATH=`pwd` 7 | popd > /dev/null 8 | 9 | source ${SCRIPT_PATH}/config.inc 10 | 11 | function check_for() { 12 | if [ ! -x `which $1` ] 13 | then 14 | ERR "$1 binary not found. $2" 15 | if [ "non-fatal" -ne "$3" ] 16 | then 17 | exit 1 18 | fi 19 | fi 20 | } 21 | 22 | ## Make sure we have all dependencies 23 | check_for "packer" "Packer does not seem available. We tested with packer version 1.4 from https://www.packer.io/downloads.html" 24 | 25 | echo Compose a VirtualBox Image 26 | pushd ${SCRIPT_PATH} 27 | 28 | packer build -force packer.json 29 | 30 | echo File Size 31 | ls -sh ~/artifacts/${BOX_NAME}/* 32 | 33 | echo MD5 34 | md5sum ~/artifacts/${BOX_NAME}/* 35 | 36 | chmod a+r ~/artifacts/${BOX_NAME}/* 37 | -------------------------------------------------------------------------------- /src/tools/dym/nodes/ReportReceiverNode.java: -------------------------------------------------------------------------------- 1 | package tools.dym.nodes; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.instrumentation.ExecutionEventNode; 5 | 6 | import tools.dym.profiles.CallsiteProfile; 7 | 8 | 9 | public class ReportReceiverNode extends ExecutionEventNode { 10 | @Child protected TypeProfileNode typeProfile; 11 | 12 | public ReportReceiverNode(final CallsiteProfile profile) { 13 | typeProfile = TypeProfileNodeGen.create(profile); 14 | profile.setReceiverProfile(typeProfile); 15 | } 16 | 17 | @Override 18 | protected void onReturnValue(final VirtualFrame frame, final Object result) { 19 | typeProfile.executeProfiling(result); 20 | } 21 | 22 | @Override 23 | protected void onReturnExceptional(final VirtualFrame frame, final Throwable exception) { 24 | typeProfile.executeProfiling(exception); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/literals/BooleanLiteralNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.literals; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | 6 | public abstract class BooleanLiteralNode extends LiteralNode { 7 | 8 | public static final class TrueLiteralNode extends BooleanLiteralNode { 9 | 10 | @Override 11 | public boolean executeBoolean(final VirtualFrame frame) { 12 | return true; 13 | } 14 | 15 | @Override 16 | public Object executeGeneric(final VirtualFrame frame) { 17 | return true; 18 | } 19 | } 20 | 21 | public static final class FalseLiteralNode extends BooleanLiteralNode { 22 | 23 | @Override 24 | public boolean executeBoolean(final VirtualFrame frame) { 25 | return false; 26 | } 27 | 28 | @Override 29 | public Object executeGeneric(final VirtualFrame frame) { 30 | return false; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/tools/dym/nodes/CallTargetNode.java: -------------------------------------------------------------------------------- 1 | package tools.dym.nodes; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | import som.interpreter.Invokable; 6 | import tools.dym.profiles.CallsiteProfile; 7 | import tools.dym.profiles.CallsiteProfile.Counter; 8 | 9 | 10 | public class CallTargetNode extends CountingNode { 11 | 12 | protected final Counter cnt; 13 | 14 | public CallTargetNode(final CallsiteProfile profile, final Invokable invokable) { 15 | super(profile); 16 | cnt = profile.createCounter(invokable); 17 | } 18 | 19 | @Override 20 | public void onEnter(final VirtualFrame frame) { 21 | super.onEnter(frame); 22 | cnt.inc(); 23 | } 24 | 25 | @Override 26 | public void onReturnValue(final VirtualFrame frame, final Object result) {} 27 | 28 | @Override 29 | public void onReturnExceptional(final VirtualFrame frame, final Throwable exception) {} 30 | } 31 | -------------------------------------------------------------------------------- /src/tools/debugger/session/BreakpointInfo.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.session; 2 | 3 | import com.oracle.truffle.api.debug.Breakpoint; 4 | 5 | import tools.debugger.FrontendConnector; 6 | 7 | 8 | public abstract class BreakpointInfo { 9 | private final boolean enabled; 10 | 11 | protected BreakpointInfo(final boolean enabled) { 12 | this.enabled = enabled; 13 | } 14 | 15 | /** 16 | * Note: Meant mostly for use by serialization. 17 | */ 18 | protected BreakpointInfo() { 19 | this(false); 20 | } 21 | 22 | /** 23 | * This is only the original value, the run-time value is represented by a 24 | * separate {@link BreakpointEnabling} or {@link Breakpoint} instance. 25 | * 26 | * @return whether the breakpoint was originally enabled 27 | */ 28 | public boolean isEnabled() { 29 | return enabled; 30 | } 31 | 32 | public abstract void registerOrUpdate(FrontendConnector frontend); 33 | } 34 | -------------------------------------------------------------------------------- /src/som/interpreter/transactions/CachedTxSlotWrite.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.transactions; 2 | 3 | import som.interpreter.nodes.dispatch.AbstractDispatchNode; 4 | import som.interpreter.nodes.dispatch.CachedSlotWrite; 5 | import som.interpreter.nodes.dispatch.DispatchGuard.CheckSObject; 6 | import som.vmobjects.SObject; 7 | import som.vmobjects.SObject.SMutableObject; 8 | 9 | 10 | public final class CachedTxSlotWrite extends CachedSlotWrite { 11 | @Child protected CachedSlotWrite write; 12 | 13 | public CachedTxSlotWrite(final CachedSlotWrite write, 14 | final CheckSObject guard, final AbstractDispatchNode nextInCache) { 15 | super(guard, nextInCache); 16 | this.write = write; 17 | } 18 | 19 | @Override 20 | public void doWrite(final SObject obj, final Object value) { 21 | SMutableObject workingCopy = Transactions.workingCopy((SMutableObject) obj); 22 | write.doWrite(workingCopy, value); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/tools/debugger/message/StepMessage.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.message; 2 | 3 | import org.java_websocket.WebSocket; 4 | 5 | import tools.debugger.FrontendConnector; 6 | import tools.debugger.entities.SteppingType; 7 | import tools.debugger.frontend.Suspension; 8 | import tools.debugger.message.Message.IncommingMessage; 9 | 10 | 11 | public class StepMessage extends IncommingMessage { 12 | private final long activityId; 13 | private final SteppingType step; 14 | 15 | /** 16 | * Note: meant for serialization. 17 | */ 18 | StepMessage() { 19 | activityId = -1; 20 | step = null; 21 | } 22 | 23 | @Override 24 | public void process(final FrontendConnector connector, final WebSocket conn) { 25 | Suspension susp = connector.getSuspension(activityId); 26 | assert susp != null : "Failed to get suspension for activityId: " + activityId; 27 | step.process(susp); 28 | susp.resume(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /core-lib/demos/STMDemo.ns: -------------------------------------------------------------------------------- 1 | class STMDemo usingPlatform: platform = Value ( 2 | | private Thread = platform threading Thread. 3 | private tx = platform transactions Transaction. 4 | |)( 5 | 6 | private class MyObj = ( 7 | | public field ::= 0. | 8 | )() 9 | 10 | private doCount: o = ( 11 | 1 halt. 12 | tx atomic: [ 13 | | cnt | 14 | cnt:: o field. 15 | o field: cnt + 1. 16 | ]. 17 | 18 | o field println. 19 | 20 | tx atomic: [ 21 | | cnt | 22 | cnt:: o field. 23 | o field: cnt + 1. 24 | ]. 25 | 26 | o field println. 27 | 28 | tx atomic: [ 29 | | cnt | 30 | cnt:: o field. 31 | o field: cnt + 1. 32 | ]. 33 | 34 | o field println. 35 | ) 36 | 37 | public main: args = ( 38 | | o | 39 | 'STM example\n' println. 40 | o:: MyObj new. 41 | 42 | Thread spawn: [ doCount: o ]. 43 | 44 | doCount: o. 45 | 46 | ^ 0 47 | ) 48 | ) 49 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/specialized/whileloops/WhileFalsePrimitiveNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.specialized.whileloops; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | import com.oracle.truffle.api.source.SourceSection; 7 | 8 | import som.vmobjects.SBlock; 9 | import som.vmobjects.SObjectWithClass; 10 | 11 | 12 | @GenerateNodeFactory 13 | public abstract class WhileFalsePrimitiveNode extends WhilePrimitiveNode { 14 | public WhileFalsePrimitiveNode(final SourceSection source) { 15 | super(source, false); 16 | } 17 | 18 | @Override 19 | @Specialization 20 | protected final SObjectWithClass doWhileConditionally(final VirtualFrame frame, 21 | final SBlock loopCondition, final SBlock loopBody) { 22 | return (SObjectWithClass) whileNode.executeEvaluated(frame, loopCondition, loopBody); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/specialized/whileloops/WhileTruePrimitiveNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.specialized.whileloops; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | import com.oracle.truffle.api.source.SourceSection; 7 | 8 | import som.vmobjects.SBlock; 9 | import som.vmobjects.SObjectWithClass; 10 | 11 | 12 | @GenerateNodeFactory 13 | public abstract class WhileTruePrimitiveNode extends WhilePrimitiveNode { 14 | public WhileTruePrimitiveNode(final SourceSection source) { 15 | super(source, true); 16 | } 17 | 18 | @Override 19 | @Specialization 20 | protected final SObjectWithClass doWhileConditionally(final VirtualFrame frame, 21 | final SBlock loopCondition, final SBlock loopBody) { 22 | return (SObjectWithClass) whileNode.executeEvaluated(frame, loopCondition, loopBody); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/som/primitives/CosPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | import com.oracle.truffle.api.instrumentation.Tag; 6 | 7 | import bd.primitives.Primitive; 8 | import som.interpreter.nodes.nary.UnaryBasicOperation; 9 | import tools.dym.Tags.OpArithmetic; 10 | 11 | 12 | @GenerateNodeFactory 13 | @Primitive(primitive = "doubleCos:", selector = "cos", receiverType = Double.class) 14 | public abstract class CosPrim extends UnaryBasicOperation { 15 | @Override 16 | protected boolean hasTagIgnoringEagerness(final Class tag) { 17 | if (tag == OpArithmetic.class) { // TODO: is this good enough? 18 | return true; 19 | } else { 20 | return super.hasTagIgnoringEagerness(tag); 21 | } 22 | } 23 | 24 | @Specialization 25 | public final double doCos(final double rcvr) { 26 | return Math.cos(rcvr); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/som/primitives/arithmetic/ArithmeticPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.arithmetic; 2 | 3 | import java.math.BigInteger; 4 | 5 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 6 | import com.oracle.truffle.api.instrumentation.Tag; 7 | 8 | import som.interpreter.nodes.nary.BinaryBasicOperation; 9 | import tools.dym.Tags.OpArithmetic; 10 | 11 | 12 | public abstract class ArithmeticPrim extends BinaryBasicOperation { 13 | @Override 14 | protected boolean hasTagIgnoringEagerness(final Class tag) { 15 | if (tag == OpArithmetic.class) { 16 | return true; 17 | } else { 18 | return super.hasTagIgnoringEagerness(tag); 19 | } 20 | } 21 | 22 | @TruffleBoundary 23 | protected static final Number reduceToLongIfPossible(final BigInteger result) { 24 | if (result.bitLength() > Long.SIZE - 1) { 25 | return result; 26 | } else { 27 | return result.longValue(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /artifact/clean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eux 2 | 3 | echo "" 4 | echo "Clean Up Image" 5 | echo "" 6 | apt-get clean -y 7 | apt-get autoclean -y 8 | 9 | find /var/lib/apt -type f | xargs rm -f 10 | find /var/lib/doc -type f | xargs rm -f 11 | find /var/cache -type f | xargs rm -f 12 | 13 | rm -rf /usr/src/vboxguest* 14 | rm -rf /usr/share/doc 15 | 16 | rm -rf /usr/src/linux-headers* 17 | rm -rf /usr/share/locale/{af,an,am,ar,ary,as,ast,az,bal,be,bg,bn,bn_IN,bo,br,bs,byn,ca,ca@valencia,ckb,cr,crh,cs,csb,cv,cy,da,de,de_AT,dv,dz,el,en_AU,en_CA,en_GB,eo,es,et,et_EE,eu,fa,fa_AF,fi,fil,fo,fr,frp,fur,fy,ga,gd,gez,gl,gu,gv,haw,he,hi,hr,ht,hu,hy,id,is,it,ja,jv,ka,kk,km,kn,ko,kok,ku,ky,lb,lg,ln,lt,lo,lv,mg,mhr,mi,mk,ml,mn,mr,ms,mt,my,nb,nds,ne,nl,nn,no,nso,oc,or,os,pa,pam,pl,ps,pt,pt_BR,qu,ro,ru,rw,sc,sd,shn,si,sk,sl,so,sq,sr,sr*latin,sv,sw,ta,te,th,ti,tig,tk,tl,tr,trv,tt,ug,uk,ur,urd,uz,ve,vec,vi,wa,wal,wo,xh,zh,zh_HK,zh_CN,zh_TW,zu} 18 | 19 | echo "" 20 | echo "Clean Up Done" 21 | echo "" 22 | -------------------------------------------------------------------------------- /src/som/primitives/arithmetic/SinPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.arithmetic; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | import com.oracle.truffle.api.instrumentation.Tag; 6 | 7 | import bd.primitives.Primitive; 8 | import som.interpreter.nodes.nary.UnaryBasicOperation; 9 | import tools.dym.Tags.OpArithmetic; 10 | 11 | 12 | @GenerateNodeFactory 13 | @Primitive(primitive = "doubleSin:", selector = "sin", receiverType = Double.class) 14 | public abstract class SinPrim extends UnaryBasicOperation { 15 | @Override 16 | protected boolean hasTagIgnoringEagerness(final Class tag) { 17 | if (tag == OpArithmetic.class) { // TODO: is this good enough? 18 | return true; 19 | } else { 20 | return super.hasTagIgnoringEagerness(tag); 21 | } 22 | } 23 | 24 | @Specialization 25 | public final double doSin(final double rcvr) { 26 | return Math.sin(rcvr); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: 'SOMns: A Simple Newspeak' 2 | # site_url: 3 | site_description: SOMns Project documentation 4 | site_author: SOMns contributors 5 | 6 | pages: 7 | - 'SOMns: A Simple Newspeak': index.md 8 | - For Users: 9 | - Basic User Setup: basic-setup.md 10 | - IDE Setup: vs-code.md 11 | - som Launcher: launcher.md 12 | - For Developers: 13 | - Development Setup: dev-setup.md 14 | - Repository and Code Layout: repo-layout.md 15 | - Development Infrastructure: infrastructure.md 16 | - Release Checklist: release-checklist.md 17 | - Extensions: extensions.md 18 | - SOMns Design Notes: 19 | - Naming Conventions: naming.md 20 | - Interaction with Kompos Debugger: kompos-connection.md 21 | - CSP Design: csp-design.md 22 | - License: LICENSE.md 23 | - README: README.md 24 | - Change Log: CHANGELOG.md 25 | - Authors: AUTHORS.md 26 | 27 | markdown_extensions: 28 | - toc: 29 | permalink: True 30 | -------------------------------------------------------------------------------- /src/som/interpreter/transactions/CachedTxSlotRead.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.transactions; 2 | 3 | import som.interpreter.nodes.dispatch.AbstractDispatchNode; 4 | import som.interpreter.nodes.dispatch.CachedSlotRead; 5 | import som.interpreter.nodes.dispatch.DispatchGuard.CheckSObject; 6 | import som.vmobjects.SObject; 7 | import som.vmobjects.SObject.SMutableObject; 8 | 9 | 10 | public final class CachedTxSlotRead extends CachedSlotRead { 11 | @Child protected CachedSlotRead read; 12 | 13 | public CachedTxSlotRead(final SlotAccess type, 14 | final CachedSlotRead read, 15 | final CheckSObject guard, final AbstractDispatchNode nextInCache) { 16 | super(type, guard, nextInCache); 17 | assert type == SlotAccess.FIELD_READ; 18 | this.read = read; 19 | } 20 | 21 | @Override 22 | public Object read(final SObject rcvr) { 23 | SMutableObject workingCopy = Transactions.workingCopy((SMutableObject) rcvr); 24 | return read.read(workingCopy); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/som/vmobjects/SAbstractObject.java: -------------------------------------------------------------------------------- 1 | package som.vmobjects; 2 | 3 | import com.oracle.truffle.api.CompilerAsserts; 4 | import com.oracle.truffle.api.interop.InteropLibrary; 5 | import com.oracle.truffle.api.library.ExportLibrary; 6 | import com.oracle.truffle.api.library.ExportMessage; 7 | 8 | import som.interop.SomInteropObject; 9 | import som.vm.constants.Nil; 10 | 11 | 12 | @ExportLibrary(InteropLibrary.class) 13 | public abstract class SAbstractObject implements SomInteropObject { 14 | 15 | public abstract SClass getSOMClass(); 16 | 17 | public abstract boolean isValue(); 18 | 19 | @Override 20 | public String toString() { 21 | CompilerAsserts.neverPartOfCompilation(); 22 | SClass clazz = getSOMClass(); 23 | if (clazz == null) { 24 | return "an Object(clazz==null)"; 25 | } 26 | return "a " + clazz.getName().getString(); 27 | } 28 | 29 | @ExportMessage 30 | public final boolean isNull() { 31 | return this == Nil.nilObject; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/tools/dym/nodes/ReportResultNode.java: -------------------------------------------------------------------------------- 1 | package tools.dym.nodes; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.instrumentation.ExecutionEventNode; 5 | 6 | import tools.dym.profiles.OperationProfile; 7 | 8 | 9 | public class ReportResultNode extends ExecutionEventNode { 10 | protected final OperationProfile profile; 11 | protected final int argIdx; 12 | 13 | public ReportResultNode(final OperationProfile profile, final int argIdx) { 14 | this.profile = profile; 15 | this.argIdx = argIdx; 16 | } 17 | 18 | @Override 19 | public void onEnter(final VirtualFrame frame) {} 20 | 21 | @Override 22 | public void onReturnValue(final VirtualFrame frame, final Object result) { 23 | profile.profileArgument(argIdx, result); 24 | } 25 | 26 | @Override 27 | public void onReturnExceptional(final VirtualFrame frame, final Throwable exception) { 28 | profile.profileArgument(argIdx, exception); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/som/interpreter/actors/SuspendExecutionNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.actors; 2 | 3 | import com.oracle.truffle.api.debug.DebuggerTags.AlwaysHalt; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | import com.oracle.truffle.api.instrumentation.Tag; 6 | 7 | import som.interpreter.nodes.nary.UnaryExpressionNode; 8 | 9 | 10 | public abstract class SuspendExecutionNode extends UnaryExpressionNode { 11 | private int skipFrames; 12 | 13 | SuspendExecutionNode(final int skipFrames) { 14 | this.skipFrames = skipFrames; 15 | } 16 | 17 | @Specialization 18 | public final Object doSAbstractObject(final Object receiver) { 19 | return receiver; 20 | } 21 | 22 | @Override 23 | protected boolean hasTagIgnoringEagerness(final Class tag) { 24 | if (tag == AlwaysHalt.class) { 25 | return true; 26 | } 27 | return super.hasTagIgnoringEagerness(tag); 28 | } 29 | 30 | public int getSkipFrames() { 31 | return skipFrames; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/tools/dym/nodes/ClosureTargetNode.java: -------------------------------------------------------------------------------- 1 | package tools.dym.nodes; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | 5 | import som.interpreter.Invokable; 6 | import tools.dym.profiles.ClosureApplicationProfile; 7 | import tools.dym.profiles.ClosureApplicationProfile.ActivationCounter; 8 | 9 | 10 | public final class ClosureTargetNode extends CountingNode { 11 | 12 | protected final ActivationCounter cnt; 13 | 14 | public ClosureTargetNode(final ClosureApplicationProfile profile, 15 | final Invokable invokable) { 16 | super(profile); 17 | cnt = profile.createCounter(invokable); 18 | } 19 | 20 | @Override 21 | public void onEnter(final VirtualFrame frame) { 22 | super.onEnter(frame); 23 | cnt.inc(); 24 | } 25 | 26 | @Override 27 | public void onReturnValue(final VirtualFrame frame, final Object result) {} 28 | 29 | @Override 30 | public void onReturnExceptional(final VirtualFrame frame, final Throwable exception) {} 31 | } 32 | -------------------------------------------------------------------------------- /src/tools/debugger/entities/SendOp.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.entities; 2 | 3 | public enum SendOp { 4 | ACTOR_MSG(Marker.ACTOR_MSG_SEND, EntityType.ACT_MSG, EntityType.ACTOR), 5 | PROMISE_MSG(Marker.PROMISE_MSG_SEND, EntityType.ACT_MSG, EntityType.PROMISE), 6 | CHANNEL_SEND(Marker.CHANNEL_MSG_SEND, EntityType.CH_MSG, EntityType.CHANNEL), 7 | PROMISE_RESOLUTION(Marker.PROMISE_RESOLUTION, EntityType.PROMISE, EntityType.PROMISE); 8 | 9 | private final byte id; 10 | private final EntityType entity; 11 | private final EntityType target; 12 | 13 | SendOp(final byte id, final EntityType entity, final EntityType target) { 14 | this.id = id; 15 | this.entity = entity; 16 | this.target = target; 17 | } 18 | 19 | public byte getId() { 20 | return id; 21 | } 22 | 23 | public EntityType getEntity() { 24 | return entity; 25 | } 26 | 27 | public EntityType getTarget() { 28 | return target; 29 | } 30 | 31 | public int getSize() { 32 | return 17; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/tools/replay/nodes/TraceActorCreationNode.java: -------------------------------------------------------------------------------- 1 | package tools.replay.nodes; 2 | 3 | import tools.concurrency.TracingActors.TracingActor; 4 | import tools.replay.actors.ActorExecutionTrace; 5 | import tools.replay.actors.ActorExecutionTrace.ActorTraceBuffer; 6 | 7 | 8 | public final class TraceActorCreationNode extends TraceNode { 9 | 10 | private static final int TRACE_ENTRY_SIZE = 5; 11 | 12 | @Child protected TraceActorContextNode tracer = new TraceActorContextNode(); 13 | @Child protected RecordIdNode id = RecordIdNodeGen.create(); 14 | 15 | public void trace(final TracingActor actor) { 16 | ActorTraceBuffer buffer = getCurrentBuffer(); 17 | buffer.ensureSufficientSpace(TRACE_ENTRY_SIZE, tracer); 18 | int pos = buffer.position(); 19 | 20 | int idLen = id.execute(buffer, pos + 1, actor.getActorId()); 21 | int idBit = (idLen - 1) << 4; 22 | 23 | buffer.putByteAt(pos, (byte) (ActorExecutionTrace.ACTOR_CREATION | idBit)); 24 | buffer.position(pos + idLen + 1); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/tools/debugger/PrimitiveCallOrigin.java: -------------------------------------------------------------------------------- 1 | package tools.debugger; 2 | 3 | import com.oracle.truffle.api.Truffle; 4 | import com.oracle.truffle.api.frame.FrameInstance; 5 | import com.oracle.truffle.api.nodes.Node; 6 | import com.oracle.truffle.api.source.SourceSection; 7 | 8 | import som.interpreter.nodes.MessageSendNode.GenericMessageSendNode; 9 | 10 | 11 | public class PrimitiveCallOrigin { 12 | public static Node getCallerNode() { 13 | int[] level = new int[1]; 14 | 15 | FrameInstance f = Truffle.getRuntime().iterateFrames(fi -> { 16 | if (level[0] == 2) { 17 | return fi; 18 | } 19 | level[0]++; 20 | return null; 21 | }); 22 | return f.getCallNode(); 23 | } 24 | 25 | public static SourceSection getCaller() { 26 | Node directCallNode = getCallerNode(); 27 | Node current = directCallNode; 28 | 29 | while (!(current instanceof GenericMessageSendNode)) { 30 | current = current.getParent(); 31 | } 32 | return current.getSourceSection(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/tools/debugger/entities/PassiveEntityType.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.entities; 2 | 3 | import tools.TraceData; 4 | 5 | 6 | public enum PassiveEntityType { 7 | CHANNEL(EntityType.CHANNEL, Marker.CHANNEL_CREATION), 8 | CHANNEL_MSG(EntityType.CH_MSG), 9 | ACTOR_MSG(EntityType.ACT_MSG), 10 | PROMISE(EntityType.PROMISE, Marker.PROMISE_CREATION); 11 | 12 | private final EntityType type; 13 | private final byte creationMarker; 14 | 15 | PassiveEntityType(final EntityType type) { 16 | this(type, 0); 17 | } 18 | 19 | PassiveEntityType(final EntityType type, final int creationMarker) { 20 | this.type = type; 21 | this.creationMarker = (byte) creationMarker; 22 | } 23 | 24 | public byte getId() { 25 | return type.id; 26 | } 27 | 28 | public String getName() { 29 | return type.name; 30 | } 31 | 32 | public byte getCreationMarker() { 33 | return creationMarker; 34 | } 35 | 36 | public int getCreationSize() { 37 | return 9 + TraceData.SOURCE_SECTION_SIZE; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/tools/debugger/message/InitializeConnection.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.message; 2 | 3 | import org.java_websocket.WebSocket; 4 | 5 | import tools.debugger.FrontendConnector; 6 | import tools.debugger.message.Message.IncommingMessage; 7 | import tools.debugger.session.BreakpointInfo; 8 | 9 | 10 | public class InitializeConnection extends IncommingMessage { 11 | 12 | private final BreakpointInfo[] breakpoints; 13 | 14 | public InitializeConnection(final BreakpointInfo[] breakpoints) { 15 | this.breakpoints = breakpoints; 16 | } 17 | 18 | InitializeConnection() { 19 | this.breakpoints = null; 20 | } 21 | 22 | public BreakpointInfo[] getBreakpoints() { 23 | return breakpoints; 24 | } 25 | 26 | @Override 27 | public void process(final FrontendConnector connector, final WebSocket conn) { 28 | if (breakpoints != null) { 29 | for (BreakpointInfo bp : breakpoints) { 30 | bp.registerOrUpdate(connector); 31 | } 32 | } 33 | connector.completeConnection(conn); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/specialized/NotMessageNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.specialized; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | import com.oracle.truffle.api.instrumentation.Tag; 7 | 8 | import bd.primitives.Primitive; 9 | import som.interpreter.nodes.nary.UnaryBasicOperation; 10 | import tools.dym.Tags.OpArithmetic; 11 | 12 | 13 | @GenerateNodeFactory 14 | @Primitive(selector = "not", receiverType = Boolean.class) 15 | public abstract class NotMessageNode extends UnaryBasicOperation { 16 | @Override 17 | protected boolean hasTagIgnoringEagerness(final Class tag) { 18 | if (tag == OpArithmetic.class) { 19 | return true; 20 | } else { 21 | return super.hasTagIgnoringEagerness(tag); 22 | } 23 | } 24 | 25 | @Specialization 26 | public final boolean doNot(final VirtualFrame frame, final boolean receiver) { 27 | return !receiver; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/tools/debugger/message/Message.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.message; 2 | 3 | import org.java_websocket.WebSocket; 4 | 5 | import tools.debugger.FrontendConnector; 6 | 7 | 8 | public abstract class Message { 9 | public abstract static class IncommingMessage extends Message { 10 | public abstract void process(FrontendConnector connector, WebSocket conn); 11 | } 12 | 13 | /** 14 | * With id to connect request and response. 15 | */ 16 | public abstract static class Request extends IncommingMessage { 17 | protected final int requestId; 18 | 19 | public Request(final int requestId) { 20 | this.requestId = requestId; 21 | } 22 | 23 | protected Request() { 24 | this.requestId = 0; 25 | } 26 | } 27 | 28 | public static class OutgoingMessage extends Message {} 29 | 30 | public abstract static class Response extends OutgoingMessage { 31 | protected int requestId; 32 | 33 | public Response(final int requestId) { 34 | this.requestId = requestId; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/som/vm/Activity.java: -------------------------------------------------------------------------------- 1 | package som.vm; 2 | 3 | import tools.debugger.entities.ActivityType; 4 | 5 | 6 | public interface Activity { 7 | String getName(); 8 | 9 | /** 10 | * The activity id. 11 | * For non-tracing activities, the id is 0. 12 | */ 13 | default long getId() { 14 | return 0; 15 | } 16 | 17 | ActivityType getType(); 18 | 19 | /** 20 | * The id for the next trace buffer used with this activity. 21 | * Since an activity is executed by at most one thread at a time, 22 | * this id allows us to order trace buffer fragments. 23 | * Non-tracing activities don't need to implement it. 24 | */ 25 | default int getNextTraceBufferId() { 26 | throw new UnsupportedOperationException("Should never be called"); 27 | } 28 | 29 | /** 30 | * Set the flag that indicates a breakpoint on joining activity. 31 | * Does nothing for non-tracing activities, i.e., when debugging is disabled. 32 | */ 33 | default void setStepToJoin(final boolean val) {} 34 | 35 | void setStepToNextTurn(boolean val); 36 | } 37 | -------------------------------------------------------------------------------- /tools/kompos/tests/stm.ns: -------------------------------------------------------------------------------- 1 | class STM usingPlatform: platform = Value ( 2 | | private Thread = platform threading Thread. 3 | private tx = platform transactions Transaction. 4 | |)( 5 | 6 | private class MyObj = ( 7 | | public field ::= 0. | 8 | )() 9 | 10 | private doCount: o id: id = ( 11 | tx atomic: [ 12 | | cnt | 13 | cnt:: o field. 14 | o field: cnt + 1. 15 | ]. 16 | 17 | ('id: ' + id asString + ' val: ' + o field asString) println. 18 | 19 | tx atomic: [ 20 | | cnt | 21 | cnt:: o field. 22 | o field: cnt + 1. 23 | ]. 24 | 25 | ('id: ' + id asString + ' val: ' + o field asString) println. 26 | 27 | tx atomic: [ 28 | | cnt | 29 | cnt:: o field. 30 | o field: cnt + 1. 31 | ]. 32 | 33 | ('id: ' + id asString + ' val: ' + o field asString) println. 34 | ) 35 | 36 | public main: args = ( 37 | | o | 38 | 'STM example\n' println. 39 | o:: MyObj new. 40 | 41 | Thread spawn: [ doCount: o id: 2 ]. 42 | 43 | doCount: o id: 1. 44 | 45 | ^ 0 46 | ) 47 | ) 48 | -------------------------------------------------------------------------------- /tools/kompos/tsfmt.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseIndentSize": 0, 3 | "indentSize": 2, 4 | "tabSize": 2, 5 | "indentStyle": 2, 6 | "newLineCharacter": "\n", 7 | "convertTabsToSpaces": true, 8 | "insertSpaceAfterCommaDelimiter": true, 9 | "insertSpaceAfterSemicolonInForStatements": true, 10 | "insertSpaceBeforeAndAfterBinaryOperators": true, 11 | "insertSpaceAfterConstructor": false, 12 | "insertSpaceAfterKeywordsInControlFlowStatements": true, 13 | "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, 14 | "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, 15 | "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, 16 | "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, 17 | "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, 18 | "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, 19 | "insertSpaceAfterTypeAssertion": false, 20 | "insertSpaceBeforeFunctionParenthesis": false, 21 | "placeOpenBraceOnNewLineForFunctions": false, 22 | "placeOpenBraceOnNewLineForControlBlocks": false 23 | } -------------------------------------------------------------------------------- /docs/release-checklist.md: -------------------------------------------------------------------------------- 1 | Release Checklist 2 | ================= 3 | 4 | This list is supposed to make sure we do not forget any important steps during 5 | release. 6 | 7 | 1. Check and update issue tracker for issues associated with current milestone 8 | 9 | 2. Update CHANGELOG.md with all elements missing 10 | A useful tool is the `github_changelog_generator` 11 | It can be used like this: 12 | 13 | sudo gem install github_changelog_generator 14 | github_changelog_generator -u smarr -p SOMns -o changelog-gen.md --since-tag v0.5.0 --token ${GITHUB_TOKEN} 15 | 16 | 3. Make sure all desired changes are part of the `dev` branch. 17 | 18 | 4. Prepare a release on GitHub with: https://github.com/smarr/SOMns/releases/new 19 | The content is normally just the last part of the CHANGELOG.md 20 | 21 | 5. If everything looks good, tag the release using the GitHub feature 22 | 23 | 6. Push the commit that is tagged as release to the `release` branch. 24 | 25 | 7. Announce the release 26 | - https://groups.google.com/forum/#!forum/som-dev 27 | - https://twitter.com/SOM_VMs 28 | -------------------------------------------------------------------------------- /src/som/primitives/HashPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives; 2 | 3 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 4 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | import bd.primitives.Primitive; 8 | import som.interpreter.nodes.nary.UnaryExpressionNode; 9 | import som.vmobjects.SAbstractObject; 10 | import som.vmobjects.SSymbol; 11 | 12 | 13 | @GenerateNodeFactory 14 | @Primitive(primitive = "objHashcode:") 15 | @Primitive(primitive = "stringHashcode:") 16 | public abstract class HashPrim extends UnaryExpressionNode { 17 | @Specialization 18 | @TruffleBoundary 19 | public final long doString(final String receiver) { 20 | return receiver.hashCode(); 21 | } 22 | 23 | @Specialization 24 | @TruffleBoundary 25 | public final long doSSymbol(final SSymbol receiver) { 26 | return receiver.getString().hashCode(); 27 | } 28 | 29 | @Specialization 30 | @TruffleBoundary 31 | public final long doSAbstractObject(final SAbstractObject receiver) { 32 | return receiver.hashCode(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/InternalObjectArrayNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.nodes.ExplodeLoop; 5 | import com.oracle.truffle.api.nodes.NodeCost; 6 | import com.oracle.truffle.api.nodes.NodeInfo; 7 | 8 | import som.interpreter.nodes.nary.ExprWithTagsNode; 9 | 10 | 11 | @NodeInfo(cost = NodeCost.NONE) 12 | public final class InternalObjectArrayNode extends ExprWithTagsNode { 13 | @Children private final ExpressionNode[] expressions; 14 | 15 | public InternalObjectArrayNode(final ExpressionNode[] expressions) { 16 | this.expressions = expressions; 17 | } 18 | 19 | @Override 20 | @ExplodeLoop 21 | public Object[] executeObjectArray(final VirtualFrame frame) { 22 | Object[] values = new Object[expressions.length]; 23 | for (int i = 0; i < expressions.length; i++) { 24 | values[i] = expressions[i].executeGeneric(frame); 25 | } 26 | return values; 27 | } 28 | 29 | @Override 30 | public Object executeGeneric(final VirtualFrame frame) { 31 | return executeObjectArray(frame); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/som/vmobjects/SObjectWithContext.java: -------------------------------------------------------------------------------- 1 | package som.vmobjects; 2 | 3 | import com.oracle.truffle.api.frame.MaterializedFrame; 4 | 5 | import som.interpreter.SArguments; 6 | 7 | 8 | /** 9 | * This role is implement by both SBlock and SClass and provides 10 | * the behavior for stepping outward through a block or object 11 | * literal's activations. 12 | * 13 | *

14 | * When a block or object literal is nested inside of another 15 | * block, a method, or an object literal its context is the activation 16 | * of that block, method, or object literal. 17 | */ 18 | 19 | public interface SObjectWithContext { 20 | 21 | /** 22 | * Return the block or object literal's enclosing activation, referred to 23 | * here as a context since it is surrounding/enclosing the current 24 | * object. 25 | */ 26 | MaterializedFrame getContext(); 27 | 28 | /** 29 | * Return the object enclosing the current object, 30 | * which is the receiver of this object. 31 | */ 32 | default SObjectWithContext getOuterSelf() { 33 | return (SObjectWithContext) SArguments.rcvr(getContext()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/specialized/OrBoolMessageNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.specialized; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | import com.oracle.truffle.api.instrumentation.Tag; 6 | 7 | import bd.tools.nodes.Operation; 8 | import som.interpreter.nodes.nary.BinaryBasicOperation; 9 | import tools.dym.Tags.OpComparison; 10 | 11 | 12 | @GenerateNodeFactory 13 | public abstract class OrBoolMessageNode extends BinaryBasicOperation 14 | implements Operation { 15 | @Override 16 | protected boolean hasTagIgnoringEagerness(final Class tag) { 17 | if (tag == OpComparison.class) { 18 | return true; 19 | } else { 20 | return super.hasTagIgnoringEagerness(tag); 21 | } 22 | } 23 | 24 | @Specialization 25 | public final boolean doOr(final boolean receiver, final boolean argument) { 26 | return receiver || argument; 27 | } 28 | 29 | @Override 30 | public String getOperation() { 31 | return "||"; 32 | } 33 | 34 | @Override 35 | public int getNumArguments() { 36 | return 2; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /docs/vs-code.md: -------------------------------------------------------------------------------- 1 | ## VS Code to Develop with the SOMns Language 2 | 3 | Currently, we provide IDE support for [VS Code](https://code.visualstudio.com/). 4 | The SOMns support can be installed via the 5 | [VS Code marketplace](https://marketplace.visualstudio.com/items?itemName=MetaConcProject.SOMns). 6 | 7 | The extension provides support for: 8 | 9 | - syntax highlighting 10 | - parse errors 11 | - code navigation 12 | - code completion 13 | - basic linting 14 | - CodeLens for running minitests 15 | - and debugging of SOMns programs 16 | 17 | This support is based on the 18 | [Language Server Protocol](https://github.com/Microsoft/language-server-protocol#readme) 19 | and could be used in other IDEs as well, but we do not currently provide 20 | extensions for them. It is however confirmed to work with NetBeans and Eclipse. 21 | 22 | #### Screenshot of SOMns Syntax Highlighting 23 | 24 | ![Screenshot of SOMns syntax highlighting](https://som-st.github.io/images/vscode-somns-syntax-highlighting.png) 25 | 26 | #### Screencast of Debugging a SOMns Program 27 | 28 | ![Screencast of SOMns debug session](https://som-st.github.io/images/vscode-somns-debugger.gif) 29 | -------------------------------------------------------------------------------- /src/tools/dym/profiles/Counter.java: -------------------------------------------------------------------------------- 1 | package tools.dym.profiles; 2 | 3 | import com.oracle.truffle.api.source.SourceSection; 4 | import com.oracle.truffle.api.utilities.JSONHelper; 5 | import com.oracle.truffle.api.utilities.JSONHelper.JSONObjectBuilder; 6 | import com.oracle.truffle.api.utilities.JSONHelper.JSONStringBuilder; 7 | 8 | import tools.dym.JsonSerializable; 9 | 10 | 11 | public class Counter implements JsonSerializable { 12 | protected final SourceSection source; 13 | 14 | private int invocationCount; 15 | 16 | public Counter(final SourceSection source) { 17 | this.source = source; 18 | } 19 | 20 | public SourceSection getSourceSection() { 21 | return source; 22 | } 23 | 24 | public void inc() { 25 | invocationCount += 1; 26 | } 27 | 28 | public int getValue() { 29 | return invocationCount; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "Cnt[" + invocationCount + "]"; 35 | } 36 | 37 | @Override 38 | public JSONStringBuilder toJson() { 39 | JSONObjectBuilder result = JSONHelper.object(); 40 | result.add("count", invocationCount); 41 | return result; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/som/UncaughtExceptions.java: -------------------------------------------------------------------------------- 1 | package som; 2 | 3 | import java.lang.Thread.UncaughtExceptionHandler; 4 | 5 | import tools.concurrency.TracingActivityThread; 6 | 7 | 8 | /** 9 | * In case an actor processing thread terminates, provide some info. 10 | */ 11 | public final class UncaughtExceptions implements UncaughtExceptionHandler { 12 | 13 | private final VM vm; 14 | 15 | public UncaughtExceptions(final VM vm) { 16 | this.vm = vm; 17 | } 18 | 19 | @Override 20 | public void uncaughtException(final Thread t, final Throwable e) { 21 | if (e instanceof ThreadDeath) { 22 | // Ignore those, we already signaled an error 23 | return; 24 | } 25 | 26 | Output.errorPrintln("Uncaught exception on " + t.getName()); 27 | 28 | TracingActivityThread thread = (TracingActivityThread) t; 29 | if (thread.getActivity() != null) { 30 | Output.errorPrintln("Processing failed for: " 31 | + thread.getActivity().toString()); 32 | } 33 | 34 | Output.errorPrintln( 35 | "Stack Trace: (printing may fail in some situation with a null pointer exception"); 36 | e.printStackTrace(); 37 | 38 | vm.requestExit(2); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/tools/superinstructions/TypeCounter.java: -------------------------------------------------------------------------------- 1 | package tools.superinstructions; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 7 | import com.oracle.truffle.api.source.SourceSection; 8 | 9 | 10 | /** 11 | * A counter which keeps track of the number of node activations 12 | * and their respective result types (that is, Java types). 13 | */ 14 | final class TypeCounter { 15 | protected final SourceSection source; 16 | private final Map, Long> activations; 17 | 18 | TypeCounter(final SourceSection source) { 19 | this.source = source; 20 | this.activations = new HashMap<>(); 21 | } 22 | 23 | public SourceSection getSourceSection() { 24 | return source; 25 | } 26 | 27 | @TruffleBoundary 28 | public void recordType(final Object result) { 29 | Class type = result.getClass(); 30 | activations.merge(type, 1L, Long::sum); 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return "TypeCnt[" + activations.size() + " types]"; 36 | } 37 | 38 | public Map, Long> getActivations() { 39 | return activations; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/som/primitives/threading/DelayPrimitives.java: -------------------------------------------------------------------------------- 1 | package som.primitives.threading; 2 | 3 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 4 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | import bd.primitives.Primitive; 8 | import som.interpreter.nodes.nary.UnaryExpressionNode; 9 | import som.interpreter.objectstorage.ObjectTransitionSafepoint; 10 | import som.vm.constants.Nil; 11 | import som.vmobjects.SObjectWithClass.SObjectWithoutFields; 12 | 13 | 14 | public final class DelayPrimitives { 15 | @GenerateNodeFactory 16 | @Primitive(primitive = "threadingWait:") 17 | public abstract static class WaitPrim extends UnaryExpressionNode { 18 | @Specialization 19 | @TruffleBoundary 20 | public final SObjectWithoutFields doLong(final long milliseconds) { 21 | try { 22 | ObjectTransitionSafepoint.INSTANCE.unregister(); 23 | Thread.sleep(milliseconds); 24 | } catch (InterruptedException e) { 25 | /* Not relevant for the moment */ 26 | } 27 | ObjectTransitionSafepoint.INSTANCE.register(); 28 | return Nil.nilObject; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/som/primitives/reflection/PerformInSuperclassPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.reflection; 2 | 3 | import com.oracle.truffle.api.Truffle; 4 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | import com.oracle.truffle.api.nodes.IndirectCallNode; 7 | 8 | import som.VM; 9 | import som.compiler.AccessModifier; 10 | import som.interpreter.nodes.dispatch.Dispatchable; 11 | import som.interpreter.nodes.nary.TernaryExpressionNode; 12 | import som.vmobjects.SAbstractObject; 13 | import som.vmobjects.SClass; 14 | import som.vmobjects.SSymbol; 15 | 16 | 17 | @GenerateNodeFactory 18 | public abstract class PerformInSuperclassPrim extends TernaryExpressionNode { 19 | @Child private IndirectCallNode call = Truffle.getRuntime().createIndirectCallNode(); 20 | 21 | @Specialization 22 | public final Object doSAbstractObject(final SAbstractObject receiver, 23 | final SSymbol selector, final SClass clazz) { 24 | VM.thisMethodNeedsToBeOptimized("PerformInSuperclassPrim"); 25 | Dispatchable invokable = clazz.lookupMessage(selector, AccessModifier.PUBLIC); 26 | return invokable.invoke(call, new Object[] {receiver}); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/tools/debugger/entities/DynamicScopeType.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.entities; 2 | 3 | import tools.TraceData; 4 | 5 | 6 | public enum DynamicScopeType { 7 | TURN(EntityType.ACT_MSG, Marker.TURN_START, Marker.TURN_END), 8 | MONITOR(EntityType.MONITOR, Marker.MONITOR_ENTER, Marker.MONITOR_EXIT), 9 | TRANSACTION(EntityType.TRANSACTION, Marker.TRANSACTION_START, Marker.TRANSACTION_END); 10 | 11 | private final EntityType type; 12 | private final byte startMarker; 13 | private final byte endMarker; 14 | 15 | DynamicScopeType(final EntityType type, final byte startMarker, final byte endMarker) { 16 | this.type = type; 17 | this.startMarker = startMarker; 18 | this.endMarker = endMarker; 19 | } 20 | 21 | public byte getId() { 22 | return type.id; 23 | } 24 | 25 | public String getName() { 26 | return type.name; 27 | } 28 | 29 | public byte getStartMarker() { 30 | return startMarker; 31 | } 32 | 33 | public byte getEndMarker() { 34 | return endMarker; 35 | } 36 | 37 | public int getStartSize() { 38 | return 9 + TraceData.SOURCE_SECTION_SIZE; 39 | } 40 | 41 | public int getEndSize() { 42 | return 1; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/tools/debugger/message/UpdateSourceSections.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.message; 2 | 3 | import bd.source.TaggedSourceCoordinate; 4 | import tools.debugger.message.Message.OutgoingMessage; 5 | 6 | 7 | /** 8 | * This message is send to update the front-end with the latest source section 9 | * information. 10 | * 11 | *

12 | * This is useful to have dynamic semantic highlighting for a dynamic language. 13 | * The highlighting can then also indicate field reads done by slot getters, 14 | * distinguish local accesses from message sends in a uniform language, etc. 15 | */ 16 | @SuppressWarnings("unused") 17 | public class UpdateSourceSections extends OutgoingMessage { 18 | private final SourceInfo[] updates; 19 | 20 | public UpdateSourceSections(final SourceInfo[] updates) { 21 | this.updates = updates; 22 | } 23 | 24 | private static final class SourceInfo { 25 | private final String sourceUri; 26 | private final TaggedSourceCoordinate[] sections; 27 | 28 | private SourceInfo(final String sourceUri, 29 | final TaggedSourceCoordinate[] sections) { 30 | this.sourceUri = sourceUri; 31 | this.sections = sections; 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/tools/snapshot/nodes/SerializerRootNode.java: -------------------------------------------------------------------------------- 1 | package tools.snapshot.nodes; 2 | 3 | import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | import com.oracle.truffle.api.nodes.RootNode; 6 | 7 | import som.interpreter.SomLanguage; 8 | 9 | 10 | public final class SerializerRootNode extends RootNode { 11 | @CompilationFinal private static SomLanguage lang; 12 | 13 | @Child protected AbstractSerializationNode serializer; 14 | 15 | public static void initializeSerialization(final SomLanguage lang) { 16 | if (lang != null && SerializerRootNode.lang == null) { 17 | SerializerRootNode.lang = lang; 18 | } 19 | } 20 | 21 | public SerializerRootNode(final AbstractSerializationNode serializer) { 22 | super(lang); 23 | assert lang != null; 24 | this.serializer = insert(serializer); 25 | } 26 | 27 | @Override 28 | public Object execute(final VirtualFrame frame) { 29 | throw new UnsupportedOperationException( 30 | "Don't use this execute method, instead directly use the serializer"); 31 | } 32 | 33 | public AbstractSerializationNode getSerializer() { 34 | return serializer; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tools/kompos/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "echoCommand": true, 4 | "options": { 5 | "cwd": "${workspaceRoot}" 6 | }, 7 | "tasks": [ 8 | { 9 | "type": "process", 10 | "group": "build", 11 | "label": "continuous compilation", 12 | "command": "npm", 13 | "isBackground": true, 14 | "args": ["run", "watch"], 15 | "problemMatcher": "$tsc-watch", 16 | "presentation": { 17 | "reveal": "silent", 18 | "panel": "shared" 19 | } 20 | }, 21 | { 22 | "type": "process", 23 | "label": "test", 24 | "group": "test", 25 | "command": "npm", 26 | "isBackground": false, 27 | "args": ["test"], 28 | "presentation": { 29 | "echo": true, 30 | "reveal": "always", 31 | "focus": true, 32 | "clear": true 33 | } 34 | }, 35 | { 36 | "type": "process", 37 | "command": "npm", 38 | "label": "format", 39 | "group": "build", 40 | "isBackground": false, 41 | "args": ["run", "format"], 42 | "presentation": { 43 | "reveal": "silent", 44 | "panel": "shared" 45 | } 46 | } 47 | ] 48 | } 49 | -------------------------------------------------------------------------------- /src/tools/debugger/nodes/BreakpointNode.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.nodes; 2 | 3 | import com.oracle.truffle.api.Assumption; 4 | import com.oracle.truffle.api.dsl.Cached; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | 7 | import tools.debugger.session.BreakpointEnabling; 8 | 9 | 10 | /** 11 | * Node to represent a breakpoint at the AST level. 12 | * It has two possible states, enable or disable. 13 | */ 14 | public abstract class BreakpointNode extends AbstractBreakpointNode { 15 | 16 | protected final BreakpointEnabling breakpoint; 17 | 18 | protected BreakpointNode(final BreakpointEnabling breakpoint) { 19 | this.breakpoint = breakpoint; 20 | } 21 | 22 | @Specialization(assumptions = "bpUnchanged", guards = "!breakpoint.guardedEnabled()") 23 | public final boolean breakpointDisabled( 24 | @Cached("breakpoint.getAssumption()") final Assumption bpUnchanged) { 25 | return breakpoint.getSteppingType().isSet(); 26 | } 27 | 28 | @Specialization(assumptions = "bpUnchanged", guards = "breakpoint.guardedEnabled()") 29 | public final boolean breakpointEnabled( 30 | @Cached("breakpoint.getAssumption()") final Assumption bpUnchanged) { 31 | return true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/tools/snapshot/deserialization/FixupInformation.java: -------------------------------------------------------------------------------- 1 | package tools.snapshot.deserialization; 2 | 3 | import java.util.Iterator; 4 | 5 | 6 | public abstract class FixupInformation { 7 | 8 | public abstract void fixUp(Object o); 9 | 10 | protected FixupInformation next; 11 | 12 | public static class FixupList implements Iterable { 13 | FixupInformation head; 14 | FixupInformation tail; 15 | 16 | public FixupList(final FixupInformation initial) { 17 | head = initial; 18 | tail = initial; 19 | } 20 | 21 | public void add(final FixupInformation fi) { 22 | tail.next = fi; 23 | tail = fi; 24 | } 25 | 26 | @Override 27 | public Iterator iterator() { 28 | return new Iterator() { 29 | FixupInformation next = head; 30 | 31 | @Override 32 | public FixupInformation next() { 33 | assert next != null; 34 | FixupInformation res = next; 35 | next = next.next; 36 | return res; 37 | } 38 | 39 | @Override 40 | public boolean hasNext() { 41 | return next != null; 42 | } 43 | }; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/ForkJoin/FibSeq.ns: -------------------------------------------------------------------------------- 1 | (* Fully sequential version, replacing all forks with compute. *) 2 | class FibSeq usingPlatform: platform andHarness: harness = ( 3 | | private Benchmark = harness Benchmark. 4 | 5 | private RESULTS = { 1. 1. 2. 3. 5. 8. 13. 21. 34. 55. 89. 144. 233. 377. 610. 6 | 987. 1597. 2584. 4181. 6765. 10946. 17711. 28657. 46368. 75025. 121393. 7 | 196418. 317811. 514229. 832040. 1346269. 2178309. 3524578. 5702887. 9227465. 8 | 14930352. 24157817. 39088169. 63245986. 102334155. 165580141. 267914296. 9 | 433494437. 701408733. 1134903170 10 | }. 11 | |)( 12 | private class Fib = Benchmark ()( 13 | public innerBenchmarkLoop: problemSize numThreads: threads = ( 14 | | r | 15 | r:: compute: problemSize. 16 | ^ verifyResult: r n: problemSize 17 | ) 18 | 19 | public verifyResult: result n: n = ( 20 | ^ result = (RESULTS at: n) 21 | ) 22 | 23 | private compute: n = ( 24 | | a b | 25 | n <= 2 ifTrue: [ ^ 1 ]. 26 | 27 | a:: compute: n - 1. 28 | b:: compute: n - 2. 29 | 30 | ^ a + b 31 | ) 32 | ) 33 | 34 | public newInstance = ( ^ Fib new ) 35 | public setupVerifiedRun: run = ( run innerIterations: 1 ) 36 | ) 37 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/specialized/AndBoolMessageNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.specialized; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | import com.oracle.truffle.api.instrumentation.Tag; 7 | 8 | import bd.tools.nodes.Operation; 9 | import som.interpreter.nodes.nary.BinaryBasicOperation; 10 | import tools.dym.Tags.OpComparison; 11 | 12 | 13 | @GenerateNodeFactory 14 | public abstract class AndBoolMessageNode extends BinaryBasicOperation 15 | implements Operation { 16 | @Override 17 | protected boolean hasTagIgnoringEagerness(final Class tag) { 18 | if (tag == OpComparison.class) { 19 | return true; 20 | } else { 21 | return super.hasTagIgnoringEagerness(tag); 22 | } 23 | } 24 | 25 | @Specialization 26 | public final boolean doAnd(final VirtualFrame frame, final boolean receiver, 27 | final boolean argument) { 28 | return receiver && argument; 29 | } 30 | 31 | @Override 32 | public String getOperation() { 33 | return "&&"; 34 | } 35 | 36 | @Override 37 | public int getNumArguments() { 38 | return 2; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/som/interpreter/actors/ErrorPromiseNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.actors; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | import bd.primitives.Primitive; 8 | import som.interpreter.actors.SPromise.Resolution; 9 | import som.interpreter.actors.SPromise.SResolver; 10 | 11 | 12 | @GenerateNodeFactory 13 | @Primitive(primitive = "actorsError:with:isBPResolver:isBPResolution:") 14 | public abstract class ErrorPromiseNode extends AbstractPromiseResolutionNode { 15 | /** 16 | * Standard error case, when the promise is errored with a value that's not a promise. 17 | */ 18 | @Specialization(guards = {"notAPromise(result)"}) 19 | public SResolver standardError(final VirtualFrame frame, final SResolver resolver, 20 | final Object result, final boolean haltOnResolver, final boolean haltOnResolution) { 21 | SPromise promise = resolver.getPromise(); 22 | 23 | if (haltOnResolver || promise.getHaltOnResolver()) { 24 | haltNode.executeEvaluated(frame, result); 25 | } 26 | 27 | resolvePromise(Resolution.ERRONEOUS, resolver, result, haltOnResolution); 28 | return resolver; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/tools/debugger/entities/EntityType.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.entities; 2 | 3 | public enum EntityType { 4 | PROCESS("process", 1), 5 | CHANNEL("channel", 2), 6 | CH_MSG("ch-msg", 3), 7 | ACTOR("actor", 4), 8 | PROMISE("promise", 5), 9 | ACT_MSG("act-msg", 6), 10 | TURN("turn", 7), 11 | TASK("task", 8), 12 | THREAD("thread", 9), 13 | LOCK("lock", 10), 14 | TRANSACTION("transaction", 11), 15 | MONITOR("monitor", 12), 16 | 17 | /** 18 | * Is used for implementation-level threads, for instance in actor or 19 | * fork/join pools. They are relevant to understand scheduling order etc, 20 | * but they are not part of the language semantics 21 | */ 22 | IMPL_THREAD("implThread", 13); 23 | 24 | public final String name; 25 | public final byte id; 26 | 27 | EntityType(final String name, final int id) { 28 | this.name = name; 29 | this.id = (byte) id; 30 | } 31 | 32 | public static byte[] getIds(final EntityType[] entities) { 33 | if (entities == null) { 34 | return null; 35 | } 36 | 37 | byte[] entityIds = new byte[entities.length]; 38 | for (int i = 0; i < entities.length; i += 1) { 39 | entityIds[i] = entities[i].id; 40 | } 41 | return entityIds; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/som/primitives/bitops/BitAndPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.bitops; 2 | 3 | import java.math.BigInteger; 4 | 5 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 6 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 7 | import com.oracle.truffle.api.dsl.Specialization; 8 | 9 | import bd.primitives.Primitive; 10 | import som.primitives.arithmetic.ArithmeticPrim; 11 | 12 | 13 | @GenerateNodeFactory 14 | @Primitive(primitive = "int:bitAnd:", selector = "&") 15 | public abstract class BitAndPrim extends ArithmeticPrim { 16 | @Specialization 17 | public final long doLong(final long left, final long right) { 18 | return left & right; 19 | } 20 | 21 | @Specialization 22 | @TruffleBoundary 23 | public final Object doBigInteger(final BigInteger left, final BigInteger right) { 24 | return left.and(right); 25 | } 26 | 27 | @Specialization 28 | @TruffleBoundary 29 | public final Object doLong(final long left, final BigInteger right) { 30 | return doBigInteger(BigInteger.valueOf(left), right); 31 | } 32 | 33 | @Specialization 34 | @TruffleBoundary 35 | public final Object doBigInteger(final BigInteger left, final long right) { 36 | return doBigInteger(left, BigInteger.valueOf(right)); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /core-lib/TestSuite/extension/src/ext/ExtensionPrims.java: -------------------------------------------------------------------------------- 1 | package ext; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | 6 | import bd.primitives.Primitive; 7 | import dep.SomeDependency; 8 | import som.interpreter.nodes.nary.UnaryExpressionNode; 9 | 10 | 11 | public abstract class ExtensionPrims { 12 | 13 | private static long cnt = 0; 14 | 15 | @GenerateNodeFactory 16 | @Primitive(primitive = "inc") 17 | public abstract static class IncPrim extends UnaryExpressionNode { 18 | @Specialization 19 | public static final Object inc(final Object o) { 20 | cnt += 1; 21 | return cnt; 22 | } 23 | } 24 | 25 | @GenerateNodeFactory 26 | @Primitive(primitive = "counter") 27 | public abstract static class CounterPrim extends UnaryExpressionNode { 28 | @Specialization 29 | public static final Object count(final Object o) { 30 | return cnt; 31 | } 32 | } 33 | 34 | @GenerateNodeFactory 35 | @Primitive(primitive = "valueFromClasspath") 36 | public abstract static class GetValuePrim extends UnaryExpressionNode { 37 | @Specialization 38 | public static final Object inc(final Object o) { 39 | return SomeDependency.getValue(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/dispatch/GenericDispatchNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.dispatch; 2 | 3 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 4 | import com.oracle.truffle.api.source.SourceSection; 5 | 6 | import som.compiler.AccessModifier; 7 | import som.compiler.MixinBuilder.MixinDefinitionId; 8 | import som.vmobjects.SClass; 9 | import som.vmobjects.SSymbol; 10 | 11 | 12 | public final class GenericDispatchNode extends AbstractGenericDispatchNode { 13 | private final AccessModifier minimalVisibility; 14 | private final MixinDefinitionId mixinId; 15 | 16 | public GenericDispatchNode(final SourceSection source, final SSymbol selector, 17 | final AccessModifier minimalAccess, final MixinDefinitionId mixinId) { 18 | super(source, selector); 19 | assert minimalAccess.ordinal() >= AccessModifier.PROTECTED.ordinal() || mixinId != null; 20 | this.minimalVisibility = minimalAccess; 21 | this.mixinId = mixinId; 22 | } 23 | 24 | @Override 25 | @TruffleBoundary 26 | protected Dispatchable doLookup(final SClass rcvrClass) { 27 | if (mixinId != null) { 28 | return rcvrClass.lookupPrivate(selector, mixinId); 29 | } else { 30 | return rcvrClass.lookupMessage(selector, minimalVisibility); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/tools/dym/profiles/BranchProfile.java: -------------------------------------------------------------------------------- 1 | package tools.dym.profiles; 2 | 3 | import com.oracle.truffle.api.source.SourceSection; 4 | import com.oracle.truffle.api.utilities.JSONHelper; 5 | import com.oracle.truffle.api.utilities.JSONHelper.JSONObjectBuilder; 6 | import com.oracle.truffle.api.utilities.JSONHelper.JSONStringBuilder; 7 | 8 | 9 | public class BranchProfile extends Counter { 10 | private long trueCount; 11 | private long falseCount; 12 | 13 | public BranchProfile(final SourceSection source) { 14 | super(source); 15 | } 16 | 17 | public void profile(final boolean branchValue) { 18 | if (branchValue) { 19 | trueCount += 1; 20 | assert trueCount > 0 : "TODO: handle overflow, by calculating a ratio"; 21 | } else { 22 | falseCount += 1; 23 | assert falseCount > 0 : "TODO: handle overflow, by calculating a ratio"; 24 | } 25 | } 26 | 27 | public long getTrueCount() { 28 | return trueCount; 29 | } 30 | 31 | public long getFalseCount() { 32 | return falseCount; 33 | } 34 | 35 | @Override 36 | public JSONStringBuilder toJson() { 37 | JSONObjectBuilder result = JSONHelper.object(); 38 | result.add("trueCount", trueCount); 39 | result.add("falseCount", falseCount); 40 | return result; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tools/kompos/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "no-unused-expression": false, 4 | "no-duplicate-variable": true, 5 | "no-trailing-whitespace": true, 6 | "no-var-keyword": true, 7 | "one-line": [true, "check-catch", "check-finally", "check-else", 8 | "check-open-brace", "check-whitespace"], 9 | "whitespace": [ 10 | "check-branch", 11 | "check-decl", 12 | "check-operator", 13 | "check-module", 14 | "check-separator", 15 | "check-type", 16 | "check-typecast"], 17 | "typedef-whitespace": [ 18 | true, { 19 | "call-signature": "nospace", 20 | "index-signature": "nospace", 21 | "parameter": "nospace", 22 | "property-declaration": "nospace", 23 | "variable-declaration": "nospace" 24 | }, { 25 | "call-signature": "space", 26 | "index-signature": "space", 27 | "parameter": "space", 28 | "property-declaration": "space", 29 | "variable-declaration": "space"}], 30 | "quotemark": [true, "double", "avoid-escape"], 31 | "curly": true, 32 | "comment-format": [true, "check-space"], 33 | "class-name": true, 34 | "semicolon": ["always"], 35 | "member-access": [ 36 | true 37 | ], 38 | "triple-equals": true 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/ForkJoin/FibOpt.ns: -------------------------------------------------------------------------------- 1 | (* Parallelized, and one of the tasks is done locally. *) 2 | class FibOpt usingPlatform: platform andHarness: harness = ( 3 | | private Benchmark = harness Benchmark. 4 | private Task = platform threading Task. 5 | 6 | private RESULTS = { 1. 1. 2. 3. 5. 8. 13. 21. 34. 55. 89. 144. 233. 377. 610. 7 | 987. 1597. 2584. 4181. 6765. 10946. 17711. 28657. 46368. 75025. 121393. 8 | 196418. 317811. 514229. 832040. 1346269. 2178309. 3524578. 5702887. 9227465. 9 | 14930352. 24157817. 39088169. 63245986. 102334155. 165580141. 267914296. 10 | 433494437. 701408733. 1134903170 11 | }. 12 | |)( 13 | private class Fib = Benchmark ()( 14 | public innerBenchmarkLoop: problemSize numThreads: threads = ( 15 | | r | 16 | r:: compute: problemSize. 17 | ^ verifyResult: r n: problemSize 18 | ) 19 | 20 | public verifyResult: result n: n = ( 21 | ^ result = (RESULTS at: n) 22 | ) 23 | 24 | private compute: n = ( 25 | | taskA b | 26 | n <= 2 ifTrue: [ ^ 1 ]. 27 | 28 | taskA:: Task spawn: [ compute: n - 1 ]. 29 | b:: compute: n - 2. 30 | 31 | ^ taskA join + b 32 | ) 33 | ) 34 | 35 | public newInstance = ( ^ Fib new ) 36 | public setupVerifiedRun: run = ( run innerIterations: 1 ) 37 | ) 38 | -------------------------------------------------------------------------------- /.settings/SOMns-tests.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /libs/java8/Unsafe.java: -------------------------------------------------------------------------------- 1 | package sun.misc; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | 6 | // Hack to compile on Java 9 with `--release 8` 7 | public final class Unsafe { 8 | public static Unsafe getUnsafe() { 9 | return null; 10 | } 11 | 12 | public native long objectFieldOffset(Field f); 13 | 14 | public native int arrayBaseOffset(Class clazz); 15 | 16 | public native int arrayIndexScale(Class clazz); 17 | 18 | public native Object getObject(Object o, long offset); 19 | 20 | public native void putObject(Object o, long offset, Object value); 21 | 22 | public native void putByte(Object o, long offset, byte value); 23 | 24 | public native void putShort(Object o, long offset, short value); 25 | 26 | public native void putInt(Object o, long offset, int value); 27 | 28 | public native long getLong(Object o, long offset); 29 | 30 | public native void putLong(Object o, long offset, long value); 31 | 32 | public native double getDouble(Object o, long offset); 33 | 34 | public native void putDouble(Object o, long offset, double value); 35 | 36 | public native void copyMemory(Object from, long offset, Object to, long offset2, long nBytes); 37 | 38 | public native boolean compareAndSwapLong(java.lang.Object arg0, long arg1, long arg2, long arg3); 39 | } 40 | -------------------------------------------------------------------------------- /src/som/primitives/AsStringPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives; 2 | 3 | import java.math.BigInteger; 4 | 5 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 6 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 7 | import com.oracle.truffle.api.dsl.Specialization; 8 | 9 | import bd.primitives.Primitive; 10 | import som.interpreter.nodes.nary.UnaryBasicOperation; 11 | import som.vmobjects.SSymbol; 12 | 13 | 14 | @GenerateNodeFactory 15 | @Primitive(primitive = "symbolAsString:") 16 | @Primitive(primitive = "intAsString:") 17 | @Primitive(primitive = "doubleAsString:") 18 | public abstract class AsStringPrim extends UnaryBasicOperation { 19 | // TODO: assign a tag 20 | 21 | @Specialization 22 | public final String doSSymbol(final SSymbol receiver) { 23 | return receiver.getString(); 24 | } 25 | 26 | @TruffleBoundary 27 | @Specialization 28 | public final String doLong(final long receiver) { 29 | return Long.toString(receiver); 30 | } 31 | 32 | @TruffleBoundary 33 | @Specialization 34 | public final String doDouble(final double receiver) { 35 | return Double.toString(receiver); 36 | } 37 | 38 | @TruffleBoundary 39 | @Specialization 40 | public final String doBigInteger(final BigInteger receiver) { 41 | return receiver.toString(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/tools/dym/nodes/InvocationProfilingNode.java: -------------------------------------------------------------------------------- 1 | package tools.dym.nodes; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.nodes.NodeCost; 5 | 6 | import tools.dym.DynamicMetrics; 7 | import tools.dym.profiles.InvocationProfile; 8 | 9 | 10 | /** 11 | * Counts invocations and reports method enter/exit to track stack level. 12 | */ 13 | public class InvocationProfilingNode extends CountingNode { 14 | 15 | // TODO: profile return value 16 | 17 | private final DynamicMetrics meter; 18 | 19 | public InvocationProfilingNode(final DynamicMetrics meter, final InvocationProfile counter) { 20 | super(counter); 21 | this.meter = meter; 22 | } 23 | 24 | @Override 25 | protected void onEnter(final VirtualFrame frame) { 26 | super.onEnter(frame); 27 | counter.profileArguments(frame.getArguments()); 28 | meter.enterMethod(); 29 | } 30 | 31 | @Override 32 | protected void onReturnValue(final VirtualFrame frame, final Object result) { 33 | meter.leaveMethod(); 34 | } 35 | 36 | @Override 37 | protected void onReturnExceptional(final VirtualFrame frame, final Throwable e) { 38 | meter.leaveMethod(); 39 | } 40 | 41 | @Override 42 | public NodeCost getCost() { 43 | return NodeCost.NONE; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2017 Stefan Marr ; 2009 Michael Haupt, michael.haupt@hpi.uni-potsdam.de, Software Architecture Group, Hasso Plattner Institute, Potsdam, Germany, http://www.hpi.uni-potsdam.de/hirschfeld/ 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/ForkJoin/FibNai.ns: -------------------------------------------------------------------------------- 1 | (* Parallelized, but no local work. *) 2 | class FibNai usingPlatform: platform andHarness: harness = ( 3 | | private Benchmark = harness Benchmark. 4 | private Task = platform threading Task. 5 | 6 | private RESULTS = { 1. 1. 2. 3. 5. 8. 13. 21. 34. 55. 89. 144. 233. 377. 610. 7 | 987. 1597. 2584. 4181. 6765. 10946. 17711. 28657. 46368. 75025. 121393. 8 | 196418. 317811. 514229. 832040. 1346269. 2178309. 3524578. 5702887. 9227465. 9 | 14930352. 24157817. 39088169. 63245986. 102334155. 165580141. 267914296. 10 | 433494437. 701408733. 1134903170 11 | }. 12 | |)( 13 | private class Fib = Benchmark ()( 14 | public innerBenchmarkLoop: problemSize numThreads: threads = ( 15 | | r | 16 | r:: compute: problemSize. 17 | ^ verifyResult: r n: problemSize 18 | ) 19 | 20 | public verifyResult: result n: n = ( 21 | ^ result = (RESULTS at: n) 22 | ) 23 | 24 | private compute: n = ( 25 | | taskA taskB | 26 | n <= 2 ifTrue: [ ^ 1 ]. 27 | 28 | taskA:: Task spawn: [ compute: n - 1 ]. 29 | taskB:: Task spawn: [ compute: n - 2 ]. 30 | 31 | ^ taskA join + taskB join 32 | ) 33 | ) 34 | 35 | public newInstance = ( ^ Fib new ) 36 | public setupVerifiedRun: run = ( run innerIterations: 1 ) 37 | ) 38 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/dispatch/TypeConditionExactProfile.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.dispatch; 2 | 3 | import com.oracle.truffle.api.CompilerDirectives; 4 | import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; 5 | 6 | 7 | public final class TypeConditionExactProfile { 8 | 9 | protected final Class expected; 10 | 11 | public TypeConditionExactProfile(final Class expected) { 12 | this.expected = expected; 13 | } 14 | 15 | @CompilationFinal protected Class cachedClass; 16 | 17 | public boolean instanceOf(final T value) { 18 | // Field needs to be cached in local variable for thread safety and startup 19 | // speed. 20 | assert value != null; 21 | 22 | Class clazz = cachedClass; 23 | if (clazz != Object.class) { 24 | if (clazz != null && clazz == value.getClass()) { 25 | return true; 26 | } else { 27 | CompilerDirectives.transferToInterpreterAndInvalidate(); 28 | if (clazz == null) { 29 | if (expected.isInstance(value)) { 30 | cachedClass = value.getClass(); 31 | return true; 32 | } else { 33 | cachedClass = Object.class; 34 | return false; 35 | } 36 | } 37 | } 38 | } 39 | return expected.isInstance(value); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /core-lib/TestSuite/BasicInterpreterTests/MethodCall.ns: -------------------------------------------------------------------------------- 1 | (* Copyright (c) 2001-2015 see AUTHORS file 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the 'Software'), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | *) 21 | class MethodCall = ()():( 22 | 23 | public test = ( 24 | ^ self test2 25 | ) 26 | 27 | public test2 = ( ^ 42 ) 28 | ) 29 | -------------------------------------------------------------------------------- /src/tools/debugger/message/StackTraceRequest.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.message; 2 | 3 | import org.java_websocket.WebSocket; 4 | 5 | import tools.TraceData; 6 | import tools.debugger.FrontendConnector; 7 | import tools.debugger.frontend.Suspension; 8 | import tools.debugger.message.Message.Request; 9 | 10 | 11 | public class StackTraceRequest extends Request { 12 | private final long activityId; 13 | 14 | /** 15 | * Index of the first frame to return. 16 | */ 17 | private final int startFrame; 18 | 19 | /** 20 | * Maximum number of frames to return, or all for 0. 21 | */ 22 | private final int levels; 23 | 24 | public StackTraceRequest(final long activityId, final int startFrame, 25 | final int levels, final int requestId) { 26 | super(requestId); 27 | assert TraceData.isWithinJSIntValueRange(activityId); 28 | this.activityId = activityId; 29 | this.startFrame = startFrame; 30 | this.levels = levels; 31 | } 32 | 33 | StackTraceRequest() { 34 | activityId = 0; 35 | startFrame = 0; 36 | levels = 0; 37 | } 38 | 39 | @Override 40 | public void process(final FrontendConnector connector, final WebSocket conn) { 41 | Suspension suspension = connector.getSuspension(activityId); 42 | suspension.sendStackTrace(startFrame, levels, requestId, connector); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/som/primitives/arrays/ToArgumentsArrayFactory.java: -------------------------------------------------------------------------------- 1 | package som.primitives.arrays; 2 | 3 | import java.util.List; 4 | 5 | import com.oracle.truffle.api.dsl.NodeFactory; 6 | import com.oracle.truffle.api.nodes.Node; 7 | 8 | 9 | /** 10 | * This class is a work around for a JDK 10 javac issue, as discussed here: 11 | * https://markmail.org/thread/v3kqlmtwfsokfaod. 12 | * 13 | * TODO: remove this class, and use normal factory directly 14 | */ 15 | public final class ToArgumentsArrayFactory implements NodeFactory { 16 | 17 | public static NodeFactory getInstance() { 18 | return ToArgumentsArrayNodeFactory.getInstance(); 19 | } 20 | 21 | @Override 22 | public ToArgumentsArrayNode createNode(final Object... arguments) { 23 | throw new UnsupportedOperationException("Should never be called"); 24 | } 25 | 26 | @Override 27 | public Class getNodeClass() { 28 | throw new UnsupportedOperationException("Should never be called"); 29 | } 30 | 31 | @Override 32 | public List>> getNodeSignatures() { 33 | throw new UnsupportedOperationException("Should never be called"); 34 | } 35 | 36 | @Override 37 | public List> getExecutionSignature() { 38 | throw new UnsupportedOperationException("Should never be called"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/ForkJoin/FibOne.ns: -------------------------------------------------------------------------------- 1 | (* Only one active task at any given time. *) 2 | class FibOne usingPlatform: platform andHarness: harness = ( 3 | | private Benchmark = harness Benchmark. 4 | private Task = platform threading Task. 5 | 6 | private RESULTS = { 1. 1. 2. 3. 5. 8. 13. 21. 34. 55. 89. 144. 233. 377. 610. 7 | 987. 1597. 2584. 4181. 6765. 10946. 17711. 28657. 46368. 75025. 121393. 8 | 196418. 317811. 514229. 832040. 1346269. 2178309. 3524578. 5702887. 9227465. 9 | 14930352. 24157817. 39088169. 63245986. 102334155. 165580141. 267914296. 10 | 433494437. 701408733. 1134903170 11 | }. 12 | |)( 13 | private class Fib = Benchmark ()( 14 | public innerBenchmarkLoop: problemSize numThreads: threads = ( 15 | | r | 16 | r:: compute: problemSize. 17 | ^ verifyResult: r n: problemSize 18 | ) 19 | 20 | public verifyResult: result n: n = ( 21 | ^ result = (RESULTS at: n) 22 | ) 23 | 24 | private compute: n = ( 25 | | taskA taskB a b | 26 | n <= 2 ifTrue: [ ^ 1 ]. 27 | 28 | taskA:: Task spawn: [ compute: n - 1 ]. 29 | a:: taskA join. 30 | 31 | taskB:: Task spawn: [ compute: n - 2 ]. 32 | b:: taskB join. 33 | 34 | ^ a + b 35 | ) 36 | ) 37 | 38 | public newInstance = ( ^ Fib new ) 39 | public setupVerifiedRun: run = ( run innerIterations: 1 ) 40 | ) 41 | -------------------------------------------------------------------------------- /src/tools/dym/CsvWriter.java: -------------------------------------------------------------------------------- 1 | package tools.dym; 2 | 3 | import java.io.File; 4 | import java.io.FileNotFoundException; 5 | import java.io.PrintWriter; 6 | 7 | 8 | public class CsvWriter implements AutoCloseable { 9 | 10 | private final PrintWriter writer; 11 | private final String[] columns; 12 | 13 | public CsvWriter(final String folder, final String fileName, final String... columns) { 14 | if (columns.length < 1) { 15 | throw new IllegalArgumentException("No column header provided"); 16 | } 17 | 18 | this.columns = columns; 19 | try { 20 | writer = new PrintWriter(folder + File.separator + fileName); 21 | } catch (FileNotFoundException e) { 22 | throw new RuntimeException(e); 23 | } 24 | write((Object[]) columns); 25 | } 26 | 27 | public void write(final Object... columns) { 28 | if (columns.length != this.columns.length) { 29 | throw new IllegalArgumentException( 30 | "Provided row has only " + columns.length + " columns, while " 31 | + this.columns.length + " are expected."); 32 | } 33 | for (int i = 0; i < columns.length; i++) { 34 | if (i != 0) { 35 | writer.print("\t"); 36 | } 37 | writer.print(columns[i]); 38 | } 39 | writer.println(); 40 | } 41 | 42 | @Override 43 | public void close() { 44 | writer.close(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /core-lib/TestSuite/BasicInterpreterTests/Exceptions.ns: -------------------------------------------------------------------------------- 1 | class Exceptions = ( 2 | | private Exception = kernel Exception. | 3 | )( 4 | public class MyException signal: msg = Exception ( 5 | | public msg = msg. | 6 | self signal. 7 | )() 8 | ) : ( 9 | 10 | public testSignalOnDo = ( 11 | | b | 12 | b:: 1. 13 | 14 | [ kernel Exception signal ] 15 | on: kernel Exception 16 | do: [:e | b:: 4 ]. 17 | 18 | ^ b 19 | ) 20 | 21 | doThrow = ( 22 | kernel Exception signal. 23 | ^ 44 24 | ) 25 | 26 | doCatch = ( 27 | [ ^ doThrow ] 28 | on: kernel Exception 29 | do: [:e | ^ 5 ] 30 | ) 31 | 32 | public testSignalOnDoMethod = ( 33 | ^ doCatch 34 | ) 35 | 36 | public testNestedSignalOnDo = ( 37 | [ [ kernel Exception signal. 38 | ^ 44 ] 39 | on: kernel IndexOutOfBounds 40 | do: [:e | ^ 33 ] ] 41 | on: kernel Exception 42 | do: [:e | ^ 22 ]. 43 | ^ 11 44 | ) 45 | 46 | public testCustomExceptionSignalOnDo = ( 47 | | exp | 48 | exp:: self new MyException. 49 | [ exp signal: 343 ] 50 | on: exp 51 | do: [:e | ^ e msg ]. 52 | ^ 66 53 | ) 54 | 55 | public testEnsure = ( 56 | [ ^ 666 ] ensure: [ ^ 444 ] 57 | ) 58 | 59 | public testEnsureWithSignal = ( 60 | [ kernel Exception signal ] ensure: [ ^ 66 ] 61 | ) 62 | ) 63 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/nary/BinaryComplexOperation.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.nary; 2 | 3 | import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; 4 | import com.oracle.truffle.api.instrumentation.Tag; 5 | 6 | import bd.primitives.nodes.WithContext; 7 | import som.VM; 8 | import tools.dym.Tags.ComplexPrimitiveOperation; 9 | 10 | 11 | /** 12 | * Nodes of this type represent arbitrarily complex operations possibly leading 13 | * to the execution of user code. 14 | * This means, these nodes map typically to more than a few native code 15 | * instructions or cause the execution of arbitrarily complex code. 16 | */ 17 | public abstract class BinaryComplexOperation extends BinaryExpressionNode { 18 | @Override 19 | protected boolean hasTagIgnoringEagerness(final Class tag) { 20 | if (tag == ComplexPrimitiveOperation.class) { 21 | return true; 22 | } else { 23 | return super.hasTagIgnoringEagerness(tag); 24 | } 25 | } 26 | 27 | public abstract static class BinarySystemOperation extends BinaryComplexOperation 28 | implements WithContext { 29 | @CompilationFinal protected VM vm; 30 | 31 | @Override 32 | public BinarySystemOperation initialize(final VM vm) { 33 | assert this.vm == null && vm != null; 34 | this.vm = vm; 35 | return this; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/snapshot/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # quit on first error 3 | set -e 4 | declare -a Savina=( 5 | "PingPong 1 0 40000" 6 | "Counting 1 0 200000" 7 | "ForkJoinThroughput 1 0 3000:60" 8 | #"ForkJoinActorCreation 1 0 20000" 9 | "ThreadRing 1 0 100:50000" 10 | "Chameneos 1 0 100:20000" 11 | "BigContention 1 0 500:120" 12 | "ConcurrentDictionary 1 0 20:600:20" 13 | "ConcurrentSortedLinkedList 1 0 10:500:10:1" 14 | "ProducerConsumerBoundedBuffer 1 0 40:5:5:10" 15 | "Philosophers 1 0 20:2000" 16 | "SleepingBarber 1 0 800:500:500:200" 17 | "CigaretteSmokers 1 0 1000:200" 18 | "LogisticsMapSeries 1 0 10000:10:346" 19 | "BankTransaction 1 0 1000:10000" 20 | "RadixSort 1 0 10000:65536:74755" 21 | "UnbalancedCobwebbedTree 1 0 10000:10:0:1" 22 | "TrapezoidalApproximation 1 0 100:100000:1:5" 23 | "AStarSearch 1 0 100:10" 24 | "NQueens 1 0 20:8:4" 25 | ) 26 | 27 | 28 | ## Determine absolute path of script 29 | pushd `dirname $0` > /dev/null 30 | SCRIPT_PATH=`pwd` 31 | popd > /dev/null 32 | 33 | SOM_DIR=$SCRIPT_PATH/../.. 34 | #-JXmx4g 35 | for args in "${Savina[@]}" 36 | do 37 | echo "$args" 38 | echo "Tracing:" 39 | $SOM_DIR/som -G -JXss4096k -at -as -sam -TF core-lib/Benchmarks/AsyncHarness.ns Savina.$args 40 | echo "" 41 | echo "========================================================" 42 | echo "" 43 | done 44 | -------------------------------------------------------------------------------- /core-lib/Benchmarks/ForkJoin.ns: -------------------------------------------------------------------------------- 1 | (* Fork/Join Benchmarks for SOMns *) 2 | class ForkJoin usingPlatform: platform andHarness: harness = ( 3 | | private Benchmark = harness Benchmark. 4 | private Task = platform threading Task. 5 | private Vector = platform kernel Vector. 6 | |)( 7 | public class Fib = Benchmark ( 8 | | private expected = createExpected. 9 | private N = 10. | 10 | )( 11 | public benchmark = ( 12 | ^ fib: N 13 | ) 14 | 15 | public fib: n = ( 16 | | a b ta tb | 17 | n <= 2 ifTrue: [ ^ 1 ]. 18 | 19 | ta:: Task spawn: [ fib: n - 1 ]. 20 | tb:: Task spawn: [ fib: n - 2 ]. 21 | 22 | a:: ta join. 23 | b:: tb join. 24 | ^ a + b 25 | ) 26 | 27 | public verifyResult: result = ( 28 | ^ (expected at: (N + 1)) = result 29 | ) 30 | 31 | private createExpected = ( 32 | ^ { 0. 1. 1. 2. 3. 5. 8. 13. 21. 34. 55. 89. 144. 233, 33 | 377. 610. 987. 1597. 2584. 4181. 6765. 10946. 17711. 34 | e. 28657. 46368. 75025. 121393. 196418. 317811. 514229, 35 | 832040. 1346269. 2178309. 3524578. 5702887. 9227465. 36 | e. 14930352. 24157817. 39088169. 63245986. 102334155, 37 | 165580141. 267914296. 433494437. 701408733. 1134903170 } 38 | ) 39 | ) : ( 40 | public newInstance = ( ^ Fib new ) 41 | public setupVerifiedRun: run = ( run innerIterations: 1 ) 42 | ) 43 | ) 44 | -------------------------------------------------------------------------------- /src/tools/dym/profiles/ClosureApplicationProfile.java: -------------------------------------------------------------------------------- 1 | package tools.dym.profiles; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.Map.Entry; 6 | 7 | import com.oracle.truffle.api.source.SourceSection; 8 | 9 | import som.interpreter.Invokable; 10 | 11 | 12 | public class ClosureApplicationProfile extends Counter { 13 | 14 | private final Map callTargetMap; 15 | 16 | public ClosureApplicationProfile(final SourceSection source) { 17 | super(source); 18 | callTargetMap = new HashMap<>(); 19 | } 20 | 21 | // TODO: remove code duplication with CallsiteProfile 22 | 23 | public ActivationCounter createCounter(final Invokable invokable) { 24 | ActivationCounter c = callTargetMap.get(invokable); 25 | if (c != null) { 26 | return c; 27 | } 28 | c = new ActivationCounter(); 29 | callTargetMap.put(invokable, c); 30 | return c; 31 | } 32 | 33 | public Map getCallTargets() { 34 | HashMap result = new HashMap<>(); 35 | for (Entry e : callTargetMap.entrySet()) { 36 | result.put(e.getKey(), e.getValue().val); 37 | } 38 | return result; 39 | } 40 | 41 | public static final class ActivationCounter { 42 | private int val; 43 | 44 | public void inc() { 45 | val += 1; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | This file lists all people with major contributions to SOMns. 2 | 3 | SOMns 4 | ===== 5 | 6 | SOMns is derived from TruffleSOM, which is derived from SOM. 7 | 8 | It is implemented and currently maintained by Stefan Marr. 9 | It includes contributions by (no particular order) 10 | 11 | - Carmen Torres Lopez, Software Languages Lab, Vrije Universiteit Brussel 12 | 13 | - Sander Lenaerts, Software Languages Lab, Vrije Universiteit Brussel 14 | 15 | - Dominik Aumayr, Institute for System Software, Johannes Kepler University Linz 16 | 17 | - Richard Roberts, Victoria University of Wellington 18 | 19 | TruffleSOM 20 | ========== 21 | 22 | TruffleSOM is based on SOM using Oracle's Truffle framework. 23 | It is implemented by Stefan Marr. 24 | 25 | SOM 26 | === 27 | 28 | SOM was originally implemented at the University of Aarhus (Denmark) in 29 | 2001/2002. The implementation of SOM was done by Jakob Roland Andersen, Kasper 30 | Verdich Lund, Lars Bak, Mads Torgersen, and Ulrik Pagh Schultz. They also 31 | wrote the original versions of the SOM Smalltalk libraries, test suites, and 32 | benchmarks, that are (in extended versions) bundled with SOM. 33 | 34 | SOM was used by Michael Haupt in courses on virtual machines at Lancaster 35 | University and Technische Universitaet Darmstadt (Germany) in VM courses in 36 | 2006. During that time, some changes were applied to SOM by Michael Haupt and 37 | Sebastian Kanthak. 38 | -------------------------------------------------------------------------------- /src/som/primitives/arithmetic/DividePrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.arithmetic; 2 | 3 | import java.math.BigInteger; 4 | 5 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 6 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 7 | import com.oracle.truffle.api.dsl.Specialization; 8 | 9 | import bd.primitives.Primitive; 10 | 11 | 12 | @GenerateNodeFactory 13 | @Primitive(primitive = "int:divideBy:", selector = "/") 14 | public abstract class DividePrim extends ArithmeticPrim { 15 | @Specialization 16 | public final long doLong(final long left, final long right) { 17 | return left / right; 18 | } 19 | 20 | @Specialization 21 | @TruffleBoundary 22 | public final Object doBigInteger(final BigInteger left, final BigInteger right) { 23 | BigInteger result = left.divide(right); 24 | return reduceToLongIfPossible(result); 25 | } 26 | 27 | @Specialization 28 | @TruffleBoundary 29 | public final Object doBigInteger(final BigInteger left, final long right) { 30 | return doBigInteger(left, BigInteger.valueOf(right)); 31 | } 32 | 33 | @Specialization 34 | @TruffleBoundary 35 | public final Object doLong(final long left, final BigInteger right) { 36 | return doBigInteger(BigInteger.valueOf(left), right); 37 | } 38 | 39 | @Specialization 40 | public final Object doLong(final long left, final double right) { 41 | return (long) (left / right); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/dispatch/LexicallyBoundDispatchNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.dispatch; 2 | 3 | import com.oracle.truffle.api.CallTarget; 4 | import com.oracle.truffle.api.Truffle; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | import com.oracle.truffle.api.nodes.DirectCallNode; 7 | import com.oracle.truffle.api.source.SourceSection; 8 | 9 | import som.instrumentation.InstrumentableDirectCallNode; 10 | import som.vm.VmSettings; 11 | 12 | 13 | /** 14 | * Private methods are special, they are linked unconditionally to the call site. 15 | * Thus, we don't need to check at the dispatch whether they apply or not. 16 | */ 17 | public final class LexicallyBoundDispatchNode extends AbstractDispatchNode { 18 | 19 | @Child private DirectCallNode cachedMethod; 20 | 21 | public LexicallyBoundDispatchNode(final SourceSection source, 22 | final CallTarget methodCallTarget) { 23 | super(source); 24 | cachedMethod = Truffle.getRuntime().createDirectCallNode(methodCallTarget); 25 | if (VmSettings.DYNAMIC_METRICS) { 26 | this.cachedMethod = insert(new InstrumentableDirectCallNode(cachedMethod, source)); 27 | } 28 | } 29 | 30 | @Override 31 | public Object executeDispatch(final VirtualFrame frame, final Object[] arguments) { 32 | return cachedMethod.call(arguments); 33 | } 34 | 35 | @Override 36 | public int lengthOfDispatchChain() { 37 | return 1; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/nary/QuaternaryExpressionNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.nary; 2 | 3 | import com.oracle.truffle.api.dsl.NodeChild; 4 | import com.oracle.truffle.api.dsl.NodeChildren; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | import som.VM; 8 | import som.interpreter.nodes.ExpressionNode; 9 | import som.vm.NotYetImplementedException; 10 | import som.vmobjects.SSymbol; 11 | 12 | 13 | @NodeChildren({ 14 | @NodeChild(value = "receiver", type = ExpressionNode.class), 15 | @NodeChild(value = "firstArg", type = ExpressionNode.class), 16 | @NodeChild(value = "secondArg", type = ExpressionNode.class), 17 | @NodeChild(value = "thirdArg", type = ExpressionNode.class)}) 18 | public abstract class QuaternaryExpressionNode extends EagerlySpecializableNode { 19 | 20 | public abstract Object executeEvaluated(VirtualFrame frame, Object receiver, 21 | Object firstArg, Object secondArg, Object thirdArg); 22 | 23 | @Override 24 | public final Object doPreEvaluated(final VirtualFrame frame, 25 | final Object[] arguments) { 26 | return executeEvaluated(frame, arguments[0], arguments[1], arguments[2], 27 | arguments[3]); 28 | } 29 | 30 | @Override 31 | public EagerPrimitiveNode wrapInEagerWrapper(final SSymbol selector, 32 | final ExpressionNode[] arguments, final VM vm) { 33 | throw new NotYetImplementedException(); // wasn't needed so far 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/tools/debugger/entities/Marker.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.entities; 2 | 3 | /** 4 | * Define Marker Constants, are used by Trace Parser. 5 | */ 6 | public class Marker { 7 | 8 | public static final byte PROCESS_CREATION = 1; 9 | public static final byte PROCESS_COMPLETION = 2; 10 | public static final byte ACTOR_CREATION = 3; 11 | public static final byte TASK_SPAWN = 4; 12 | public static final byte THREAD_SPAWN = 5; 13 | 14 | public static final byte TURN_START = 6; 15 | public static final byte TURN_END = 7; 16 | public static final byte MONITOR_ENTER = 8; 17 | public static final byte MONITOR_EXIT = 9; 18 | public static final byte TRANSACTION_START = 10; 19 | public static final byte TRANSACTION_END = 11; 20 | 21 | public static final byte CHANNEL_CREATION = 12; 22 | public static final byte PROMISE_CREATION = 13; 23 | 24 | public static final byte ACTOR_MSG_SEND = 14; 25 | public static final byte CHANNEL_MSG_SEND = 15; 26 | public static final byte PROMISE_RESOLUTION = 16; 27 | 28 | public static final byte CHANNEL_MSG_RCV = 17; 29 | public static final byte TASK_JOIN = 18; 30 | public static final byte THREAD_JOIN = 19; 31 | 32 | public static final byte IMPL_THREAD = 20; 33 | public static final byte IMPL_THREAD_CURRENT_ACTIVITY = 21; 34 | 35 | public static final byte PROMISE_MSG_SEND = 22; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /src/som/interpreter/actors/ResolvePromiseNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.actors; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | 7 | import bd.primitives.Primitive; 8 | import som.interpreter.actors.SPromise.Resolution; 9 | import som.interpreter.actors.SPromise.SResolver; 10 | 11 | 12 | @GenerateNodeFactory 13 | @Primitive(primitive = "actorsResolve:with:isBPResolver:isBPResolution:") 14 | public abstract class ResolvePromiseNode extends AbstractPromiseResolutionNode { 15 | /** 16 | * Normal case, when the promise is resolved with a value that's not a promise. 17 | * Here we need to distinguish the explicit promises to ask directly to the promise 18 | * if a promise resolution breakpoint was set. 19 | */ 20 | @Specialization(guards = {"notAPromise(result)"}) 21 | public SResolver normalResolution(final VirtualFrame frame, 22 | final SResolver resolver, final Object result, 23 | final boolean haltOnResolver, final boolean haltOnResolution) { 24 | SPromise promise = resolver.getPromise(); 25 | 26 | if (haltOnResolver || promise.getHaltOnResolver()) { 27 | haltNode.executeEvaluated(frame, result); 28 | } 29 | 30 | resolvePromise(Resolution.SUCCESSFUL, resolver, result, 31 | haltOnResolution || promise.getHaltOnResolution()); 32 | return resolver; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /tools/kompos/src/controller.ts: -------------------------------------------------------------------------------- 1 | import { 2 | SourceMessage, StoppedMessage, SymbolMessage, InitializationResponse, 3 | StackTraceResponse, ScopesResponse, ProgramInfoResponse, 4 | VariablesResponse 5 | } from "./messages"; 6 | import { VmConnection } from "./vm-connection"; 7 | import { Activity } from "./execution-data"; 8 | 9 | /** A basic controller, providing an interface, but not providing any behavior. */ 10 | export class Controller { 11 | protected readonly vmConnection: VmConnection; 12 | 13 | constructor(vmConnection: VmConnection) { 14 | this.vmConnection = vmConnection; 15 | this.vmConnection.setController(this); 16 | } 17 | 18 | public newActivities(_newActivities: Activity[]) { } 19 | 20 | public onConnect() { } 21 | public onClose() { } 22 | public onError() { } 23 | 24 | public onReceivedSource(_msg: SourceMessage) { } 25 | public onStoppedMessage(_msg: StoppedMessage) { } 26 | public onSymbolMessage(_msg: SymbolMessage) { } 27 | public onStackTrace(_msg: StackTraceResponse) { } 28 | public onScopes(_msg: ScopesResponse) { } 29 | public onProgramInfo(_msg: ProgramInfoResponse) { } 30 | public onInitializationResponse(_msg: InitializationResponse) { } 31 | public onVariables(_msg: VariablesResponse) { } 32 | public onUnknownMessage(_msg: any) { } 33 | 34 | public onTracingData(_data: DataView) { } 35 | 36 | public onToggleSectionBreakpoint(_sectionId: string, _type: string) { } 37 | } 38 | -------------------------------------------------------------------------------- /src/tools/debugger/frontend/ApplicationThreadTask.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.frontend; 2 | 3 | import tools.debugger.FrontendConnector; 4 | 5 | 6 | /** 7 | * A task that needs to be executed by the application thread while it is in a 8 | * {@link Suspension}. 9 | */ 10 | abstract class ApplicationThreadTask { 11 | /** 12 | * @return continue waiting on true, resume execution on false. 13 | */ 14 | abstract boolean execute(); 15 | 16 | static class Resume extends ApplicationThreadTask { 17 | @Override 18 | public boolean execute() { 19 | return false; 20 | } 21 | } 22 | 23 | static class SendStackTrace extends ApplicationThreadTask { 24 | private final int startFrame; 25 | private final int levels; 26 | private final int requestId; 27 | 28 | private final FrontendConnector frontend; 29 | private final Suspension suspension; 30 | 31 | SendStackTrace(final int startFrame, final int levels, 32 | final FrontendConnector frontend, final Suspension suspension, 33 | final int requestId) { 34 | this.startFrame = startFrame; 35 | this.levels = levels; 36 | this.frontend = frontend; 37 | this.suspension = suspension; 38 | this.requestId = requestId; 39 | } 40 | 41 | @Override 42 | public boolean execute() { 43 | frontend.sendStackTrace(startFrame, levels, suspension, requestId); 44 | return true; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /core-lib/TestSuite/BasicInterpreterTests/ObjectCreation.ns: -------------------------------------------------------------------------------- 1 | (* Copyright (c) 2001-2015 see AUTHORS file 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the 'Software'), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | *) 21 | class ObjectCreation = (| public foo = 3. |)( 22 | public class A = (| public foo = 42. |)() 23 | ):( 24 | public testNew = ( ^ self new ) 25 | public testImmutableRead = ( ^ self new foo ) 26 | public testImmutableReadInner = ( ^ self new A new foo ) 27 | ) 28 | -------------------------------------------------------------------------------- /src/som/compiler/ScopeBuilder.java: -------------------------------------------------------------------------------- 1 | package som.compiler; 2 | 3 | import som.compiler.Variable.Internal; 4 | import som.compiler.Variable.Local; 5 | import som.interpreter.LexicalScope; 6 | import som.vmobjects.SSymbol; 7 | 8 | 9 | /** 10 | * The super class of {@link MixinBuilder} and {@link MethodBuilder}. 11 | * It manages scope information; 12 | */ 13 | public abstract class ScopeBuilder { 14 | protected final ScopeBuilder outer; 15 | 16 | protected final LS scope; 17 | 18 | protected ScopeBuilder(final ScopeBuilder outer, final LexicalScope outerScope) { 19 | this.outer = outer; 20 | this.scope = createScope(outerScope); 21 | } 22 | 23 | public final ScopeBuilder getOuter() { 24 | return outer; 25 | } 26 | 27 | public LS getScope() { 28 | return scope; 29 | } 30 | 31 | protected abstract LS createScope(LexicalScope outer); 32 | 33 | public abstract MixinBuilder getMixin(); 34 | 35 | public abstract MethodBuilder getMethod(); 36 | 37 | protected abstract int getContextLevel(SSymbol varName); 38 | 39 | protected abstract Local getLocal(SSymbol varName); 40 | 41 | protected abstract Variable getVariable(SSymbol varName); 42 | 43 | protected abstract boolean hasArgument(SSymbol varName); 44 | 45 | public abstract Internal getFrameOnStackMarkerVar(); 46 | 47 | protected abstract boolean isImmutable(); 48 | 49 | public abstract String getName(); 50 | } 51 | -------------------------------------------------------------------------------- /src/som/primitives/arithmetic/SqrtPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.arithmetic; 2 | 3 | import java.math.BigInteger; 4 | 5 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 6 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 7 | import com.oracle.truffle.api.dsl.Specialization; 8 | import com.oracle.truffle.api.instrumentation.Tag; 9 | 10 | import bd.primitives.Primitive; 11 | import som.interpreter.nodes.nary.UnaryBasicOperation; 12 | import tools.dym.Tags.OpArithmetic; 13 | 14 | 15 | @GenerateNodeFactory 16 | @Primitive(primitive = "intSqrt:") 17 | @Primitive(primitive = "doubleSqrt:") 18 | @Primitive(selector = "sqrt", receiverType = {Long.class, BigInteger.class, Double.class}) 19 | public abstract class SqrtPrim extends UnaryBasicOperation { 20 | @Override 21 | protected boolean hasTagIgnoringEagerness(final Class tag) { 22 | if (tag == OpArithmetic.class) { 23 | return true; 24 | } else { 25 | return super.hasTagIgnoringEagerness(tag); 26 | } 27 | } 28 | 29 | @Specialization 30 | public final double doLong(final long receiver) { 31 | return Math.sqrt(receiver); 32 | } 33 | 34 | @Specialization 35 | @TruffleBoundary 36 | public final double doBigInteger(final BigInteger receiver) { 37 | return Math.sqrt(receiver.doubleValue()); 38 | } 39 | 40 | @Specialization 41 | public final double doDouble(final double receiver) { 42 | return Math.sqrt(receiver); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/tools/dym/profiles/LoopProfile.java: -------------------------------------------------------------------------------- 1 | package tools.dym.profiles; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.Map.Entry; 6 | 7 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 8 | import com.oracle.truffle.api.source.SourceSection; 9 | 10 | 11 | public class LoopProfile extends Counter { 12 | 13 | private int currentIterations; 14 | 15 | private final Map loopIterations; 16 | 17 | public LoopProfile(final SourceSection source) { 18 | super(source); 19 | loopIterations = new HashMap<>(); 20 | currentIterations = 0; 21 | } 22 | 23 | public void recordLoopIteration() { 24 | currentIterations += 1; 25 | assert currentIterations >= 0 : "TODO: handle overflow"; 26 | } 27 | 28 | @TruffleBoundary 29 | public void recordLoopExit() { 30 | loopIterations.merge(currentIterations, 1, Integer::sum); 31 | currentIterations = 0; 32 | } 33 | 34 | public Map getIterations() { 35 | return loopIterations; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "LoopProf" + mapToString(); 41 | } 42 | 43 | private String mapToString() { 44 | String result = "["; 45 | for (Entry e : loopIterations.entrySet()) { 46 | if (!"[".equals(result)) { 47 | result += "; "; 48 | } 49 | result += e.getKey() + "=" + e.getValue(); 50 | } 51 | return result + "]"; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/ISuperReadNode.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2014 Stefan Marr, stefan.marr@vub.ac.be 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy 5 | * of this software and associated documentation files (the "Software"), to deal 6 | * in the Software without restriction, including without limitation the rights 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | * copies of the Software, and to permit persons to whom the Software is 9 | * furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | * THE SOFTWARE. 21 | */ 22 | package som.interpreter.nodes; 23 | 24 | public interface ISuperReadNode extends ISpecialSend { 25 | @Override 26 | default boolean isSuperSend() { 27 | return true; 28 | }; 29 | 30 | boolean isClassSide(); 31 | } 32 | -------------------------------------------------------------------------------- /src/som/primitives/ClassPrims.java: -------------------------------------------------------------------------------- 1 | package som.primitives; 2 | 3 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 4 | import com.oracle.truffle.api.dsl.Specialization; 5 | 6 | import bd.primitives.Primitive; 7 | import som.VM; 8 | import som.interpreter.Types; 9 | import som.interpreter.nodes.nary.UnaryExpressionNode; 10 | import som.vmobjects.SAbstractObject; 11 | import som.vmobjects.SClass; 12 | 13 | 14 | public class ClassPrims { 15 | 16 | // TODO: move to new mirror class 17 | @GenerateNodeFactory 18 | @Primitive(primitive = "mirrorAClassesName:") 19 | public abstract static class NamePrim extends UnaryExpressionNode { 20 | @Specialization 21 | public final SAbstractObject doSClass(final SClass receiver) { 22 | return receiver.getName(); 23 | } 24 | } 25 | 26 | @GenerateNodeFactory 27 | @Primitive(primitive = "mirrorClassName:") 28 | public abstract static class ClassNamePrim extends UnaryExpressionNode { 29 | @Specialization 30 | public final SAbstractObject doSClass(final Object receiver) { 31 | VM.thisMethodNeedsToBeOptimized("should specialize, to avoid Types.getClassOf()"); 32 | return Types.getClassOf(receiver).getName(); 33 | } 34 | } 35 | 36 | @GenerateNodeFactory 37 | public abstract static class SuperClassPrim extends UnaryExpressionNode { 38 | @Specialization 39 | public final SAbstractObject doSClass(final SClass receiver) { 40 | return receiver.getSuperClass(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/tools/Tagging.java: -------------------------------------------------------------------------------- 1 | package tools; 2 | 3 | import java.util.HashSet; 4 | import java.util.Map; 5 | import java.util.Set; 6 | 7 | import com.oracle.truffle.api.instrumentation.Instrumenter; 8 | import com.oracle.truffle.api.instrumentation.Tag; 9 | import com.oracle.truffle.api.nodes.RootNode; 10 | import com.oracle.truffle.api.source.SourceSection; 11 | 12 | 13 | public abstract class Tagging { 14 | private Tagging() {} 15 | 16 | public static void collectSourceSectionsAndTags( 17 | final Iterable rootNodes, 18 | final Map>> sourceSectionsAndTags, 19 | final Instrumenter instrumenter) { 20 | if (rootNodes == null) { 21 | return; 22 | } 23 | for (RootNode root : rootNodes) { 24 | root.accept(node -> { 25 | @SuppressWarnings("rawtypes") 26 | Set t = instrumenter.queryTags(node); 27 | @SuppressWarnings("unchecked") 28 | Set> tags = t; 29 | 30 | if (node.getSourceSection() == null) { 31 | return true; 32 | } 33 | 34 | if (tags.size() > 0) { 35 | if (sourceSectionsAndTags.containsKey(node.getSourceSection())) { 36 | sourceSectionsAndTags.get(node.getSourceSection()).addAll(tags); 37 | } else { 38 | sourceSectionsAndTags.put(node.getSourceSection(), new HashSet<>(tags)); 39 | } 40 | } 41 | return true; 42 | }); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/dispatch/AbstractDispatchNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.dispatch; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.instrumentation.GenerateWrapper; 5 | import com.oracle.truffle.api.instrumentation.InstrumentableNode; 6 | import com.oracle.truffle.api.instrumentation.ProbeNode; 7 | import com.oracle.truffle.api.nodes.Node; 8 | import com.oracle.truffle.api.source.SourceSection; 9 | 10 | import som.vm.VmSettings; 11 | 12 | 13 | @GenerateWrapper 14 | public abstract class AbstractDispatchNode extends Node 15 | implements DispatchChain, InstrumentableNode { 16 | public static final int INLINE_CACHE_SIZE = VmSettings.DYNAMIC_METRICS ? 100 : 6; 17 | 18 | protected final SourceSection sourceSection; 19 | 20 | protected AbstractDispatchNode(final SourceSection source) { 21 | this.sourceSection = source; 22 | } 23 | 24 | /** 25 | * For wrapped nodes only. 26 | */ 27 | protected AbstractDispatchNode() { 28 | this.sourceSection = null; 29 | } 30 | 31 | @Override 32 | public SourceSection getSourceSection() { 33 | return sourceSection; 34 | } 35 | 36 | public abstract Object executeDispatch(VirtualFrame frame, Object[] arguments); 37 | 38 | @Override 39 | public boolean isInstrumentable() { 40 | return true; 41 | } 42 | 43 | @Override 44 | public WrapperNode createWrapper(final ProbeNode probe) { 45 | return new AbstractDispatchNodeWrapper(this, probe); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tools/kompos/tests/actor.ns: -------------------------------------------------------------------------------- 1 | class Actor usingPlatform: platform = Value ( 2 | | private actors = platform actors. 3 | private system = platform system. 4 | private Exception = platform kernel Exception. 5 | |)( 6 | 7 | private class MyActor = ()( 8 | public foo = ( 9 | 'Start #foo' println. 10 | 11 | 'Done with #foo' println. 12 | ^ self 13 | ) 14 | ) 15 | 16 | public msgAndPromiseCallback: completionPP = ( 17 | | a | 18 | a:: (actors createActorFromValue: MyActor) <-: new. 19 | 20 | (a <-: foo) whenResolved: [:r | 21 | 'Callback after #foo' println. 22 | 'Got as result: ' print. 23 | r println. 24 | 25 | (* End Program *) 26 | completionPP resolve: 0. 27 | ]. 28 | 29 | 'msgAndPromiseCallback returning' println. 30 | ) 31 | 32 | public multipleTurns: completionPP = ( 33 | | a | 34 | a:: (actors createActorFromValue: MyActor) <-: new. 35 | a <-: foo. 36 | a <-: foo. 37 | a <-: foo whenResolved: [:r | 38 | completionPP resolve: 0 39 | ]. 40 | ) 41 | 42 | public main: args = ( 43 | | completionPP a test | 44 | 'Actor breakpoint tests' println. 45 | 46 | completionPP:: actors createPromisePair. 47 | test:: args at: 2. 48 | ('Run test: ' + test) println. 49 | 50 | test = 'msgAndPromiseCallback' ifTrue: [ msgAndPromiseCallback: completionPP ]. 51 | test = 'multipleTurns' ifTrue: [ multipleTurns: completionPP ]. 52 | 53 | 54 | ^ completionPP promise 55 | ) 56 | ) 57 | -------------------------------------------------------------------------------- /tools/kompos/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Launch Tests", 6 | "type": "node", 7 | "request": "launch", 8 | "program": "${workspaceRoot}/node_modules/mocha/bin/_mocha", 9 | "stopOnEntry": false, 10 | "args": ["-d", "-r", "node-define", "-u", "bdd", "${workspaceRoot}/out/tests/"], 11 | "cwd": "${workspaceRoot}", 12 | "preLaunchTask": null, 13 | "runtimeExecutable": null, 14 | "runtimeArgs": [ 15 | "--nolazy" 16 | ], 17 | "env": { 18 | "NODE_ENV": "development" 19 | }, 20 | "console": "internalConsole", 21 | "sourceMaps": true, 22 | "outDir": "${workspaceRoot}/out/" 23 | }, 24 | { 25 | "name": "Attach", 26 | "type": "node", 27 | "request": "attach", 28 | "port": 37474, 29 | "address": "localhost", 30 | "restart": false, 31 | "sourceMaps": false, 32 | "outDir": null, 33 | "localRoot": "${workspaceRoot}", 34 | "remoteRoot": null 35 | }, 36 | { 37 | "name": "Attach to Process", 38 | "type": "node", 39 | "request": "attach", 40 | "processId": "${command.PickProcess}", 41 | "port": 5858, 42 | "sourceMaps": false, 43 | "outDir": null 44 | }, 45 | { 46 | "name": "Launch index.html", 47 | "type": "chrome", 48 | "request": "launch", 49 | "url": "http://localhost:8888/index.html", 50 | "webRoot": "${workspaceRoot}" 51 | } 52 | ] 53 | } -------------------------------------------------------------------------------- /core-lib/TestSuite/BasicInterpreterTests/Return.ns: -------------------------------------------------------------------------------- 1 | (* Copyright (c) 2001-2015 see AUTHORS file 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the 'Software'), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | *) 21 | class Return = ()() : ( 22 | 23 | public returnIntLiteral = ( ^ 33 ) 24 | 25 | public returnUnarySend = ( ^ returnIntLiteral ) 26 | 27 | public returnSelf = ( ^ self ) 28 | 29 | public returnSelfImplicitly = ( ) 30 | 31 | public noReturnReturnsSelf = ( 1 ) 32 | 33 | public blockReturnsImplicitlyLastValue = ( ^ ([4] value) ) 34 | ) 35 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/specialized/whileloops/WhileWithDynamicBlocksNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.specialized.whileloops; 2 | 3 | import com.oracle.truffle.api.CompilerAsserts; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | 6 | import som.vm.NotYetImplementedException; 7 | import som.vmobjects.SBlock; 8 | import som.vmobjects.SInvokable; 9 | 10 | 11 | public final class WhileWithDynamicBlocksNode extends AbstractWhileNode { 12 | private final SInvokable conditionMethod; 13 | private final SInvokable bodyMethod; 14 | 15 | public static WhileWithDynamicBlocksNode create(final SBlock rcvr, 16 | final SBlock arg, final boolean predicateBool) { 17 | return new WhileWithDynamicBlocksNode(rcvr, arg, predicateBool); 18 | } 19 | 20 | private WhileWithDynamicBlocksNode(final SBlock rcvr, final SBlock arg, 21 | final boolean predicateBool) { 22 | super(rcvr, arg, predicateBool); 23 | conditionMethod = rcvr.getMethod(); 24 | bodyMethod = arg.getMethod(); 25 | } 26 | 27 | @Override 28 | public Object executeGeneric(final VirtualFrame frame) { 29 | CompilerAsserts.neverPartOfCompilation("WhileWithDynamicBlocksNode.generic"); 30 | throw new NotYetImplementedException(); 31 | } 32 | 33 | @Override 34 | protected Object doWhileConditionally(final SBlock loopCondition, 35 | final SBlock loopBody) { 36 | assert loopCondition.getMethod() == conditionMethod; 37 | assert loopBody.getMethod() == bodyMethod; 38 | return doWhileUnconditionally(loopCondition, loopBody); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/tools/debugger/session/LineBreakpoint.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.session; 2 | 3 | import java.net.URI; 4 | import java.util.Objects; 5 | 6 | import tools.debugger.FrontendConnector; 7 | 8 | 9 | public class LineBreakpoint extends BreakpointInfo { 10 | private final URI sourceUri; 11 | private final int line; 12 | 13 | public LineBreakpoint(final boolean enabled, final URI sourceUri, final int line) { 14 | super(enabled); 15 | this.sourceUri = sourceUri; 16 | this.line = line; 17 | } 18 | 19 | /** 20 | * Note: Meant for use by serialization. 21 | */ 22 | protected LineBreakpoint() { 23 | super(); 24 | this.sourceUri = null; 25 | this.line = 0; 26 | } 27 | 28 | public int getLine() { 29 | return line; 30 | } 31 | 32 | public URI getURI() { 33 | return sourceUri; 34 | } 35 | 36 | @Override 37 | public void registerOrUpdate(final FrontendConnector frontend) { 38 | frontend.registerOrUpdate(this); 39 | } 40 | 41 | @Override 42 | public int hashCode() { 43 | return Objects.hash(sourceUri, line); 44 | } 45 | 46 | @Override 47 | public boolean equals(final Object obj) { 48 | if (obj == this) { 49 | return true; 50 | } 51 | if (obj == null || obj.getClass() != getClass()) { 52 | return false; 53 | } 54 | LineBreakpoint o = (LineBreakpoint) obj; 55 | return o.line == line && o.sourceUri.equals(sourceUri); 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return "LineBreakpoint[" + line + ", " + sourceUri.toString() + "]"; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/tools/debugger/message/VariablesRequest.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.message; 2 | 3 | import org.java_websocket.WebSocket; 4 | 5 | import com.google.gson.annotations.SerializedName; 6 | 7 | import tools.TraceData; 8 | import tools.debugger.FrontendConnector; 9 | import tools.debugger.frontend.Suspension; 10 | import tools.debugger.message.Message.Request; 11 | 12 | 13 | public final class VariablesRequest extends Request { 14 | private final long variablesReference; 15 | 16 | private final FilterType filter; 17 | private final Long start; 18 | private final Long count; 19 | 20 | public enum FilterType { 21 | @SerializedName("indexed") 22 | INDEXED, 23 | @SerializedName("named") 24 | NAMED 25 | } 26 | 27 | VariablesRequest(final int requestId, final long variablesReference, final FilterType filter, 28 | final Long start, final Long count) { 29 | super(requestId); 30 | assert TraceData.isWithinJSIntValueRange(variablesReference); 31 | this.variablesReference = variablesReference; 32 | this.filter = filter; 33 | this.start = start; 34 | this.count = count; 35 | } 36 | 37 | VariablesRequest() { 38 | variablesReference = 0; 39 | filter = null; 40 | start = null; 41 | count = null; 42 | } 43 | 44 | @Override 45 | public void process(final FrontendConnector connector, final WebSocket conn) { 46 | Suspension suspension = connector.getSuspensionForGlobalId(variablesReference); 47 | suspension.sendVariables(variablesReference, connector, requestId, filter, start, count); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/specialized/whileloops/WhilePrimitiveNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.specialized.whileloops; 2 | 3 | import com.oracle.truffle.api.frame.VirtualFrame; 4 | import com.oracle.truffle.api.instrumentation.Tag; 5 | import com.oracle.truffle.api.source.SourceSection; 6 | 7 | import som.interpreter.nodes.ExpressionNode; 8 | import som.interpreter.nodes.nary.BinaryComplexOperation; 9 | import som.vmobjects.SBlock; 10 | import som.vmobjects.SObjectWithClass; 11 | import tools.dym.Tags.LoopNode; 12 | 13 | 14 | public abstract class WhilePrimitiveNode extends BinaryComplexOperation { 15 | final boolean predicateBool; 16 | @Child protected WhileCache whileNode; 17 | 18 | protected WhilePrimitiveNode(final SourceSection source, final boolean predicateBool) { 19 | this.predicateBool = predicateBool; 20 | this.whileNode = WhileCacheNodeGen.create(predicateBool, null, null).initialize(source); 21 | } 22 | 23 | protected WhilePrimitiveNode(final WhilePrimitiveNode node) { 24 | this(node.getSourceSection(), node.predicateBool); 25 | } 26 | 27 | @Override 28 | protected boolean hasTagIgnoringEagerness(final Class tag) { 29 | if (tag == LoopNode.class) { 30 | return true; 31 | } else { 32 | return super.hasTagIgnoringEagerness(tag); 33 | } 34 | } 35 | 36 | protected abstract SObjectWithClass doWhileConditionally(VirtualFrame frame, 37 | SBlock loopCondition, SBlock loopBody); 38 | 39 | @Override 40 | public boolean isResultUsed(final ExpressionNode child) { 41 | return false; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/som/primitives/arithmetic/DoubleDivPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.arithmetic; 2 | 3 | import java.math.BigInteger; 4 | 5 | import com.oracle.truffle.api.CompilerAsserts; 6 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 7 | import com.oracle.truffle.api.dsl.Specialization; 8 | 9 | import bd.primitives.Primitive; 10 | import som.vm.NotYetImplementedException; 11 | import som.vmobjects.SAbstractObject; 12 | 13 | 14 | @GenerateNodeFactory 15 | @Primitive(primitive = "int:divideDouble:") 16 | @Primitive(primitive = "double:divideDouble:") 17 | @Primitive(selector = "//") 18 | public abstract class DoubleDivPrim extends ArithmeticPrim { 19 | @Specialization 20 | public final double doDouble(final double left, final double right) { 21 | return left / right; 22 | } 23 | 24 | @Specialization 25 | public final double doLong(final long left, final long right) { 26 | return ((double) left) / right; 27 | } 28 | 29 | @Specialization 30 | public final double doDouble(final double left, final long right) { 31 | return doDouble(left, (double) right); 32 | } 33 | 34 | @Specialization 35 | public final SAbstractObject doLong(final long left, final BigInteger right) { 36 | CompilerAsserts.neverPartOfCompilation("DoubleDiv100"); 37 | // TODO: need to implement the "/" case here 38 | // directly: return resendAsBigInteger("/", left, (SBigInteger) rightObj, frame.pack()); 39 | throw new NotYetImplementedException(); 40 | } 41 | 42 | @Specialization 43 | public final double doLong(final long left, final double right) { 44 | return left / right; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/specialized/IntDownToDoMessageNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.specialized; 2 | 3 | import com.oracle.truffle.api.dsl.Cached; 4 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 5 | import com.oracle.truffle.api.dsl.Specialization; 6 | import com.oracle.truffle.api.nodes.DirectCallNode; 7 | 8 | import bd.primitives.Primitive; 9 | import som.interpreter.nodes.specialized.IntToDoMessageNode.ToDoSplzr; 10 | import som.vmobjects.SBlock; 11 | import som.vmobjects.SInvokable; 12 | 13 | 14 | @GenerateNodeFactory 15 | @Primitive(selector = "downTo:do:", noWrapper = true, disabled = true, 16 | specializer = ToDoSplzr.class) 17 | public abstract class IntDownToDoMessageNode extends IntToDoMessageNode { 18 | @Override 19 | @Specialization(guards = "block.getMethod() == blockMethod") 20 | public final long doIntToDo(final long receiver, 21 | final long limit, final SBlock block, 22 | @Cached("block.getMethod()") final SInvokable blockMethod, 23 | @Cached("create(blockMethod)") final DirectCallNode valueSend) { 24 | return IntToByDoMessageNode.doLoop(valueSend, this, receiver, 25 | limit, -1, block); 26 | } 27 | 28 | @Override 29 | @Specialization(guards = "block.getMethod() == blockMethod") 30 | public final long doIntToDo(final long receiver, 31 | final double dLimit, final SBlock block, 32 | @Cached("block.getMethod()") final SInvokable blockMethod, 33 | @Cached("create(blockMethod)") final DirectCallNode valueSend) { 34 | return IntToByDoMessageNode.doLoop(valueSend, this, receiver, 35 | (long) dLimit, -1, block); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tools/kompos/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "search.exclude": { 4 | "**/.git": true, 5 | "**/node_modules": true, 6 | "**/out": true 7 | }, 8 | // Columns at which to show vertical rulers 9 | "editor.rulers": [ 10 | 80 11 | ], 12 | // The number of spaces a tab is equal to. 13 | "editor.tabSize": 2, 14 | "files.trimTrailingWhitespace": true 15 | // Don't enable VS code autoformat, because it uses currently outdated tsfmt 16 | // "editor.formatOnSave": true, 17 | // "typescript.format.insertSpaceAfterCommaDelimiter": true, 18 | // "typescript.format.insertSpaceAfterSemicolonInForStatements": true, 19 | // "typescript.format.insertSpaceBeforeAndAfterBinaryOperators": true, 20 | // "typescript.format.insertSpaceAfterKeywordsInControlFlowStatements": true, 21 | // "typescript.format.insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, 22 | // "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, 23 | // "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, 24 | // "typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, 25 | // "typescript.format.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, 26 | // "typescript.format.insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, 27 | // "typescript.format.insertSpaceBeforeFunctionParenthesis": false, 28 | // "typescript.format.placeOpenBraceOnNewLineForFunctions": false, 29 | // "typescript.format.placeOpenBraceOnNewLineForControlBlocks": false 30 | } 31 | -------------------------------------------------------------------------------- /core-lib/TestSuite/BasicInterpreterTests/Blocks.ns: -------------------------------------------------------------------------------- 1 | (* Copyright (c) 2001-2015 see AUTHORS file 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the 'Software'), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | *) 21 | class Blocks = ()():( 22 | 23 | public arg1 = ( ^ [:a | a - 1] value: 43 ) 24 | 25 | public arg2 = ( ^ [:a :b | a * b ] value: 11 with: 7 ) 26 | 27 | public argAndLocal = ( 28 | ^ ([:a | 29 | | blockLocal | 30 | blockLocal:: 3. 31 | a + blockLocal] value: 5) 32 | ) 33 | 34 | public argAndContext = ( | methodLocal | 35 | ^ ([:a | 36 | methodLocal:: 3. 37 | a + methodLocal] value: 5) 38 | ) 39 | ) 40 | -------------------------------------------------------------------------------- /core-lib/TestSuite/BenchmarkHarnessTests.ns: -------------------------------------------------------------------------------- 1 | class BenchmarkHarnessTests usingPlatform: platform testFramework: minitest = ( 2 | | private TestContext = minitest TestContext. 3 | private harness = (platform system loadModule: '../Benchmarks/Harness.ns' nextTo: self) usingPlatform: platform. 4 | private Random = harness Random. 5 | private JenkinsRandom = harness JenkinsRandom. 6 | | 7 | )( 8 | public class RandomTest = TestContext ()( 9 | public testSequenceOfNumbers = ( 10 | | rand | 11 | rand:: Random new. 12 | assert: 22896 equals: rand next. 13 | assert: 34761 equals: rand next. 14 | assert: 34014 equals: rand next. 15 | assert: 39231 equals: rand next. 16 | assert: 52540 equals: rand next. 17 | assert: 41445 equals: rand next. 18 | assert: 1546 equals: rand next. 19 | assert: 5947 equals: rand next. 20 | assert: 65224 equals: rand next. 21 | ) 22 | ) : ( TEST_CONTEXT = () ) 23 | 24 | public class JenkinsRandomTest = TestContext ()( 25 | public testSequenceOfNumbers = ( 26 | | rand | 27 | rand:: JenkinsRandom new: 49734321. 28 | assert: -1345591281 equals: rand next. 29 | assert: -1516981560 equals: rand next. 30 | assert: 419616523 equals: rand next. 31 | assert: -805570250 equals: rand next. 32 | assert: 1296315377 equals: rand next. 33 | assert: 1914610007 equals: rand next. 34 | assert: -1925891300 equals: rand next. 35 | assert: 1567309459 equals: rand next. 36 | assert: 30344262 equals: rand next. 37 | assert: -1594794131 equals: rand next. 38 | ) 39 | 40 | ) : ( TEST_CONTEXT = () ) 41 | ) 42 | -------------------------------------------------------------------------------- /src/som/primitives/arithmetic/GreaterThanPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.arithmetic; 2 | 3 | import java.math.BigInteger; 4 | 5 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 6 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 7 | import com.oracle.truffle.api.dsl.Specialization; 8 | 9 | import bd.primitives.Primitive; 10 | import som.primitives.ComparisonPrim; 11 | 12 | 13 | @GenerateNodeFactory 14 | @Primitive(selector = ">") 15 | public abstract class GreaterThanPrim extends ComparisonPrim { 16 | @Specialization 17 | public final boolean doLong(final long left, final long right) { 18 | return left > right; 19 | } 20 | 21 | @Specialization 22 | @TruffleBoundary 23 | public final boolean doBigInteger(final BigInteger left, final BigInteger right) { 24 | return left.compareTo(right) > 0; 25 | } 26 | 27 | @Specialization 28 | public final boolean doDouble(final double left, final double right) { 29 | return left > right; 30 | } 31 | 32 | @Specialization 33 | @TruffleBoundary 34 | public final boolean doLong(final long left, final BigInteger right) { 35 | return doBigInteger(BigInteger.valueOf(left), right); 36 | } 37 | 38 | @Specialization 39 | public final boolean doLong(final long left, final double right) { 40 | return doDouble(left, right); 41 | } 42 | 43 | @Specialization 44 | @TruffleBoundary 45 | public final boolean doBigInteger(final BigInteger left, final long right) { 46 | return doBigInteger(left, BigInteger.valueOf(right)); 47 | } 48 | 49 | @Specialization 50 | public final boolean doDouble(final double left, final long right) { 51 | return doDouble(left, (double) right); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/tools/debugger/message/StoppedMessage.java: -------------------------------------------------------------------------------- 1 | package tools.debugger.message; 2 | 3 | import tools.TraceData; 4 | import tools.debugger.entities.ActivityType; 5 | import tools.debugger.frontend.Suspension; 6 | import tools.debugger.message.Message.OutgoingMessage; 7 | 8 | 9 | @SuppressWarnings("unused") 10 | public final class StoppedMessage extends OutgoingMessage { 11 | private String reason; 12 | private long activityId; 13 | private byte activityType; 14 | private String text; 15 | private boolean allThreadsStopped; 16 | 17 | private StoppedMessage(final Reason reason, final long activityId, 18 | final ActivityType type, final String text) { 19 | assert TraceData.isWithinJSIntValueRange(activityId); 20 | this.reason = reason.value; 21 | this.activityId = activityId; 22 | this.activityType = type.getId(); 23 | this.text = text; 24 | this.allThreadsStopped = false; 25 | } 26 | 27 | private enum Reason { 28 | step("step"), 29 | breakpoint("breakpoint"), 30 | exception("exception"), 31 | pause("pause"); 32 | 33 | private final String value; 34 | 35 | Reason(final String value) { 36 | this.value = value; 37 | } 38 | } 39 | 40 | public static StoppedMessage create(final Suspension suspension) { 41 | Reason reason; 42 | if (suspension.getEvent().getBreakpoints().isEmpty()) { 43 | reason = Reason.step; 44 | } else { 45 | reason = Reason.breakpoint; 46 | } 47 | 48 | ActivityType type = suspension.getActivity().getType(); 49 | 50 | // TODO: look into additional details that can be provided as text 51 | return new StoppedMessage(reason, suspension.activityId, type, ""); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/som/primitives/arithmetic/LessThanOrEqualPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.arithmetic; 2 | 3 | import java.math.BigInteger; 4 | 5 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 6 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 7 | import com.oracle.truffle.api.dsl.Specialization; 8 | 9 | import bd.primitives.Primitive; 10 | import som.primitives.ComparisonPrim; 11 | 12 | 13 | @GenerateNodeFactory 14 | @Primitive(selector = "<=") 15 | public abstract class LessThanOrEqualPrim extends ComparisonPrim { 16 | @Specialization 17 | public final boolean doLong(final long left, final long right) { 18 | return left <= right; 19 | } 20 | 21 | @Specialization 22 | @TruffleBoundary 23 | public final boolean doBigInteger(final BigInteger left, final BigInteger right) { 24 | return left.compareTo(right) <= 0; 25 | } 26 | 27 | @Specialization 28 | public final boolean doDouble(final double left, final double right) { 29 | return left <= right; 30 | } 31 | 32 | @Specialization 33 | @TruffleBoundary 34 | public final boolean doLong(final long left, final BigInteger right) { 35 | return doBigInteger(BigInteger.valueOf(left), right); 36 | } 37 | 38 | @Specialization 39 | public final boolean doLong(final long left, final double right) { 40 | return doDouble(left, right); 41 | } 42 | 43 | @Specialization 44 | @TruffleBoundary 45 | public final boolean doBigInteger(final BigInteger left, final long right) { 46 | return doBigInteger(left, BigInteger.valueOf(right)); 47 | } 48 | 49 | @Specialization 50 | public final boolean doDouble(final double left, final long right) { 51 | return doDouble(left, (double) right); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/som/primitives/arithmetic/GreaterThanOrEqualPrim.java: -------------------------------------------------------------------------------- 1 | package som.primitives.arithmetic; 2 | 3 | import java.math.BigInteger; 4 | 5 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; 6 | import com.oracle.truffle.api.dsl.GenerateNodeFactory; 7 | import com.oracle.truffle.api.dsl.Specialization; 8 | 9 | import bd.primitives.Primitive; 10 | import som.primitives.ComparisonPrim; 11 | 12 | 13 | @GenerateNodeFactory 14 | @Primitive(selector = ">=") 15 | public abstract class GreaterThanOrEqualPrim extends ComparisonPrim { 16 | @Specialization 17 | public final boolean doLong(final long left, final long right) { 18 | return left >= right; 19 | } 20 | 21 | @Specialization 22 | @TruffleBoundary 23 | public final boolean doBigInteger(final BigInteger left, final BigInteger right) { 24 | return left.compareTo(right) >= 0; 25 | } 26 | 27 | @Specialization 28 | public final boolean doDouble(final double left, final double right) { 29 | return left >= right; 30 | } 31 | 32 | @Specialization 33 | @TruffleBoundary 34 | public final boolean doLong(final long left, final BigInteger right) { 35 | return doBigInteger(BigInteger.valueOf(left), right); 36 | } 37 | 38 | @Specialization 39 | public final boolean doLong(final long left, final double right) { 40 | return doDouble(left, right); 41 | } 42 | 43 | @Specialization 44 | @TruffleBoundary 45 | public final boolean doBigInteger(final BigInteger left, final long right) { 46 | return doBigInteger(left, BigInteger.valueOf(right)); 47 | } 48 | 49 | @Specialization 50 | public final boolean doDouble(final double left, final long right) { 51 | return doDouble(left, (double) right); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/som/interpreter/nodes/nary/BinaryExpressionNode.java: -------------------------------------------------------------------------------- 1 | package som.interpreter.nodes.nary; 2 | 3 | import com.oracle.truffle.api.dsl.NodeChild; 4 | import com.oracle.truffle.api.dsl.NodeChildren; 5 | import com.oracle.truffle.api.frame.VirtualFrame; 6 | import com.oracle.truffle.api.instrumentation.GenerateWrapper; 7 | import com.oracle.truffle.api.instrumentation.ProbeNode; 8 | 9 | import som.VM; 10 | import som.interpreter.nodes.ExpressionNode; 11 | import som.vmobjects.SSymbol; 12 | 13 | 14 | @NodeChildren({ 15 | @NodeChild(value = "receiver", type = ExpressionNode.class), 16 | @NodeChild(value = "argument", type = ExpressionNode.class)}) 17 | @GenerateWrapper 18 | public abstract class BinaryExpressionNode extends EagerlySpecializableNode { 19 | 20 | protected BinaryExpressionNode() {} 21 | 22 | protected BinaryExpressionNode(final BinaryExpressionNode wrappedNode) {} 23 | 24 | public abstract Object executeEvaluated(VirtualFrame frame, Object receiver, 25 | Object argument); 26 | 27 | @Override 28 | public WrapperNode createWrapper(final ProbeNode probe) { 29 | return new BinaryExpressionNodeWrapper(this, probe); 30 | } 31 | 32 | @Override 33 | public final Object doPreEvaluated(final VirtualFrame frame, 34 | final Object[] arguments) { 35 | return executeEvaluated(frame, arguments[0], arguments[1]); 36 | } 37 | 38 | @Override 39 | public EagerPrimitiveNode wrapInEagerWrapper(final SSymbol selector, 40 | final ExpressionNode[] arguments, final VM vm) { 41 | EagerBinaryPrimitiveNode result = 42 | new EagerBinaryPrimitiveNode(selector, arguments[0], arguments[1], this); 43 | result.initialize(sourceSection); 44 | return result; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/tools/superinstructions/TypeCountingNode.java: -------------------------------------------------------------------------------- 1 | package tools.superinstructions; 2 | 3 | import com.oracle.truffle.api.CompilerDirectives; 4 | import com.oracle.truffle.api.frame.VirtualFrame; 5 | import com.oracle.truffle.api.instrumentation.ExecutionEventNode; 6 | import com.oracle.truffle.api.nodes.UnexpectedResultException; 7 | 8 | import som.interpreter.ReturnException; 9 | import som.interpreter.SomException; 10 | import som.vm.NotYetImplementedException; 11 | 12 | 13 | /** 14 | * Execution event node to be used with {@link TypeCounter} to count node activations while 15 | * also keeping track of the result types. 16 | */ 17 | final class TypeCountingNode extends ExecutionEventNode { 18 | protected final TypeCounter counter; 19 | 20 | TypeCountingNode(final TypeCounter counter) { 21 | this.counter = counter; 22 | } 23 | 24 | @Override 25 | protected void onReturnValue(final VirtualFrame frame, final Object result) { 26 | counter.recordType(result); 27 | } 28 | 29 | @Override 30 | protected void onReturnExceptional(final VirtualFrame frame, final Throwable e) { 31 | // TODO: make language independent 32 | if (e instanceof ReturnException) { 33 | counter.recordType(((ReturnException) e).result()); 34 | } else if (e instanceof UnexpectedResultException) { 35 | counter.recordType(((UnexpectedResultException) e).getResult()); 36 | } else if (e instanceof SomException) { 37 | // TODO: why don't we consider exceptions as return types? 38 | // If the SOMns code throws an exception, we should just ignore this. 39 | return; 40 | } else { 41 | CompilerDirectives.transferToInterpreter(); 42 | throw new NotYetImplementedException(); 43 | } 44 | } 45 | } 46 | --------------------------------------------------------------------------------