From a081cbf2cf3223da081d960b68c12887d130b8ec Mon Sep 17 00:00:00 2001 From: adam Date: Tue, 11 May 2004 19:15:19 -0700 Subject: [PATCH 01/16] added tex.jar target darcs-hash:20040512021519-5007d-eb51c10dfb6abab5257ef473c349b95e32e49de0.gz --- Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Makefile b/Makefile index 4d5c279..7e28241 100644 --- a/Makefile +++ b/Makefile @@ -173,6 +173,14 @@ env.sh: Makefile $(tasks)/full_toolchain build/org/ibex/nestedvm/Compiler.class runtime_classes = Runtime Registers UsermodeConstants util/Seekable +tex.jar: $(runtime_classes:%=build/org/ibex/nestedvm/%.class) upstream/build/build_tex + echo -e "Manifest-Version: 1.0\nMain-Class: org.ibex.core.Main\n" > .manifest + cp upstream/build/tex/TeX.class build + cd build && jar cfm ../$@ ../.manifest \ + $(runtime_classes:%=org/ibex/nestedvm/%.class) \ + org/ibex/nestedvm/Runtime\$$*.class \ + org/ibex/nestedvm/util/Seekable\$$*.class + runtime.jar: $(runtime_classes:%=build/org/ibex/nestedvm/%.class) cd build && jar cf ../$@ \ $(runtime_classes:%=org/ibex/nestedvm/%.class) \ -- 1.7.10.4 From 44145497d3cd0810b719577029dbdced42af72ad Mon Sep 17 00:00:00 2001 From: brian Date: Tue, 11 May 2004 21:00:57 -0700 Subject: [PATCH 02/16] size chart fix darcs-hash:20040512040057-24bed-9bb7a0b098e5dd708bdafd1fe10368cf311f1468.gz --- doc/charts/chart9.dat | 8 ++++---- doc/charts/chart9.gnuplot | 11 ++++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/doc/charts/chart9.dat b/doc/charts/chart9.dat index 7d1a1b6..cda89a8 100644 --- a/doc/charts/chart9.dat +++ b/doc/charts/chart9.dat @@ -1,4 +1,4 @@ -2.2 484 256 164 -3.8 452 252 160 -5.4 332 200 120 -7.0 216 116 76 +2.6 484 256 164 72 +4.6 452 252 160 72 +6.6 332 200 120 56 +8.6 216 116 76 32 diff --git a/doc/charts/chart9.gnuplot b/doc/charts/chart9.gnuplot index 42141ec..27b0682 100644 --- a/doc/charts/chart9.gnuplot +++ b/doc/charts/chart9.gnuplot @@ -3,10 +3,10 @@ set terminal postscript landscape color "Helvetica" 19 set output 'unfilled.eps' set yrange [0:500] -set xrange [1:7.4] +set xrange [1:9.0] set data style boxes set boxwidth 0.4 -set xtics ("DJpeg" 1.8, "Freetype" 3.4, "Boehm-GC" 5.0, "LibMSPack" 6.6) +set xtics ("DJpeg" 2.0, "Freetype" 4.0, "Boehm-GC" 6.0, "LibMSPack" 8.0) set xlabel "Application" set ylabel "Size (kilobytes)" set title "Size of MIPS Binary vs Java Bytecode" @@ -16,7 +16,8 @@ set grid #set label "159" at 2.95, 169 #set label "256" at 3.35, 266 plot \ - 'chart9.dat' using ($1-0.8):($2) title "Class", \ - 'chart9.dat' using ($1-0.4):($3) title "Native", \ - 'chart9.dat' using ($1):($4) title "Compressed Class" + 'chart9.dat' using ($1-1.2):($2) title "Class", \ + 'chart9.dat' using ($1-0.8):($3) title "MIPS Binary", \ + 'chart9.dat' using ($1-0.4):($4) title "Compressed Class", \ + 'chart9.dat' using ($1):($5) title "Compressed MIPS" -- 1.7.10.4 From abe7c48fc6762412703430702e60db9cd834b55a Mon Sep 17 00:00:00 2001 From: brian Date: Tue, 11 May 2004 21:05:10 -0700 Subject: [PATCH 03/16] verify problem in lookupSymbol darcs-hash:20040512040510-24bed-2457769686a91a782cebfb8b591705a76b3fc2ae.gz --- src/org/ibex/nestedvm/ClassFileCompiler.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/org/ibex/nestedvm/ClassFileCompiler.java b/src/org/ibex/nestedvm/ClassFileCompiler.java index 451ece7..f0b9153 100644 --- a/src/org/ibex/nestedvm/ClassFileCompiler.java +++ b/src/org/ibex/nestedvm/ClassFileCompiler.java @@ -265,8 +265,9 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const a(fac.createCheckCast(new ObjectType("java.lang.Integer"))); a(fac.createInvoke("java.lang.Integer","intValue",Type.INT,Type.NO_ARGS,INVOKEVIRTUAL)); a(InstructionConstants.IRETURN); - bh.setTarget(a(InstructionConstants.ICONST_M1)); - a(InstructionConstants.IRETURN); + bh.setTarget(a(InstructionConstants.POP)); + a(InstructionConstants.ICONST_M1); + a(InstructionConstants.IRETURN); lookupSymbol.setMaxLocals(); lookupSymbol.setMaxStack(); cl.addMethod(lookupSymbol.getMethod()); -- 1.7.10.4 From b6be9bcc91cf8e995a0e616a480813cdbef09dc2 Mon Sep 17 00:00:00 2001 From: brian Date: Tue, 11 May 2004 21:07:18 -0700 Subject: [PATCH 04/16] inputoutputstream fd fix darcs-hash:20040512040718-24bed-fca30a23831de2b6049261ced7439137fbcf8439.gz --- src/org/ibex/nestedvm/Runtime.java | 4 ++-- src/tests/CallTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/org/ibex/nestedvm/Runtime.java b/src/org/ibex/nestedvm/Runtime.java index c501d0d..50b5162 100644 --- a/src/org/ibex/nestedvm/Runtime.java +++ b/src/org/ibex/nestedvm/Runtime.java @@ -1194,8 +1194,8 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { } public void _close() { - try {is.close(); } catch(IOException e) { /*ignore*/ } - try {os.close(); } catch(IOException e) { /*ignore*/ } + if(is != null) try { is.close(); } catch(IOException e) { /*ignore*/ } + if(os != null) try { os.close(); } catch(IOException e) { /*ignore*/ } } public int read(byte[] a, int off, int length) throws ErrnoException { diff --git a/src/tests/CallTest.java b/src/tests/CallTest.java index 978eb87..95184ce 100644 --- a/src/tests/CallTest.java +++ b/src/tests/CallTest.java @@ -26,7 +26,7 @@ public class CallTest { case 1: return rt.strdup("OS: " + System.getProperty("os.name")); case 2: return rt.strdup(System.getProperty("os.version")); case 3: return rt.strdup(new Date().toString()); - case 4: return rt.addFD(new Runtime.OutputStreamFD(new CustomOS())); + case 4: return rt.addFD(new Runtime.InputOutputStreamFD(null,new CustomOS())); case 5: System.out.println("In callJava() in Java"); try { rt.call("backinmips"); } catch(Runtime.CallException e) { } -- 1.7.10.4 From 95c62ecbe81cfc11432e0755f741264d64d46776 Mon Sep 17 00:00:00 2001 From: brian Date: Tue, 11 May 2004 21:08:22 -0700 Subject: [PATCH 05/16] speedtest updates darcs-hash:20040512040822-24bed-bc2b0a049f2eeee777019ee11ca1472d0c035e14.gz --- src/tests/SpeedTest.java | 26 ++++++++++++++++++++++++++ src/tests/Test.c | 7 +++++++ 2 files changed, 33 insertions(+) diff --git a/src/tests/SpeedTest.java b/src/tests/SpeedTest.java index c3c21a3..667d9a2 100644 --- a/src/tests/SpeedTest.java +++ b/src/tests/SpeedTest.java @@ -2,6 +2,9 @@ package tests; import org.ibex.nestedvm.Runtime; +import java.io.*; +import java.util.*; + class SpeedTest { private static long start,end; private static long now() { return System.currentTimeMillis(); } @@ -9,6 +12,24 @@ class SpeedTest { private static void end() { end = now(); } private static float diff() { return ((float)(end-start))/1000; } + /*private static InputStream is = new InputStream() { + int left = 100*1024*1024; + int c = 0; + public int read() { if(left==0) return -1; left--; return (c++)&0xff; } + public int read(byte[] buf, int pos,int len) { + len = Math.min(left,len); + Arrays.fill(buf,pos,len,(byte)c++); + left -= len; + return len; + } + public void close() { left = 100*1024*1024; } + }; + + private static OutputStream os = new OutputStream() { + public void write(int c) { } + public void write(byte[] buf, int pos, int len) { } + };*/ + public static void main(String[] args) throws Exception { float d; @@ -45,11 +66,16 @@ class SpeedTest { for(int i=0;i Date: Tue, 11 May 2004 21:08:36 -0700 Subject: [PATCH 06/16] ABS.X fix darcs-hash:20040512040836-24bed-c0763a692e735c42e73240fdb7469898dddb59cf.gz --- src/org/ibex/nestedvm/ClassFileCompiler.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/org/ibex/nestedvm/ClassFileCompiler.java b/src/org/ibex/nestedvm/ClassFileCompiler.java index f0b9153..1f6ecd4 100644 --- a/src/org/ibex/nestedvm/ClassFileCompiler.java +++ b/src/org/ibex/nestedvm/ClassFileCompiler.java @@ -1262,13 +1262,7 @@ public class ClassFileCompiler extends Compiler implements org.apache.bcel.Const b1 = a(InstructionFactory.createBranchInstruction(IFGT,null)); a(d ? InstructionConstants.DCONST_0 : InstructionConstants.FCONST_0); - if(d) { - a(InstructionConstants.DUP2_X2); - a(InstructionConstants.POP2); - } else { - a(InstructionConstants.POP); - } - a(InstructionConstants.DSUB); + a(d ? InstructionConstants.DSUB : InstructionConstants.FSUB); b1.setTarget(setDouble(d)); -- 1.7.10.4 From a5ac4a3d6bf4ca158c3111c2fd03a4628f28c3b3 Mon Sep 17 00:00:00 2001 From: adam Date: Thu, 13 May 2004 17:44:23 -0700 Subject: [PATCH 07/16] added tex stuff darcs-hash:20040514004423-5007d-4d20abf5ec306d3a86025221474b82f6c17b36ad.gz --- Makefile | 9 +- upstream/Makefile | 3 +- upstream/build/tex/tangle.p | 790 +++++++++++++++++++++++++++++++++++++++++++ upstream/build/tex/tex.ch | 687 +++++++++++++++++++++++++++++++++++++ 4 files changed, 1484 insertions(+), 5 deletions(-) create mode 100644 upstream/build/tex/tangle.p create mode 100644 upstream/build/tex/tex.ch diff --git a/Makefile b/Makefile index 7e28241..2cabf44 100644 --- a/Makefile +++ b/Makefile @@ -173,13 +173,14 @@ env.sh: Makefile $(tasks)/full_toolchain build/org/ibex/nestedvm/Compiler.class runtime_classes = Runtime Registers UsermodeConstants util/Seekable -tex.jar: $(runtime_classes:%=build/org/ibex/nestedvm/%.class) upstream/build/build_tex - echo -e "Manifest-Version: 1.0\nMain-Class: org.ibex.core.Main\n" > .manifest +tex.jar: $(runtime_classes:%=build/org/ibex/nestedvm/%.class) upstream/tasks/build_tex + echo -e "Manifest-Version: 1.0\nMain-Class: TeX\n" > .manifest cp upstream/build/tex/TeX.class build cd build && jar cfm ../$@ ../.manifest \ + TeX.class \ $(runtime_classes:%=org/ibex/nestedvm/%.class) \ - org/ibex/nestedvm/Runtime\$$*.class \ - org/ibex/nestedvm/util/Seekable\$$*.class + org/ibex/nestedvm/*.class \ + org/ibex/nestedvm/util/*.class runtime.jar: $(runtime_classes:%=build/org/ibex/nestedvm/%.class) cd build && jar cf ../$@ \ diff --git a/upstream/Makefile b/upstream/Makefile index ecbc416..e91b0c2 100644 --- a/upstream/Makefile +++ b/upstream/Makefile @@ -55,7 +55,8 @@ tasks/download_tex: ; touch $@ tasks/extract_tex: mkdir -p build/tex cd build/tex; wget -N http://www.math.uni.wroc.pl/~hebisch/tex_p/tex.web - cd build/tex; wget -N http://www.math.uni.wroc.pl/~hebisch/tex_p/tex.ch +# cd build/tex; wget -N http://www.math.uni.wroc.pl/~hebisch/tex_p/tex.ch + cd build/tex; wget -N http://www.tug.org/tex-archive/systems/knuth/local/tex/initex.ch && mv initex.ch tex.ch cd build/tex; wget -N http://www.gnu-pascal.de/crystal/gpc/en/attachments/5593/tangle.p.gz && gunzip tangle.p.gz touch $@ diff --git a/upstream/build/tex/tangle.p b/upstream/build/tex/tangle.p new file mode 100644 index 0000000..dae682c --- /dev/null +++ b/upstream/build/tex/tangle.p @@ -0,0 +1,790 @@ +program TANGLE(webfile,changefile,Pascalfile,pool);label 9999;const{8:} +bufsize=100;maxbytes=45000;maxtoks=50000;maxnames=4000;maxtexts=2000; +hashsize=353;longestname=400;linelength=72;outbufsize=144;stacksize=50; +maxidlength=12;unambiglength=7;{:8}type{11:}ASCIIcode=0..255;{:11}{12:} +{:12}{37:}eightbits=0..255; +sixteenbits=0..65535;{:37}{39:}namepointer=0..maxnames;{:39}{43:} +textpointer=0..maxtexts;{:43}{78:} +outputstate=record endfield:sixteenbits;bytefield:sixteenbits; +namefield:namepointer;replfield:textpointer;modfield:0..12287;end;{:78} +var{9:}history:0..3;{:9}{13:}xord:array[char]of ASCIIcode; +xchr:array[ASCIIcode]of char;{:13}{20:}termout:text;{:20}{23:} +webfile:text;changefile:text;{:23}{25:}Pascalfile:text; +pool:text;{:25}{27:}buffer:array[0..bufsize]of ASCIIcode;{:27}{29:} +phaseone:boolean;{:29}{38:} +bytemem:packed array[0..1,0..maxbytes]of ASCIIcode; +tokmem:packed array[0..2,0..maxtoks]of eightbits; +bytestart:array[0..maxnames]of sixteenbits; +tokstart:array[0..maxtexts]of sixteenbits; +link:array[0..maxnames]of sixteenbits; +ilk:array[0..maxnames]of sixteenbits; +equiv:array[0..maxnames]of sixteenbits; +textlink:array[0..maxtexts]of sixteenbits;{:38}{40:}nameptr:namepointer; +stringptr:namepointer;byteptr:array[0..1]of 0..maxbytes; +poolchecksum:integer;{:40}{44:}textptr:textpointer; +tokptr:array[0..2]of 0..maxtoks;z:0..2; +{maxtokptr:array[0..2]of 0..maxtoks;}{:44}{50:}idfirst:0..bufsize; +idloc:0..bufsize;doublechars:0..bufsize; +hash,chophash:array[0..hashsize]of sixteenbits; +choppedid:array[0..unambiglength]of ASCIIcode;{:50}{65:} +modtext:array[0..longestname]of ASCIIcode;{:65}{70:} +lastunnamed:textpointer;{:70}{79:}curstate:outputstate; +stack:array[1..stacksize]of outputstate;stackptr:0..stacksize;{:79}{80:} +zo:0..2;{:80}{82:}bracelevel:eightbits;{:82}{86:}curval:integer;{:86} +{94:}outbuf:array[0..outbufsize]of ASCIIcode;outptr:0..outbufsize; +breakptr:0..outbufsize;semiptr:0..outbufsize;{:94}{95:} +outstate:eightbits;outval,outapp:integer;outsign:ASCIIcode; +lastsign:-1..+1;{:95}{100:}outcontrib:array[1..linelength]of ASCIIcode; +{:100}{124:}ii:integer;line:integer;otherline:integer;templine:integer; +limit:0..bufsize;loc:0..bufsize;inputhasended:boolean;changing:boolean; +{:124}{126:}changebuffer:array[0..bufsize]of ASCIIcode; +changelimit:0..bufsize;{:126}{143:}curmodule:namepointer; +scanninghex:boolean;{:143}{156:}nextcontrol:eightbits;{:156}{164:} +currepltext:textpointer;{:164}{171:}modulecount:0..12287;{:171}{179:} +{troubleshooting:boolean;ddt:integer;dd:integer;debugcycle:integer; +debugskipped:integer;termin:text;}{:179}{185:}{wo:0..1;}{:185}{30:} +{procedure debughelp;forward;}{:30}{31:}procedure error; +var j:0..outbufsize;k,l:0..bufsize;begin if phaseone then{32:} +begin if changing then write(termout,'. (change file ')else write( +termout,'. (');writeln(termout,'l.',line:1,')'); +if loc>=limit then l:=limit else l:=loc; +for k:=1 to l do if buffer[k-1]=9 then write(termout,' ')else write( +termout,xchr[buffer[k-1]]);writeln(termout); +for k:=1 to l do write(termout,' '); +for k:=l+1 to limit do write(termout,xchr[buffer[k-1]]); +write(termout,' ');end{:32}else{33:} +begin writeln(termout,'. (l.',line:1,')'); +for j:=1 to outptr do write(termout,xchr[outbuf[j-1]]); +write(termout,'... ');end{:33};{break(termout);}history:=2; +{debugskipped:=debugcycle;debughelp;}end;{:31}{34:}procedure jumpout; +begin goto 9999;end;{:34}procedure initialize;var{16:}i:0..255;{:16} +{41:}wi:0..1;{:41}{45:}zi:0..2;{:45}{51:}h:0..hashsize;{:51}begin{10:} +history:=0;{:10}{14:}xchr[32]:=' ';xchr[33]:='!';xchr[34]:='"'; +xchr[35]:='#';xchr[36]:='$';xchr[37]:='%';xchr[38]:='&';xchr[39]:=''''; +xchr[40]:='(';xchr[41]:=')';xchr[42]:='*';xchr[43]:='+';xchr[44]:=','; +xchr[45]:='-';xchr[46]:='.';xchr[47]:='/';xchr[48]:='0';xchr[49]:='1'; +xchr[50]:='2';xchr[51]:='3';xchr[52]:='4';xchr[53]:='5';xchr[54]:='6'; +xchr[55]:='7';xchr[56]:='8';xchr[57]:='9';xchr[58]:=':';xchr[59]:=';'; +xchr[60]:='<';xchr[61]:='=';xchr[62]:='>';xchr[63]:='?';xchr[64]:='@'; +xchr[65]:='A';xchr[66]:='B';xchr[67]:='C';xchr[68]:='D';xchr[69]:='E'; +xchr[70]:='F';xchr[71]:='G';xchr[72]:='H';xchr[73]:='I';xchr[74]:='J'; +xchr[75]:='K';xchr[76]:='L';xchr[77]:='M';xchr[78]:='N';xchr[79]:='O'; +xchr[80]:='P';xchr[81]:='Q';xchr[82]:='R';xchr[83]:='S';xchr[84]:='T'; +xchr[85]:='U';xchr[86]:='V';xchr[87]:='W';xchr[88]:='X';xchr[89]:='Y'; +xchr[90]:='Z';xchr[91]:='[';xchr[92]:='\';xchr[93]:=']';xchr[94]:='^'; +xchr[95]:='_';xchr[96]:='`';xchr[97]:='a';xchr[98]:='b';xchr[99]:='c'; +xchr[100]:='d';xchr[101]:='e';xchr[102]:='f';xchr[103]:='g'; +xchr[104]:='h';xchr[105]:='i';xchr[106]:='j';xchr[107]:='k'; +xchr[108]:='l';xchr[109]:='m';xchr[110]:='n';xchr[111]:='o'; +xchr[112]:='p';xchr[113]:='q';xchr[114]:='r';xchr[115]:='s'; +xchr[116]:='t';xchr[117]:='u';xchr[118]:='v';xchr[119]:='w'; +xchr[120]:='x';xchr[121]:='y';xchr[122]:='z';xchr[123]:='{'; +xchr[124]:='|';xchr[125]:='}';xchr[126]:='~';xchr[0]:=' '; +xchr[127]:=' ';{:14}{17:}for i:=1 to 31 do xchr[i]:=' '; +for i:=128 to 255 do xchr[i]:=' ';{:17}{18:} +for i:=0 to 255 do xord[chr(i)]:=32;for i:=1 to 255 do xord[xchr[i]]:=i; +xord[' ']:=32;{:18}{21:}rewrite(termout,'TTY:');{:21}{26:} +rewrite(Pascalfile);rewrite(pool);{:26}{42:} +for wi:=0 to 1 do begin bytestart[wi]:=0;byteptr[wi]:=0;end; +bytestart[2]:=0;nameptr:=1;stringptr:=256;poolchecksum:=271828;{:42} +{46:}for zi:=0 to 2 do begin tokstart[zi]:=0;tokptr[zi]:=0;end; +tokstart[3]:=0;textptr:=1;z:=1 mod 3;{:46}{48:}ilk[0]:=0;equiv[0]:=0; +{:48}{52:}for h:=0 to hashsize-1 do begin hash[h]:=0;chophash[h]:=0;end; +{:52}{71:}lastunnamed:=0;textlink[0]:=0;{:71}{144:}scanninghex:=false; +{:144}{152:}modtext[0]:=32;{:152}{180:}{troubleshooting:=true; +debugcycle:=1;debugskipped:=0;troubleshooting:=false;debugcycle:=99999; +reset(termin,'TTY:','/I');}{:180}end;{:2}{24:}procedure openinput; +begin reset(webfile);reset(changefile);end;{:24}{28:} +function inputln(var f:text):boolean;var finallimit:0..bufsize; +begin limit:=0;finallimit:=0; +if eof(f)then inputln:=false else begin while not eoln(f)do begin buffer +[limit]:=xord[f^];get(f);limit:=limit+1; +if buffer[limit-1]<>32 then finallimit:=limit; +if limit=bufsize then begin while not eoln(f)do get(f);limit:=limit-1; +if finallimit>limit then finallimit:=limit;begin writeln(termout); +write(termout,'! Input line too long');end;loc:=0;error;end;end; +readln(f);limit:=finallimit;inputln:=true;end;end;{:28}{49:} +procedure printid(p:namepointer);var k:0..maxbytes;w:0..1; +begin if p>=nameptr then write(termout,'IMPOSSIBLE')else begin w:=p mod +2; +for k:=bytestart[p]to bytestart[p+2]-1 do write(termout,xchr[bytemem[w,k +]]);end;end;{:49}{53:}function idlookup(t:eightbits):namepointer; +label 31,32;var c:eightbits;i:0..bufsize;h:0..hashsize;k:0..maxbytes; +w:0..1;l:0..bufsize;p,q:namepointer;s:0..unambiglength; +begin l:=idloc-idfirst;{54:}h:=buffer[idfirst];i:=idfirst+1; +while i0 do begin if bytestart[p+2]-bytestart[p]=l then{56:} +begin i:=idfirst;k:=bytestart[p];w:=p mod 2; +while(i0)then{57:} +begin if((p<>nameptr)and(t<>0)and(ilk[p]=0))or((p=nameptr)and(t=0)and( +buffer[idfirst]<>34))then{58:}begin i:=idfirst;s:=0;h:=0; +while(i95 then begin +if buffer[i]>=97 then choppedid[s]:=buffer[i]-32 else choppedid[s]:= +buffer[i];h:=(h+h+choppedid[s])mod hashsize;s:=s+1;end;i:=i+1;end; +choppedid[s]:=0;end{:58};if p<>nameptr then{59:} +begin if ilk[p]=0 then begin if t=1 then begin writeln(termout); +write(termout,'! This identifier has already appeared');error;end;{60:} +q:=chophash[h]; +if q=p then chophash[h]:=equiv[p]else begin while equiv[q]<>p do q:= +equiv[q];equiv[q]:=equiv[p];end{:60};end else begin writeln(termout); +write(termout,'! This identifier was defined before');error;end; +ilk[p]:=t;end{:59}else{61:} +begin if(t=0)and(buffer[idfirst]<>34)then{62:}begin q:=chophash[h]; +while q<>0 do begin{63:}begin k:=bytestart[q];s:=0;w:=q mod 2; +while(k95 then begin if c>=97 then c:=c-32; +if choppedid[s]<>c then goto 32;s:=s+1;end;k:=k+1;end; +if(k=bytestart[q+2])and(choppedid[s]<>0)then goto 32; +begin writeln(termout);write(termout,'! Identifier conflict with ');end; +for k:=bytestart[q]to bytestart[q+2]-1 do write(termout,xchr[bytemem[w,k +]]);error;q:=0;32:end{:63};q:=equiv[q];end;equiv[p]:=chophash[h]; +chophash[h]:=p;end{:62};w:=nameptr mod 2;k:=byteptr[w]; +if k+l>maxbytes then begin writeln(termout); +write(termout,'! Sorry, ','byte memory',' capacity exceeded');error; +history:=3;jumpout;end; +if nameptr>maxnames-2 then begin writeln(termout); +write(termout,'! Sorry, ','name',' capacity exceeded');error;history:=3; +jumpout;end;i:=idfirst;while i34 then ilk[p]:=t else{64:} +begin ilk[p]:=1; +if l-doublechars=2 then equiv[p]:=buffer[idfirst+1]+32768 else begin +equiv[p]:=stringptr+32768;l:=l-doublechars-1; +if l>99 then begin writeln(termout); +write(termout,'! Preprocessed string is too long');error;end; +stringptr:=stringptr+1;write(pool,xchr[48+l div 10],xchr[48+l mod 10]); +poolchecksum:=poolchecksum+poolchecksum+l; +while poolchecksum>536870839 do poolchecksum:=poolchecksum-536870839; +i:=idfirst+1;while i536870839 do poolchecksum:=poolchecksum-536870839; +if(buffer[i]=34)or(buffer[i]=64)then i:=i+2 else i:=i+1;end; +writeln(pool);end;end{:64};end{:61};end{:57};idlookup:=p;end;{:53}{66:} +function modlookup(l:sixteenbits):namepointer;label 31;var c:0..4; +j:0..longestname;k:0..maxbytes;w:0..1;p:namepointer;q:namepointer; +begin c:=2;q:=0;p:=ilk[0];while p<>0 do begin{68:}begin k:=bytestart[p]; +w:=p mod 2;c:=1;j:=1; +while(kl then c:=1 else c:=4 else if j>l then c:=3 +else if modtext[j]maxbytes then begin writeln(termout); +write(termout,'! Sorry, ','byte memory',' capacity exceeded');error; +history:=3;jumpout;end; +if nameptr>maxnames-2 then begin writeln(termout); +write(termout,'! Sorry, ','name',' capacity exceeded');error;history:=3; +jumpout;end;p:=nameptr;if c=0 then link[q]:=p else ilk[q]:=p;link[p]:=0; +ilk[p]:=0;c:=1;equiv[p]:=0; +for j:=1 to l do bytemem[w,k+j-1]:=modtext[j];byteptr[w]:=k+l; +bytestart[nameptr+2]:=k+l;nameptr:=nameptr+1;{:67}; +31:if c<>1 then begin begin writeln(termout); +write(termout,'! Incompatible section names');error;end;p:=0;end; +modlookup:=p;end;{:66}{69:} +function prefixlookup(l:sixteenbits):namepointer;var c:0..4; +count:0..maxnames;j:0..longestname;k:0..maxbytes;w:0..1;p:namepointer; +q:namepointer;r:namepointer;begin q:=0;p:=ilk[0];count:=0;r:=0; +while p<>0 do begin{68:}begin k:=bytestart[p];w:=p mod 2;c:=1;j:=1; +while(kl then c:=1 else c:=4 else if j>l then c:=3 +else if modtext[j]1 then if count=0 then begin writeln(termout); +write(termout,'! Name does not match');error; +end else begin writeln(termout);write(termout,'! Ambiguous prefix'); +error;end;prefixlookup:=r;end;{:69}{73:} +procedure storetwobytes(x:sixteenbits); +begin if tokptr[z]+2>maxtoks then begin writeln(termout); +write(termout,'! Sorry, ','token',' capacity exceeded');error; +history:=3;jumpout;end;tokmem[z,tokptr[z]]:=x div 256; +tokmem[z,tokptr[z]+1]:=x mod 256;tokptr[z]:=tokptr[z]+2;end;{:73}{74:} +{procedure printrepl(p:textpointer);var k:0..maxtoks;a:sixteenbits; +zp:0..2; +begin if p>=textptr then write(termout,'BAD')else begin k:=tokstart[p]; +zp:=p mod 3;while k=128 then[75:]begin k:=k+1; +if a<168 then begin a:=(a-128)*256+tokmem[zp,k];printid(a); +if bytemem[a mod 2,bytestart[a]]=34 then write(termout,'"')else write( +termout,' ');end else if a<208 then begin write(termout,'@<'); +printid((a-168)*256+tokmem[zp,k]);write(termout,'@>'); +end else begin a:=(a-208)*256+tokmem[zp,k]; +write(termout,'@',xchr[123],a:1,'@',xchr[125]);end; +end[:75]else[76:]case a of 9:write(termout,'@',xchr[123]); +10:write(termout,'@',xchr[125]);12:write(termout,'@'''); +13:write(termout,'@"');125:write(termout,'@$');0:write(termout,'#'); +64:write(termout,'@@');2:write(termout,'@=');3:write(termout,'@\'); +else write(termout,xchr[a])end[:76];k:=k+1;end;end;end;}{:74}{84:} +procedure pushlevel(p:namepointer); +begin if stackptr=stacksize then begin writeln(termout); +write(termout,'! Sorry, ','stack',' capacity exceeded');error; +history:=3;jumpout;end else begin stack[stackptr]:=curstate; +stackptr:=stackptr+1;curstate.namefield:=p;curstate.replfield:=equiv[p]; +zo:=curstate.replfield mod 3; +curstate.bytefield:=tokstart[curstate.replfield]; +curstate.endfield:=tokstart[curstate.replfield+3];curstate.modfield:=0; +end;end;{:84}{85:}procedure poplevel;label 10; +begin if textlink[curstate.replfield]=0 then begin if ilk[curstate. +namefield]=3 then{91:}begin nameptr:=nameptr-1;textptr:=textptr-1; +z:=textptr mod 3;{if tokptr[z]>maxtokptr[z]then maxtokptr[z]:=tokptr[z]; +}tokptr[z]:=tokstart[textptr]; +{byteptr[nameptr mod 2]:=byteptr[nameptr mod 2]-1;}end{:91}; +end else if textlink[curstate.replfield]0 then begin curstate:=stack[stackptr]; +zo:=curstate.replfield mod 3;end;10:end;{:85}{87:} +function getoutput:sixteenbits;label 20,30,31;var a:sixteenbits; +b:eightbits;bal:sixteenbits;k:0..maxbytes;w:0..1; +begin 20:if stackptr=0 then begin a:=0;goto 31;end; +if curstate.bytefield=curstate.endfield then begin curval:=-curstate. +modfield;poplevel;if curval=0 then goto 20;a:=129;goto 31;end; +a:=tokmem[zo,curstate.bytefield]; +curstate.bytefield:=curstate.bytefield+1;if a<128 then if a=0 then{92:} +begin pushlevel(nameptr-1);goto 20;end{:92}else goto 31; +a:=(a-128)*256+tokmem[zo,curstate.bytefield]; +curstate.bytefield:=curstate.bytefield+1;if a<10240 then{89:} +begin case ilk[a]of 0:begin curval:=a;a:=130;end; +1:begin curval:=equiv[a]-32768;a:=128;end;2:begin pushlevel(a);goto 20; +end;3:begin{90:} +while(curstate.bytefield=curstate.endfield)and(stackptr>0)do poplevel; +if(stackptr=0)or(tokmem[zo,curstate.bytefield]<>40)then begin begin +writeln(termout);write(termout,'! No parameter given for ');end; +printid(a);error;goto 20;end;{93:}bal:=1; +curstate.bytefield:=curstate.bytefield+1; +while true do begin b:=tokmem[zo,curstate.bytefield]; +curstate.bytefield:=curstate.bytefield+1; +if b=0 then storetwobytes(nameptr+32767)else begin if b>=128 then begin +begin if tokptr[z]=maxtoks then begin writeln(termout); +write(termout,'! Sorry, ','token',' capacity exceeded');error; +history:=3;jumpout;end;tokmem[z,tokptr[z]]:=b;tokptr[z]:=tokptr[z]+1; +end;b:=tokmem[zo,curstate.bytefield]; +curstate.bytefield:=curstate.bytefield+1; +end else case b of 40:bal:=bal+1;41:begin bal:=bal-1; +if bal=0 then goto 30;end; +39:repeat begin if tokptr[z]=maxtoks then begin writeln(termout); +write(termout,'! Sorry, ','token',' capacity exceeded');error; +history:=3;jumpout;end;tokmem[z,tokptr[z]]:=b;tokptr[z]:=tokptr[z]+1; +end;b:=tokmem[zo,curstate.bytefield]; +curstate.bytefield:=curstate.bytefield+1;until b=39;else end; +begin if tokptr[z]=maxtoks then begin writeln(termout); +write(termout,'! Sorry, ','token',' capacity exceeded');error; +history:=3;jumpout;end;tokmem[z,tokptr[z]]:=b;tokptr[z]:=tokptr[z]+1; +end;end;end;30:{:93};equiv[nameptr]:=textptr;ilk[nameptr]:=2; +w:=nameptr mod 2;k:=byteptr[w]; +{if k=maxbytes then begin writeln(termout); +write(termout,'! Sorry, ','byte memory',' capacity exceeded');error; +history:=3;jumpout;end;bytemem[w,k]:=35;k:=k+1;byteptr[w]:=k;} +if nameptr>maxnames-2 then begin writeln(termout); +write(termout,'! Sorry, ','name',' capacity exceeded');error;history:=3; +jumpout;end;bytestart[nameptr+2]:=k;nameptr:=nameptr+1; +if textptr>maxtexts-3 then begin writeln(termout); +write(termout,'! Sorry, ','text',' capacity exceeded');error;history:=3; +jumpout;end;textlink[textptr]:=0;tokstart[textptr+3]:=tokptr[z]; +textptr:=textptr+1;z:=textptr mod 3{:90};pushlevel(a);goto 20;end; +else begin writeln(termout); +write(termout,'! This can''t happen (','output',')');error;history:=3; +jumpout;end end;goto 31;end{:89};if a<20480 then{88:}begin a:=a-10240; +if equiv[a]<>0 then pushlevel(a)else if a<>0 then begin begin writeln( +termout);write(termout,'! Not present: <');end;printid(a); +write(termout,'>');error;end;goto 20;end{:88};curval:=a-20480;a:=129; +curstate.modfield:=curval;31:{if troubleshooting then debughelp;} +getoutput:=a;end;{:87}{97:}procedure flushbuffer;var k:0..outbufsize; +b:0..outbufsize;begin b:=breakptr; +if(semiptr<>0)and(outptr-semiptr<=linelength)then breakptr:=semiptr; +for k:=1 to breakptr do write(Pascalfile,xchr[outbuf[k-1]]); +writeln(Pascalfile);line:=line+1; +if line mod 100=0 then begin write(termout,'.'); +if line mod 500=0 then write(termout,line:1);{break(termout);}end; +if breakptrb then b:=breakptr;end; +for k:=breakptr to outptr-1 do outbuf[k-breakptr]:=outbuf[k];end; +outptr:=outptr-breakptr;breakptr:=b-breakptr;semiptr:=0; +if outptr>linelength then begin begin writeln(termout); +write(termout,'! Long line must be truncated');error;end; +outptr:=linelength;end;end;{:97}{99:}procedure appval(v:integer); +var k:0..outbufsize;begin k:=outbufsize;repeat outbuf[k]:=v mod 10; +v:=v div 10;k:=k-1;until v=0;repeat k:=k+1; +begin outbuf[outptr]:=outbuf[k]+48;outptr:=outptr+1;end; +until k=outbufsize;end;{:99}{101:}procedure sendout(t:eightbits; +v:sixteenbits);label 20;var k:0..linelength;begin{102:} +20:case outstate of 1:if t<>3 then begin breakptr:=outptr; +if t=2 then begin outbuf[outptr]:=32;outptr:=outptr+1;end;end; +2:begin begin outbuf[outptr]:=44-outapp;outptr:=outptr+1;end; +if outptr>linelength then flushbuffer;breakptr:=outptr;end; +3,4:begin{103:} +if(outval<0)or((outval=0)and(lastsign<0))then begin outbuf[outptr]:=45; +outptr:=outptr+1; +end else if outsign>0 then begin outbuf[outptr]:=outsign; +outptr:=outptr+1;end;appval(abs(outval)); +if outptr>linelength then flushbuffer;{:103};outstate:=outstate-2; +goto 20;end;5:{104:}begin if(t=3)or({105:} +((t=2)and(v=3)and(((outcontrib[1]=68)and(outcontrib[2]=73)and(outcontrib +[3]=86))or((outcontrib[1]=77)and(outcontrib[2]=79)and(outcontrib[3]=68)) +))or((t=0)and((v=42)or(v=47))){:105})then begin{103:} +if(outval<0)or((outval=0)and(lastsign<0))then begin outbuf[outptr]:=45; +outptr:=outptr+1; +end else if outsign>0 then begin outbuf[outptr]:=outsign; +outptr:=outptr+1;end;appval(abs(outval)); +if outptr>linelength then flushbuffer;{:103};outsign:=43;outval:=outapp; +end else outval:=outval+outapp;outstate:=3;goto 20;end{:104}; +0:if t<>3 then breakptr:=outptr;else end{:102}; +if t<>0 then for k:=1 to v do begin outbuf[outptr]:=outcontrib[k]; +outptr:=outptr+1;end else begin outbuf[outptr]:=v;outptr:=outptr+1;end; +if outptr>linelength then flushbuffer; +if(t=0)and((v=59)or(v=125))then begin semiptr:=outptr;breakptr:=outptr; +end;if t>=2 then outstate:=1 else outstate:=0 end;{:101}{106:} +procedure sendsign(v:integer); +begin case outstate of 2,4:outapp:=outapp*v;3:begin outapp:=v; +outstate:=4;end;5:begin outval:=outval+outapp;outapp:=v;outstate:=4;end; +else begin breakptr:=outptr;outapp:=v;outstate:=2;end end; +lastsign:=outapp;end;{:106}{107:}procedure sendval(v:integer); +label 666,10;begin case outstate of 1:begin{110:} +if(outptr=breakptr+3)or((outptr=breakptr+4)and(outbuf[breakptr]=32))then +if((outbuf[outptr-3]=68)and(outbuf[outptr-2]=73)and(outbuf[outptr-1]=86) +)or((outbuf[outptr-3]=77)and(outbuf[outptr-2]=79)and(outbuf[outptr-1]=68 +))then goto 666{:110};outsign:=32;outstate:=3;outval:=v; +breakptr:=outptr;lastsign:=+1;end;0:begin{109:} +if(outptr=breakptr+1)and((outbuf[breakptr]=42)or(outbuf[breakptr]=47)) +then goto 666{:109};outsign:=0;outstate:=3;outval:=v;breakptr:=outptr; +lastsign:=+1;end;{108:}2:begin outsign:=43;outstate:=3;outval:=outapp*v; +end;3:begin outstate:=5;outapp:=v;begin writeln(termout); +write(termout,'! Two numbers occurred without a sign between them'); +error;end;end;4:begin outstate:=5;outapp:=outapp*v;end; +5:begin outval:=outval+outapp;outapp:=v;begin writeln(termout); +write(termout,'! Two numbers occurred without a sign between them'); +error;end;end;{:108}else goto 666 end;goto 10;666:{111:} +if v>=0 then begin if outstate=1 then begin breakptr:=outptr; +begin outbuf[outptr]:=32;outptr:=outptr+1;end;end;appval(v); +if outptr>linelength then flushbuffer;outstate:=1; +end else begin begin outbuf[outptr]:=40;outptr:=outptr+1;end; +begin outbuf[outptr]:=45;outptr:=outptr+1;end;appval(-v); +begin outbuf[outptr]:=41;outptr:=outptr+1;end; +if outptr>linelength then flushbuffer;outstate:=0;end{:111};10:end; +{:107}{113:}procedure sendtheoutput;label 2,21,22;var curchar:eightbits; +k:0..linelength;j:0..maxbytes;w:0..1;n:integer; +begin while stackptr>0 do begin curchar:=getoutput; +21:case curchar of 0:;{116:} +65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88, +89,90:begin outcontrib[1]:=curchar;sendout(2,1);end; +97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115 +,116,117,118,119,120,121,122:begin outcontrib[1]:=curchar-32; +sendout(2,1);end;130:begin k:=0;j:=bytestart[curval];w:=curval mod 2; +while(k=97 then outcontrib[k]:=outcontrib[k]-32 else if +outcontrib[k]=95 then k:=k-1;end;sendout(2,k);end;{:116}{119:} +48,49,50,51,52,53,54,55,56,57:begin n:=0;repeat curchar:=curchar-48; +if n>=214748364 then begin writeln(termout); +write(termout,'! Constant too big');error;end else n:=10*n+curchar; +curchar:=getoutput;until(curchar>57)or(curchar<48);sendval(n);k:=0; +if curchar=101 then curchar:=69;if curchar=69 then goto 2 else goto 21; +end;125:sendval(poolchecksum);12:begin n:=0;curchar:=48; +repeat curchar:=curchar-48;if n>=268435456 then begin writeln(termout); +write(termout,'! Constant too big');error;end else n:=8*n+curchar; +curchar:=getoutput;until(curchar>55)or(curchar<48);sendval(n);goto 21; +end;13:begin n:=0;curchar:=48; +repeat if curchar>=65 then curchar:=curchar-55 else curchar:=curchar-48; +if n>=134217728 then begin writeln(termout); +write(termout,'! Constant too big');error;end else n:=16*n+curchar; +curchar:=getoutput; +until(curchar>70)or(curchar<48)or((curchar>57)and(curchar<65)); +sendval(n);goto 21;end;128:sendval(curval);46:begin k:=1; +outcontrib[1]:=46;curchar:=getoutput; +if curchar=46 then begin outcontrib[2]:=46;sendout(1,2); +end else if(curchar>=48)and(curchar<=57)then goto 2 else begin sendout(0 +,46);goto 21;end;end;{:119}43,45:sendsign(44-curchar);{114:} +4:begin outcontrib[1]:=65;outcontrib[2]:=78;outcontrib[3]:=68; +sendout(2,3);end;5:begin outcontrib[1]:=78;outcontrib[2]:=79; +outcontrib[3]:=84;sendout(2,3);end;6:begin outcontrib[1]:=73; +outcontrib[2]:=78;sendout(2,2);end;31:begin outcontrib[1]:=79; +outcontrib[2]:=82;sendout(2,2);end;24:begin outcontrib[1]:=58; +outcontrib[2]:=61;sendout(1,2);end;26:begin outcontrib[1]:=60; +outcontrib[2]:=62;sendout(1,2);end;28:begin outcontrib[1]:=60; +outcontrib[2]:=61;sendout(1,2);end;29:begin outcontrib[1]:=62; +outcontrib[2]:=61;sendout(1,2);end;30:begin outcontrib[1]:=61; +outcontrib[2]:=61;sendout(1,2);end;32:begin outcontrib[1]:=46; +outcontrib[2]:=46;sendout(1,2);end;{:114}39:{117:}begin k:=1; +outcontrib[1]:=39;repeat if k0 then begin bracelevel:=bracelevel-1; +if bracelevel=0 then sendout(0,125)else sendout(0,93); +end else begin writeln(termout);write(termout,'! Extra @}');error;end; +129:begin if bracelevel=0 then sendout(0,123)else sendout(0,91); +if curval<0 then begin sendout(0,58);sendval(-curval); +end else begin sendval(curval);sendout(0,58);end; +if bracelevel=0 then sendout(0,125)else sendout(0,93);end;{:121} +127:begin sendout(3,0);outstate:=6;end;2:{118:}begin k:=0; +repeat if k0 do begin if outptr<=linelength then breakptr:=outptr; +flushbuffer;end;outstate:=0;end{:122};else begin writeln(termout); +write(termout,'! Can''t output ASCII code ',curchar:1);error;end end; +goto 22;2:{120:}repeat if k69)and((curchar<48)or(curchar>57)); +if k=linelength then begin writeln(termout); +write(termout,'! Fraction too long');error;end;sendout(3,k); +goto 21{:120};22:end;end;{:113}{127:}function linesdontmatch:boolean; +label 10;var k:0..bufsize;begin linesdontmatch:=true; +if changelimit<>limit then goto 10; +if limit>0 then for k:=0 to limit-1 do if changebuffer[k]<>buffer[k]then +goto 10;linesdontmatch:=false;10:end;{:127}{128:} +procedure primethechangebuffer;label 22,30,10;var k:0..bufsize; +begin changelimit:=0;{129:}while true do begin line:=line+1; +if not inputln(changefile)then goto 10;if limit<2 then goto 22; +if buffer[0]<>64 then goto 22; +if(buffer[1]>=88)and(buffer[1]<=90)then buffer[1]:=buffer[1]+32; +if buffer[1]=120 then goto 30; +if(buffer[1]=121)or(buffer[1]=122)then begin loc:=2; +begin writeln(termout);write(termout,'! Where is the matching @x?'); +error;end;end;22:end;30:{:129};{130:}repeat line:=line+1; +if not inputln(changefile)then begin begin writeln(termout); +write(termout,'! Change file ended after @x');error;end;goto 10;end; +until limit>0;{:130};{131:}begin changelimit:=limit; +if limit>0 then for k:=0 to limit-1 do changebuffer[k]:=buffer[k]; +end{:131};10:end;{:128}{132:}procedure checkchange;label 10; +var n:integer;k:0..bufsize;begin if linesdontmatch then goto 10;n:=0; +while true do begin changing:=not changing;templine:=otherline; +otherline:=line;line:=templine;line:=line+1; +if not inputln(changefile)then begin begin writeln(termout); +write(termout,'! Change file ended before @y');error;end;changelimit:=0; +changing:=not changing;templine:=otherline;otherline:=line; +line:=templine;goto 10;end;{133:} +if limit>1 then if buffer[0]=64 then begin if(buffer[1]>=88)and(buffer[1 +]<=90)then buffer[1]:=buffer[1]+32; +if(buffer[1]=120)or(buffer[1]=122)then begin loc:=2; +begin writeln(termout);write(termout,'! Where is the matching @y?'); +error;end;end else if buffer[1]=121 then begin if n>0 then begin loc:=2; +begin writeln(termout); +write(termout,'! Hmm... ',n:1,' of the preceding lines failed to match') +;error;end;end;goto 10;end;end{:133};{131:}begin changelimit:=limit; +if limit>0 then for k:=0 to limit-1 do changebuffer[k]:=buffer[k]; +end{:131};changing:=not changing;templine:=otherline;otherline:=line; +line:=templine;line:=line+1; +if not inputln(webfile)then begin begin writeln(termout); +write(termout,'! WEB file ended during a change');error;end; +inputhasended:=true;goto 10;end;if linesdontmatch then n:=n+1;end; +10:end;{:132}{135:}procedure getline;label 20; +begin 20:if changing then{137:}begin line:=line+1; +if not inputln(changefile)then begin begin writeln(termout); +write(termout,'! Change file ended without @z');error;end;buffer[0]:=64; +buffer[1]:=122;limit:=2;end; +if limit>1 then if buffer[0]=64 then begin if(buffer[1]>=88)and(buffer[1 +]<=90)then buffer[1]:=buffer[1]+32; +if(buffer[1]=120)or(buffer[1]=121)then begin loc:=2; +begin writeln(termout);write(termout,'! Where is the matching @z?'); +error;end;end else if buffer[1]=122 then begin primethechangebuffer; +changing:=not changing;templine:=otherline;otherline:=line; +line:=templine;end;end;end{:137};if not changing then begin{136:} +begin line:=line+1; +if not inputln(webfile)then inputhasended:=true else if limit= +changelimit then if buffer[0]=changebuffer[0]then if changelimit>0 then +checkchange;end{:136};if changing then goto 20;end;loc:=0; +buffer[limit]:=32;end;{:135}{139:} +function controlcode(c:ASCIIcode):eightbits; +begin case c of 64:controlcode:=64;39:controlcode:=12; +34:controlcode:=13;36:controlcode:=125;32,9:controlcode:=136; +42:begin write(termout,'*',modulecount+1:1);{break(termout);} +controlcode:=136;end;68,100:controlcode:=133;70,102:controlcode:=132; +123:controlcode:=9;125:controlcode:=10;80,112:controlcode:=134; +84,116,94,46,58:controlcode:=131;38:controlcode:=127; +60:controlcode:=135;61:controlcode:=2;92:controlcode:=3; +else controlcode:=0 end;end;{:139}{140:}function skipahead:eightbits; +label 30;var c:eightbits; +begin while true do begin if loc>limit then begin getline; +if inputhasended then begin c:=136;goto 30;end;end;buffer[limit+1]:=64; +while buffer[loc]<>64 do loc:=loc+1;if loc<=limit then begin loc:=loc+2; +c:=controlcode(buffer[loc-1]);if(c<>0)or(buffer[loc-1]=62)then goto 30; +end;end;30:skipahead:=c;end;{:140}{141:}procedure skipcomment;label 10; +var bal:eightbits;c:ASCIIcode;begin bal:=0; +while true do begin if loc>limit then begin getline; +if inputhasended then begin begin writeln(termout); +write(termout,'! Input ended in mid-comment');error;end;goto 10;end;end; +c:=buffer[loc];loc:=loc+1;{142:}if c=64 then begin c:=buffer[loc]; +if(c<>32)and(c<>9)and(c<>42)and(c<>122)and(c<>90)then loc:=loc+1 else +begin begin writeln(termout); +write(termout,'! Section ended in mid-comment');error;end;loc:=loc-1; +goto 10; +end end else if(c=92)and(buffer[loc]<>64)then loc:=loc+1 else if c=123 +then bal:=bal+1 else if c=125 then begin if bal=0 then goto 10; +bal:=bal-1;end{:142};end;10:end;{:141}{145:}function getnext:eightbits; +label 20,30,31;var c:eightbits;d:eightbits;j,k:0..longestname; +begin 20:if loc>limit then begin getline; +if inputhasended then begin c:=136;goto 31;end;end;c:=buffer[loc]; +loc:=loc+1;if scanninghex then{146:} +if((c>=48)and(c<=57))or((c>=65)and(c<=70))then goto 31 else scanninghex +:=false{:146}; +case c of 65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85 +,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111 +,112,113,114,115,116,117,118,119,120,121,122:{148:} +begin if((c=101)or(c=69))and(loc>1)then if(buffer[loc-2]<=57)and(buffer[ +loc-2]>=48)then c:=0;if c<>0 then begin loc:=loc-1;idfirst:=loc; +repeat loc:=loc+1;d:=buffer[loc]; +until((d<48)or((d>57)and(d<65))or((d>90)and(d<97))or(d>122))and(d<>95); +if loc>idfirst+1 then begin c:=130;idloc:=loc;end;end else c:=69; +end{:148};34:{149:}begin doublechars:=0;idfirst:=loc-1; +repeat d:=buffer[loc];loc:=loc+1; +if(d=34)or(d=64)then if buffer[loc]=d then begin loc:=loc+1;d:=0; +doublechars:=doublechars+1; +end else begin if d=64 then begin writeln(termout); +write(termout,'! Double @ sign missing');error; +end end else if loc>limit then begin begin writeln(termout); +write(termout,'! String constant didn''t end');error;end;d:=34;end; +until d=34;idloc:=loc-1;c:=130;end{:149};64:{150:} +begin c:=controlcode(buffer[loc]);loc:=loc+1; +if c=0 then goto 20 else if c=13 then scanninghex:=true else if c=135 +then{151:}begin{153:}k:=0; +while true do begin if loc>limit then begin getline; +if inputhasended then begin begin writeln(termout); +write(termout,'! Input ended in section name');error;end;goto 30;end; +end;d:=buffer[loc];{154:}if d=64 then begin d:=buffer[loc+1]; +if d=62 then begin loc:=loc+2;goto 30;end; +if(d=32)or(d=9)or(d=42)then begin begin writeln(termout); +write(termout,'! Section name didn''t end');error;end;goto 30;end; +k:=k+1;modtext[k]:=64;loc:=loc+1;end{:154};loc:=loc+1; +if k=longestname-2 then begin begin writeln(termout); +write(termout,'! Section name too long: ');end; +for j:=1 to 25 do write(termout,xchr[modtext[j]]);write(termout,'...'); +if history=0 then history:=1;end{:155}; +if(modtext[k]=32)and(k>0)then k:=k-1;{:153}; +if k>3 then begin if(modtext[k]=46)and(modtext[k-1]=46)and(modtext[k-2]= +46)then curmodule:=prefixlookup(k-3)else curmodule:=modlookup(k); +end else curmodule:=modlookup(k);end{:151} +else if c=131 then begin repeat c:=skipahead;until c<>64; +if buffer[loc-1]<>62 then begin writeln(termout); +write(termout,'! Improper @ within control text');error;end;goto 20;end; +end{:150};{147:} +46:if buffer[loc]=46 then begin if loc<=limit then begin c:=32; +loc:=loc+1;end; +end else if buffer[loc]=41 then begin if loc<=limit then begin c:=93; +loc:=loc+1;end;end; +58:if buffer[loc]=61 then begin if loc<=limit then begin c:=24; +loc:=loc+1;end;end; +61:if buffer[loc]=61 then begin if loc<=limit then begin c:=30; +loc:=loc+1;end;end; +62:if buffer[loc]=61 then begin if loc<=limit then begin c:=29; +loc:=loc+1;end;end; +60:if buffer[loc]=61 then begin if loc<=limit then begin c:=28; +loc:=loc+1;end; +end else if buffer[loc]=62 then begin if loc<=limit then begin c:=26; +loc:=loc+1;end;end; +40:if buffer[loc]=42 then begin if loc<=limit then begin c:=9; +loc:=loc+1;end; +end else if buffer[loc]=46 then begin if loc<=limit then begin c:=91; +loc:=loc+1;end;end; +42:if buffer[loc]=41 then begin if loc<=limit then begin c:=10; +loc:=loc+1;end;end;{:147}32,9:goto 20;123:begin skipcomment;goto 20;end; +125:begin begin writeln(termout);write(termout,'! Extra }');error;end; +goto 20;end;else if c>=128 then goto 20 else end; +31:{if troubleshooting then debughelp;}getnext:=c;end;{:145}{157:} +procedure scannumeric(p:namepointer);label 21,30; +var accumulator:integer;nextsign:-1..+1;q:namepointer;val:integer; +begin{158:}accumulator:=0;nextsign:=+1; +while true do begin nextcontrol:=getnext; +21:case nextcontrol of 48,49,50,51,52,53,54,55,56,57:begin{160:}val:=0; +repeat val:=10*val+nextcontrol-48;nextcontrol:=getnext; +until(nextcontrol>57)or(nextcontrol<48){:160}; +begin accumulator:=accumulator+nextsign*(val);nextsign:=+1;end;goto 21; +end;12:begin{161:}val:=0;nextcontrol:=48; +repeat val:=8*val+nextcontrol-48;nextcontrol:=getnext; +until(nextcontrol>55)or(nextcontrol<48){:161}; +begin accumulator:=accumulator+nextsign*(val);nextsign:=+1;end;goto 21; +end;13:begin{162:}val:=0;nextcontrol:=48; +repeat if nextcontrol>=65 then nextcontrol:=nextcontrol-7; +val:=16*val+nextcontrol-48;nextcontrol:=getnext; +until(nextcontrol>70)or(nextcontrol<48)or((nextcontrol>57)and( +nextcontrol<65)){:162};begin accumulator:=accumulator+nextsign*(val); +nextsign:=+1;end;goto 21;end;130:begin q:=idlookup(0); +if ilk[q]<>1 then begin nextcontrol:=42;goto 21;end; +begin accumulator:=accumulator+nextsign*(equiv[q]-32768);nextsign:=+1; +end;end;43:;45:nextsign:=-nextsign;132,133,135,134,136:goto 30; +59:begin writeln(termout); +write(termout,'! Omit semicolon in numeric definition');error;end; +else {159:}begin begin writeln(termout); +write(termout,'! Improper numeric definition will be flushed');error; +end;repeat nextcontrol:=skipahead until(nextcontrol>=132); +if nextcontrol=135 then begin loc:=loc-2;nextcontrol:=getnext;end; +accumulator:=0;goto 30;end{:159}end;end;30:{:158}; +if abs(accumulator)>=32768 then begin begin writeln(termout); +write(termout,'! Value too big: ',accumulator:1);error;end; +accumulator:=0;end;equiv[p]:=accumulator+32768;end;{:157}{165:} +procedure scanrepl(t:eightbits);label 22,30,31,21;var a:sixteenbits; +b:ASCIIcode;bal:eightbits;begin bal:=0; +while true do begin 22:a:=getnext;case a of 40:bal:=bal+1; +41:if bal=0 then begin writeln(termout);write(termout,'! Extra )'); +error;end else bal:=bal-1;39:{168:}begin b:=39; +while true do begin begin if tokptr[z]=maxtoks then begin writeln( +termout);write(termout,'! Sorry, ','token',' capacity exceeded');error; +history:=3;jumpout;end;tokmem[z,tokptr[z]]:=b;tokptr[z]:=tokptr[z]+1; +end;if b=64 then if buffer[loc]=64 then loc:=loc+1 else begin writeln( +termout);write(termout,'! You should double @ signs in strings');error; +end;if loc=limit then begin begin writeln(termout); +write(termout,'! String didn''t end');error;end;buffer[loc]:=39; +buffer[loc+1]:=0;end;b:=buffer[loc];loc:=loc+1; +if b=39 then begin if buffer[loc]<>39 then goto 31 else begin loc:=loc+1 +;begin if tokptr[z]=maxtoks then begin writeln(termout); +write(termout,'! Sorry, ','token',' capacity exceeded');error; +history:=3;jumpout;end;tokmem[z,tokptr[z]]:=39;tokptr[z]:=tokptr[z]+1; +end;end;end;end;31:end{:168};35:if t=3 then a:=0;{167:} +130:begin a:=idlookup(0); +begin if tokptr[z]=maxtoks then begin writeln(termout); +write(termout,'! Sorry, ','token',' capacity exceeded');error; +history:=3;jumpout;end;tokmem[z,tokptr[z]]:=(a div 256)+128; +tokptr[z]:=tokptr[z]+1;end;a:=a mod 256;end; +135:if t<>135 then goto 30 else begin begin if tokptr[z]=maxtoks then +begin writeln(termout); +write(termout,'! Sorry, ','token',' capacity exceeded');error; +history:=3;jumpout;end;tokmem[z,tokptr[z]]:=(curmodule div 256)+168; +tokptr[z]:=tokptr[z]+1;end;a:=curmodule mod 256;end;2:{169:} +begin begin if tokptr[z]=maxtoks then begin writeln(termout); +write(termout,'! Sorry, ','token',' capacity exceeded');error; +history:=3;jumpout;end;tokmem[z,tokptr[z]]:=2;tokptr[z]:=tokptr[z]+1; +end;buffer[limit+1]:=64; +21:if buffer[loc]=64 then begin if loc=limit then begin writeln(termout); +write(termout,'! Verbatim string didn''t end');error; +end else if buffer[loc+1]<>62 then begin writeln(termout); +write(termout,'! You should double @ signs in verbatim strings');error; +end;loc:=loc+2;end{:169}; +133,132,134:if t<>135 then goto 30 else begin begin writeln(termout); +write(termout,'! @',xchr[buffer[loc-1]],' is ignored in Pascal text'); +error;end;goto 22;end;136:goto 30;{:167}else end; +begin if tokptr[z]=maxtoks then begin writeln(termout); +write(termout,'! Sorry, ','token',' capacity exceeded');error; +history:=3;jumpout;end;tokmem[z,tokptr[z]]:=a;tokptr[z]:=tokptr[z]+1; +end;end;30:nextcontrol:=a;{166:} +if bal>0 then begin if bal=1 then begin writeln(termout); +write(termout,'! Missing )');error;end else begin writeln(termout); +write(termout,'! Missing ',bal:1,' )''s');error;end; +while bal>0 do begin begin if tokptr[z]=maxtoks then begin writeln( +termout);write(termout,'! Sorry, ','token',' capacity exceeded');error; +history:=3;jumpout;end;tokmem[z,tokptr[z]]:=41;tokptr[z]:=tokptr[z]+1; +end;bal:=bal-1;end;end{:166}; +if textptr>maxtexts-3 then begin writeln(termout); +write(termout,'! Sorry, ','text',' capacity exceeded');error;history:=3; +jumpout;end;currepltext:=textptr;tokstart[textptr+3]:=tokptr[z]; +textptr:=textptr+1;if z=2 then z:=0 else z:=z+1;end;{:165}{170:} +procedure definemacro(t:eightbits);var p:namepointer; +begin p:=idlookup(t);scanrepl(t);equiv[p]:=currepltext; +textlink[currepltext]:=0;end;{:170}{172:}procedure scanmodule; +label 22,30,10;var p:namepointer;begin modulecount:=modulecount+1;{173:} +nextcontrol:=0; +while true do begin 22:while nextcontrol<=132 do begin nextcontrol:= +skipahead;if nextcontrol=135 then begin loc:=loc-2;nextcontrol:=getnext; +end;end;if nextcontrol<>133 then goto 30;nextcontrol:=getnext; +if nextcontrol<>130 then begin begin writeln(termout); +write(termout,'! Definition flushed, must start with ', +'identifier of length > 1');error;end;goto 22;end;nextcontrol:=getnext; +if nextcontrol=61 then begin scannumeric(idlookup(1));goto 22; +end else if nextcontrol=30 then begin definemacro(2);goto 22; +end else{174:}if nextcontrol=40 then begin nextcontrol:=getnext; +if nextcontrol=35 then begin nextcontrol:=getnext; +if nextcontrol=41 then begin nextcontrol:=getnext; +if nextcontrol=61 then begin begin writeln(termout); +write(termout,'! Use == for macros');error;end;nextcontrol:=30;end; +if nextcontrol=30 then begin definemacro(3);goto 22;end;end;end;end; +{:174};begin writeln(termout); +write(termout,'! Definition flushed since it starts badly');error;end; +end;30:{:173};{175:}case nextcontrol of 134:p:=0;135:begin p:=curmodule; +{176:}repeat nextcontrol:=getnext;until nextcontrol<>43; +if(nextcontrol<>61)and(nextcontrol<>30)then begin begin writeln(termout) +;write(termout,'! Pascal text flushed, = sign is missing');error;end; +repeat nextcontrol:=skipahead;until nextcontrol=136;goto 10;end{:176}; +end;else goto 10 end;{177:}storetwobytes(53248+modulecount);{:177}; +scanrepl(135);{178:} +if p=0 then begin textlink[lastunnamed]:=currepltext; +lastunnamed:=currepltext; +end else if equiv[p]=0 then equiv[p]:=currepltext else begin p:=equiv[p] +;while textlink[p]0 then begin for ii:=0 to changelimit do buffer[ii]:= +changebuffer[ii];limit:=changelimit;changing:=true;line:=otherline; +loc:=changelimit;begin writeln(termout); +write(termout,'! Change file entry did not match');error;end;end{:138}; +phaseone:=false;{:183};{for ii:=0 to 2 do maxtokptr[ii]:=tokptr[ii];} +{112:}if textlink[0]=0 then begin begin writeln(termout); +write(termout,'! No output was specified.');end; +if history=0 then history:=1;end else begin begin writeln(termout); +write(termout,'Writing the output file');end;{break(termout);}{83:} +stackptr:=1;bracelevel:=0;curstate.namefield:=0; +curstate.replfield:=textlink[0];zo:=curstate.replfield mod 3; +curstate.bytefield:=tokstart[curstate.replfield]; +curstate.endfield:=tokstart[curstate.replfield+3];curstate.modfield:=0; +{:83};{96:}outstate:=0;outptr:=0;breakptr:=0;semiptr:=0;outbuf[0]:=0; +line:=1;{:96};sendtheoutput;{98:}breakptr:=outptr;semiptr:=0; +flushbuffer;if bracelevel<>0 then begin writeln(termout); +write(termout,'! Program ended at brace level ',bracelevel:1);error;end; +{:98};begin writeln(termout);write(termout,'Done.');end;end{:112}; +9999:if stringptr>256 then{184:}begin begin writeln(termout); +write(termout,stringptr-256:1,' strings written to string pool file.'); +end;write(pool,'*'); +for ii:=1 to 9 do begin outbuf[ii]:=poolchecksum mod 10; +poolchecksum:=poolchecksum div 10;end; +for ii:=9 downto 1 do write(pool,xchr[48+outbuf[ii]]);writeln(pool); +end{:184};{[186:]begin writeln(termout); +write(termout,'Memory usage statistics:');end;begin writeln(termout); +write(termout,nameptr:1,' names, ',textptr:1,' replacement texts;');end; +begin writeln(termout);write(termout,byteptr[0]:1);end; +for wo:=1 to 1 do write(termout,'+',byteptr[wo]:1); +if phaseone then for ii:=0 to 2 do maxtokptr[ii]:=tokptr[ii]; +write(termout,' bytes, ',maxtokptr[0]:1); +for ii:=1 to 2 do write(termout,'+',maxtokptr[ii]:1); +write(termout,' tokens.');[:186];}{187:} +case history of 0:begin writeln(termout); +write(termout,'(No errors were found.)');end;1:begin writeln(termout); +write(termout,'(Did you see the warning message above?)');end; +2:begin writeln(termout); +write(termout,'(Pardon me, but I think I spotted something wrong.)'); +end;3:begin writeln(termout); +write(termout,'(That was a fatal error, my friend.)');end;end{:187}; +end.{:182} diff --git a/upstream/build/tex/tex.ch b/upstream/build/tex/tex.ch new file mode 100644 index 0000000..d39a89c --- /dev/null +++ b/upstream/build/tex/tex.ch @@ -0,0 +1,687 @@ +% Change file for GNU Pascal and Linux +% (by Don Knuth, 2000; see ../tex-sparc for the prehistory) +% (I'm no longer keeping the "efficiency" changes; just enuf for TRIP test) +% +% Use this file as is to make an INITEX. To get triptex, use the +% shell script ``ini_to_trip'' and re-TANGLE. + +% History: +% 2000.04.30 first sketch --- untested --- see FIXTHIS for parts not done yet + +% NOTE: the module numbers in this change file refer to Volume B. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [0] WEAVE: only print changes +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +\def\botofcontents{\vskip 0pt plus 1fil minus 1.5in} +@y +\def\botofcontents{\vskip 0pt plus 1fil minus 1.5in} +\let\maybe=\iffalse +\def\title{\TeX82 changes for GNU Pascal} +\def\glob{13}\def\gglob{20, 26} % these are defined in module 1 +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1.2] banner line +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d banner=='This is TeX, Version 3.14159' {printed when \TeX\ starts} +@y +@d banner=='This is TeX, Version 3.14159 for Java' {printed when \TeX\ starts} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1.7] debug..gubed, stat..tats +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d debug==@{ {change this to `$\\{debug}\equiv\null$' when debugging} +@d gubed==@t@>@} {change this to `$\\{gubed}\equiv\null$' when debugging} +@y +@d debug==@{ {the trip test will use debugging} +@d gubed==@t@>@} +@z +@x +@d stat==@{ {change this to `$\\{stat}\equiv\null$' when gathering + usage statistics} +@d tats==@t@>@} {change this to `$\\{tats}\equiv\null$' when gathering + usage statistics} +@y +@d stat== +@d tats== +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1.8] init..tini +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d init== {change this to `$\\{init}\equiv\.{@@\{}$' in the production version} +@d tini== {change this to `$\\{tini}\equiv\.{@@\}}$' in the production version} +@y +@d init== +@d tini== +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1.10] othercases, feature of ISO Extended Pascal +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d othercases == others: {default for cases not listed explicitly} +@y +@d othercases == otherwise {default for cases not listed explicitly} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1.11] compile-time constants +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@!mem_max=30000; {greatest index in \TeX's internal |mem| array; + must be strictly less than |max_halfword|; + must be equal to |mem_top| in \.{INITEX}, otherwise |>=mem_top|} +@!mem_min=0; {smallest index in \TeX's internal |mem| array; + must be |min_halfword| or more; + must be equal to |mem_bot| in \.{INITEX}, otherwise |<=mem_bot|} +@!buf_size=500; {maximum number of characters simultaneously present in + current lines of open files and in control sequences between + \.{\\csname} and \.{\\endcsname}; must not exceed |max_halfword|} +@!error_line=72; {width of context lines on terminal error messages} +@!half_error_line=42; {width of first lines of contexts in terminal + error messages; should be between 30 and |error_line-15|} +@!max_print_line=79; {width of longest text lines output; should be at least 60} +@!stack_size=200; {maximum number of simultaneous input sources} +@!max_in_open=6; {maximum number of input files and error insertions that + can be going on simultaneously} +@!font_max=75; {maximum internal font number; must not exceed |max_quarterword| + and must be at most |font_base+256|} +@!font_mem_size=20000; {number of words of |font_info| for all fonts} +@!param_size=60; {maximum number of simultaneous macro parameters} +@!nest_size=40; {maximum number of semantic levels simultaneously active} +@!max_strings=3000; {maximum number of strings; must not exceed |max_halfword|} +@!string_vacancies=8000; {the minimum number of characters that should be + available for the user's control sequences and font names, + after \TeX's own error messages are stored} +@!pool_size=32000; {maximum number of characters in strings, including all + error messages and help texts, and the names of all fonts and + control sequences; must exceed |string_vacancies| by the total + length of \TeX's own strings, which is currently about 23000} +@!save_size=600; {space for saving values outside of current group; must be + at most |max_halfword|} +@!trie_size=8000; {space for hyphenation patterns; should be larger for + \.{INITEX} than it is in production versions of \TeX} +@!trie_op_size=500; {space for ``opcodes'' in the hyphenation patterns} +@!dvi_buf_size=800; {size of the output buffer; must be a multiple of 8} +@!file_name_size=40; {file names shouldn't be longer than this} +@!pool_name='TeXformats:TEX.POOL '; + {string of length |file_name_size|; tells where the string pool appears} +@y +@!mem_max=300000; {greatest index in \TeX's internal |mem| array; + must be strictly less than |max_halfword|; + must be equal to |mem_top| in \.{INITEX}, otherwise |>=mem_top|} +@!mem_min=0; {smallest index in \TeX's internal |mem| array; + must be |min_halfword| or more; + must be equal to |mem_bot| in \.{INITEX}, otherwise |<=mem_bot|} +@!buf_size=5000; {maximum number of characters simultaneously present in + current lines of open files and in control sequences between + \.{\\csname} and \.{\\endcsname}; must not exceed |max_halfword|} +@!error_line=79; {width of context lines on terminal error messages} +@!half_error_line=50; {width of first lines of contexts in terminal + error messages; should be between 30 and |error_line-15|} +@!max_print_line=79; {width of longest text lines output; should be at least 60} +@!stack_size=200; {maximum number of simultaneous input sources} +@!max_in_open=15; {maximum number of input files and error insertions that + can be going on simultaneously} +@!font_max=127; {maximum internal font number; must not exceed |max_quarterword| + and must be at most |font_base+256|} +@!font_mem_size=40000; {number of words of |font_info| for all fonts} +@!param_size=60; {maximum number of simultaneous macro parameters} +@!nest_size=40; {maximum number of semantic levels simultaneously active} +@!max_strings=30000; {maximum number of strings; must not exceed |max_halfword|} +@!string_vacancies=8000; {the minimum number of characters that should be + available for the user's control sequences and font names, + after \TeX's own error messages are stored} +@!pool_size=100000; {maximum number of characters in strings, including all + error messages and help texts, and the names of all fonts and + control sequences; must exceed |string_vacancies| by the total + length of \TeX's own strings, which is currently about 23000} +@!save_size=6000; {space for saving values outside of current group; must be + at most |max_halfword|} +@!trie_size=30000; {space for hyphenation patterns; should be larger for + \.{INITEX} than it is in production versions of \TeX} +@!trie_op_size=500; {space for ``opcodes'' in the hyphenation patterns} +@!dvi_buf_size=800; {size of the output buffer; must be a multiple of 8} +@!file_name_size=1024; {file names shouldn't be longer than this} +@!pool_name='tex.pool'; + {string of length |file_name_size|; the string pool name} +@.TeXformats@> +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [1.12] sensitive compile-time constants +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d mem_bot=0 {smallest index in the |mem| array dumped by \.{INITEX}; + must not be less than |mem_min|} +@d mem_top==30000 {largest index in the |mem| array dumped by \.{INITEX}; + must be substantially larger than |mem_bot| + and not greater than |mem_max|} +@d font_base=0 {smallest internal font number; must not be less + than |min_quarterword|} +@d hash_size=2100 {maximum number of control sequences; it should be at most + about |(mem_max-mem_min)/10|} +@d hash_prime=1777 {a prime number equal to about 85\pct! of |hash_size|} +@d hyph_size=307 {another prime; the number of \.{\\hyphenation} exceptions} +@y +@d mem_bot=0 {smallest index in the |mem| array dumped by \.{INITEX}; + must not be less than |mem_min|} +@d mem_top==300000 {largest index in the |mem| array dumped by \.{INITEX}; + must be substantially larger than |mem_bot| + and not greater than |mem_max|} +@d font_base=0 {smallest internal font number; must not be less + than |min_quarterword|} +@d hash_size=10000 {maximum number of control sequences; it should be at most + about |(mem_max-mem_min)/10|} +@d hash_prime=3443 {a prime number equal to about 85\pct! of |hash_size|} +@d hyph_size=307 {another prime; the number of \.{\\hyphenation} exceptions} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [2.23] allow any character that we can input to get in +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +for i:=0 to @'37 do xchr[i]:=' '; +for i:=@'177 to @'377 do xchr[i]:=' '; +@y +for i:=0 to @'37 do xchr[i]:=chr(i); +for i:=@'177 to @'377 do xchr[i]:=chr(i); +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [3.25] file types +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@!eight_bits=0..255; {unsigned one-byte quantity} +@!alpha_file=packed file of text_char; {files that contain textual data} +@y +@!eight_bits=ByteCard; {unsigned one-byte quantity} +@!alpha_file=t@&e@&x@&t; {files that contain textual data} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [3.27] file opening +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@ The \ph\ compiler with which the present version of \TeX\ was prepared has +extended the rules of \PASCAL\ in a very convenient way. To open file~|f|, +we can write +$$\vbox{\halign{#\hfil\qquad&#\hfil\cr +|reset(f,@t\\{name}@>,'/O')|&for input;\cr +|rewrite(f,@t\\{name}@>,'/O')|&for output.\cr}}$$ +The `\\{name}' parameter, which is of type `{\bf packed array +$[\langle\\{any}\rangle]$ of \\{char}}', stands for the name of +the external file that is being opened for input or output. +Blank spaces that might appear in \\{name} are ignored. + +The `\.{/O}' parameter tells the operating system not to issue its own +error messages if something goes wrong. If a file of the specified name +cannot be found, or if such a file cannot be opened for some other reason +(e.g., someone may already be trying to write the same file), we will have +|@!erstat(f)<>0| after an unsuccessful |reset| or |rewrite|. This allows +\TeX\ to undertake appropriate corrective action. +@:PASCAL H}{\ph@> +@^system dependencies@> + +\TeX's file-opening procedures return |false| if no file identified by +|name_of_file| could be opened. + +@d reset_OK(#)==erstat(#)=0 +@d rewrite_OK(#)==erstat(#)=0 + +@p function a_open_in(var f:alpha_file):boolean; + {open a text file for input} +begin reset(f,name_of_file,'/O'); a_open_in:=reset_OK(f); +end; +@# +function a_open_out(var f:alpha_file):boolean; + {open a text file for output} +begin rewrite(f,name_of_file,'/O'); a_open_out:=rewrite_OK(f); +end; +@# +function b_open_in(var f:byte_file):boolean; + {open a binary file for input} +begin reset(f,name_of_file,'/O'); b_open_in:=reset_OK(f); +end; +@# +function b_open_out(var f:byte_file):boolean; + {open a binary file for output} +begin rewrite(f,name_of_file,'/O'); b_open_out:=rewrite_OK(f); +end; +@# +function w_open_in(var f:word_file):boolean; + {open a word file for input} +begin reset(f,name_of_file,'/O'); w_open_in:=reset_OK(f); +end; +@# +function w_open_out(var f:word_file):boolean; + {open a word file for output} +begin rewrite(f,name_of_file,'/O'); w_open_out:=rewrite_OK(f); +end; +@y +@ An external C procedure, |test_access| is used to check whether or not the +open will work. It is declared in the ``ext.h'' include file, and it returns +|true| or |false|. The |name_of_file| global holds the file name whose access +is to be tested. +The first parameter for |test_access| is the access mode, +one of |read_access_mode| or |write_access_mode|. + +We also implement path searching in |test_access|: its second parameter is +one of the ``file path'' constants defined below. If |name_of_file| +doesn't start with |'/'| then |test_access| tries prepending pathnames +from the appropriate path list until success or the end of path list +is reached. +On return, |name_of_file| contains the original name with the path +that succeeded (if any) prepended. It is the name used in the various +open procedures. + +Note that |a_open_in| has been redefined to take an additional argument, +which should be one of the ``file path'' specifiers. +Since |b_open_in| is only used for \.{TFM} files, and +|w_open_in| is only used for format files, we don't need a path specifying +argument for them. +Path searching is not done for output files. + +@d read_access_mode=4 {``read'' mode for |test_access|} +@d write_access_mode=2 {``write'' mode for |test_access|} + +@d no_file_path=0 {no path searching should be done} +@d input_file_path=1 {path specifier for \.{\\input} files} +@d read_file_path=2 {path specifier for \.{\\read} files} +@d font_file_path=3 {path specifier for \.{TFM} files} +@d format_file_path=4 {path specifier for format files} +@d pool_file_path=5 {path specifier for the pool file} + +@p function a_open_in(var f:alpha_file):boolean; + {open a text file for input} +begin reset(f,name_of_file); a_open_in:=IOResult=0; +end; + + + +@# +function a_open_out(var f:alpha_file):boolean; + {open a text file for output} +var @!ok:boolean; +begin + rewrite(f,name_of_file); +a_open_out:=true; +end; +@# +function b_open_in(var f:byte_file):boolean; + {open a binary file for input} +var @!ok:boolean; +begin + reset(f,name_of_file); +b_open_in:=true; +end; +@# +function b_open_out(var f:byte_file):boolean; + {open a binary file for output} +var @!ok:boolean; +begin + rewrite(f,name_of_file); +b_open_out:=true; +end; +@# +function w_open_in(var f:word_file):boolean; + {open a word file for input} +var @!ok:boolean; +begin + reset(f,name_of_file); +w_open_in:=true; +end; +@# +function w_open_out(var f:word_file):boolean; + {open a word file for output} +var @!ok:boolean; +begin + rewrite(f,name_of_file); +w_open_out:=true; +end; +@z + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [3.32] term_in/out are input,output +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@!term_in:alpha_file; {the terminal as an input file} +@!term_out:alpha_file; {the terminal as an output file} + +@y +@!{the terminal as an input file} + +@z + +@x +@d t_open_in==reset(term_in,'TTY:','/O/I') {open the terminal for text input} +@d t_open_out==rewrite(term_out,'TTY:','/O') {open the terminal for text output} +@y +@d term_in==Input +@d term_out==Output +@d t_open_in==do_nothing +@d t_open_out==do_nothing +@z + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [3.34] flushing output +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +these operations can be specified in \ph: +@^system dependencies@> + +@d update_terminal == break(term_out) {empty the terminal output buffer} +@d clear_terminal == break_in(term_in,true) {clear the terminal input buffer} +@d wake_up_terminal == do_nothing {cancel the user's cancellation of output} +@y +these operations can be specified with Berkeley {\mc UNIX}: +@^system dependencies@> + +@d update_terminal == {nothing necessary on UNIX} +@d clear_terminal == {nothing necessary on UNIX} +@d wake_up_terminal == {nothing necessary on UNIX} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [4.38] string data +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@!packed_ASCII_code = 0..255; {elements of |str_pool| array} +@y +@!packed_ASCII_code = ByteCard; {elements of |str_pool| array} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [4.51,52,53] make TEX.POOL lowercase in messages +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +else bad_pool('! I can''t read TEX.POOL.') +@y +else bad_pool('! I can''t read tex.pool.') +@z +@x +begin if eof(pool_file) then bad_pool('! TEX.POOL has no check sum.'); +@y +begin if eof(pool_file) then bad_pool('! tex.pool has no check sum.'); +@z +@x + bad_pool('! TEX.POOL line doesn''t begin with two digits.'); +@y + bad_pool('! tex.pool line doesn''t begin with two digits.'); +@z +@x + bad_pool('! TEX.POOL check sum doesn''t have nine digits.'); +@y + bad_pool('! tex.pool check sum doesn''t have nine digits.'); +@z +@x +done: if a<>@$ then bad_pool('! TEX.POOL doesn''t match; TANGLE me again.'); +@y +done: if a<>@$ then bad_pool('! tex.pool doesn''t match; tangle me again.'); +@z + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [8.110] ranges for quarter,half words FIXTHIS +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d min_quarterword=0 {smallest allowable value in a |quarterword|} +@d max_quarterword=255 {largest allowable value in a |quarterword|} +@d min_halfword==0 {smallest allowable value in a |halfword|} +@d max_halfword==65535 {largest allowable value in a |halfword|} +@y +@d min_quarterword=-128 {smallest allowable value in a |quarterword|} +@d max_quarterword=127 {largest allowable value in a |quarterword|} +@d min_halfword==-2147483648 {smallest allowable value in a |halfword|} +@d max_halfword==2147483647 {largest allowable value in a |halfword|} +@z + +@x +@= +@!quarterword = min_quarterword..max_quarterword; {1/4 of a word} +@!halfword=min_halfword..max_halfword; {1/2 of a word} +@!two_choices = 1..2; {used when there are two variants in a record} +@!four_choices = 1..4; {used when there are four variants in a record} +@y +@= +@!quarterword = min_quarterword..max_quarterword; {1/4 of a word} +@!halfword=min_halfword..max_halfword; {1/2 of a word} +@!two_choices = 1..2; {used when there are two variants in a record} +@!four_choices = 1..4; {used when there are four variants in a record} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [11.165] fix the word "free" so that it doesn't conflict with a runtime proc +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +been included. (You may want to decrease the size of |mem| while you +@^debugging@> +are debugging.) +@y +been included. (You may want to decrease the size of |mem| while you +@^debugging@> +are debugging.) + +@d free==free_arr +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [12.186] glue_ratio fix FIXTHIS +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +floating point underflow on the author's computer. +@^system dependencies@> +@^dirty \PASCAL@> + +@= +g:=float(glue_set(p)); +if (g<>float_constant(0))and(glue_sign(p)<>normal) then + begin print(", glue set "); + if glue_sign(p)=shrinking then print("- "); + if abs(mem[p+glue_offset].int)<@'4000000 then print("?.?") + else if abs(g)>float_constant(20000) then + begin if g>float_constant(0) then print_char(">") + else print("< -"); + print_glue(20000*unity,glue_order(p),0); + end + else print_glue(round(unity*g),glue_order(p),0); +@^real multiplication@> + end +@y +floating point underflow on the author's computer. +For the {\mc VAX}, the only possible random value that could hurt is +a reserved value with 1 in the sign bit and 0 for the (excess) exponent. +Because the sign-plus-exponent is in the middle of the word, the chances +of this happening are miniscule, and ignored here. +@^system dependencies@> +@^dirty \PASCAL@> + +@= +g:=float(glue_set(p)); +if (g<>float_constant(0))and(glue_sign(p)<>normal) then + begin print(", glue set "); + if glue_sign(p)=shrinking then print("- "); + if abs(float(glue_set(p)))>20000.0 then + begin if float(glue_set(p))>0 then print_char(">") + else print("< -"); + print_glue(20000*unity,glue_order(p),0); + end + else print_glue(round(float(glue_set(p))*unity),glue_order(p),0); +@^real multiplication@> + end +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.513] area and extension rules +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@ The file names we shall deal with for illustrative purposes have the +following structure: If the name contains `\.>' or `\.:', the file area +consists of all characters up to and including the final such character; +otherwise the file area is null. If the remaining file name contains +`\..', the file extension consists of all such characters from the first +remaining `\..' to the end, otherwise the file extension is null. +@^system dependencies@> + +We can scan such file names easily by using two global variables that keep track +of the occurrences of area and extension delimiters: + +@= +@!area_delimiter:pool_pointer; {the most recent `\.>' or `\.:', if any} +@!ext_delimiter:pool_pointer; {the relevant `\..', if any} +@y +@ The file names we shall deal with for SunOS have the +following structure: If the name contains `\./', the file area +consists of all characters up to and including the final such character; +otherwise the file area is null. If the remaining file name contains +`\..', the file extension consists of all such characters from the first +remaining `\..' to the end, otherwise the file extension is null. +@^system dependencies@> + +We can scan such file names easily by using two global variables that keep +track of the occurrences of area and extension delimiters: + +@= +@!area_delimiter:pool_pointer; {the most recent `\./', if any} +@!ext_delimiter:pool_pointer; {the most recent `\..', if any} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.516] more_name +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x + if (c=">")or(c=":") then +@y + if c="/" then +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.520] default format +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +@d format_default_length=20 {length of the |TEX_format_default| string} +@d format_area_length=11 {length of its area part} +@d format_ext_length=4 {length of its `\.{.fmt}' part} +@y +Under Linux we don't give the area part, instead depending +on the path searching that will happen during file opening. + +@d format_default_length=9 {length of the |TEX_format_default| string} +@d format_area_length=0 {length of its area part} +@d format_ext_length=4 {length of its `\.{.fmt}' part} +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.521] plain format location +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +TEX_format_default:='TeXformats:plain.fmt'; +@y +TEX_format_default:='plain.fmt'; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.524] format file opening: only try once, with path search +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x + pack_buffered_name(0,loc,j-1); {try first without the system file area} + if w_open_in(fmt_file) then goto found; + pack_buffered_name(format_area_length,loc,j-1); + {now try the system format file area} + if w_open_in(fmt_file) then goto found; +@y + pack_buffered_name(0,loc,j-1); + if w_open_in(fmt_file) then goto found; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [29.525] make_name_string +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +@x +which simply makes a \TeX\ string from the value of |name_of_file|, should +ideally be changed to deduce the full name of file~|f|, which is the file +most recently opened, if it is possible to do this in a \PASCAL\ program. +@^system dependencies@> + +This routine might be called after string memory has overflowed, hence +we dare not use `|str_room|'. + +@p function make_name_string:str_number; +var k:1..file_name_size; {index into |name_of_file|} +begin if (pool_ptr+name_length>pool_size)or(str_ptr=max_strings)or + (cur_length>0) then + make_name_string:="?" +else begin for k:=1 to name_length do append_char(xord[name_of_file[k]]); + make_name_string:=make_string; + end; +end; +@y +which simply makes a \TeX\ string from the value of |name_of_file|, should +ideally be changed to deduce the full name of file~|f|, which is the file +most recently opened, if it is possible to do this in a \PASCAL\ program. +With the Berkeley {\mc UNIX} version, we know that |name_of_file| +contains |name_of_file| prepended with the directory name that was found +by path searching. +If |name_of_file| starts with |'./'|, we don't use that part of the +name, since {\mc UNIX} users understand that. +@^system dependencies@> + +This routine might be called after string memory has overflowed, hence +we dare not use `|str_room|'. + +@p function make_name_string:str_number; +var k,@!kstart:1..file_name_size; {index into |name_of_file|} +begin +k:=1; +while (k" ") do + incr(k); +name_length:=k-1; {the real |name_length|} +if (pool_ptr+name_length>pool_size)or(str_ptr=max_strings)or + (cur_length>0) then + make_name_string:="?" +else begin + if (xord[name_of_file[1]]=".") and (xord[name_of_file[2]]="/") then + kstart:=3 + else + kstart:=1; + for k:=kstart to name_length do append_char(xord[name_of_file[k]]); + make_name_string:=make_string; + end +end; +@z + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% [30.563] opening tfm file: now path searching is done +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Set temp_int to value of first byte +@x +@ @= +file_opened:=false; +if aire="" then pack_file_name(nom,TEX_font_area,".tfm") +else pack_file_name(nom,aire,".tfm"); +if not b_open_in(tfm_file) then abort; +file_opened:=true +@y +@ Here we have to ``prime the pump'' for the |temp_int| trick explained below. + + @= +file_opened:=false; +pack_file_name(nom,aire,".tfm"); +if not b_open_in(tfm_file) then abort; +begin + var temp_int:integer; + temp_int:=tfm_file^; + if temp_int<0 then temp_int:=temp_int+256; +end; +file_opened:=true +@z + -- 1.7.10.4 From 1684a8aef368fc7b18842ef548c6bda6618c56aa Mon Sep 17 00:00:00 2001 From: adam Date: Fri, 14 May 2004 01:12:07 -0700 Subject: [PATCH 08/16] remove pdftex-specific stuff from paper darcs-hash:20040514081207-5007d-4849ad0df552aea1bd264e58ec1383c713ab9ebf.gz --- doc/ivme04.tex | 84 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/doc/ivme04.tex b/doc/ivme04.tex index c9ea61d..13500be 100644 --- a/doc/ivme04.tex +++ b/doc/ivme04.tex @@ -5,11 +5,11 @@ \sloppy \usepackage{palatino} \usepackage{url} -\usepackage{pdftricks} -\begin{psinputs} - \usepackage{pstricks} - \usepackage{pst-node} -\end{psinputs} +%\usepackage{pdftricks} +%\begin{psinputs} +\usepackage{pstricks} +\usepackage{pst-node} +%\end{psinputs} \usepackage{parskip} \usepackage{tabularx} \usepackage{alltt} @@ -122,7 +122,7 @@ The four program representations of interest in this context, along with their specific types in the C-to-JVM instantiation of the problem are shown in the following diagram: -\begin{pdfpic} +%\begin{pdfpic} \newlength{\MyLength} \settowidth{\MyLength}{machine code} \newcommand{\MyBox}[1]{\makebox[\MyLength][c]{#1}} @@ -138,15 +138,15 @@ problem are shown in the following diagram: & \\[0pt] \psset{nodesep=5pt,arrows=->} \end{psmatrix} -\end{pdfpic} +%\end{pdfpic} To illustrate the context of this diagram, the following arcs show the translations performed by a few familiar tools: -\begin{pdfpic} -\newlength{\MyLength} -\settowidth{\MyLength}{xmachine codex} -\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}} +%\begin{pdfpic} +%\newlength{\MyLength} +%\settowidth{\MyLength}{xmachine codex} +%\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}} \psmatrix[colsep=2,rowsep=0,nrot=:D] & \\[0pt] [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt] @@ -163,7 +163,7 @@ translations performed by a few familiar tools: \ncline{s1}{b1}\aput{:U}{\tt javac} \ncline{b1}{b0}\aput{:D}{\tt gcj}\bput{:D}{JITs} \endpsmatrix -\end{pdfpic} +%\end{pdfpic} Existing techniques for translating unsafe code into VM bytecode generally fall into two categories, which we expand upon in the @@ -175,10 +175,10 @@ source-to-binary translation. The most common technique employed is partial translation from unsafe source code to safe source code: -\begin{pdfpic} -\newlength{\MyLength} -\settowidth{\MyLength}{xmachine codex} -\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}} +%\begin{pdfpic} +%\newlength{\MyLength} +%\settowidth{\MyLength}{xmachine codex} +%\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}} \psmatrix[colsep=2,rowsep=0,nrot=:U] & \\[0pt] & \\[0pt] @@ -194,7 +194,7 @@ source code to safe source code: \ncline{s0}{s1}\aput{:U}{source-to}\bput{:U}{source} \ncline{s1}{b1}\aput{:U}{\tt javac} \endpsmatrix -\end{pdfpic} +%\end{pdfpic} A number of existing systems employ this technique; they can be divided into two categories: those which perform a partial @@ -255,10 +255,10 @@ process. Source-to-binary translation involves a compiler for the unsafe language which has been modified to emit safe bytecode. -\begin{pdfpic} -\newlength{\MyLength} -\settowidth{\MyLength}{xmachine codex} -\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}} +%\begin{pdfpic} +%\newlength{\MyLength} +%\settowidth{\MyLength}{xmachine codex} +%\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}} \psmatrix[colsep=2,rowsep=0,nrot=:U] & \\[0pt] [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt] @@ -272,7 +272,7 @@ language which has been modified to emit safe bytecode. \psset{nodesep=5pt,arrows=->} \ncline{s0}{b1}\bput{:U}{source-to-binary} \endpsmatrix -\end{pdfpic} +%\end{pdfpic} An experimental ``JVM backend'' for the {\tt gcc} compiler, known as {\tt egcs-jvm} \cite{egcsjvm}, attempts this approach. Since {\tt @@ -382,7 +382,7 @@ carry a performance penalty on physical MIPS implementations. Our choice of a paged representation for memory carries only a small performance disadvantage: -\epsfig{file=charts/chart5,width=3in} +\epsfig{file=charts/chart5,height=2.7in,angle=-90} Additionally, this representation lets us to take advantage of the fact that on most JVM's, checking for a {\tt NullPointerException} @@ -437,10 +437,10 @@ translation. In this mode, NestedVM translates MIPS binaries into Java source code, which is then fed to a Java compiler in order to produce bytecode files: -\begin{pdfpic} -\newlength{\MyLength} -\settowidth{\MyLength}{xmachine codex} -\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}} +%\begin{pdfpic} +%\newlength{\MyLength} +%\settowidth{\MyLength}{xmachine codex} +%\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}} \psmatrix[colsep=2,rowsep=0,nrot=:U] & \\[0pt] & \\[0pt] @@ -456,7 +456,7 @@ produce bytecode files: \ncline{s1}{b1}\aput{:U}{\tt javac} \ncline{b0}{s1}\naput{\tt NestedVM} \endpsmatrix -\end{pdfpic} +%\end{pdfpic} \begin{figure*}[t] \begin{minipage}[c]{7in}% @@ -539,10 +539,10 @@ Translating unsafe code for use within a JVM proceeds as follows: After implementing the binary-to-source compiler, a binary-to-binary translation mode was added. -\begin{pdfpic} -\newlength{\MyLength} -\settowidth{\MyLength}{xmachine codex} -\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}} +%\begin{pdfpic} +%\newlength{\MyLength} +%\settowidth{\MyLength}{xmachine codex} +%\newcommand{\MyBox}[1]{\makebox[\MyLength]{#1}} \psmatrix[colsep=2,rowsep=0,nrot=:U] & \\[0pt] [name=s0]\MyBox{unsafe source} & [name=s1]\MyBox{safe source} \\[0pt] @@ -557,7 +557,7 @@ translation mode was added. \ncline{s0}{b0}\bput{:U}{\tt gcc} \ncline{b0}{b1}\naput{\tt NestedVM} \endpsmatrix -\end{pdfpic} +%\end{pdfpic} This mode has several advantages: @@ -707,7 +707,7 @@ local variables for registers did not offer much of a performance advantage, presumably since the JVM's JIT is intelligent enough to register-allocate temporaries for fields. -\epsfig{file=charts/chart4,width=3in} +\epsfig{file=charts/chart4,height=2.7in,angle=-90} Unfortunately, Java imposes a 64kb limit on the size of the bytecode for a single method. This presents a problem for NestedVM, and @@ -752,7 +752,7 @@ methods invoked from the trampoline. Trial and error led to the conclusion that HotSpot \cite{hotspot} -- the most widely deployed JVM -- performs best when 128 MIPS instructions are mapped to each method. -\epsfig{file=charts/chart1,width=3in} +\epsfig{file=charts/chart1,height=2.7in,angle=-90} This phenomenon is due to two factors: @@ -832,7 +832,7 @@ file) eliminates this problem entirely. Compiling directly to bytecode offers a substantial performance gain: -\epsfig{file=charts/chart3,width=3in} +\epsfig{file=charts/chart3,height=2.7in,angle=-90} Most of this improvement comes from the handling of branch instructions and from taking advantage of the JVM stack to eliminate @@ -918,7 +918,7 @@ case} arm shrinks by one instruction. The net result is quite reasonably sized {\tt .class} files: -\epsfig{file=charts/chart9,width=3in} +\epsfig{file=charts/chart9,height=2.7in,angle=-90} \subsection{Compiler Flags} @@ -981,7 +981,7 @@ source-to-MIPS compiler: The following chart quantifies the performance gain conferred by each of the major optimizations outlined in this section: -\epsfig{file=charts/chart10,width=3in} +\epsfig{file=charts/chart10,height=2.7in,angle=-90} @@ -1000,11 +1000,11 @@ and {\tt verdan32.exe}. The {\tt libfreetype} test consisted of rendering ASCII characters 32-127 of {\tt Comic.TTF} at sizes from 8 to 48 incrementing by 4 for a total of 950 glyphs. -\epsfig{file=charts/chart8,width=3in} +\epsfig{file=charts/chart8,height=2.7in,angle=-90} -\epsfig{file=charts/chart7,width=3in} +\epsfig{file=charts/chart7,height=2.7in,angle=-90} -\epsfig{file=charts/chart6,width=3in} +\epsfig{file=charts/chart6,height=2.7in,angle=-90} \section{Sample Applications} @@ -1069,7 +1069,7 @@ for checking the ``cpu time'' of a process. Unfortunately we had to substitute wall-clock time on an otherwise-quiescent machine as an approximation. -\epsfig{file=charts/chart11,width=3in} +\epsfig{file=charts/chart11,height=2.7in,angle=-90} -- 1.7.10.4 From 68323ce26509ae9876f8dcf3e52e0e8de64983f8 Mon Sep 17 00:00:00 2001 From: adam Date: Fri, 14 May 2004 01:12:52 -0700 Subject: [PATCH 09/16] add fancy NesTeX banner to TeX darcs-hash:20040514081252-5007d-3cce20d3a4df8805b668a08361b3d7d51745dbd9.gz --- upstream/build/tex/tex.ch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/upstream/build/tex/tex.ch b/upstream/build/tex/tex.ch index d39a89c..841f8e9 100644 --- a/upstream/build/tex/tex.ch +++ b/upstream/build/tex/tex.ch @@ -28,7 +28,7 @@ @x @d banner=='This is TeX, Version 3.14159' {printed when \TeX\ starts} @y -@d banner=='This is TeX, Version 3.14159 for Java' {printed when \TeX\ starts} +@d banner=='This is '#27'[33;1mNesTeX'#27'[0m, Version 3.14159 for '#27'[31;1mJava'#27'[0m' @z %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- 1.7.10.4 From 67d59e4b183264e377e0350a85e98d7ca8c33bac Mon Sep 17 00:00:00 2001 From: adam Date: Fri, 14 May 2004 01:13:07 -0700 Subject: [PATCH 10/16] filename trimming for TeX darcs-hash:20040514081307-5007d-a1ffa920f9c63362975b93960739018ba9797f19.gz --- upstream/build/tex/tex.ch | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/upstream/build/tex/tex.ch b/upstream/build/tex/tex.ch index 841f8e9..0a2fe05 100644 --- a/upstream/build/tex/tex.ch +++ b/upstream/build/tex/tex.ch @@ -268,17 +268,17 @@ end; @y @ An external C procedure, |test_access| is used to check whether or not the open will work. It is declared in the ``ext.h'' include file, and it returns -|true| or |false|. The |name_of_file| global holds the file name whose access +|true| or |false|. The |Trim(name_of_file)| global holds the file name whose access is to be tested. The first parameter for |test_access| is the access mode, one of |read_access_mode| or |write_access_mode|. We also implement path searching in |test_access|: its second parameter is -one of the ``file path'' constants defined below. If |name_of_file| +one of the ``file path'' constants defined below. If |Trim(name_of_file)| doesn't start with |'/'| then |test_access| tries prepending pathnames from the appropriate path list until success or the end of path list is reached. -On return, |name_of_file| contains the original name with the path +On return, |Trim(name_of_file)| contains the original name with the path that succeeded (if any) prepended. It is the name used in the various open procedures. @@ -301,7 +301,10 @@ Path searching is not done for output files. @p function a_open_in(var f:alpha_file):boolean; {open a text file for input} -begin reset(f,name_of_file); a_open_in:=IOResult=0; +var str:String; +begin +reset(f,name_of_file); +a_open_in:=IOResult=0; end; @@ -311,7 +314,7 @@ function a_open_out(var f:alpha_file):boolean; {open a text file for output} var @!ok:boolean; begin - rewrite(f,name_of_file); + rewrite(f,Trim(name_of_file)); a_open_out:=true; end; @# @@ -319,7 +322,7 @@ function b_open_in(var f:byte_file):boolean; {open a binary file for input} var @!ok:boolean; begin - reset(f,name_of_file); + reset(f,Trim(name_of_file)); b_open_in:=true; end; @# @@ -327,7 +330,7 @@ function b_open_out(var f:byte_file):boolean; {open a binary file for output} var @!ok:boolean; begin - rewrite(f,name_of_file); + rewrite(f,Trim(name_of_file)); b_open_out:=true; end; @# @@ -335,7 +338,7 @@ function w_open_in(var f:word_file):boolean; {open a word file for input} var @!ok:boolean; begin - reset(f,name_of_file); + reset(f,Trim(name_of_file)); w_open_in:=true; end; @# @@ -343,7 +346,7 @@ function w_open_out(var f:word_file):boolean; {open a word file for output} var @!ok:boolean; begin - rewrite(f,name_of_file); + rewrite(f,Trim(name_of_file)); w_open_out:=true; end; @z -- 1.7.10.4 From 1559c0f40ba4ce4d6eb544cd1593beb60a0f49b2 Mon Sep 17 00:00:00 2001 From: adam Date: Fri, 14 May 2004 01:13:24 -0700 Subject: [PATCH 11/16] build TeX, use it to compile paper darcs-hash:20040514081324-5007d-4918c0201775abb4a694161822997616c4e34519.gz --- Makefile | 13 ++++++++++--- upstream/Makefile | 40 +++++++++++++++++++++------------------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 2cabf44..c744751 100644 --- a/Makefile +++ b/Makefile @@ -173,7 +173,7 @@ env.sh: Makefile $(tasks)/full_toolchain build/org/ibex/nestedvm/Compiler.class runtime_classes = Runtime Registers UsermodeConstants util/Seekable -tex.jar: $(runtime_classes:%=build/org/ibex/nestedvm/%.class) upstream/tasks/build_tex +tex.jar: $(mips_objects) $(runtime_classes:%=build/org/ibex/nestedvm/%.class) upstream/tasks/build_tex echo -e "Manifest-Version: 1.0\nMain-Class: TeX\n" > .manifest cp upstream/build/tex/TeX.class build cd build && jar cfm ../$@ ../.manifest \ @@ -390,8 +390,15 @@ doc/charts/%.pdf: doc/charts/%.dat doc/charts/%.gnuplot cd doc/charts; chmod +x boxfill.pl; ./boxfill.pl -g -o unfilled.eps $*.eps cd doc/charts; ps2pdf $*.eps -doc/ivme04.pdf: doc/ivme04.tex doc/acmconf.cls $(charts:%.dat=%.pdf) - cd doc; pdflatex ivme04.tex && ./pst2pdf && pdflatex ivme04.tex +tex := java -cp $(usr)/../../build:.. TeX + +#tex := java -cp $(usr)/../../build:.. org.ibex.nestedvm.Interpreter ../tex.mips +doc/ivme04.pdf: doc/ivme04.tex doc/acmconf.cls $(charts:%.dat=%.pdf) tex.jar upstream/tasks/extract_texinputs + cp upstream/build/tex/tex.pool upstream/build/tex/texinputs/tex.pool + cd upstream/build/tex/texinputs; echo '\latex.ltx' | $(tex) + cd upstream/build/tex/texinputs; ln -fs ../../../../doc/* .; rm -f ivme04.aux; touch ivme04.aux; touch ivme04.bbl + cd upstream/build/tex/texinputs; echo '\&latex \input ivme04.tex' | $(tex) + cd upstream/build/tex/texinputs; dvipdf ivme04.dvi pdf: doc/ivme04.pdf open doc/ivme04.pdf diff --git a/upstream/Makefile b/upstream/Makefile index e91b0c2..1d61401 100644 --- a/upstream/Makefile +++ b/upstream/Makefile @@ -2,10 +2,12 @@ version_gcc = 3.3 version_gpc = 20030830 +version_texinputs = 1.0 url_gcc-core = http://mirrors.rcn.net/pub/sourceware/gcc/releases/gcc-$(version_gcc)/gcc-core-$(version_gcc).tar.gz url_gcc-c++ = http://mirrors.rcn.net/pub/sourceware/gcc/releases/gcc-$(version_gcc)/gcc-g++-$(version_gcc).tar.gz url_gcc-gpc = http://www.gnu-pascal.de/alpha/gpc-$(version_gpc).tar.gz url_gcc-g77 = http://mirrors.rcn.net/pub/sourceware/gcc/releases/gcc-$(version_gcc)/gcc-g77-$(version_gcc).tar.gz +url_texinputs = http://www.megacz.com/tmp/texinputs-$(version_texinputs).tgz patches_gcc = gcc-fixes.patch gcc-fdata-sections-bss.patch configure_gcc = --target=mips-unknown-elf --disable-threads --with-gnu-ld --with-gnu-as --with-newlib=yes --enable-sjlj-exceptions --enable-languages="c" configure_gcc_step2 = $(configure_gcc) --enable-languages="c,c++,pascal,f77" @@ -51,14 +53,6 @@ clean_%: rm -rf "build/$(*)"* rm -f "tasks/build_$*" "tasks/patch_$*" "tasks/extract_$*" -tasks/download_tex: ; touch $@ -tasks/extract_tex: - mkdir -p build/tex - cd build/tex; wget -N http://www.math.uni.wroc.pl/~hebisch/tex_p/tex.web -# cd build/tex; wget -N http://www.math.uni.wroc.pl/~hebisch/tex_p/tex.ch - cd build/tex; wget -N http://www.tug.org/tex-archive/systems/knuth/local/tex/initex.ch && mv initex.ch tex.ch - cd build/tex; wget -N http://www.gnu-pascal.de/crystal/gpc/en/attachments/5593/tangle.p.gz && gunzip tangle.p.gz - touch $@ gpc := $(usr)/bin/mips-unknown-elf-gpc gpc_flags := --big-endian -w -lgpc -lc $(usr)/mips-unknown-elf/lib/support*.o @@ -68,24 +62,32 @@ g77_flags := --big-endian -w -lg2c -lc $(usr)/mips-unknown-elf/lib/support*.o g77_flags += -Wl,-T,$(usr)/mips-unknown-elf/lib/linker.ld # FIXME ugly path hacks evil bad -nestedvm := java -cp $(usr)/../build/bcel/bcel-5.1.jar:$(usr)/../../nestedvm.jar org.ibex.nestedvm.Compiler -outformat class +nestedvm := java -cp $(usr)/../build/bcel/bcel-5.1.jar:$(usr)/../../build org.ibex.nestedvm.Compiler -outformat class + +tasks/download_tex: ; mkdir -p build/tex; touch $@ +build/tex/tex.web: ; curl -o $@ http://www.math.uni.wroc.pl/~hebisch/tex_p/tex.web +build/dtex/tangle.p: ; curl http://www.gnu-pascal.de/crystal/gpc/en/attachments/5593/tangle.p.gz | zcat > $@ +tasks/extract_tex: build/tex/tex.web build/tex/tangle.p; touch $@ -tasks/build_tex: tasks/full_toolchain tasks/extract_tex +build/tex/tangle.mips: build/tex/tangle.p tasks/full_toolchain tasks/extract_tex tasks/build_gcc_step2 cd build/tex; $(gpc) tangle.p $(gpc_flags) -o tangle.mips - cd build/tex; $(nestedvm) -o unixruntime -outfile Tangle.class Tangle tangle.mips - cd build/tex; java -cp .:$(usr)/../../nestedvm.jar Tangle \ - --gpc-rts=-nPascalfile:tex.unpatched.p \ +build/tex/Tangle.class: build/tex/tangle.mips + $(nestedvm) -o unixruntime -outfile $@ Tangle $< +build/tex/tex.p: build/tex/tex.web build/tex/tex.ch build/tex/Tangle.class + rm -f build/tex/tex.p build/tex/tex.pool + cd build/tex; java -cp .:$(usr)/../../build Tangle \ + --gpc-rts=-nPascalfile:tex.p \ --gpc-rts=-npool:tex.pool \ --gpc-rts=-nwebfile:tex.web \ --gpc-rts=-nchangefile:tex.ch - cd build/tex; cat tex.unpatched.p | sed s_STANDARDTEXT_TEXT_ | sed 's_\\^DIV_\\^ DIV_g' > tex.p - cd build/tex; PATH=$$PATH:../../install/bin; $(gpc) tex.p $(gpc_flags) -o tex.mips +build/tex/tex.mips: build/tex/tex.p tasks/full_toolchain tasks/build_gcc_step2 + cd build/tex; $(gpc) tex.p $(gpc_flags) -o tex.mips +tasks/build_tex: build/tex/tex.mips cd build/tex; $(nestedvm) -o unixruntime -outfile TeX.class TeX tex.mips - #ln -s tex.pool 'TeXformats:TEX.POOL ' - #ln -s trip.tfm 'TeXfonts:trip.tfm ' - #ln -s trip.tex 'trip.tex ' + touch $@ +tasks/extract_texinputs: tasks/build_tex tasks/download_texinputs + cd build/tex; tar xvzf ../../download/texinputs-1.0.tgz touch $@ - tasks/extract_linpack: tasks/download_linpack ; touch $@ tasks/download_linpack: mkdir -p build/linpack -- 1.7.10.4 From 1891ef5fe0ab1a3d699aeacb897471ff93ce2bc8 Mon Sep 17 00:00:00 2001 From: adam Date: Fri, 14 May 2004 01:13:42 -0700 Subject: [PATCH 12/16] horrendous hack for TeX... Brian, please forgive me darcs-hash:20040514081342-5007d-9cc74c5b9b297c7986664c43d154827dc63ac0a7.gz --- src/org/ibex/nestedvm/UnixRuntime.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/org/ibex/nestedvm/UnixRuntime.java b/src/org/ibex/nestedvm/UnixRuntime.java index 2b32965..dbe562d 100644 --- a/src/org/ibex/nestedvm/UnixRuntime.java +++ b/src/org/ibex/nestedvm/UnixRuntime.java @@ -926,6 +926,8 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { public FD open(UnixRuntime r, String path, int flags, int mode) throws ErrnoException { + // FIXME: horrendous, ugly hack needed by TeX... sorry Brian... + path = path.trim(); final File f = hostFile(path); return r.hostFSOpen(f,flags,mode,this); } -- 1.7.10.4 From f26168c62381bad692b6ccd782ba73336bfce180 Mon Sep 17 00:00:00 2001 From: brian Date: Tue, 11 May 2004 21:07:55 -0700 Subject: [PATCH 13/16] g77/linpack darcs-hash:20040512040755-24bed-47c92c97dd557c0a4823f2876e8f3b1156841158.gz --- Makefile | 4 +++- upstream/Makefile | 13 ++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index c744751..8a6af84 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ tasks = upstream/tasks flags = -march=mips1 MIPS_CC = mips-unknown-elf-gcc MIPS_CXX = mips-unknown-elf-g++ +MIPS_G77 = mips-unknown-elf-g77 # Be VERY careful about changing any of these as they can break binary # compatibility and create hard to find bugs @@ -233,6 +234,7 @@ rebuild-constants: $(tasks)/build_newlib build/tests/Env.class: build/org/ibex/nestedvm/Runtime.class build/org/ibex/nestedvm/Interpreter.class # Generic Hello Worldish test +test_COMPILERFLAGS = -o unixruntime test: build/tests/Test.class $(JAVA) -cp build tests.Test "arg 1" "arg 2" "arg 3" inttest: build/tests/Test.mips build/org/ibex/nestedvm/Interpreter.class @@ -261,7 +263,7 @@ Paranoia_CFLAGS = "-Wno-error" Paranoia_LDFLAGS = -lm paranoiatest: build/tests/Paranoia.class $(JAVA) -cp build tests.Paranoia - + # # Freetype Stuff # diff --git a/upstream/Makefile b/upstream/Makefile index 1d61401..30bfa0a 100644 --- a/upstream/Makefile +++ b/upstream/Makefile @@ -5,12 +5,9 @@ version_gpc = 20030830 version_texinputs = 1.0 url_gcc-core = http://mirrors.rcn.net/pub/sourceware/gcc/releases/gcc-$(version_gcc)/gcc-core-$(version_gcc).tar.gz url_gcc-c++ = http://mirrors.rcn.net/pub/sourceware/gcc/releases/gcc-$(version_gcc)/gcc-g++-$(version_gcc).tar.gz -url_gcc-gpc = http://www.gnu-pascal.de/alpha/gpc-$(version_gpc).tar.gz -url_gcc-g77 = http://mirrors.rcn.net/pub/sourceware/gcc/releases/gcc-$(version_gcc)/gcc-g77-$(version_gcc).tar.gz -url_texinputs = http://www.megacz.com/tmp/texinputs-$(version_texinputs).tgz patches_gcc = gcc-fixes.patch gcc-fdata-sections-bss.patch configure_gcc = --target=mips-unknown-elf --disable-threads --with-gnu-ld --with-gnu-as --with-newlib=yes --enable-sjlj-exceptions --enable-languages="c" -configure_gcc_step2 = $(configure_gcc) --enable-languages="c,c++,pascal,f77" +configure_gcc_step2 = $(configure_gcc) --enable-languages="c,c++" version_binutils = 2.14 url_binutils = ftp://ftp.gnu.org/gnu/binutils/binutils-$(version_binutils).tar.gz @@ -28,6 +25,8 @@ url_regex = ftp://ftp.zoo.toronto.edu/pub/regex.shar version_bcel = 5.1 url_bcel = http://mirrors.mix5.com/apache/jakarta/bcel/binaries/bcel-$(version_bcel).tar.gz +url_linpack = http://www.math.iastate.edu/burkardt/f_src/linpack_bench/linpack_bench.f + .SECONDARY: # This is broken in gmake < 3.79.1 upstream = $(shell pwd) @@ -105,7 +104,7 @@ tasks/download_%: cd download && wget --passive-ftp -N $(url_$*) touch $@ -tasks/download_gcc: tasks/download_gcc-core tasks/download_gcc-c++ tasks/download_gcc-gpc tasks/download_gcc-g77 +tasks/download_gcc: tasks/download_gcc-core tasks/download_gcc-c++ touch $@ tasks/extract_%: tasks/download_% @@ -120,10 +119,6 @@ tasks/extract_gcc: tasks/download_gcc mkdir -p build cd build && gzip -dc ../download/gcc-core-$(version_gcc).tar.gz | tar xf - cd build && gzip -dc ../download/gcc-g++-$(version_gcc).tar.gz | tar xf - - cd build && gzip -dc ../download/gcc-g77-$(version_gcc).tar.gz | tar xf - - cd build && gzip -dc ../download/gpc-$(version_gpc).tar.gz | tar xf - && \ - rm -rf gcc-$(version_gcc)/gcc/p/; mv gpc-$(version_gpc)/p gcc-$(version_gcc)/gcc/p - rmdir build/gpc-$(version_gpc) touch $@ tasks/patch_%: tasks/extract_% -- 1.7.10.4 From 896193619af1e0534356ac622494ae77c7e42594 Mon Sep 17 00:00:00 2001 From: brian Date: Thu, 20 May 2004 05:33:14 -0700 Subject: [PATCH 14/16] better networking support darcs-hash:20040520123314-24bed-f16b309086633d3f650cbfc8fe8752930ad91cda.gz --- Makefile | 2 +- src/org/ibex/nestedvm/Interpreter.java | 2 +- src/org/ibex/nestedvm/Runtime.java | 19 ++-- src/org/ibex/nestedvm/UnixRuntime.java | 123 +++++++++++++++++--- src/org/ibex/nestedvm/UsermodeConstants.java | 154 +++++++++++++++++++++++++- src/org/ibex/nestedvm/support.s | 54 +++++++-- src/org/ibex/nestedvm/support_aux.c | 125 ++++++++++++++++++++- src/org/ibex/nestedvm/syscalls.h | 17 ++- src/tests/Echo.java | 4 +- 9 files changed, 452 insertions(+), 48 deletions(-) diff --git a/Makefile b/Makefile index 8a6af84..baabb85 100644 --- a/Makefile +++ b/Makefile @@ -221,7 +221,7 @@ rebuild-constants: $(tasks)/build_newlib echo "public interface UsermodeConstants {"; \ tr '\t' ' ' | sed -n ' \ s/ */ /g; \ - s/ *# *define \([A-Z_][A-Za-z0-9_]*\) \([0-9][0-9x]*\)/ public static final int \1 = \2;/p'; \ + s/ *# *define \([A-Z_][A-Za-z0-9_]*\) \([0-9][0-9a-fA-Fx]*\)/ public static final int \1 = \2;/p'; \ echo "}"; \ ) > src/org/ibex/nestedvm/UsermodeConstants.java diff --git a/src/org/ibex/nestedvm/Interpreter.java b/src/org/ibex/nestedvm/Interpreter.java index 437869f..df9a111 100644 --- a/src/org/ibex/nestedvm/Interpreter.java +++ b/src/org/ibex/nestedvm/Interpreter.java @@ -125,7 +125,7 @@ public class Interpreter extends UnixRuntime implements Cloneable { continue OUTER; case 12: // SYSCALL this.pc = pc; - r[V0] = syscall(r[V0],r[A0],r[A1],r[A2],r[A3]); + r[V0] = syscall(r[V0],r[A0],r[A1],r[A2],r[A3],r[T0],r[T1]); if(state != RUNNING) { this.pc = nextPC; break OUTER; } break; case 13: // BREAK diff --git a/src/org/ibex/nestedvm/Runtime.java b/src/org/ibex/nestedvm/Runtime.java index 50b5162..2a4567f 100644 --- a/src/org/ibex/nestedvm/Runtime.java +++ b/src/org/ibex/nestedvm/Runtime.java @@ -996,20 +996,23 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { syscall should be the contents of V0 and a, b, c, and d should be the contenst of A0, A1, A2, and A3. The call MAY change the state @see Runtime#state state */ - protected final int syscall(int syscall, int a, int b, int c, int d) { + protected final int syscall(int syscall, int a, int b, int c, int d, int e, int f) { try { - return _syscall(syscall,a,b,c,d); - } catch(ErrnoException e) { - return -e.errno; - } catch(FaultException e) { + int n = _syscall(syscall,a,b,c,d,e,f); + //if(n < 0) System.err.println("syscall: " + syscall + " returned " + n); + return n; + } catch(ErrnoException ex) { + //ex.printStackTrace(); + return -ex.errno; + } catch(FaultException ex) { return -EFAULT; - } catch(RuntimeException e) { - e.printStackTrace(); + } catch(RuntimeException ex) { + ex.printStackTrace(); throw new Error("Internal Error in _syscall()"); } } - int _syscall(int syscall, int a, int b, int c, int d) throws ErrnoException, FaultException { + int _syscall(int syscall, int a, int b, int c, int d, int e, int f) throws ErrnoException, FaultException { switch(syscall) { case SYS_null: return 0; case SYS_exit: return sys_exit(a); diff --git a/src/org/ibex/nestedvm/UnixRuntime.java b/src/org/ibex/nestedvm/UnixRuntime.java index dbe562d..1c33a08 100644 --- a/src/org/ibex/nestedvm/UnixRuntime.java +++ b/src/org/ibex/nestedvm/UnixRuntime.java @@ -3,8 +3,7 @@ package org.ibex.nestedvm; import org.ibex.nestedvm.util.*; import java.io.*; import java.util.*; -import java.net.Socket; -import java.net.ServerSocket; +import java.net.*; // FEATURE: vfork @@ -109,7 +108,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } } - int _syscall(int syscall, int a, int b, int c, int d) throws ErrnoException, FaultException { + int _syscall(int syscall, int a, int b, int c, int d, int e, int f) throws ErrnoException, FaultException { switch(syscall) { case SYS_kill: return sys_kill(a,b); case SYS_fork: return sys_fork(); @@ -126,11 +125,18 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { case SYS_getdents: return sys_getdents(a,b,c,d); case SYS_unlink: return sys_unlink(a); case SYS_getppid: return sys_getppid(); - case SYS_opensocket: return sys_opensocket(a,b); - case SYS_listensocket: return sys_listensocket(a); - case SYS_accept: return sys_accept(a); + case SYS_socket: return sys_socket(a,b,c); + case SYS_connect: return sys_connect(a,b,c); + case SYS_resolve_hostname: return sys_resolve_hostname(a,b,c); + case SYS_setsockopt: return sys_setsockopt(a,b,c,d,e); + case SYS_getsockopt: return sys_getsockopt(a,b,c,d,e); + case SYS_bind: return sys_bind(a,b,c); + case SYS_listen: return sys_listen(a,b); + case SYS_accept: return sys_accept(a,b,c); + case SYS_shutdown: return sys_shutdown(a,b); + case SYS_sysctl: return sys_sysctl(a,b,c,d,e,f); - default: return super._syscall(syscall,a,b,c,d); + default: return super._syscall(syscall,a,b,c,d,e,f); } } @@ -165,7 +171,8 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { case 28: // SIGWINCH break; default: - return syscall(SYS_exit,128+signal,0,0,0); + // FEATURE: This is ugly, make a clean interface to sys_exit + return syscall(SYS_exit,128+signal,0,0,0,0,0); } return 0; } @@ -524,15 +531,101 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { return n; } - private static class SocketFD extends InputOutputStreamFD { - private final Socket s; + static class SocketFD extends FD { + public static final int TYPE_STREAM = 0; + public static final int TYPE_DGRAM = 1; + public static final int LISTEN = 2; + public int type() { return flags & 1; } + public boolean listen() { return (flags & 2) != 0; } - public SocketFD(Socket s) throws IOException { - super(s.getInputStream(),s.getOutputStream()); - this.s = s; + int flags; + int options; + Object o; + InetAddress bindAddr; + int bindPort = -1; + DatagramPacket dp; + InputStream is; + OutputStream os; + + public SocketFD(int type) { flags = type; } + + public void setOptions() { + try { + if(o != null && type() == TYPE_STREAM && !listen()) { + ((Socket)o).setKeepAlive((options & SO_KEEPALIVE) != 0); + } + } catch(SocketException e) { + if(STDERR_DIAG) e.printStackTrace(); + } } - public void _close() { try { s.close(); } catch(IOException e) { } } + public void _close() { + if(o != null) { + try { + if(type() == TYPE_STREAM) { + if(listen()) ((ServerSocket)o).close(); + else ((Socket)o).close(); + } else { + ((DatagramSocket)o).close(); + } + } catch(IOException e) { + /* ignore */ + } + } + } + + public int read(byte[] a, int off, int length) throws ErrnoException { + if(type() == TYPE_STREAM) { + if(is == null) throw new ErrnoException(EPIPE); + try { + int n = is.read(a,off,length); + return n < 0 ? 0 : n; + } catch(IOException e) { + throw new ErrnoException(EIO); + } + } else { + DatagramSocket ds = (DatagramSocket) o; + dp.setData(a,off,length); + try { + ds.receive(dp); + } catch(IOException e) { + throw new ErrnoException(EIO); + } + return dp.getLength(); + } + } + + public int write(byte[] a, int off, int length) throws ErrnoException { + if(type() == TYPE_STREAM) { + if(os == null) throw new ErrnoException(EPIPE); + try { + os.write(a,off,length); + return length; + } catch(IOException e) { + throw new ErrnoException(EIO); + } + } else { + DatagramSocket ds = (DatagramSocket) o; + dp.setData(a,off,length); + try { + ds.send(dp); + } catch(IOException e) { + throw new ErrnoException(EIO); + } + return dp.getLength(); + } + } + + // FEATURE: Check that these are correct + public int flags() { + if(is != null && os != null) return O_RDWR; + if(is != null) return O_RDONLY; + if(os != null) return O_WRONLY; + return 0; + } + + // FEATURE: Populate this properly + public FStat _fstat() { return new FStat(); } } public int sys_opensocket(int cstring, int port) throws FaultException, ErrnoException { @@ -580,7 +673,7 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { } catch(IOException e) { return -EIO; } - } + }*/ // FEATURE: Run through the fork/wait stuff one more time public static class GlobalState { diff --git a/src/org/ibex/nestedvm/UsermodeConstants.java b/src/org/ibex/nestedvm/UsermodeConstants.java index b2bf093..1341de1 100644 --- a/src/org/ibex/nestedvm/UsermodeConstants.java +++ b/src/org/ibex/nestedvm/UsermodeConstants.java @@ -50,9 +50,157 @@ public interface UsermodeConstants { public static final int SYS_usleep = 45; public static final int SYS_getppid = 46; public static final int SYS_mkfifo = 47; - public static final int SYS_opensocket = 48; - public static final int SYS_listensocket = 49; - public static final int SYS_accept = 50; + public static final int SYS_klogctl = 51; + public static final int SYS_realpath = 52; + public static final int SYS_sysctl = 53; + public static final int SYS_setpriority = 54; + public static final int SYS_getpriority = 55; + public static final int SYS_socket = 56; + public static final int SYS_connect = 57; + public static final int SYS_resolve_hostname = 58; + public static final int SYS_accept = 59; + public static final int SYS_setsockopt = 60; + public static final int SYS_getsockopt = 61; + public static final int SYS_listen = 62; + public static final int SYS_bind = 63; + public static final int SYS_shutdown = 64; + public static final int AF_INET = 2; + public static final int SOCK_STREAM = 1; + public static final int SOCK_DGRAM = 2; + public static final int HOST_NOT_FOUND = 1; + public static final int TRY_AGAIN = 2; + public static final int NO_RECOVERY = 3; + public static final int NO_DATA = 4; + public static final int SOL_SOCKET = 0xffff; + public static final int SO_REUSEADDR = 0x0004; + public static final int SO_KEEPALIVE = 0x0008; + public static final int SHUT_RD = 0; + public static final int SHUT_WR = 1; + public static final int SHUT_RDWR = 2; + public static final int INADDR_ANY = 0; + public static final int CTL_MAXNAME = 12; + public static final int CTL_UNSPEC = 0; /* unused */ + public static final int CTL_KERN = 1; /* "high kernel": proc, limits */ + public static final int CTL_VM = 2; /* virtual memory */ + public static final int CTL_VFS = 3; /* file system, mount type is next */ + public static final int CTL_NET = 4; /* network, see socket.h */ + public static final int CTL_DEBUG = 5; /* debugging parameters */ + public static final int CTL_HW = 6; /* generic cpu/io */ + public static final int CTL_MACHDEP = 7; /* machine dependent */ + public static final int CTL_USER = 8; /* user-level */ + public static final int CTL_P1003_1B = 9; /* POSIX 1003.1B */ + public static final int CTL_MAXID = 10; /* number of valid top-level ids */ + public static final int KERN_OSTYPE = 1; /* string: system version */ + public static final int KERN_OSRELEASE = 2; /* string: system release */ + public static final int KERN_OSREV = 3; /* int: system revision */ + public static final int KERN_VERSION = 4; /* string: compile time info */ + public static final int KERN_MAXVNODES = 5; /* int: max vnodes */ + public static final int KERN_MAXPROC = 6; /* int: max processes */ + public static final int KERN_MAXFILES = 7; /* int: max open files */ + public static final int KERN_ARGMAX = 8; /* int: max arguments to exec */ + public static final int KERN_SECURELVL = 9; /* int: system security level */ + public static final int KERN_HOSTNAME = 10; /* string: hostname */ + public static final int KERN_HOSTID = 11; /* int: host identifier */ + public static final int KERN_CLOCKRATE = 12; /* struct: struct clockrate */ + public static final int KERN_VNODE = 13; /* struct: vnode structures */ + public static final int KERN_PROC = 14; /* struct: process entries */ + public static final int KERN_FILE = 15; /* struct: file entries */ + public static final int KERN_PROF = 16; /* node: kernel profiling info */ + public static final int KERN_POSIX1 = 17; /* int: POSIX.1 version */ + public static final int KERN_NGROUPS = 18; /* int: # of supplemental group ids */ + public static final int KERN_JOB_CONTROL = 19; /* int: is job control available */ + public static final int KERN_SAVED_IDS = 20; /* int: saved set-user/group-ID */ + public static final int KERN_BOOTTIME = 21; /* struct: time kernel was booted */ + public static final int KERN_NISDOMAINNAME = 22; /* string: YP domain name */ + public static final int KERN_UPDATEINTERVAL = 23; /* int: update process sleep time */ + public static final int KERN_OSRELDATE = 24; /* int: OS release date */ + public static final int KERN_NTP_PLL = 25; /* node: NTP PLL control */ + public static final int KERN_BOOTFILE = 26; /* string: name of booted kernel */ + public static final int KERN_MAXFILESPERPROC = 27; /* int: max open files per proc */ + public static final int KERN_MAXPROCPERUID = 28; /* int: max processes per uid */ + public static final int KERN_DUMPDEV = 29; /* dev_t: device to dump on */ + public static final int KERN_IPC = 30; /* node: anything related to IPC */ + public static final int KERN_DUMMY = 31; /* unused */ + public static final int KERN_PS_STRINGS = 32; /* int: address of PS_STRINGS */ + public static final int KERN_USRSTACK = 33; /* int: address of USRSTACK */ + public static final int KERN_LOGSIGEXIT = 34; /* int: do we log sigexit procs? */ + public static final int KERN_MAXID = 35; /* number of valid kern ids */ + public static final int KERN_PROC_ALL = 0; /* everything */ + public static final int KERN_PROC_PID = 1; /* by process id */ + public static final int KERN_PROC_PGRP = 2; /* by process group id */ + public static final int KERN_PROC_SESSION = 3; /* by session of pid */ + public static final int KERN_PROC_TTY = 4; /* by controlling tty */ + public static final int KERN_PROC_UID = 5; /* by effective uid */ + public static final int KERN_PROC_RUID = 6; /* by real uid */ + public static final int KERN_PROC_ARGS = 7; /* get/set arguments/proctitle */ + public static final int KIPC_MAXSOCKBUF = 1; /* int: max size of a socket buffer */ + public static final int KIPC_SOCKBUF_WASTE = 2; /* int: wastage factor in sockbuf */ + public static final int KIPC_SOMAXCONN = 3; /* int: max length of connection q */ + public static final int KIPC_MAX_LINKHDR = 4; /* int: max length of link header */ + public static final int KIPC_MAX_PROTOHDR = 5; /* int: max length of network header */ + public static final int KIPC_MAX_HDR = 6; /* int: max total length of headers */ + public static final int KIPC_MAX_DATALEN = 7; /* int: max length of data? */ + public static final int KIPC_MBSTAT = 8; /* struct: mbuf usage statistics */ + public static final int KIPC_NMBCLUSTERS = 9; /* int: maximum mbuf clusters */ + public static final int HW_MACHINE = 1; /* string: machine class */ + public static final int HW_MODEL = 2; /* string: specific machine model */ + public static final int HW_NCPU = 3; /* int: number of cpus */ + public static final int HW_BYTEORDER = 4; /* int: machine byte order */ + public static final int HW_PHYSMEM = 5; /* int: total memory */ + public static final int HW_USERMEM = 6; /* int: non-kernel memory */ + public static final int HW_PAGESIZE = 7; /* int: software page size */ + public static final int HW_DISKNAMES = 8; /* strings: disk drive names */ + public static final int HW_DISKSTATS = 9; /* struct: diskstats[] */ + public static final int HW_FLOATINGPT = 10; /* int: has HW floating point? */ + public static final int HW_MACHINE_ARCH = 11; /* string: machine architecture */ + public static final int HW_MAXID = 12; /* number of valid hw ids */ + public static final int USER_CS_PATH = 1; /* string: _CS_PATH */ + public static final int USER_BC_BASE_MAX = 2; /* int: BC_BASE_MAX */ + public static final int USER_BC_DIM_MAX = 3; /* int: BC_DIM_MAX */ + public static final int USER_BC_SCALE_MAX = 4; /* int: BC_SCALE_MAX */ + public static final int USER_BC_STRING_MAX = 5; /* int: BC_STRING_MAX */ + public static final int USER_COLL_WEIGHTS_MAX = 6; /* int: COLL_WEIGHTS_MAX */ + public static final int USER_EXPR_NEST_MAX = 7; /* int: EXPR_NEST_MAX */ + public static final int USER_LINE_MAX = 8; /* int: LINE_MAX */ + public static final int USER_RE_DUP_MAX = 9; /* int: RE_DUP_MAX */ + public static final int USER_POSIX2_VERSION = 10; /* int: POSIX2_VERSION */ + public static final int USER_POSIX2_C_BIND = 11; /* int: POSIX2_C_BIND */ + public static final int USER_POSIX2_C_DEV = 12; /* int: POSIX2_C_DEV */ + public static final int USER_POSIX2_CHAR_TERM = 13; /* int: POSIX2_CHAR_TERM */ + public static final int USER_POSIX2_FORT_DEV = 14; /* int: POSIX2_FORT_DEV */ + public static final int USER_POSIX2_FORT_RUN = 15; /* int: POSIX2_FORT_RUN */ + public static final int USER_POSIX2_LOCALEDEF = 16; /* int: POSIX2_LOCALEDEF */ + public static final int USER_POSIX2_SW_DEV = 17; /* int: POSIX2_SW_DEV */ + public static final int USER_POSIX2_UPE = 18; /* int: POSIX2_UPE */ + public static final int USER_STREAM_MAX = 19; /* int: POSIX2_STREAM_MAX */ + public static final int USER_TZNAME_MAX = 20; /* int: POSIX2_TZNAME_MAX */ + public static final int USER_MAXID = 21; /* number of valid user ids */ + public static final int CTL_P1003_1B_ASYNCHRONOUS_IO = 1; /* boolean */ + public static final int CTL_P1003_1B_MAPPED_FILES = 2; /* boolean */ + public static final int CTL_P1003_1B_MEMLOCK = 3; /* boolean */ + public static final int CTL_P1003_1B_MEMLOCK_RANGE = 4; /* boolean */ + public static final int CTL_P1003_1B_MEMORY_PROTECTION = 5; /* boolean */ + public static final int CTL_P1003_1B_MESSAGE_PASSING = 6; /* boolean */ + public static final int CTL_P1003_1B_PRIORITIZED_IO = 7; /* boolean */ + public static final int CTL_P1003_1B_PRIORITY_SCHEDULING = 8; /* boolean */ + public static final int CTL_P1003_1B_REALTIME_SIGNALS = 9; /* boolean */ + public static final int CTL_P1003_1B_SEMAPHORES = 10; /* boolean */ + public static final int CTL_P1003_1B_FSYNC = 11; /* boolean */ + public static final int CTL_P1003_1B_SHARED_MEMORY_OBJECTS = 12; /* boolean */ + public static final int CTL_P1003_1B_SYNCHRONIZED_IO = 13; /* boolean */ + public static final int CTL_P1003_1B_TIMERS = 14; /* boolean */ + public static final int CTL_P1003_1B_AIO_LISTIO_MAX = 15; /* int */ + public static final int CTL_P1003_1B_AIO_MAX = 16; /* int */ + public static final int CTL_P1003_1B_AIO_PRIO_DELTA_MAX = 17; /* int */ + public static final int CTL_P1003_1B_DELAYTIMER_MAX = 18; /* int */ + public static final int CTL_P1003_1B_MQ_OPEN_MAX = 19; /* int */ + public static final int CTL_P1003_1B_PAGESIZE = 20; /* int */ + public static final int CTL_P1003_1B_RTSIG_MAX = 21; /* int */ + public static final int CTL_P1003_1B_SEM_NSEMS_MAX = 22; /* int */ + public static final int CTL_P1003_1B_SEM_VALUE_MAX = 23; /* int */ + public static final int CTL_P1003_1B_SIGQUEUE_MAX = 24; /* int */ + public static final int CTL_P1003_1B_TIMER_MAX = 25; /* int */ + public static final int CTL_P1003_1B_MAXID = 26; public static final int EPERM = 1; /* Not super-user */ public static final int ENOENT = 2; /* No such file or directory */ public static final int ESRCH = 3; /* No such process */ diff --git a/src/org/ibex/nestedvm/support.s b/src/org/ibex/nestedvm/support.s index 0cd7e74..050ef4f 100644 --- a/src/org/ibex/nestedvm/support.s +++ b/src/org/ibex/nestedvm/support.s @@ -9,6 +9,9 @@ #define a3 $7 #define t0 $8 #define t1 $9 +#define t2 $10 +#define t3 $11 +#define sp $29 #define ra $31 /* We intentionally don't take advantage of delay slots because @@ -30,26 +33,42 @@ name: \ .end name; #define SYSCALL_R(name) SYSCALL_R2(_##name##_r,SYS_##name) +#define SYSCALL_R_LONG(name) SYSCALL_R2_LONG(_##name##_r,SYS_##name) + #define SYSCALL_R2(name,number) \ + SYSCALL_R2_BEG(name,number) \ + SYSCALL_R2_END(name) + + +#define SYSCALL_R2_LONG(name,number) \ + SYSCALL_R2_BEG(name,number) \ + lw a3,16(sp); \ + lw t0,20(sp); \ + lw t1,24(sp); \ + SYSCALL_R2_END(name) + +#define SYSCALL_R2_BEG(name,number) \ .section .text.name,"ax",@progbits; \ .align 2; \ .globl name; \ .ent name; \ name: \ li v0, number; \ - move t0, a0; \ + move t2, a0; \ move a0, a1; \ move a1, a2; \ move a2, a3; \ + +#define SYSCALL_R2_END(name) \ syscall; \ - addu t1,v0,255; \ - sltu t1,t1,255; \ - bne t1,zero,$L##name##_errno;\ + addu t3,v0,255; \ + sltu t3,t3,255; \ + bne t3,zero,$L##name##_errno;\ nop; \ j ra; \ nop; \ $L##name##_errno: \ - move a0, t0; \ + move a0, t2; \ move a1, v0; \ j _syscall_set_errno; \ nop; \ @@ -60,7 +79,7 @@ $L##name##_errno: \ .globl _call_helper .ent _call_helper _call_helper: - subu $sp,$sp,32 + subu sp,sp,32 /* addr */ move $2,$4 @@ -72,8 +91,8 @@ _call_helper: move $7,$16 /* args 5 and 6 */ - sw $17,16($sp) - sw $18,20($sp) + sw $17,16(sp) + sw $18,20(sp) /* call the func */ jal $31,$2 @@ -124,7 +143,7 @@ SYSCALL_R(readlink) SYSCALL_R(lstat) SYSCALL_R(symlink) SYSCALL_R(link) -SYSCALL_R(getdents) +SYSCALL_R_LONG(getdents) /*SYSCALL(memcpy) */ /*SYSCALL(memset) */ SYSCALL_R(dup) @@ -136,6 +155,17 @@ SYSCALL_R(ftruncate) SYSCALL_R(usleep) SYSCALL(getppid) SYSCALL_R(mkfifo) -SYSCALL_R2(__open_socket_r,SYS_opensocket) -SYSCALL_R2(__listen_socket_r,SYS_listensocket) -SYSCALL_R2(__accept_r,SYS_accept) +SYSCALL_R(klogctl) +SYSCALL_R(realpath) +SYSCALL_R2_LONG(__sysctl_r,SYS_sysctl) +SYSCALL_R(getpriority) +SYSCALL_R(setpriority) +SYSCALL_R(socket) +SYSCALL_R(connect) +SYSCALL_R2(__resolve_hostname_r,SYS_resolve_hostname) +SYSCALL_R(accept) +SYSCALL_R_LONG(setsockopt) +SYSCALL_R_LONG(getsockopt) +SYSCALL_R(listen) +SYSCALL_R(bind) +SYSCALL_R(shutdown) diff --git a/src/org/ibex/nestedvm/support_aux.c b/src/org/ibex/nestedvm/support_aux.c index 513434e..c309899 100644 --- a/src/org/ibex/nestedvm/support_aux.c +++ b/src/org/ibex/nestedvm/support_aux.c @@ -9,6 +9,10 @@ #include #include #include +#include +#include +#include +#include int _syscall_set_errno(struct _reent *ptr, int err) { ptr->_errno = -err; @@ -62,6 +66,16 @@ extern rt _##f##_r(struct _reent *ptr, t1 a, t2 b, t3 c, t4 d); \ rt f(t1 a, t2 b, t3 c, t4 d) { return _##f##_r(_REENT,a,b,c,d); } #define REENT_WRAPPER4(f,t1,t2,t3,t4) REENT_WRAPPER4R(f,int,t1,t2,t3,t4) +#define REENT_WRAPPER5R(f,rt,t1,t2,t3,t4,t5) \ +extern rt _##f##_r(struct _reent *ptr, t1 a, t2 b, t3 c, t4 d, t5 e); \ +rt f(t1 a, t2 b, t3 c, t4 d, t5 e) { return _##f##_r(_REENT,a,b,c,d,e); } +#define REENT_WRAPPER5(f,t1,t2,t3,t4,t5) REENT_WRAPPER5R(f,int,t1,t2,t3,t4,t5) + +#define REENT_WRAPPER6R(f,rt,t1,t2,t3,t4,t5,t6) \ +extern rt _##f##_r(struct _reent *ptr, t1 a, t2 b, t3 c, t4 d, t5 e, t6 f); \ +rt f(t1 a, t2 b, t3 c, t4 d, t5 e, t6 f) { return _##f##_r(_REENT,a,b,c,d,e,f); } +#define REENT_WRAPPER6(f,t1,t2,t3,t4,t5,t6) REENT_WRAPPER6R(f,int,t1,t2,t3,t4,t5,t6) + REENT_WRAPPER2(mkdir,const char *,mode_t) REENT_WRAPPER2(access,const char *,int) REENT_WRAPPER1(rmdir,const char *) @@ -90,9 +104,21 @@ REENT_WRAPPER3(mknod,const char *,mode_t,dev_t) REENT_WRAPPER2(ftruncate,int,off_t) REENT_WRAPPER1(usleep,unsigned int) REENT_WRAPPER2(mkfifo,const char *, mode_t) -REENT_WRAPPER2(_open_socket,const char *,int) -REENT_WRAPPER1(_listen_socket,int) -REENT_WRAPPER1(_accept,int) +REENT_WRAPPER3(klogctl,int,char*,int) +REENT_WRAPPER2R(realpath,char *,const char *,char *) +REENT_WRAPPER6(_sysctl,int *,int, void *, size_t*, void *, size_t) +REENT_WRAPPER6(sysctl,int *, int, void *, size_t*, void *, size_t) +REENT_WRAPPER2(getpriority,int,int) +REENT_WRAPPER3(setpriority,int,int,int) +REENT_WRAPPER3(connect,int,const struct sockaddr *,socklen_t) +REENT_WRAPPER3(socket,int,int,int) +REENT_WRAPPER3(_resolve_hostname,const char *,char*,size_t*) +REENT_WRAPPER3(accept,int,struct sockaddr *,socklen_t*) +REENT_WRAPPER5(getsockopt,int,int,int,void*,socklen_t*) +REENT_WRAPPER5(setsockopt,int,int,int,const void*,socklen_t) +REENT_WRAPPER3(bind,int,const struct sockaddr *,socklen_t) +REENT_WRAPPER2(listen,int,int) +REENT_WRAPPER2(shutdown,int,int) extern int __execve_r(struct _reent *ptr, const char *path, char *const argv[], char *const envp[]); int _execve(const char *path, char *const argv[], char *const envp[]) { @@ -225,6 +251,67 @@ int closedir(DIR *dir) { } /* + * Networking/Socket stuff + */ + +/* This should really be part of the newlib _reent structure */ +int h_errno; + +char *inet_ntoa(struct in_addr in) { + static char buf[18]; + const unsigned char *p = (void*) ∈ + snprintf(buf,sizeof(buf),"%u.%u.%u.%u",p[0],p[1],p[2],p[3]); + return buf; +} + +struct servent *getservbyname(const char *name,const char *proto) { + return NULL; +} + +static const char *h_errlist[] = { "No Error","Unknown host", "Host name lookup failure","Unknown server error","No address associated with name" }; + +const char *hstrerror(int err) { + if(err < 0 || err > 4) return "Unknown Error"; + return h_errlist[err]; +} + +void herror(const char *string) { + fprintf(stderr,"%s: %s\n",string,hstrerror(h_errno)); +} + +extern int _resolve_hostname(const char *, char *buf, size_t *size); + +struct hostent *gethostbyname(const char *hostname) { +#define MAX_ADDRS 256 + static struct hostent hostent; + static char saved_hostname[128]; + static char *addr_list[MAX_ADDRS+1]; + static char addr_list_buf[MAX_ADDRS*sizeof(struct in_addr)]; + static char *aliases[1]; + + unsigned char buf[MAX_ADDRS*sizeof(struct in_addr)]; + size_t size = sizeof(buf); + int err,i,n=0; + + err = _resolve_hostname(hostname,buf,&size); + if(err != 0) { h_errno = err; return NULL; } + + memcpy(addr_list_buf,buf,size); + for(i=0;i 2) + (void)close(fd); + } + return (0); +} diff --git a/src/org/ibex/nestedvm/syscalls.h b/src/org/ibex/nestedvm/syscalls.h index d62bb2c..c9ce7ca 100644 --- a/src/org/ibex/nestedvm/syscalls.h +++ b/src/org/ibex/nestedvm/syscalls.h @@ -45,6 +45,17 @@ #define SYS_usleep 45 #define SYS_getppid 46 #define SYS_mkfifo 47 -#define SYS_opensocket 48 -#define SYS_listensocket 49 -#define SYS_accept 50 +#define SYS_klogctl 51 +#define SYS_realpath 52 +#define SYS_sysctl 53 +#define SYS_setpriority 54 +#define SYS_getpriority 55 +#define SYS_socket 56 +#define SYS_connect 57 +#define SYS_resolve_hostname 58 +#define SYS_accept 59 +#define SYS_setsockopt 60 +#define SYS_getsockopt 61 +#define SYS_listen 62 +#define SYS_bind 63 +#define SYS_shutdown 64 diff --git a/src/tests/Echo.java b/src/tests/Echo.java index 6ef97ae..33ed2a6 100644 --- a/src/tests/Echo.java +++ b/src/tests/Echo.java @@ -22,8 +22,8 @@ public class Echo { task.closeFD(0); task.closeFD(1); //task.closeFD(2); - task.addFD(new Runtime.InputStreamFD(sock.getInputStream())); - task.addFD(new Runtime.OutputStreamFD(sock.getOutputStream())); + task.addFD(new Runtime.InputOutputStreamFD(sock.getInputStream())); + task.addFD(new Runtime.InputOutputStreamFD(sock.getOutputStream())); //task.dupFD(1); int status = task.run(new String[]{"EchoHelper"} ); -- 1.7.10.4 From 37a9506df9dab17552c6c34b62dc4295504b6c8c Mon Sep 17 00:00:00 2001 From: brian Date: Thu, 20 May 2004 05:36:15 -0700 Subject: [PATCH 15/16] uname/sysctl support darcs-hash:20040520123615-24bed-e8cbfb1444e79e3677d18b8293aa6466a9128575.gz --- src/org/ibex/nestedvm/Runtime.java | 9 + src/org/ibex/nestedvm/UnixRuntime.java | 281 +++++++++++++++++++++++++++++++- src/org/ibex/nestedvm/support_aux.c | 95 +++++++++++ 3 files changed, 384 insertions(+), 1 deletion(-) diff --git a/src/org/ibex/nestedvm/Runtime.java b/src/org/ibex/nestedvm/Runtime.java index 2a4567f..4d965e7 100644 --- a/src/org/ibex/nestedvm/Runtime.java +++ b/src/org/ibex/nestedvm/Runtime.java @@ -9,6 +9,8 @@ import java.io.*; import java.util.Arrays; public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { + public static final String VERSION = "1.0"; + /** True to write useful diagnostic information to stderr when things go wrong */ final static boolean STDERR_DIAG = true; @@ -1422,6 +1424,13 @@ public abstract class Runtime implements UsermodeConstants,Registers,Cloneable { } } + static byte[] getNullTerminatedBytes(String s) { + byte[] buf1 = getBytes(s); + byte[] buf2 = new byte[buf1.length+1]; + System.arraycopy(buf1,0,buf2,0,buf1.length); + return buf2; + } + final static String toHex(int n) { return "0x" + Long.toString(n & 0xffffffffL, 16); } final static int min(int a, int b) { return a < b ? a : b; } final static int max(int a, int b) { return a > b ? a : b; } diff --git a/src/org/ibex/nestedvm/UnixRuntime.java b/src/org/ibex/nestedvm/UnixRuntime.java index 1c33a08..4c9ed5a 100644 --- a/src/org/ibex/nestedvm/UnixRuntime.java +++ b/src/org/ibex/nestedvm/UnixRuntime.java @@ -628,7 +628,286 @@ public abstract class UnixRuntime extends Runtime implements Cloneable { public FStat _fstat() { return new FStat(); } } - public int sys_opensocket(int cstring, int port) throws FaultException, ErrnoException { + private int sys_socket(int domain, int type, int proto) { + if(domain != AF_INET || (type != SOCK_STREAM && type != SOCK_DGRAM)) return -EPROTONOSUPPORT; + return addFD(new SocketFD(type == SOCK_STREAM ? SocketFD.TYPE_STREAM : SocketFD.TYPE_DGRAM)); + } + + private SocketFD getSocketFD(int fdn) throws ErrnoException { + if(fdn < 0 || fdn >= OPEN_MAX) throw new ErrnoException(EBADFD); + if(fds[fdn] == null) throw new ErrnoException(EBADFD); + if(!(fds[fdn] instanceof SocketFD)) throw new ErrnoException(ENOTSOCK); + + return (SocketFD) fds[fdn]; + } + + private int sys_connect(int fdn, int addr, int namelen) throws ErrnoException, FaultException { + SocketFD fd = getSocketFD(fdn); + + if(fd.type() == SocketFD.TYPE_STREAM && fd.o != null) return -EISCONN; + int word1 = memRead(addr); + if( ((word1 >>> 16)&0xff) != AF_INET) return -EAFNOSUPPORT; + int port = word1 & 0xffff; + byte[] ip = new byte[4]; + copyin(addr+4,ip,4); + + InetAddress inetAddr; + try { + inetAddr = InetAddress.getByAddress(ip); + } catch(UnknownHostException e) { + return -EADDRNOTAVAIL; + } + + try { + switch(fd.type()) { + case SocketFD.TYPE_STREAM: { + Socket s = new Socket(inetAddr,port); + fd.o = s; + fd.setOptions(); + fd.is = s.getInputStream(); + fd.os = s.getOutputStream(); + break; + } + case SocketFD.TYPE_DGRAM: { + DatagramSocket s = (DatagramSocket) fd.o; + if(s == null) s = new DatagramSocket(); + s.connect(inetAddr,port); + break; + } + default: + throw new Error("should never happen"); + } + } catch(IOException e) { + return -ECONNREFUSED; + } + + return 0; + } + + private int sys_resolve_hostname(int chostname, int addr, int sizeAddr) throws FaultException { + String hostname = cstring(chostname); + int size = memRead(sizeAddr); + InetAddress[] inetAddrs; + try { + inetAddrs = InetAddress.getAllByName(hostname); + } catch(UnknownHostException e) { + return HOST_NOT_FOUND; + } + int count = min(size/4,inetAddrs.length); + for(int i=0;i>> 16)&0xff) != AF_INET) return -EAFNOSUPPORT; + int port = word1 & 0xffff; + InetAddress inetAddr = null; + if(memRead(addr+4) != 0) { + byte[] ip = new byte[4]; + copyin(addr+4,ip,4); + + try { + inetAddr = InetAddress.getByAddress(ip); + } catch(UnknownHostException e) { + return -EADDRNOTAVAIL; + } + } + + switch(fd.type()) { + case SocketFD.TYPE_STREAM: { + fd.bindAddr = inetAddr; + fd.bindPort = port; + return 0; + } + case SocketFD.TYPE_DGRAM: { + DatagramSocket s = (DatagramSocket) fd.o; + if(s != null) s.close(); + try { + fd.o = inetAddr != null ? new DatagramSocket(port,inetAddr) : new DatagramSocket(port); + } catch(IOException e) { + return -EADDRINUSE; + } + return 0; + } + default: + throw new Error("should never happen"); + } + } + + private int sys_listen(int fdn, int backlog) throws ErrnoException { + SocketFD fd = getSocketFD(fdn); + if(fd.type() != SocketFD.TYPE_STREAM) return -EOPNOTSUPP; + if(fd.o != null) return -EISCONN; + if(fd.bindPort < 0) return -EOPNOTSUPP; + + try { + fd.o = new ServerSocket(fd.bindPort,backlog,fd.bindAddr); + fd.flags |= SocketFD.LISTEN; + return 0; + } catch(IOException e) { + return -EADDRINUSE; + } + + } + + private int sys_accept(int fdn, int addr, int lenaddr) throws ErrnoException, FaultException { + SocketFD fd = getSocketFD(fdn); + if(fd.type() != SocketFD.TYPE_STREAM) return -EOPNOTSUPP; + if(!fd.listen()) return -EOPNOTSUPP; + + int size = memRead(lenaddr); + + ServerSocket s = (ServerSocket) fd.o; + Socket client; + try { + client = s.accept(); + } catch(IOException e) { + return -EIO; + } + + if(size >= 8) { + memWrite(addr,(6 << 24) | (AF_INET << 16) | client.getPort()); + byte[] b = client.getInetAddress().getAddress(); + copyout(b,addr+4,4); + memWrite(lenaddr,8); + } + + SocketFD clientFD = new SocketFD(SocketFD.TYPE_STREAM); + clientFD.o = client; + try { + clientFD.is = client.getInputStream(); + clientFD.os = client.getOutputStream(); + } catch(IOException e) { + return -EIO; + } + int n = addFD(clientFD); + if(n == -1) { clientFD.close(); return -ENFILE; } + return n; + } + + private int sys_shutdown(int fdn, int how) throws ErrnoException { + SocketFD fd = getSocketFD(fdn); + if(fd.type() != SocketFD.TYPE_STREAM || fd.listen()) return -EOPNOTSUPP; + if(fd.o == null) return -ENOTCONN; + + Socket s = (Socket) fd.o; + + try { + if(how == SHUT_RD || how == SHUT_RDWR) s.shutdownInput(); + if(how == SHUT_WR || how == SHUT_RDWR) s.shutdownOutput(); + } catch(IOException e) { + return -EIO; + } + + return 0; + } + + private static String hostName() { + try { + return InetAddress.getLocalHost().getHostName(); + } catch(UnknownHostException e) { + return "darkstar"; + } + } + + private int sys_sysctl(int nameaddr, int namelen, int oldp, int oldlenaddr, int newp, int newlen) throws FaultException { + if(newp != 0) return -EPERM; + if(namelen == 0) return -ENOENT; + if(oldp == 0) return 0; + + Object o = null; + switch(memRead(nameaddr)) { + case CTL_KERN: + if(namelen != 2) break; + switch(memRead(nameaddr+4)) { + case KERN_OSTYPE: o = "NestedVM"; break; + case KERN_HOSTNAME: o = hostName(); break; + case KERN_OSRELEASE: o = VERSION; break; + case KERN_VERSION: o = "NestedVM Kernel Version " + VERSION; break; + } + break; + case CTL_HW: + if(namelen != 2) break; + switch(memRead(nameaddr+4)) { + case HW_MACHINE: o = "NestedVM Virtual Machine"; break; + } + break; + } + if(o == null) return -ENOENT; + int len = memRead(oldlenaddr); + if(o instanceof String) { + byte[] b = getNullTerminatedBytes((String)o); + if(len < b.length) return -ENOMEM; + len = b.length; + copyout(b,oldp,len); + memWrite(oldlenaddr,len); + } else if(o instanceof Integer) { + if(len < 4) return -ENOMEM; + memWrite(oldp,((Integer)o).intValue()); + } else { + throw new Error("should never happen"); + } + return 0; + } + + + /*public int sys_opensocket(int cstring, int port) throws FaultException, ErrnoException { String hostname = cstring(cstring); try { FD fd = new SocketFD(new Socket(hostname,port)); diff --git a/src/org/ibex/nestedvm/support_aux.c b/src/org/ibex/nestedvm/support_aux.c index c309899..78cc495 100644 --- a/src/org/ibex/nestedvm/support_aux.c +++ b/src/org/ibex/nestedvm/support_aux.c @@ -155,6 +155,19 @@ long _pathconf_r(struct _reent *ptr,const char *path, int name) { } } +int _sysctl_r(struct _reent *ptr, int *name, int namelen, void *oldp, size_t *oldlen, void *newp, size_t newlen) { + if(name[0] != CTL_USER) return _sysctl(name,namelen,oldp,oldlen,newp,newlen); + if(newp != NULL) { ptr->_errno = EPERM; return -1; } + if(namelen != 2) { ptr->_errno = EINVAL; return -1; } + + switch(name[1]) { + default: + fprintf(stderr,"WARNING: sysctl: Unknown name: %d\n",name[1]); + ptr->_errno = EINVAL; + return -1; + } +} + void sync() { /* do nothing*/ } @@ -425,6 +438,88 @@ const char *path; return(bname); } +/* FreeBSD's uname */ +int +uname(name) +struct utsname *name; +{ + int mib[2], rval; + size_t len; + char *p; + int oerrno; + + rval = 0; + + mib[0] = CTL_KERN; + mib[1] = KERN_OSTYPE; + len = sizeof(name->sysname); + oerrno = errno; + if (sysctl(mib, 2, &name->sysname, &len, NULL, 0) == -1) { + if(errno == ENOMEM) + errno = oerrno; + else + rval = -1; + } + name->sysname[sizeof(name->sysname) - 1] = '\0'; + + mib[0] = CTL_KERN; + mib[1] = KERN_HOSTNAME; + len = sizeof(name->nodename); + oerrno = errno; + if (sysctl(mib, 2, &name->nodename, &len, NULL, 0) == -1) { + if(errno == ENOMEM) + errno = oerrno; + else + rval = -1; + } + name->nodename[sizeof(name->nodename) - 1] = '\0'; + + mib[0] = CTL_KERN; + mib[1] = KERN_OSRELEASE; + len = sizeof(name->release); + oerrno = errno; + if (sysctl(mib, 2, &name->release, &len, NULL, 0) == -1) { + if(errno == ENOMEM) + errno = oerrno; + else + rval = -1; + } + name->release[sizeof(name->release) - 1] = '\0'; + + /* The version may have newlines in it, turn them into spaces. */ + mib[0] = CTL_KERN; + mib[1] = KERN_VERSION; + len = sizeof(name->version); + oerrno = errno; + if (sysctl(mib, 2, &name->version, &len, NULL, 0) == -1) { + if (errno == ENOMEM) + errno = oerrno; + else + rval = -1; + } + name->version[sizeof(name->version) - 1] = '\0'; + for (p = name->version; len--; ++p) { + if (*p == '\n' || *p == '\t') { + if (len > 1) + *p = ' '; + else + *p = '\0'; + } + } + + mib[0] = CTL_HW; + mib[1] = HW_MACHINE; + len = sizeof(name->machine); + oerrno = errno; + if (sysctl(mib, 2, &name->machine, &len, NULL, 0) == -1) { + if (errno == ENOMEM) + errno = oerrno; + else + rval = -1; + } + name->machine[sizeof(name->machine) - 1] = '\0'; + return (rval); +} /* FreeBSD's daemon() - modified for nestedvm */ int -- 1.7.10.4 From 960bb4430543bc48cdb46e5ad49afc24bfa04f3b Mon Sep 17 00:00:00 2001 From: brian Date: Thu, 20 May 2004 05:36:48 -0700 Subject: [PATCH 16/16] misc cleanup darcs-hash:20040520123648-24bed-f3171f46c8d8996de749f1a306d5374a5ab912ca.gz --- src/org/ibex/nestedvm/crt0.c | 2 -- src/org/ibex/nestedvm/linker.ld | 5 +++-- src/tests/SpeedTest.java | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/org/ibex/nestedvm/crt0.c b/src/org/ibex/nestedvm/crt0.c index a85cdbc..7e2c69e 100644 --- a/src/org/ibex/nestedvm/crt0.c +++ b/src/org/ibex/nestedvm/crt0.c @@ -1,7 +1,5 @@ #include -extern int _gp[]; - extern int main(int argc, char **argv, char **envp); extern void exit(int status); extern int atexit(void (*f)()); diff --git a/src/org/ibex/nestedvm/linker.ld b/src/org/ibex/nestedvm/linker.ld index 13330f1..ca67d9c 100644 --- a/src/org/ibex/nestedvm/linker.ld +++ b/src/org/ibex/nestedvm/linker.ld @@ -46,11 +46,12 @@ SECTIONS { . = ALIGN(16); _gp = . + 0x8000; .sdata : { - *(.rosdata*) *(.sdata*) *(.gnu.linkonce.s*) + *(.rosdata*) *(.sdata*) *(.gnu.linkonce.s) *(.gnu.linkonce.s.*) } .sbss : { - *(.sbss*) *(.scommon*) + *(.sbss*) *(.scommon*) *(.gnu.linkonce.sb*) } + .bss : { *(.bss*) *(.gnu.linkonce.b*) *(COMMON) } diff --git a/src/tests/SpeedTest.java b/src/tests/SpeedTest.java index 667d9a2..35941c1 100644 --- a/src/tests/SpeedTest.java +++ b/src/tests/SpeedTest.java @@ -2,8 +2,8 @@ package tests; import org.ibex.nestedvm.Runtime; -import java.io.*; -import java.util.*; +//import java.io.*; +//import java.util.*; class SpeedTest { private static long start,end; -- 1.7.10.4