Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Live Code Updates #394

Open
wants to merge 20 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,6 @@ traces
/tests/streams/*.txt
npm-debug.log*
/.metadata
.DS_Store
/SOMns.iml
/libs/black-diamonds
10 changes: 10 additions & 0 deletions build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -529,4 +529,14 @@ kernel: ${kernel}</echo>

<move file="${svm.dir}/som-native" todir="${src.dir}/../" />
</target>

<target name="intellijinit" depends="source">
<exec executable="${mx.cmd}" dir="${svm.dir}" failonerror="true">
<env key="JAVA_HOME" value="${jvmci.home}" />
<arg value="--dynamicimports"/>
<arg value="../truffle,../tools,../compiler,../sdk"/>
<arg value="intellijinit"/>
</exec>
</target>

</project>
13 changes: 13 additions & 0 deletions src/som/VM.java
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,8 @@ public void setupInstruments(final Env env) {
: "Currently, CandidateIdentifer and Snapshots are not compatible";
structuralProbe = SnapshotBackend.getProbe();
}

structuralProbe = new StructuralProbe<>();
}

public SClass loadExtensionModule(final String filename) {
Expand All @@ -419,6 +421,13 @@ public MixinDefinition loadModule(final String filename) throws IOException {
return objectSystem.loadModule(filename);
}

public MixinDefinition loadModule(final String filename,MixinDefinition oldModule) throws IOException {
if (oldModule == null) {
return objectSystem.loadModule(filename);
}
return objectSystem.reLoadModule(filename,oldModule);
}

public MixinDefinition loadModule(final Source source) throws IOException {
return objectSystem.loadModule(source);
}
Expand All @@ -443,4 +452,8 @@ public static void resetClassReferences(final boolean callFromUnitTest) {

ChannelPrimitives.resetClassReferences();
}

public StructuralProbe<SSymbol, MixinDefinition, SInvokable, SlotDefinition, Variable> getStructuralProbe(){
return structuralProbe;
}
}
29 changes: 28 additions & 1 deletion src/som/compiler/MixinBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,29 @@ public MixinBuilder(final ScopeBuilder<?> outer, final AccessModifier accessModi
this.structuralProbe = structuralProbe;
}

public MixinBuilder(final ScopeBuilder<?> outer, final AccessModifier accessModifier,
final SSymbol name, final SourceSection nameSection,
final StructuralProbe<SSymbol, MixinDefinition, SInvokable, SlotDefinition, Variable> structuralProbe,
final SomLanguage language, final MixinDefinitionId mixinId){
super(outer, outer == null ? null : outer.getScope());
this.name = name;
this.nameSection = nameSection;
this.mixinId = mixinId;

this.classSide = false;
this.language = language;

this.classScope = createScope(scope);

this.initializer = new MethodBuilder(this, structuralProbe);
this.primaryFactoryMethod =
new MethodBuilder(this, classScope, false, language, structuralProbe);
this.superclassAndMixinResolutionBuilder = createSuperclassResolutionBuilder();

this.accessModifier = accessModifier;
this.structuralProbe = structuralProbe;
}

public static class MixinDefinitionError extends SemanticDefinitionError {
private static final long serialVersionUID = 5030639383869198851L;

Expand Down Expand Up @@ -493,7 +516,7 @@ protected boolean isImmutable() {
return true;
}

private void setHolders(final MixinDefinition clsDef) {
public void setHolders(final MixinDefinition clsDef) {
assert clsDef != null;
for (Dispatchable disp : dispatchables.getValues()) {
if (disp instanceof SInvokable) {
Expand Down Expand Up @@ -675,6 +698,10 @@ public void addNestedMixin(final MixinDefinition nestedMixin)
slots.put(name, cacheSlot);
}

public void addSlotsUnsafe(EconomicMap<SSymbol, SlotDefinition> newSlots){
slots.putAll(newSlots);
}

public MixinDefinitionId getMixinId() {
return mixinId;
}
Expand Down
3 changes: 2 additions & 1 deletion src/som/compiler/MixinDefinition.java
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ protected static boolean sameClassConstruction(final Object a, final Object b) {
return sameClassConstruction(aC.getSuperClass(), bC.getSuperClass());
}

private final ArrayList<ClassFactory> cache = new ArrayList<>(2);
public final ArrayList<ClassFactory> cache = new ArrayList<>(2);

private ClassFactory getCached(final Object superclassAndMixins) {
if (superclassAndMixins == null) {
Expand Down Expand Up @@ -907,4 +907,5 @@ public SSymbol getIdentifier() {

return identifier;
}

}
46 changes: 46 additions & 0 deletions src/som/compiler/Parser.java
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,13 @@ public MixinBuilder moduleDeclaration() throws ProgramDefinitionError {
return classDeclaration(null, AccessModifier.PUBLIC);
}

public MixinBuilder moduleDeclaration(MixinBuilder.MixinDefinitionId mixinDefinitionId) throws ProgramDefinitionError {
compatibilityNewspeakVersionAndFileCategory();

comments();
return classDeclaration(null, AccessModifier.PUBLIC, mixinDefinitionId);
}

protected String className() throws ParseError {
String mixinName = text;
expect(Identifier, IdentifierTag.class);
Expand Down Expand Up @@ -380,6 +387,45 @@ private MixinBuilder classDeclaration(final MixinBuilder outerBuilder,
return mxnBuilder;
}

private MixinBuilder classDeclaration(final MixinBuilder outerBuilder,
final AccessModifier accessModifier, MixinBuilder.MixinDefinitionId mixinDefinitionId) throws ProgramDefinitionError {
expectIdentifier("class", "Found unexpected token %(found)s. " +
"Tried parsing a class declaration and expected 'class' instead.",
KeywordTag.class);

int coord = getStartIndex();
String mixinName = className();
SourceSection nameSS = getSource(coord);

MixinBuilder mxnBuilder = new MixinBuilder(outerBuilder, accessModifier,
symbolFor(mixinName), nameSS, structuralProbe, language,mixinDefinitionId);

MethodBuilder primaryFactory = mxnBuilder.getPrimaryFactoryMethodBuilder();
coord = getStartIndex();

// Newspeak-spec: this is not strictly sufficient for Newspeak
// it could also parse a binary selector here, I think
// but, doesn't seem so useful, so, let's keep it simple
if (sym == Identifier || sym == Keyword) {
messagePattern(primaryFactory);
} else {
// in the standard case, the primary factory method is #new
primaryFactory.addArgument(Symbols.SELF, getEmptySource());
primaryFactory.setSignature(Symbols.NEW);
}
mxnBuilder.setupInitializerBasedOnPrimaryFactory(getSource(coord));

comments();

expect(Equal, "Unexpected symbol %(found)s."
+ " Tried to parse the class declaration of " + mixinName
+ " and expect '=' before the (optional) inheritance declaration.",
KeywordTag.class);

inheritanceListAndOrBody(mxnBuilder);
return mxnBuilder;
}

private void inheritanceListAndOrBody(final MixinBuilder mxnBuilder)
throws ProgramDefinitionError {
if (sym == NewTerm) {
Expand Down
17 changes: 17 additions & 0 deletions src/som/compiler/SourcecodeCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,21 @@ protected final MixinDefinition compile(final Parser parser,
language.getVM().reportLoadedSource(source);
return result;
}

public MixinDefinition recompileModule(Source source, StructuralProbe<SSymbol, MixinDefinition, SInvokable, SlotDefinition, Variable> structuralProbe) throws ProgramDefinitionError {
Parser parser = new Parser(source.getCharacters().toString(), source, null, language);
int coord = parser.getStartIndex();
MixinBuilder mxnBuilder = parser.moduleDeclaration();
MixinDefinition result = mxnBuilder.assemble(parser.getSource(coord));
return result;
}

public MixinDefinition recompileModule(Source source, StructuralProbe<SSymbol, MixinDefinition, SInvokable, SlotDefinition, Variable> structuralProbe, MixinDefinition oldModule) throws ProgramDefinitionError {
Parser parser = new Parser(source.getCharacters().toString(), source, null, language);
int coord = parser.getStartIndex();
MixinBuilder mxnBuilder = parser.moduleDeclaration(oldModule.getMixinId());
//mxnBuilder.addSlotsUnsafe(oldModule.getSlots());
MixinDefinition result = mxnBuilder.assemble(parser.getSource(coord));
return result;
}
}
3 changes: 3 additions & 0 deletions src/som/interpreter/nodes/dispatch/ClassSlotAccessNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ public SClass read(final SObject rcvr) {
if (cachedValue == Nil.nilObject) {
return instantiateAndWriteUnsynced(rcvr);
} else {
if (cachedValue == null) {
return instantiateAndWriteUnsynced(rcvr);
}
assert cachedValue instanceof SClass;
return (SClass) cachedValue;
}
Expand Down
30 changes: 30 additions & 0 deletions src/som/interpreter/nodes/dispatch/DispatchGuard.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package som.interpreter.nodes.dispatch;

import com.oracle.truffle.api.Assumption;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.TruffleRuntime;
import com.oracle.truffle.api.nodes.InvalidAssumptionException;

import som.compiler.MixinDefinition.SlotDefinition;
Expand All @@ -14,6 +18,15 @@


public abstract class DispatchGuard {

@CompilerDirectives.CompilationFinal
private static Assumption noModuleReloaded = Truffle.getRuntime().createAssumption("noMoRel");

public static void invalidateAssumption() {
noModuleReloaded.invalidate();
noModuleReloaded = Truffle.getRuntime().createAssumption("noMoRel");
}

public abstract boolean entryMatches(Object obj)
throws InvalidAssumptionException;

Expand Down Expand Up @@ -58,41 +71,53 @@ public static CheckSObject createSObjectCheck(final SObject obj) {
private static final class CheckClass extends DispatchGuard {

private final Class<?> expected;
private final Assumption noLoad = noModuleReloaded;

CheckClass(final Class<?> expectedClass) {
this.expected = expectedClass;
}

@Override
public boolean entryMatches(final Object obj) throws InvalidAssumptionException {
noLoad.check();
return obj.getClass() == expected;
}
}

private static final class CheckTrue extends DispatchGuard {

private final Assumption noLoad = noModuleReloaded;

@Override
public boolean entryMatches(final Object obj) throws InvalidAssumptionException {
noLoad.check();
return obj == Boolean.TRUE;
}
}

private static final class CheckFalse extends DispatchGuard {

private final Assumption noLoad = noModuleReloaded;

@Override
public boolean entryMatches(final Object obj) throws InvalidAssumptionException {
noLoad.check();
return obj == Boolean.FALSE;
}
}

private static final class CheckObjectWithoutFields extends DispatchGuard {

private final ClassFactory expected;
private final Assumption noLoad = noModuleReloaded;

CheckObjectWithoutFields(final ClassFactory expected) {
this.expected = expected;
}

@Override
public boolean entryMatches(final Object obj) throws InvalidAssumptionException {
noLoad.check();
return obj instanceof SObjectWithoutFields &&
((SObjectWithoutFields) obj).getFactory() == expected;
}
Expand All @@ -101,20 +126,23 @@ public boolean entryMatches(final Object obj) throws InvalidAssumptionException
private static final class CheckSClass extends DispatchGuard {

private final ClassFactory expected;
private final Assumption noLoad = noModuleReloaded;

CheckSClass(final ClassFactory expected) {
this.expected = expected;
}

@Override
public boolean entryMatches(final Object obj) throws InvalidAssumptionException {
noLoad.check();
return obj instanceof SClass &&
((SClass) obj).getFactory() == expected;
}
}

public abstract static class CheckSObject extends DispatchGuard {
protected final ObjectLayout expected;
protected final Assumption noLoad = noModuleReloaded;

CheckSObject(final ObjectLayout expected) {
this.expected = expected;
Expand All @@ -136,6 +164,7 @@ private static final class CheckSMutableObject extends CheckSObject {

@Override
public boolean entryMatches(final Object obj) throws InvalidAssumptionException {
noLoad.check();
expected.checkIsLatest();
return obj instanceof SMutableObject &&
((SMutableObject) obj).getObjectLayout() == expected;
Expand All @@ -155,6 +184,7 @@ private static final class CheckSImmutableObject extends CheckSObject {

@Override
public boolean entryMatches(final Object obj) throws InvalidAssumptionException {
noLoad.check();
expected.checkIsLatest();
return obj instanceof SImmutableObject &&
((SImmutableObject) obj).getObjectLayout() == expected;
Expand Down
2 changes: 1 addition & 1 deletion src/som/interpreter/objectstorage/ClassFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public final class ClassFactory {
private final MixinDefinition mixinDef;

private final EconomicSet<SlotDefinition> instanceSlots;
private final EconomicMap<SSymbol, Dispatchable> dispatchables;
public final EconomicMap<SSymbol, Dispatchable> dispatchables;

private final boolean hasOnlyImmutableFields;

Expand Down
6 changes: 5 additions & 1 deletion src/som/interpreter/objectstorage/StorageLocation.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,20 @@ public static StorageLocation createForObject(final ObjectLayout layout,
}

protected final ObjectLayout layout;
protected final SlotDefinition slot;
protected SlotDefinition slot;

protected StorageLocation(final ObjectLayout layout, final SlotDefinition slot) {
this.layout = layout;
this.slot = slot;
}


public SlotDefinition getSlot() {
return slot;
}
public void setSlot(SlotDefinition slot) {
this.slot = slot;
}

/**
* @return true, if it is an object location, false otherwise.
Expand Down
Loading