-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix classloader and parser handling for libraries, add tests
- resolves a ClassNotFoundException when libraries contain multiple classes - resolves a ParserException when using libraries in the same file that imports them - adds automated tests for compiling and using libraries
- Loading branch information
1 parent
1edb277
commit 0117f50
Showing
9 changed files
with
185 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,44 @@ | ||
package aya.instruction.named; | ||
|
||
import aya.ReprStream; | ||
import aya.StaticData; | ||
import aya.eval.BlockEvaluator; | ||
import aya.exceptions.runtime.InternalAyaRuntimeException; | ||
import aya.instruction.Instruction; | ||
import aya.obj.symbol.SymbolConstants; | ||
import aya.parser.SourceStringRef; | ||
|
||
public class NamedOperatorInstruction extends Instruction { | ||
|
||
private NamedOperator op; | ||
|
||
public NamedOperatorInstruction(SourceStringRef source, NamedOperator op) { | ||
super(source); | ||
this.op = op; | ||
} | ||
|
||
@Override | ||
public void execute(BlockEvaluator blockEvaluator) { | ||
this.op.execute(blockEvaluator); | ||
|
||
} | ||
|
||
@Override | ||
public ReprStream repr(ReprStream stream) { | ||
return this.op.repr(stream); | ||
} | ||
private final String opName; | ||
private NamedOperator op = null; | ||
|
||
public NamedOperatorInstruction(SourceStringRef source, String opName) { | ||
super(source); | ||
this.opName = opName; | ||
} | ||
|
||
private void loadOp() { | ||
if (op != null) { | ||
return; | ||
} | ||
|
||
op = StaticData.getInstance().getNamedInstruction(opName); | ||
if (op == null) { | ||
throw new InternalAyaRuntimeException(SymbolConstants.NOT_AN_OP_ERROR, "Named instruction :(" + opName + ") does not exist"); | ||
} | ||
} | ||
|
||
@Override | ||
public void execute(BlockEvaluator blockEvaluator) { | ||
this.loadOp(); | ||
op.execute(blockEvaluator); | ||
} | ||
|
||
@Override | ||
public ReprStream repr(ReprStream stream) { | ||
// repr doesn't need to load the OP-instance, we already know the opName. | ||
stream.print(":(" + opName + ")"); | ||
return stream; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package example; | ||
|
||
import aya.eval.BlockEvaluator; | ||
import aya.instruction.named.NamedInstructionStore; | ||
import aya.instruction.named.NamedOperator; | ||
import aya.obj.list.Str; | ||
|
||
import java.util.Collection; | ||
import java.util.List; | ||
|
||
public class ExampleStore implements NamedInstructionStore { | ||
private static DataStorage data; | ||
|
||
@Override | ||
public Collection<NamedOperator> getNamedInstructions() { | ||
return List.of( | ||
new OpPut(), | ||
new OpGet() | ||
); | ||
} | ||
|
||
private static class OpPut extends NamedOperator { | ||
public OpPut() { | ||
super("example.put"); | ||
} | ||
|
||
@Override | ||
public void execute(BlockEvaluator blockEvaluator) { | ||
data = new DataStorage(blockEvaluator.pop().str()); | ||
} | ||
} | ||
|
||
private static class OpGet extends NamedOperator { | ||
public OpGet() { | ||
super("example.get"); | ||
} | ||
|
||
@Override | ||
public void execute(BlockEvaluator blockEvaluator) { | ||
blockEvaluator.push(aya.obj.list.List.fromStr(new Str(data.value))); | ||
} | ||
} | ||
|
||
/** | ||
* Use an extra class for this to verify that the class (/classloader) is not unloaded | ||
*/ | ||
private static class DataStorage { | ||
String value; | ||
|
||
public DataStorage(String value) { | ||
this.value = value; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
example.ExampleStore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
<project name="example-lib" default="jar" basedir="."> | ||
<!-- verify that all parameters were passed --> | ||
<fail unless="aya.classpath"/> | ||
|
||
<!-- re-define the parameters, so that they can be used with autocompletion --> | ||
<property name="aya.classpath" value="ALREADY_DEFINED"/> | ||
|
||
<property name="target.dir" location="${basedir}/target/"/> | ||
<property name="target.manifest.file" location="${target.dir}/manifest.mf"/> | ||
<property name="target.jar.file" location="${target.dir}/example.jar"/> | ||
|
||
<target name="check_modified"> | ||
<!-- if the source files were not modified after the jar file, set 'is_uptodate' --> | ||
<uptodate targetfile="${target.jar.file}" property="is_uptodate"> | ||
<srcfiles dir="${basedir}"> | ||
<include name="aya.instruction.named.NamedInstructionStore"/> | ||
<include name="build.xml"/> | ||
<include name="ExampleStore.java"/> | ||
</srcfiles> | ||
</uptodate> | ||
</target> | ||
|
||
<target name="jar" depends="check_modified" unless="is_uptodate"> | ||
<!-- reset the target directory --> | ||
<delete failonerror="false" dir="${target.dir}"/> | ||
<mkdir dir="${target.dir}"/> | ||
|
||
<!-- compile and jar the example library --> | ||
<javac destdir="${target.dir}" debug="true" target="11" source="11" | ||
srcdir="${basedir}" includeantruntime="false" includes="ExampleStore.java" classpathref="${aya.classpath}"> | ||
</javac> | ||
|
||
<manifest file="${target.manifest.file}"/> | ||
<copy file="aya.instruction.named.NamedInstructionStore" todir="${target.dir}/META-INF/services/"/> | ||
<jar jarfile="${target.jar.file}" manifest="${target.manifest.file}"> | ||
<fileset dir="${target.dir}"> | ||
<include name="**/*.class"/> | ||
<include name="META-INF/**"/> | ||
</fileset> | ||
</jar> | ||
</target> | ||
|
||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
[ | ||
|
||
.# check loaded namedOps match expected | ||
{ | ||
"$(:(sys.ad))/test/lib/example/target/example.jar" :lib_path; | ||
"load example.jar from $(lib_path)" :P | ||
lib_path :(library.load) :ops; | ||
"example.jar ops: $(ops)" :P | ||
ops [":(example.put)" ":(example.get)"] | ||
} | ||
|
||
.# verify that accessing namedOp that does not exist still causes an error | ||
{ | ||
{ :(does.not.exist) "ok" } {"failed"} .K :call_result; | ||
"calling undefined namedOp: $(call_result)" :P | ||
call_result "failed" | ||
} | ||
|
||
.# verify that basic library usage works | ||
{ | ||
"my-data" :(example.put) | ||
:(example.get) :lib_output; | ||
"obtained data from lib: $(lib_output)":P | ||
lib_output "my-data" | ||
} | ||
|
||
] :# { test.test } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,3 +74,5 @@ | |
|
||
.# Also load and auto-run many examples | ||
"test/examples" load_test | ||
|
||
"test/lib/lib" load_test |