]> gitweb.factorcode.org Git - factor.git/commitdiff
compiler work
authorSlava Pestov <slava@factorcode.org>
Sat, 11 Sep 2004 19:26:24 +0000 (19:26 +0000)
committerSlava Pestov <slava@factorcode.org>
Sat, 11 Sep 2004 19:26:24 +0000 (19:26 +0000)
16 files changed:
Makefile
doc/devel-guide.tex
factor/FactorInterpreter.java
library/compiler/assembler.factor
library/compiler/assembly-x86.factor
library/compiler/compiler.factor
library/compiler/words.factor
library/cross-compiler.factor
library/image.factor
library/platform/jvm/cross-compiler.factor
library/platform/native/boot.factor
library/platform/native/cross-compiler.factor
library/platform/native/parse-syntax.factor
library/test/image.factor
library/test/x86-compiler/compiler.factor
native/memory.c

index 1ef2485b088e73714d01f7693e8a768f74f45ec7..c8c1ce7f8a6d6cf2c5427c4e7cb3a6173a0be1e1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@ CC = gcc
 # On PowerPC G5:
 # CFLAGS = -mcpu=970 -mtune=970 -mpowerpc64 -ffast-math -O3
 # On Pentium 4:
-# CFLAGS = -march=pentium4 -ffast-math -O3
+# CFLAGS = -march=pentium4 -ffast-math -O3 -fomit-frame-pointer
 # Add -fomit-frame-pointer if you don't care about debugging
 CFLAGS = -Os -g -Wall
 
index 9b31957c3ca5860d09f034aa29275ef0d296d94c..e04f1c21aac1d4f82e69d4d163928206247dad68 100644 (file)
@@ -409,6 +409,7 @@ is pushed on the stack. Try evaluating the following:
 call .s
 \emph{\{ 5 \}}
 \end{alltt}
+
 \texttt{call} \texttt{( quot -{}- )} executes the quotation at the
 top of the stack. Using \texttt{call} with a literal quotation is
 useless; writing out the elements of the quotation has the same effect.
@@ -442,10 +443,6 @@ More combinators will be introduced in later sections.
 
 \subsection{Recursion}
 
-The idea of \emph{recursion} is key to understanding Factor. A \emph{recursive} word definition is one that refers to itself, usually in one branch of a conditional.
-
-FIXME
-
 \section{Numbers}
 
 Factor provides a rich set of math words. Factor numbers more closely model the mathematical concept of a number than other languages. Where possible, exact answers are given -- for example, adding or multiplying two integers never results in overflow, and dividing two integers yields a fraction rather than a truncated result. Complex numbers are supported, allowing many functions to be computed with parameters that would raise errors or return ``not a number'' in other languages.
@@ -2400,11 +2397,28 @@ The name stack is really just a vector. The words \texttt{>n} and \texttt{n>} ar
 : n> ( n:namespace -- namespace ) namestack* vector-pop ;
 \end{alltt}
 
-\section{Metaprogramming}
+\section{The execution model in depth}
 
-Recall that code quotations are in fact just linked lists. Factor code is data, and vice versa. Essentially, the interpreter iterates through code quotations, pushing literals and executing words. When a word is executed, one of two things happen -- either the word has a colon definition, and the interpreter is invoked recursively on the definition, or the word is primitive, and it is executed by the underlying virtual machine. A word is itself a first-class object.
+\subsection{Recursion}
 
-It is the job of the parser to transform source code denoting literals and words into their internal representations. This is done using a vocabulary of \emph{parsing words}. The prettyprinter does the converse, by printing out data structures in a parsable form (both to humans and Factor). Because code is data, text representation of source code doubles as a way to serialize almost any Factor object.
+The idea of \emph{recursion} is key to understanding Factor. A \emph{recursive} word definition is one that refers to itself, usually in one branch of a conditional.
+
+
+tail recursion
+
+preserving values between iterations
+
+ensuring a consistent stack effect
+
+works well with lists, since only the head is passed
+
+not so well with vectors and strings -- need an obj+index
+
+\subsection{Combinators}
+
+a combinator is a recursive word that takes quotations
+
+how to ensure a consistent stack view for the quotations
 
 \subsection{Looking at words}
 
@@ -2452,24 +2466,6 @@ If the primitive number is set to 1, the word is a colon definition and the para
 
 The word \texttt{define ( word quot -{}- )} defines a word to have the specified colon definition. Note that \texttt{create} and  \texttt{define} perform an action somewhat analagous to the \texttt{: ... ;} notation for colon definitions, except at parse time rather than run time.
 
