@@ -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
0 commit comments