Skip to content

Commit 4d612c6

Browse files
committed
Progress
Bug: TypeRPC rdual not setting dual. Bug: Not printing TypeFunPtr open. Bug: Making closed vs open TFPs Bug: Split file-paths into CompUnit tree & simple names
1 parent f20d27e commit 4d612c6

10 files changed

Lines changed: 110 additions & 50 deletions

File tree

chapter25/src/main/java/com/seaofnodes/simple/Parser.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ public class Parser {
2828
private Lexer _lexer;
2929

3030
// Class prefix string; TODO: use something short: "%"
31-
private static final String clzPrefix = "class:";
31+
public static final String CLZ = "class:";
32+
private static final String clzPrefix = CLZ;
3233
public static String addClzPrefix( String x ) {
3334
assert !x.startsWith(clzPrefix);
3435
return (clzPrefix+x).intern();
@@ -2055,7 +2056,7 @@ private Node func() {
20552056
}
20562057
require("->");
20572058
// Make a concrete function type, with a fidx
2058-
TypeFunPtr tfp = TypeFunPtr.make1((byte)2,false,ts.asAry(),Type.BOTTOM,_code.fidx(_ref._cname));
2059+
TypeFunPtr tfp = TypeFunPtr.make1((byte)2,true,ts.asAry(),Type.BOTTOM,_code.fidx(_ref._cname));
20592060
ReturnNode ret = parseFunctionBody(tfp,loc,ids.asAry());
20602061
return con(tfp.makeFrom(ret.expr()._type));
20612062
}

chapter25/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -706,16 +706,26 @@ private void exportElf(CompUnit cu, ElfWriter elf, boolean main) {
706706
// This is a state machine which lazily searches down the set of search
707707
// paths until the requested module is class is found.
708708

709-
// Map from external Strings to either partially read ElfFile or ExternNode
709+
// Map from external Strings to either partially read Simple ElfFile or ExternNode
710710
public final HashMap<String,Object> _externSymbols = new HashMap<>();
711711

712712
// State machine elements; the outermost element is _externPaths
713713
private int _extPathIdx; // Search index into the extern path list
714714
private final Ary<File> _files = new Ary<>(File.class); // Files in the current extern path being searched
715715
private int _extFileIdx; // Index into _files
716716

717+
public ElfReader findExternalSimple( String name ) {
718+
return findExternalSymbol(name) instanceof ElfReader elf ? elf : null;
719+
}
720+
717721
public ExternNode findExternal( String name ) {
722+
return findExternalSymbol(name) instanceof ExternNode extern ? extern : null;
723+
}
718724

725+
// Search the search-path for the name; return an ElfReader if found in a
726+
// Simple-made ELF; return an ExternNode if from another ELF, or null if
727+
// not found.
728+
private Object findExternalSymbol( String name ) {
719729
// State Machine!
720730

721731
while( true ) {
@@ -727,11 +737,7 @@ public ExternNode findExternal( String name ) {
727737
return extern;
728738

729739
case ElfReader elf:
730-
// Name maps to an unparsed ElfReader. Pull out all the
731-
// published symbols from the ELF and map them.
732-
TypeStruct clz = elf.loadSimple(this);
733-
_externSymbols.put(clz._name, new ExternNode(TypeMemPtr.make(clz),clz._name));
734-
break;
740+
return elf;
735741

736742
case null:
737743
// Name is unknown. Advance the file-system search, pulling

chapter25/src/main/java/com/seaofnodes/simple/codegen/CompUnit.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@ public class CompUnit {
8282
_src = null;
8383
}
8484

85+
// External Simple object file, or namespace parent, found on an external search path.
86+
CompUnit( File obj, CompUnit par, String fname, String cname, String name ) {
87+
_par = par;
88+
_name = name;
89+
_fname= fname;
90+
_cname= cname;
91+
_ext = null;
92+
_smp = null;
93+
_obj = obj;
94+
_src = null;
95+
}
96+
8597
// Return true if _obj is out-of-date relative to dependents.
8698
private boolean checkDependentObjs() {
8799
ElfReader elf = CODE.getElf(_obj);

chapter25/src/main/java/com/seaofnodes/simple/codegen/ParseAll.java

Lines changed: 69 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,27 @@ public abstract class ParseAll {
2020
// Return a compilation unit (cached or new). If new, it does not necessarily
2121
// need to be compiled.
2222
public static CompUnit makeCUnit( CodeGen code, CompUnit par, String name ) throws IOException {
23-
String fname = par==null ? name : par._fname + "/" + name;
23+
return makeCUnit(code,par,name,null,false);
24+
}
25+
26+
private static CompUnit makeCUnit( CodeGen code, CompUnit par, String name, File obj ) throws IOException {
27+
return makeCUnit(code,par,name,obj,obj!=null);
28+
}
29+
30+
private static CompUnit makeCUnit( CodeGen code, CompUnit par, String name, File obj, boolean external ) throws IOException {
31+
// Slashed file name? Move leading parts into parent CUs.
32+
int idx = name.indexOf("/");
33+
if( idx >= 0 ) {
34+
String head = name.substring(0,idx);
35+
CompUnit sub = makeCUnit(code,par,head,external ? externalObj(code,par,head) : null,external);
36+
return makeCUnit(code,sub,name.substring(idx+1).intern(),obj,external);
37+
}
38+
39+
String fname = par==null ? name : (par._fname + "/" + name).intern();
2440
CompUnit cunit = code._compunits.get(fname);
2541
if( cunit != null ) return cunit;
2642
String cname = par==null ? name : (par._cname + "." + name).intern();
27-
code._compunits.put(fname, cunit = new CompUnit(par,fname,cname,name));
43+
code._compunits.put(fname, cunit = external ? new CompUnit(obj,par,fname,cname,name) : new CompUnit(par,fname,cname,name));
2844
return cunit;
2945
}
3046

@@ -44,10 +60,7 @@ static void parseSource( CodeGen code, String fname, String src ) {
4460
static void parsePath(CodeGen code, String fname) {
4561
try {
4662
// Split and build the parent-path down to the source file.
47-
String[] ss = fname.split("/");
48-
CompUnit cu = null;
49-
for( String s : ss )
50-
cu = makeCUnit( code, cu, s );
63+
CompUnit cu = makeCUnit( code, null, fname );
5164
// Compile this CompUnit
5265
parseAll(code,cu);
5366
} catch( IOException ioe ) {
@@ -85,6 +98,9 @@ private static void parseAll(CodeGen code, CompUnit cunit) {
8598
TypeStruct[] tss = Type.closeOver(ary.asAry(),Parser.TYPES);
8699
for( TypeStruct ts : tss )
87100
Parser.TYPES.put(ts._name,ts);
101+
for( CompUnit cu : code._compunits.values() )
102+
if( cu._ext==null )
103+
cu._clz = (TypeStruct)Parser.TYPES.get(Parser.addClzPrefix(cu._cname));
88104

89105
// Walk over all Nodes, and upgrade the internal constants to the
90106
// closed-over types.
@@ -128,15 +144,12 @@ private static void parseOne( CodeGen code, CompUnit cunit ) {
128144
// Search the module for the fref
129145
try {
130146
CompUnit xcunit = findCUnitModule(code,cunit,fref._name);
147+
if( xcunit == null )
148+
xcunit = findCUnitExternalSimple(code,fref._name);
131149
if( xcunit != null ) {
132150
// Replace the FRef with the discovered class name.
133151
fref._name = Parser.addClzPrefix(xcunit._cname);
134152
cunit.addDep(xcunit);
135-
136-
// Module search failed, now try external paths
137-
} else if( (xcunit = findCUnitExternal( code, fref._name ) ) != null ) {
138-
// fref.addDef(xcunit.extern);
139-
throw Utils.TODO();
140153
} else {
141154
throw new RuntimeException("Undefined name '" + fref._name +"'");
142155
}
@@ -170,9 +183,10 @@ private static CompUnit findRequiredType(CodeGen code, CompUnit cunit, String ty
170183
if( xcunit != null )
171184
return xcunit;
172185
}
173-
return null;
186+
return findCUnitExternalSimple(code,typeName);
174187
}
175188

189+
// Load the public symbols for this CompUnit, and add dependent CompUnits to the NEEDS_LOAD list.
176190
private static void loadDeps(CodeGen code, CompUnit cunit) {
177191
// Load IR after parsing
178192
if( NEEDS_LOAD.find(cunit) != -1 )
@@ -182,9 +196,9 @@ private static void loadDeps(CodeGen code, CompUnit cunit) {
182196
// Load dependent classes
183197
ElfReader elf = ElfReader.load(cunit._obj,cunit);
184198
elf.loadPublicSymbols();
185-
for( String symbol : elf._deps ) {
199+
for( String fname : elf._deps ) {
186200
// Check CompUnit for being up to date
187-
CompUnit sub = makeCUnit(code,null,symbol);
201+
CompUnit sub = makeCUnit(code,null,fname,depObj(code,cunit,fname));
188202
// If not seen before or out of date, parse the new nested cunit
189203
if( sub._clz == null )
190204
WORK.add(sub);
@@ -194,6 +208,21 @@ private static void loadDeps(CodeGen code, CompUnit cunit) {
194208
}
195209
}
196210

211+
private static File depObj(CodeGen code, CompUnit cunit, String fname) {
212+
if( cunit._smp != null )
213+
return null;
214+
ElfReader elf = code.findExternalSimple(Parser.addClzPrefix(fname.replace('/','.')));
215+
if( elf == null )
216+
throw new RuntimeException("Cannot find external Simple dependency '"+fname+"'");
217+
return elf._file;
218+
}
219+
220+
private static File externalObj(CodeGen code, CompUnit par, String name) {
221+
String cname = par==null ? name : par._cname + "." + name;
222+
ElfReader elf = code.findExternalSimple(Parser.addClzPrefix(cname));
223+
return elf == null ? null : elf._file;
224+
}
225+
197226
private static void loadCompUnit(CodeGen code, CompUnit cunit) {
198227
// Expecting a previously compiled object file
199228
assert cunit._obj != null;
@@ -227,6 +256,9 @@ private static void loadCompUnit(CodeGen code, CompUnit cunit) {
227256
// Add the new top-level loaded class
228257
// assert !Parser.TYPES.containsKey(cunit._clz._name);
229258
Parser.TYPES.put(cunit._clz._name,cunit._clz);
259+
Field inst = cunit._clz.field(cunit._name);
260+
if( inst != null ) // Also the instance type, if a constructor exists
261+
Parser.TYPES.put(cunit._cname, ((TypeMem)((TypeFunPtr)inst._t)._ret)._t);
230262
Parser.resolveType(cunit._clz._name);
231263
}
232264

@@ -245,11 +277,7 @@ public static CompUnit findCompUnit(CodeGen code, CompUnit cu, String symbol) {
245277
CompUnit local = findCUnitModule(code,cu,symbol);
246278
if( local != null )
247279
return local;
248-
// Module search failed, now try external paths as a class symbol
249-
CompUnit ext = findCUnitExternal( code, Parser.addClzPrefix(symbol) );
250-
if( ext != null )
251-
return ext;
252-
return null;
280+
return findCUnitExternalSimple(code,symbol);
253281
} catch( IOException ioe ) {
254282
throw new RuntimeException(ioe);
255283
}
@@ -313,26 +341,32 @@ private static CompUnit findCUnitModule( CodeGen code, CompUnit cunit, String sy
313341

314342

315343

316-
// Search external references only. This should go deep on well known
317-
// container classes (tar, zip) and needs check for all the symbols in the
318-
// file, not just the file name (which is only checked here).
319-
private static CompUnit findCUnitExternal( CodeGen code, String symbol ) {
320-
if( symbol.contains( "." ) )
321-
throw new RuntimeException("Need to handle nested external symbols");
344+
// Search external Simple objects only. C linkage uses explicit "C"
345+
// declarations, which produce ExternNodes and are resolved by the linker.
346+
private static CompUnit findCUnitExternalSimple( CodeGen code, String symbol ) {
347+
String clzName = symbol.startsWith(Parser.CLZ) ? symbol : Parser.addClzPrefix(symbol);
348+
String cname = clzName.substring(Parser.CLZ.length());
349+
String fname = cname.replace('.','/');
322350

323-
// Already found external symbol. Expect lots of lookups on common symbols
324-
// like malloc/stdin/write
325-
CompUnit cunit = code._compunits.get(symbol);
351+
CompUnit cunit = code._compunits.get(fname);
326352
if( cunit != null )
327353
return cunit;
328354

329-
// For now only look in file names, recursively in directories.
330-
// TODO: search tar files, zip files, contents of .obj files.
331-
ExternNode ext = code.findExternal(symbol);
332-
if( ext == null )
333-
return null; // Failed to find in extern libraries
334-
// Add external symbol mapping
335-
code._compunits.put( symbol, cunit = new CompUnit(ext,symbol) );
355+
ElfReader elf = code.findExternalSimple(clzName);
356+
if( elf == null )
357+
return null;
358+
359+
try {
360+
cunit = makeCUnit(code,null,fname,elf._file);
361+
} catch( IOException ioe ) {
362+
throw new RuntimeException(ioe);
363+
}
364+
TypeStruct clz = (TypeStruct)Parser.TYPES.get(clzName);
365+
if( clz == null )
366+
Parser.TYPES.put(clzName,clz = TypeStruct.make(clzName,true));
367+
cunit._clz = clz;
368+
if( WORK.find(cunit) == -1 && NEEDS_LOAD.find(cunit) == -1 )
369+
WORK.add(cunit);
336370
return cunit;
337371
}
338372

chapter25/src/main/java/com/seaofnodes/simple/type/TypeFunPtr.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ static Type[] xdual(Type[] ts) {
182182
// Replace recursively all TypeBuilders with cyclic TypeStructs
183183
@Override Type _upgradeType(HashMap<String,Type> TYPES) {
184184
Type[] sig = new Type[_sig.length];
185-
TypeFunPtr fun = malloc(_nil,true,sig,null,_fidxs);
185+
TypeFunPtr fun = malloc(_nil,_open,sig,null,_fidxs);
186186
// Now start the recursion
187187
fun._ret = _ret._upgradeType(TYPES);
188188
for( int i=0; i<sig.length; i++ )
@@ -219,7 +219,7 @@ public int nfcns() {
219219
// Tag 7 - null,close+fidxs+nargs
220220
@Override int TAGOFF() { return 8; }
221221
@Override public void packed( BAOS baos, HashMap<String,Integer> strs ) {
222-
assert _open;
222+
assert _open; // Open: Passing extra args is fine, and extras ignored.
223223
if( _nil==2 && nargs()<6 && nfcns() == 1 ) {
224224
baos.write(TAGOFFS[_type] + nargs());
225225
baos.packed2(fidx());
@@ -293,6 +293,7 @@ SB _print(SB sb, BitSet visit, boolean html ) {
293293
if( _sig!=null )
294294
for( Type t : _sig )
295295
sb.p(t==null ? "---" : t.str()).p(" "); // Short form in signature
296+
if( !_open ) sb.p("^ ");
296297
_ret.print(sb.p(html ? "&rarr; " : "-> "),visit,html).p(" #");
297298
// Print fidxs
298299
return sb.p(printFIDX()).p("}").p(q());

chapter25/src/main/java/com/seaofnodes/simple/type/TypeRPC.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,12 @@ public TypeRPC xmeet(Type other) {
6161
return make(XInt.meet(_rpcs,rpc._rpcs));
6262
}
6363

64-
@Override Type xdual() { return malloc(XInt.dual(_rpcs)); }
64+
@Override TypeRPC xdual() { return malloc(XInt.dual(_rpcs)); }
65+
@Override Type rdual() {
66+
TypeRPC d = xdual();
67+
(_dual = d)._dual = this;
68+
return d;
69+
}
6570

6671
@Override boolean _isConstant() { return XInt.isConstant(_rpcs); }
6772
@Override boolean _isGLB(boolean mem) { return true; }

chapter25/src/main/java/com/seaofnodes/simple/type/TypeStruct.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ public final TypeStruct close() {
161161
TypeStruct ts = (TypeStruct)VISIT.get(namePlusFinal);
162162
if( ts!=null ) return ts;
163163
TypeStruct base = name==null ? (TypeStruct)TYPES.get(_name) : this;
164+
if( base == null ) base = this;
164165
ts = base.recurPre(namePlusFinal, _name, name != _name && name != null && _open );
165166
Field[] flds = ts._fields;
166167
// Now start the recursion

chapter25/src/test/java/com/seaofnodes/simple/Chapter18Test.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ public void testFcn4() {
145145
public void testFcn5() {
146146
CodeGen code = new CodeGen("val _fact = { int x -> x <= 1 ? 1 : x*_fact(x-1); }; return _fact(arg);");
147147
code.parse().opto().typeCheck();
148-
assertEquals("Stop[ return Phi(Region,1,(arg*#2)); return Phi(Region,1,(Parm_x(_fact,Top,(arg-1),(x-1))*#2)); ]", code.print());
148+
assertEquals("Stop[ return #2; return Phi(Region,1,(Parm_x(_fact,Top,arg,(x-1))*#2)); ]", code.print());
149149
assertEquals( "1", Eval2.eval(code, 0));
150150
assertEquals( "1", Eval2.eval(code, 1));
151151
assertEquals( "2", Eval2.eval(code, 2));

chapter25/src/test/java/com/seaofnodes/simple/Chapter19Test.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public void testString() {
5757
hashCode(new String{cs="Hello, World!";});
5858
""";
5959
CodeGen code = new CodeGen(src).driver(Phase.LocalSched);
60-
assertEquals("Stop[ return Phi(Region,123456789,Phi(Loop,0,(.[]+((Phi_hash<<5)-Phi_hash)))); return MEM[ 2:___ 3:___ 4:.cs=(*[]u8)Bot; 5:#!-5:[0,[],[]]]; return Phi(Region,0,1,1,0); return Phi(Region,._hashCode,Phi(Region,123456789,Phi(Loop,0,(.[]+((Phi_hash<<5)-Phi_hash))))); ]", code.print());
60+
assertEquals("Stop[ return #2; return MEM[ 2:___ 3:___ 4:.cs=(*[]u8)Bot; 5:#!-5:[0,[],[]]]; return Phi(Region,1,1,0,0); return Phi(Region,._hashCode,Phi(Region,123456789,Phi(Loop,0,(.[]+((Phi_hash<<5)-Phi_hash))))); ]", code.print());
6161
assertEquals("4029215624828139541", Eval2.eval(code, 2));
6262
}
6363

chapter25/src/test/java/com/seaofnodes/simple/Chapter23Test.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,9 @@ public void testFRefFields() {
223223
""";
224224

225225
CodeGen code = new CodeGen(src).parse().opto().typeCheck();
226-
assertEquals("Stop[ return #2; return Phi(Region,0,1); ]", code.print());
226+
assertEquals("return Phi(Region,0,1);", code.print());
227227
assertEquals("1", Eval2.eval(code, 0));
228-
testCPU(src,"x86_64_v2", "win64",22,null);
228+
testCPU(src,"x86_64_v2", "win64",19,null);
229229
};
230230

231231
@Test

0 commit comments

Comments
 (0)