-\subsection{The prettyprinter}
-
-We've already seen the word \texttt{.} which prints the top of the stack in a form that may be read back in. The word \texttt{prettyprint} is similar, except the output is in an indented, multiple-line format. Both words are in the \texttt{prettyprint} vocabulary. Here is an example:
-
-\begin{alltt}
-{[} 1 {[} 2 3 4 {]} 5 {]} .
-\emph{{[} 1 {[} 2 3 4 {]} 5 {]}}
-{[} 1 {[} 2 3 4 {]} 5 {]} prettyprint
-\emph{{[}
-    1 {[}
-        2 3 4
-    {]} 5
-{]}}
-\end{alltt}
-
-
-\subsection{The parser}
-
 \subsection{Parsing words}
 
 Lets take a closer look at Factor syntax. Consider a simple expression,
@@ -2538,6 +2534,29 @@ next occurrence of \texttt{{}''}, and appends this string to the
 current node of the parse tree. Note that strings and words are different
 types of objects. Strings are covered in great detail later.
 
+\section{NOT DONE}
+
+Recall that code quotations are in fact just linked lists. Factor code is data, and vice versa. Essentially, the interpreter iterates through code quotations, pushing literals and executing words. When a word is executed, one of two things happen -- either the word has a colon definition, and the interpreter is invoked recursively on the definition, or the word is primitive, and it is executed by the underlying virtual machine. A word is itself a first-class object.
+
+It is the job of the parser to transform source code denoting literals and words into their internal representations. This is done using a vocabulary of \emph{parsing words}. The prettyprinter does the converse, by printing out data structures in a parsable form (both to humans and Factor). Because code is data, text representation of source code doubles as a way to serialize almost any Factor object.
+
+\subsection{The prettyprinter}
+
+We've already seen the word \texttt{.} which prints the top of the stack in a form that may be read back in. The word \texttt{prettyprint} is similar, except the output is in an indented, multiple-line format. Both words are in the \texttt{prettyprint} vocabulary. Here is an example:
+
+\begin{alltt}
+{[} 1 {[} 2 3 4 {]} 5 {]} .
+\emph{{[} 1 {[} 2 3 4 {]} 5 {]}}
+{[} 1 {[} 2 3 4 {]} 5 {]} prettyprint
+\emph{{[}
+    1 {[}
+        2 3 4
+    {]} 5
+{]}}
+\end{alltt}
+
+
+\subsection{Profiling}
 
 \section{PRACTICAL: Infix syntax}
 
index 6ab77d451d1387efae806b8f20dbdba5ec1f0bc4..ba2a9682414046a136254adfad6d41aa6aa59a88 100644 (file)
@@ -35,7 +35,7 @@ import java.io.*;
 
 public class FactorInterpreter implements FactorObject, Runnable
 {
-       public static final String VERSION = "0.65";
+       public static final String VERSION = "0.66";
 
        public static final Cons DEFAULT_USE = new Cons("builtins",
                new Cons("syntax",new Cons("scratchpad",null)));
index 6411bf076d9cb60de68a26de5c16751635bf3bca..1466530bd3569c28d23fb4212c3f607a4b054150 100644 (file)
@@ -26,6 +26,7 @@
 ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 IN: compiler
+USE: combinators
 USE: math
 USE: kernel
 USE: stack
@@ -36,6 +37,13 @@ USE: stack
 : init-assembler ( -- )
     compiled-offset literal-table + set-compiled-offset ;
 
+: compile-aligned ( n -- )
+    dup compiled-offset mod dup 0 = [
+        2drop
+    ] [
+        - compiled-offset + set-compiled-offset
+    ] ifte ;
+
 : intern-literal ( obj -- lit# )
     address-of
     literal-top set-compiled-cell
index 34cdcf145f5ce00734153fd1d14daf87024b4398..286f119c0b5cc67930c0cffda9f26d2c350b87ab 100644 (file)
@@ -41,6 +41,9 @@ USE: combinators
 : ESI 6 ;
 : EDI 7 ;
 
+: MOD-R/M ( r/m reg/opcode mod -- )
+    6 shift swap 3 shift bitor bitor compile-byte ;
+
 : PUSH ( reg -- )
     HEX: 50 + compile-byte ;
 
@@ -57,7 +60,7 @@ USE: combinators
         drop HEX: a1 compile-byte
     ] [
         HEX: 8b compile-byte
-        3 shift BIN: 101 bitor compile-byte
+        BIN: 101 swap 0 MOD-R/M
     ] ifte compile-cell ;
 
 : I>[R] ( imm reg -- )
@@ -71,21 +74,21 @@ USE: combinators
         nip HEX: a3 compile-byte
     ] [
         HEX: 89 compile-byte
-        swap 3 shift BIN: 101 bitor compile-byte
+        swap BIN: 101 swap 0 MOD-R/M
     ] ifte compile-cell ;
 
 : [R]>R ( reg reg -- )
     #! MOV INDIRECT <reg> TO <reg>.
-    HEX: 8b compile-byte  swap 3 shift bitor compile-byte ;
+    HEX: 8b compile-byte  swap 0 MOD-R/M ;
 
 : R>[R] ( reg reg -- )
     #! MOV <reg> TO INDIRECT <reg>.
-    HEX: 89 compile-byte  swap 3 shift bitor compile-byte ;
+    HEX: 89 compile-byte  swap 0 MOD-R/M ;
 
 : I+[I] ( imm addr -- )
     #! ADD <imm> TO ADDRESS <addr>
     HEX: 81 compile-byte
-    HEX: 05 compile-byte
+    BIN: 101 0 0 MOD-R/M
     compile-cell
     compile-cell ;
 
@@ -93,14 +96,14 @@ USE: combinators
     #! SUBTRACT <imm> FROM <reg>, STORE RESULT IN <reg>
     over -128 127 between? [
         HEX: 83 compile-byte
-        HEX: e8 + compile-byte
+        BIN: 101 BIN: 11 MOD-R/M
         compile-byte
     ] [
         dup EAX = [
             drop HEX: 2d compile-byte
         ] [
             HEX: 81 compile-byte
-            BIN: 11101000 bitor
+            BIN: 101 BIN: 11 MOD-R/M
         ] ifte
         compile-cell
     ] ifte ;
@@ -111,11 +114,11 @@ USE: combinators
     #! 81 38 33 33 33 00       cmpl   $0x333333,(%eax)
     over -128 127 between? [
         HEX: 83 compile-byte
-        HEX: 38 + compile-byte
+        BIN: 111 0 MOD-R/M
         compile-byte
     ] [
         HEX: 81 compile-byte
-        HEX: 38 + compile-byte
+        BIN: 111 0 MOD-R/M
         compile-cell
     ] ifte ;
 
@@ -127,8 +130,8 @@ USE: combinators
     4 DATASTACK I+[I] ;
 
 : [LITERAL] ( cell -- )
-    #! Push literal on data stack by following an indirect
-    #! pointer.
+    #! Push complex literal on data stack by following an
+    #! indirect pointer.
     ECX PUSH
     ( cell -- ) ECX [I]>R
     DATASTACK EAX [I]>R
index 2103b06d38dab53ac7b0c3aea3837819676b623c..c7c9a19f75490525e1cc373b485b062ee324ef8c 100644 (file)
@@ -132,6 +132,7 @@ USE: words
     ] with-scope ;
 
 : begin-compiling ( word -- )
+    cell compile-aligned
     compiled-offset "compiled-xt" rot set-word-property ;
 
 : end-compiling ( word -- xt )
index 973f7fb62c561a578f5068e72c36594b6c00b5e2..2461a901517913385bcfb7b0d2352b1fe3d6ae2b 100644 (file)
 ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 IN: compiler
+USE: combinators
 USE: words
 USE: stack
 USE: kernel
 USE: math
+USE: lists
 
-: compile-ifte ( -- )
-    pop-literal pop-literal  commit-literals
+: compile-f-test ( -- fixup )
+    #! Push addr where we write the branch target address.
     POP-DS
     ! ptr to condition is now in EAX
     f address-of EAX CMP-I-[R]
-    compiled-offset JE ( -- fixup ) >r
+    compiled-offset JE ;
+
+: branch-target ( fixup -- )
+    cell compile-aligned compiled-offset swap fixup ;
+
+: compile-else ( fixup -- fixup )
+    #! Push addr where we write the branch target address,
+    #! and fixup branch target address from compile-f-test.
+    #! Push f for the fixup if we're tail position.
+    tail? [ RET f ] [ 0 JUMP ] ifte swap branch-target ;
+
+: compile-end-if ( fixup -- )
+    tail? [ drop RET ] [ branch-target ] ifte ;
+
+: compile-ifte ( -- )
+    pop-literal pop-literal  commit-literals
+    compile-f-test >r
     ( t -- ) compile-quot
-    RET
-    compiled-offset  r> ( fixup -- ) fixup
+    r> compile-else >r
     ( f -- ) compile-quot
-    RET ;
+    r> compile-end-if ;
 
-[ compile-ifte ]
-"compiling"
-"ifte" [ "combinators" ] search
-set-word-property
+[
+    [ ifte compile-ifte ]
+] [
+    unswons "compiling" swap set-word-property
+] each
index def7a9f474423ad822de399512b8cdb31b2d85df..16f14ff2d71dae5c42c4499b1dfd790c53c6a5d8 100644 (file)
@@ -25,7 +25,6 @@
 ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-IN: cross-compiler
 USE: combinators
 USE: kernel
 USE: lists
@@ -127,7 +126,7 @@ DEFER: set-word-plist
 IN: unparser
 DEFER: unparse-float
 
-IN: cross-compiler
+IN: image
 
 : primitives, ( -- )
     1 [
index 531ac6a2b76bd44a137b96f51b6aed812c33f9f0..5bfd0cc0f9b474f75066b1b0157fa8027b1e4454 100644 (file)
 ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-IN: cross-compiler
+IN: namespaces
+
+( Java Factor doesn't have this )
+: namespace-buckets 23 ;
+
+IN: image
 USE: combinators
 USE: errors
 USE: hashtables
@@ -254,12 +259,6 @@ DEFER: '
 
 ( Word definitions )
 
-IN: namespaces
-
-: namespace-buckets 23 ;
-
-IN: cross-compiler
-
 : (vocabulary) ( name -- vocab )
     #! Vocabulary for target image.
     dup "vocabularies" get hash dup [
index ebfb392b802f7b7aae8d00f7bdfc4e1ffb65d8c2..5f9ff4aa34bec867b7f00d40b6da98ea2936f2a6 100644 (file)
@@ -25,7 +25,7 @@
 ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-IN: cross-compiler
+IN: image
 USE: combinators
 USE: kernel
 USE: lists
index bd432d62fcd399436230020fefc4116fadd7b202..0018cfcae5d43edd6003dc8ace45e023e80d91e4 100644 (file)
@@ -26,7 +26,7 @@
 ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 USE: lists
-USE: cross-compiler
+USE: image
 
 primitives,
 [
index 8d276074e189c37088583fa947f701d9694eae09..78a758cd60842c75b83991fada8de728befdbc5d 100644 (file)
@@ -25,7 +25,7 @@
 ! OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 ! ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-IN: cross-compiler
+IN: image
 USE: namespaces
 USE: parser
 
index 5a258dbc6019eff8b9d9503694b2e35ebd301d48..61b1287fba4e95607b83f11f9e3a9bc5ae183468 100644 (file)
@@ -28,7 +28,6 @@
 IN: syntax
 
 USE: combinators
-USE: cross-compiler
 USE: errors
 USE: kernel
 USE: lists
index 269ead768f7caf0f89f1d6b34626cda369c716bf..22203b3fc4f6ef1a7c34f071cd44b1719ed2b6e5 100644 (file)
@@ -1,5 +1,5 @@
 USE: test
-USE: cross-compiler
+USE: image
 USE: namespaces
 USE: stdio
 
index 7d1988f608fab523fe20391ade7889cebb593656..5624ed9e86c68c9cb20efe0863267ece6f7a1b38 100644 (file)
@@ -75,3 +75,8 @@ garbage-collection
 : one-rec [ f one-rec ] [ "hi" ] ifte ; compiled
 
 [ "hi" ] [ t one-rec ] unit-test
+
+: after-ifte-test
+    t [ ] [ ] ifte 5 ; compiled
+
+[ 5 ] [ after-ifte-test ] unit-test
index 38da000eaec67a0bd314d7b9a96767b1630a8a0a..cd374235888640ca2d5e217681f4fa1598699a00 100644 (file)
@@ -7,7 +7,8 @@ void* alloc_guarded(CELL size)
        int pagesize = getpagesize();
 
        char* array = mmap((void*)0,pagesize + size + pagesize,
-               PROT_READ | PROT_WRITE,MAP_ANON | MAP_PRIVATE,-1,0);
+               PROT_READ | PROT_WRITE | PROT_EXEC,
+               MAP_ANON | MAP_PRIVATE,-1,0);
 
        if(mprotect(array,pagesize,PROT_NONE) == -1)
                fatal_error("Cannot allocate low guard page",(CELL)array);