diff --git a/.gitignore b/.gitignore index 290f075aae..f4334f3727 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ temp logs work build-support/wordsize +*.bak diff --git a/Makefile b/Makefile index 973ba1f3d4..ffcbf6364c 100644 --- a/Makefile +++ b/Makefile @@ -161,7 +161,7 @@ factor: $(DLL_OBJS) $(EXE_OBJS) clean: rm -f vm/*.o - rm -f factor*.dll libfactor*.* + rm -f factor*.dll libfactor.{a,so,dylib} vm/resources.o: $(WINDRES) vm/factor.rs vm/resources.o diff --git a/README.txt b/README.txt index 754791aa1a..98616539d2 100755 --- a/README.txt +++ b/README.txt @@ -43,13 +43,10 @@ Compilation will yield an executable named 'factor' on Unix, For X11 support, you need recent development libraries for libc, Freetype, X11, OpenGL and GLUT. On a Debian-derived Linux distribution -(like Ubuntu), you can use the line +(like Ubuntu), you can use the following line to grab everything: sudo apt-get install libc6-dev libfreetype6-dev libx11-dev glutg3-dev -to grab everything (if you're on a non-debian-derived distro please tell -us what the equivalent command is on there and it can be added). - * Bootstrapping the Factor image Once you have compiled the Factor runtime, you must bootstrap the Factor diff --git a/basis/alarms/alarms.factor b/basis/alarms/alarms.factor index 7fdeca9ae6..9cc05b4159 100644 --- a/basis/alarms/alarms.factor +++ b/basis/alarms/alarms.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2005, 2008 Slava Pestov, Doug Coleman. ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays calendar combinators generic init -kernel math namespaces sequences heaps boxes threads debugger +kernel math namespaces sequences heaps boxes threads quotations assocs math.order ; IN: alarms @@ -35,7 +35,7 @@ ERROR: bad-alarm-frequency frequency ; [ time>> ] dip before=? ; : reschedule-alarm ( alarm -- ) - dup [ swap interval>> time+ ] change-time register-alarm ; + dup [ swap interval>> time+ now max ] change-time register-alarm ; : call-alarm ( alarm -- ) [ entry>> box> drop ] diff --git a/basis/alien/arrays/arrays-docs.factor b/basis/alien/arrays/arrays-docs.factor index 09a09cdc6f..c5efe1e030 100644 --- a/basis/alien/arrays/arrays-docs.factor +++ b/basis/alien/arrays/arrays-docs.factor @@ -1,69 +1,7 @@ IN: alien.arrays USING: help.syntax help.markup byte-arrays alien.c-types ; -ARTICLE: "c-arrays-factor" "Converting C arrays to and from Factor arrays" -"Each primitive C type has a pair of words, " { $snippet ">" { $emphasis "type" } "-array" } " and " { $snippet { $emphasis "type" } "-array>" } ", for converting an array of Factor objects to and from a " { $link byte-array } " of C values. This set of words consists of:" -{ $subsection >c-bool-array } -{ $subsection >c-char-array } -{ $subsection >c-double-array } -{ $subsection >c-float-array } -{ $subsection >c-int-array } -{ $subsection >c-long-array } -{ $subsection >c-longlong-array } -{ $subsection >c-short-array } -{ $subsection >c-uchar-array } -{ $subsection >c-uint-array } -{ $subsection >c-ulong-array } -{ $subsection >c-ulonglong-array } -{ $subsection >c-ushort-array } -{ $subsection >c-void*-array } -{ $subsection c-bool-array> } -{ $subsection c-char-array> } -{ $subsection c-double-array> } -{ $subsection c-float-array> } -{ $subsection c-int-array> } -{ $subsection c-long-array> } -{ $subsection c-longlong-array> } -{ $subsection c-short-array> } -{ $subsection c-uchar-array> } -{ $subsection c-uint-array> } -{ $subsection c-ulong-array> } -{ $subsection c-ulonglong-array> } -{ $subsection c-ushort-array> } -{ $subsection c-void*-array> } ; - -ARTICLE: "c-arrays-get/set" "Reading and writing elements in C arrays" -"Each C type has a pair of words, " { $snippet { $emphasis "type" } "-nth" } " and " { $snippet "set-" { $emphasis "type" } "-nth" } ", for reading and writing values of this type stored in an array. This set of words includes but is not limited to:" -{ $subsection char-nth } -{ $subsection set-char-nth } -{ $subsection uchar-nth } -{ $subsection set-uchar-nth } -{ $subsection short-nth } -{ $subsection set-short-nth } -{ $subsection ushort-nth } -{ $subsection set-ushort-nth } -{ $subsection int-nth } -{ $subsection set-int-nth } -{ $subsection uint-nth } -{ $subsection set-uint-nth } -{ $subsection long-nth } -{ $subsection set-long-nth } -{ $subsection ulong-nth } -{ $subsection set-ulong-nth } -{ $subsection longlong-nth } -{ $subsection set-longlong-nth } -{ $subsection ulonglong-nth } -{ $subsection set-ulonglong-nth } -{ $subsection float-nth } -{ $subsection set-float-nth } -{ $subsection double-nth } -{ $subsection set-double-nth } -{ $subsection void*-nth } -{ $subsection set-void*-nth } ; - ARTICLE: "c-arrays" "C arrays" "C arrays are allocated in the same manner as other C data; see " { $link "c-byte-arrays" } " and " { $link "malloc" } "." $nl -"C type specifiers for array types are documented in " { $link "c-types-specs" } "." -{ $subsection "c-arrays-factor" } -{ $subsection "c-arrays-get/set" } ; +"C type specifiers for array types are documented in " { $link "c-types-specs" } "." ; diff --git a/basis/alien/arrays/arrays.factor b/basis/alien/arrays/arrays.factor index 94472e8261..727492edb1 100644 --- a/basis/alien/arrays/arrays.factor +++ b/basis/alien/arrays/arrays.factor @@ -8,6 +8,8 @@ UNION: value-type array struct-type ; M: array c-type ; +M: array c-type-class drop object ; + M: array heap-size unclip heap-size [ * ] reduce ; M: array c-type-align first c-type-align ; diff --git a/basis/alien/c-types/c-types-docs.factor b/basis/alien/c-types/c-types-docs.factor index 739b45486f..a2b555b057 100644 --- a/basis/alien/c-types/c-types-docs.factor +++ b/basis/alien/c-types/c-types-docs.factor @@ -89,16 +89,6 @@ HELP: malloc-byte-array { $warning "Don't forget to deallocate the memory with a call to " { $link free } "." } { $errors "Throws an error if memory allocation fails." } ; -HELP: define-nth -{ $values { "name" "a word name" } { "vocab" "a vocabulary name" } } -{ $description "Defines a word " { $snippet { $emphasis "name" } "-nth" } " with stack effect " { $snippet "( n c-ptr -- value )" } " for reading the value with C type " { $snippet "name" } " stored at an alien pointer, displaced by a multiple of the C type's size." } -{ $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ; - -HELP: define-set-nth -{ $values { "name" "a word name" } { "vocab" "a vocabulary name" } } -{ $description "Defines a word " { $snippet "set-" { $emphasis "name" } "-nth" } " with stack effect " { $snippet "( value n c-ptr -- )" } " for writing the value with C type " { $snippet "name" } " to an alien pointer, displaced by a multiple of the C type's size." } -{ $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ; - HELP: box-parameter { $values { "n" integer } { "ctype" string } } { $description "Generates code for converting a C value stored at offset " { $snippet "n" } " from the top of the stack into a Factor object to be pushed on the data stack." } @@ -115,12 +105,12 @@ HELP: unbox-return { $notes "This is an internal word used by the compiler when compiling callbacks." } ; HELP: define-deref -{ $values { "name" "a word name" } { "vocab" "a vocabulary name" } } +{ $values { "name" "a word name" } } { $description "Defines a word " { $snippet "*name" } " with stack effect " { $snippet "( c-ptr -- value )" } " for reading a value with C type " { $snippet "name" } " stored at an alien pointer." } { $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ; HELP: define-out -{ $values { "name" "a word name" } { "vocab" "a vocabulary name" } } +{ $values { "name" "a word name" } } { $description "Defines a word " { $snippet "<" { $emphasis "name" } ">" } " with stack effect " { $snippet "( value -- array )" } ". This word allocates a byte array large enough to hold a value with C type " { $snippet "name" } ", and writes the value at the top of the stack to the array." } { $notes "This is an internal word called when defining C types, there is no need to call it on your own." } ; @@ -230,9 +220,7 @@ $nl "You can copy a range of bytes from memory into a byte array:" { $subsection memory>byte-array } "You can copy a byte array to memory unsafely:" -{ $subsection byte-array>memory } -"A wrapper for temporarily allocating a block of memory:" -{ $subsection with-malloc } ; +{ $subsection byte-array>memory } ; ARTICLE: "c-data" "Passing data between Factor and C" "Two defining characteristics of Factor are dynamic typing and automatic memory management, which are somewhat incompatible with the machine-level data model exposed by C. Factor's C library interface defines its own set of C data types, distinct from Factor language types, together with automatic conversion between Factor values and C types. For example, C integer types must be declared and are fixed-width, whereas Factor supports arbitrary-precision integers." diff --git a/basis/alien/c-types/c-types-tests.factor b/basis/alien/c-types/c-types-tests.factor index edda9e7fdb..31542b2699 100644 --- a/basis/alien/c-types/c-types-tests.factor +++ b/basis/alien/c-types/c-types-tests.factor @@ -8,7 +8,7 @@ sequences system libc alien.strings io.encodings.utf8 ; [ { "blah" 123 } ] [ { "blah" xyz } expand-constants ] unit-test -: foo ( -- n ) "fdafd" f dlsym [ 123 ] unless* ; +: foo ( -- n ) &: fdafd [ 123 ] unless* ; [ 123 ] [ foo ] unit-test @@ -55,4 +55,6 @@ TYPEDEF: uchar* MyLPBYTE 0 B{ 1 2 3 4 } ] must-fail -[ t ] [ { t f t } >c-bool-array { 1 0 1 } >c-int-array = ] unit-test +os windows? cpu x86.64? and [ + [ -2147467259 ] [ 2147500037 *long ] unit-test +] when diff --git a/basis/alien/c-types/c-types.factor b/basis/alien/c-types/c-types.factor index a93c87611d..ae148e3ac0 100644 --- a/basis/alien/c-types/c-types.factor +++ b/basis/alien/c-types/c-types.factor @@ -4,7 +4,7 @@ USING: byte-arrays arrays assocs kernel kernel.private libc math namespaces make parser sequences strings words assocs splitting math.parser cpu.architecture alien alien.accessors quotations layouts system compiler.units io.files io.encodings.binary -accessors combinators effects continuations ; +accessors combinators effects continuations fry ; IN: alien.c-types DEFER: @@ -13,13 +13,15 @@ DEFER: *char : little-endian? ( -- ? ) 1 *char 1 = ; foldable TUPLE: c-type +class boxer boxer-quot unboxer unboxer-quot getter setter reg-class size align stack-align? ; : new-c-type ( class -- type ) new - int-regs >>reg-class ; + int-regs >>reg-class + object >>class ; inline : ( -- type ) \ c-type new-c-type ; @@ -50,7 +52,7 @@ GENERIC: c-type ( name -- type ) foldable : parse-array-type ( name -- array ) "[" split unclip - >r [ "]" ?tail drop string>number ] map r> prefix ; + [ [ "]" ?tail drop string>number ] map ] dip prefix ; M: string c-type ( name -- type ) CHAR: ] over member? [ @@ -63,6 +65,12 @@ M: string c-type ( name -- type ) ] ?if ] if ; +GENERIC: c-type-class ( name -- class ) + +M: c-type c-type-class class>> ; + +M: string c-type-class c-type c-type-class ; + GENERIC: c-type-boxer ( name -- boxer ) M: c-type c-type-boxer boxer>> ; @@ -164,7 +172,7 @@ GENERIC: stack-size ( type -- size ) foldable M: string stack-size c-type stack-size ; -M: c-type stack-size size>> ; +M: c-type stack-size size>> cell align ; GENERIC: byte-length ( seq -- n ) flushable @@ -172,12 +180,12 @@ M: byte-array byte-length length ; : c-getter ( name -- quot ) c-type-getter [ - [ "Cannot read struct fields with type" throw ] + [ "Cannot read struct fields with this type" throw ] ] unless* ; : c-setter ( name -- quot ) c-type-setter [ - [ "Cannot write struct fields with type" throw ] + [ "Cannot write struct fields with this type" throw ] ] unless* ; : ( n type -- array ) @@ -193,36 +201,21 @@ M: byte-array byte-length length ; 1 swap malloc-array ; inline : malloc-byte-array ( byte-array -- alien ) - dup length dup malloc [ -rot memcpy ] keep ; + dup length [ nip malloc dup ] 2keep memcpy ; : memory>byte-array ( alien len -- byte-array ) - dup [ -rot memcpy ] keep ; + [ nip (byte-array) dup ] 2keep memcpy ; : byte-array>memory ( byte-array base -- ) swap dup length memcpy ; -: (define-nth) ( word type quot -- ) +: array-accessor ( type quot -- def ) [ \ swap , [ heap-size , [ * >fixnum ] % ] [ % ] bi* - ] [ ] make define-inline ; - -: nth-word ( name vocab -- word ) - >r "-nth" append r> create ; - -: define-nth ( name vocab -- ) - dupd nth-word swap dup c-getter (define-nth) ; - -: set-nth-word ( name vocab -- word ) - >r "set-" swap "-nth" 3append r> create ; - -: define-set-nth ( name vocab -- ) - dupd set-nth-word swap dup c-setter (define-nth) ; + ] [ ] make ; : typedef ( old new -- ) c-types get set-at ; -: define-c-type ( type name vocab -- ) - >r tuck typedef r> [ define-nth ] 2keep define-set-nth ; - TUPLE: long-long-type < c-type ; : ( -- type ) @@ -240,62 +233,34 @@ M: long-long-type box-parameter ( n type -- ) M: long-long-type box-return ( type -- ) f swap box-parameter ; -: define-deref ( name vocab -- ) - >r dup CHAR: * prefix r> create - swap c-getter 0 prefix define-inline ; +: define-deref ( name -- ) + [ CHAR: * prefix "alien.c-types" create ] + [ c-getter 0 prefix ] bi + define-inline ; -: define-out ( name vocab -- ) - over [ tuck 0 ] over c-setter append swap - >r >r constructor-word r> r> prefix define-inline ; +: define-out ( name -- ) + [ "alien.c-types" constructor-word ] + [ dup c-setter '[ _ [ 0 @ ] keep ] ] + bi define-inline ; : c-bool> ( int -- ? ) zero? not ; -: >c-array ( seq type word -- byte-array ) - [ [ dup length ] dip ] dip - [ [ execute ] 2curry each-index ] 2keep drop ; inline - -: >c-array-quot ( type vocab -- quot ) - dupd set-nth-word [ >c-array ] 2curry ; - -: to-array-word ( name vocab -- word ) - >r ">c-" swap "-array" 3append r> create ; - -: define-to-array ( type vocab -- ) - [ to-array-word ] 2keep >c-array-quot - (( array -- byte-array )) define-declared ; - -: c-array>quot ( type vocab -- quot ) - [ - \ swap , - nth-word 1quotation , - [ curry map ] % - ] [ ] make ; - -: from-array-word ( name vocab -- word ) - >r "c-" swap "-array>" 3append r> create ; - -: define-from-array ( type vocab -- ) - [ from-array-word ] 2keep c-array>quot - (( c-ptr n -- array )) define-declared ; - : define-primitive-type ( type name -- ) - "alien.c-types" - { - [ define-c-type ] - [ define-deref ] - [ define-to-array ] - [ define-from-array ] - [ define-out ] - } 2cleave ; + [ typedef ] + [ define-deref ] + [ define-out ] + tri ; : expand-constants ( c-type -- c-type' ) dup array? [ - unclip >r [ - dup word? [ - def>> { } swap with-datastack first - ] when - ] map r> prefix + unclip [ + [ + dup word? [ + def>> { } swap with-datastack first + ] when + ] map + ] dip prefix ] when ; : malloc-file-contents ( path -- alien len ) @@ -304,8 +269,20 @@ M: long-long-type box-return ( type -- ) : if-void ( type true false -- ) pick "void" = [ drop nip call ] [ nip call ] if ; inline +: primitive-types + { + "char" "uchar" + "short" "ushort" + "int" "uint" + "long" "ulong" + "longlong" "ulonglong" + "float" "double" + "void*" "bool" + } ; + [ + c-ptr >>class [ alien-cell ] >>getter [ set-alien-cell ] >>setter bootstrap-cell >>size @@ -315,6 +292,7 @@ M: long-long-type box-return ( type -- ) "void*" define-primitive-type + integer >>class [ alien-signed-8 ] >>getter [ set-alien-signed-8 ] >>setter 8 >>size @@ -324,6 +302,7 @@ M: long-long-type box-return ( type -- ) "longlong" define-primitive-type + integer >>class [ alien-unsigned-8 ] >>getter [ set-alien-unsigned-8 ] >>setter 8 >>size @@ -333,6 +312,7 @@ M: long-long-type box-return ( type -- ) "ulonglong" define-primitive-type + integer >>class [ alien-signed-cell ] >>getter [ set-alien-signed-cell ] >>setter bootstrap-cell >>size @@ -342,6 +322,7 @@ M: long-long-type box-return ( type -- ) "long" define-primitive-type + integer >>class [ alien-unsigned-cell ] >>getter [ set-alien-unsigned-cell ] >>setter bootstrap-cell >>size @@ -351,6 +332,7 @@ M: long-long-type box-return ( type -- ) "ulong" define-primitive-type + integer >>class [ alien-signed-4 ] >>getter [ set-alien-signed-4 ] >>setter 4 >>size @@ -360,6 +342,7 @@ M: long-long-type box-return ( type -- ) "int" define-primitive-type + integer >>class [ alien-unsigned-4 ] >>getter [ set-alien-unsigned-4 ] >>setter 4 >>size @@ -369,6 +352,7 @@ M: long-long-type box-return ( type -- ) "uint" define-primitive-type + fixnum >>class [ alien-signed-2 ] >>getter [ set-alien-signed-2 ] >>setter 2 >>size @@ -378,6 +362,7 @@ M: long-long-type box-return ( type -- ) "short" define-primitive-type + fixnum >>class [ alien-unsigned-2 ] >>getter [ set-alien-unsigned-2 ] >>setter 2 >>size @@ -387,6 +372,7 @@ M: long-long-type box-return ( type -- ) "ushort" define-primitive-type + fixnum >>class [ alien-signed-1 ] >>getter [ set-alien-signed-1 ] >>setter 1 >>size @@ -396,6 +382,7 @@ M: long-long-type box-return ( type -- ) "char" define-primitive-type + fixnum >>class [ alien-unsigned-1 ] >>getter [ set-alien-unsigned-1 ] >>setter 1 >>size @@ -414,6 +401,7 @@ M: long-long-type box-return ( type -- ) "bool" define-primitive-type + float >>class [ alien-float ] >>getter [ [ >float ] 2dip set-alien-float ] >>setter 4 >>size @@ -425,6 +413,7 @@ M: long-long-type box-return ( type -- ) "float" define-primitive-type + float >>class [ alien-double ] >>getter [ [ >float ] 2dip set-alien-double ] >>setter 8 >>size @@ -436,6 +425,6 @@ M: long-long-type box-return ( type -- ) "double" define-primitive-type "long" "ptrdiff_t" typedef - + "long" "intptr_t" typedef "ulong" "size_t" typedef ] with-compilation-unit diff --git a/basis/alien/parser/parser.factor b/basis/alien/parser/parser.factor new file mode 100644 index 0000000000..193893fabc --- /dev/null +++ b/basis/alien/parser/parser.factor @@ -0,0 +1,19 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien alien.c-types arrays assocs effects grouping kernel +parser sequences splitting words fry locals ; +IN: alien.parser + +: parse-arglist ( parameters return -- types effect ) + [ 2 group unzip [ "," ?tail drop ] map ] + [ [ { } ] [ 1array ] if-void ] + bi* ; + +: function-quot ( return library function types -- quot ) + '[ _ _ _ _ alien-invoke ] ; + +:: define-function ( return library function parameters -- ) + function create-in dup reset-generic + return library function + parameters return parse-arglist [ function-quot ] dip + define-declared ; diff --git a/basis/alien/prettyprint/prettyprint.factor b/basis/alien/prettyprint/prettyprint.factor new file mode 100644 index 0000000000..0794ab7789 --- /dev/null +++ b/basis/alien/prettyprint/prettyprint.factor @@ -0,0 +1,14 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel combinators alien alien.strings alien.syntax +prettyprint.backend prettyprint.custom prettyprint.sections ; +IN: alien.prettyprint + +M: alien pprint* + { + { [ dup expired? ] [ drop \ BAD-ALIEN pprint-word ] } + { [ dup pinned-c-ptr? not ] [ drop "( displaced alien )" text ] } + [ \ ALIEN: [ alien-address pprint* ] pprint-prefix ] + } cond ; + +M: dll pprint* dll-path dup "DLL\" " "\"" pprint-string ; diff --git a/basis/alien/strings/strings-docs.factor b/basis/alien/strings/strings-docs.factor index 3dc358336c..19c29e613e 100644 --- a/basis/alien/strings/strings-docs.factor +++ b/basis/alien/strings/strings-docs.factor @@ -31,10 +31,6 @@ HELP: string>symbol $nl "On Windows CE, symbols are represented as UCS2 strings, and on all other platforms they are ASCII strings." } ; -HELP: utf16n -{ $class-description "The encoding descriptor for UTF-16 without a byte order mark in native endian order. This is useful mostly for FFI calls which take input of strings of the type wchar_t*" } -{ $see-also "encodings-introduction" } ; - ARTICLE: "c-strings" "C strings" "C string types are arrays with shape " { $snippet "{ \"char*\" encoding }" } ", where " { $snippet "encoding" } " is an encoding descriptor. The type " { $snippet "\"char*\"" } " is an alias for " { $snippet "{ \"char*\" utf8 }" } ". See " { $link "encodings-descriptors" } " for information about encoding descriptors." $nl diff --git a/basis/alien/strings/strings-tests.factor b/basis/alien/strings/strings-tests.factor index c1a509041e..263453ba1c 100644 --- a/basis/alien/strings/strings-tests.factor +++ b/basis/alien/strings/strings-tests.factor @@ -1,6 +1,6 @@ USING: alien.strings tools.test kernel libc io.encodings.8-bit io.encodings.utf8 io.encodings.utf16 -io.encodings.ascii alien io.encodings.string ; +io.encodings.utf16n io.encodings.ascii alien io.encodings.string ; IN: alien.strings.tests [ "\u0000ff" ] diff --git a/basis/alien/strings/strings.factor b/basis/alien/strings/strings.factor index 70bbe773ee..e9053cd5c1 100644 --- a/basis/alien/strings/strings.factor +++ b/basis/alien/strings/strings.factor @@ -2,14 +2,14 @@ ! See http://factorcode.org/license.txt for BSD license. USING: arrays sequences kernel accessors math alien.accessors alien.c-types byte-arrays words io io.encodings -io.streams.byte-array io.streams.memory io.encodings.utf8 -io.encodings.utf16 system alien strings cpu.architecture ; +io.encodings.utf8 io.streams.byte-array io.streams.memory system +alien strings cpu.architecture fry vocabs.loader combinators ; IN: alien.strings GENERIC# alien>string 1 ( c-ptr encoding -- string/f ) M: c-ptr alien>string - >r r> + [ ] [ ] bi* "\0" swap stream-read-until drop ; M: f alien>string @@ -40,6 +40,9 @@ PREDICATE: string-type < pair M: string-type c-type ; +M: string-type c-type-class + drop object ; + M: string-type heap-size drop "void*" heap-size ; @@ -74,10 +77,10 @@ M: string-type c-type-unboxer drop "void*" c-type-unboxer ; M: string-type c-type-boxer-quot - second [ alien>string ] curry [ ] like ; + second '[ _ alien>string ] ; M: string-type c-type-unboxer-quot - second [ string>alien ] curry [ ] like ; + second '[ _ string>alien ] ; M: string-type c-type-getter drop [ alien-cell ] ; @@ -85,27 +88,22 @@ M: string-type c-type-getter M: string-type c-type-setter drop [ set-alien-cell ] ; -! Native-order UTF-16 +HOOK: alien>native-string os ( alien -- string ) -SINGLETON: utf16n - -: utf16n ( -- descriptor ) - little-endian? utf16le utf16be ? ; foldable - -M: utf16n drop utf16n ; - -M: utf16n drop utf16n ; - -: alien>native-string ( alien -- string ) - os windows? [ utf16n ] [ utf8 ] if alien>string ; +HOOK: native-string>alien os ( string -- alien ) : dll-path ( dll -- string ) path>> alien>native-string ; : string>symbol ( str -- alien ) - [ os wince? [ utf16n ] [ utf8 ] if string>alien ] - over string? [ call ] [ map ] if ; + dup string? + [ native-string>alien ] + [ [ native-string>alien ] map ] if ; { "char*" utf8 } "char*" typedef -{ "char*" utf16n } "wchar_t*" typedef "char*" "uchar*" typedef + +{ + { [ os windows? ] [ "alien.strings.windows" require ] } + { [ os unix? ] [ "alien.strings.unix" require ] } +} cond diff --git a/basis/alien/strings/unix/unix.factor b/basis/alien/strings/unix/unix.factor new file mode 100644 index 0000000000..a7b1467344 --- /dev/null +++ b/basis/alien/strings/unix/unix.factor @@ -0,0 +1,8 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.strings io.encodings.utf8 system ; +IN: alien.strings.unix + +M: unix alien>native-string utf8 alien>string ; + +M: unix native-string>alien utf8 string>alien ; diff --git a/basis/alien/strings/windows/windows.factor b/basis/alien/strings/windows/windows.factor new file mode 100644 index 0000000000..55c69246de --- /dev/null +++ b/basis/alien/strings/windows/windows.factor @@ -0,0 +1,13 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.strings alien.c-types io.encodings.utf8 +io.encodings.utf16n system ; +IN: alien.strings.windows + +M: windows alien>native-string utf16n alien>string ; + +M: wince native-string>alien utf16n string>alien ; + +M: winnt native-string>alien utf8 string>alien ; + +{ "char*" utf16n } "wchar_t*" typedef diff --git a/basis/alien/structs/fields/fields.factor b/basis/alien/structs/fields/fields.factor index 19e5b8c326..abce91f56f 100644 --- a/basis/alien/structs/fields/fields.factor +++ b/basis/alien/structs/fields/fields.factor @@ -29,10 +29,10 @@ PREDICATE: slot-writer < word "writing" word-prop >boolean ; writer>> swap "writing" set-word-prop ; : reader-word ( class name vocab -- word ) - >r >r "-" r> 3append r> create ; + [ "-" glue ] dip create ; : writer-word ( class name vocab -- word ) - >r [ swap "set-" % % "-" % % ] "" make r> create ; + [ [ swap "set-" % % "-" % % ] "" make ] dip create ; : ( struct-name vocab type field-name -- spec ) field-spec new @@ -52,25 +52,21 @@ PREDICATE: slot-writer < word "writing" word-prop >boolean ; [ (>>offset) ] [ type>> heap-size + ] 2bi ] reduce ; -: define-struct-slot-word ( spec word quot -- ) - rot offset>> prefix define-inline ; +: define-struct-slot-word ( word quot spec -- ) + offset>> prefix define-inline ; : define-getter ( type spec -- ) [ set-reader-props ] keep - [ ] [ reader>> ] [ type>> [ c-getter ] [ c-type-boxer-quot ] bi append - ] tri - define-struct-slot-word ; + ] + [ ] tri define-struct-slot-word ; : define-setter ( type spec -- ) [ set-writer-props ] keep - [ ] - [ writer>> ] - [ type>> c-setter ] tri - define-struct-slot-word ; + [ writer>> ] [ type>> c-setter ] [ ] tri define-struct-slot-word ; : define-field ( type spec -- ) [ define-getter ] [ define-setter ] 2bi ; diff --git a/basis/alien/structs/structs-tests.factor b/basis/alien/structs/structs-tests.factor index 8c7d9f9b29..ec0c01c2e7 100644 --- a/basis/alien/structs/structs-tests.factor +++ b/basis/alien/structs/structs-tests.factor @@ -38,7 +38,7 @@ C-UNION: barx [ 120 ] [ "barx" heap-size ] unit-test "help" vocab [ - "help" "help" lookup "help" set + "print-topic" "help" lookup "help" set [ ] [ \ foox-x "help" get execute ] unit-test [ ] [ \ set-foox-x "help" get execute ] unit-test ] when diff --git a/basis/alien/structs/structs.factor b/basis/alien/structs/structs.factor index ce30a2ee25..a3c616cda2 100644 --- a/basis/alien/structs/structs.factor +++ b/basis/alien/structs/structs.factor @@ -1,58 +1,63 @@ ! Copyright (C) 2004, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays generic hashtables kernel kernel.private -math namespaces parser sequences strings words libc +math namespaces parser sequences strings words libc fry alien.c-types alien.structs.fields cpu.architecture ; IN: alien.structs -: if-value-structs? ( ctype true false -- ) - value-structs? - [ drop call ] [ >r 2drop "void*" r> call ] if ; inline - TUPLE: struct-type size align fields ; M: struct-type heap-size size>> ; +M: struct-type c-type-class drop object ; + M: struct-type c-type-align align>> ; M: struct-type c-type-stack-align? drop f ; -M: struct-type unbox-parameter - [ %unbox-struct ] [ unbox-parameter ] if-value-structs? ; +: if-value-struct ( ctype true false -- ) + [ dup value-struct? ] 2dip '[ drop "void*" @ ] if ; inline -M: struct-type unbox-return - f swap %unbox-struct ; +M: struct-type unbox-parameter + [ %unbox-large-struct ] [ unbox-parameter ] if-value-struct ; M: struct-type box-parameter - [ %box-struct ] [ box-parameter ] if-value-structs? ; + [ %box-large-struct ] [ box-parameter ] if-value-struct ; + +: if-small-struct ( c-type true false -- ? ) + [ dup struct-small-enough? ] 2dip '[ f swap @ ] if ; inline + +M: struct-type unbox-return + [ %unbox-small-struct ] [ %unbox-large-struct ] if-small-struct ; M: struct-type box-return - f swap %box-struct ; + [ %box-small-struct ] [ %box-large-struct ] if-small-struct ; M: struct-type stack-size - [ heap-size ] [ stack-size ] if-value-structs? ; + [ heap-size ] [ stack-size ] if-value-struct ; : c-struct? ( type -- ? ) (c-type) struct-type? ; -: (define-struct) ( name vocab size align fields -- ) - >r [ align ] keep r> +: (define-struct) ( name size align fields -- ) + [ [ align ] keep ] dip struct-type boa - -rot define-c-type ; + swap typedef ; -: define-struct-early ( name vocab fields -- fields ) - -rot [ rot first2 ] 2curry map ; +: make-fields ( name vocab fields -- fields ) + [ first2 ] with with map ; : compute-struct-align ( types -- n ) [ c-type-align ] map supremum ; : define-struct ( name vocab fields -- ) - pick >r - [ struct-offsets ] keep - [ [ type>> ] map compute-struct-align ] keep - [ (define-struct) ] keep - r> [ swap define-field ] curry each ; + [ + [ 2drop ] [ make-fields ] 3bi + [ struct-offsets ] keep + [ [ type>> ] map compute-struct-align ] keep + [ (define-struct) ] keep + ] [ 2drop '[ _ swap define-field ] ] 3bi each ; -: define-union ( name vocab members -- ) +: define-union ( name members -- ) [ expand-constants ] map [ [ heap-size ] map supremum ] keep compute-struct-align f (define-struct) ; diff --git a/basis/alien/syntax/syntax-docs.factor b/basis/alien/syntax/syntax-docs.factor index 37cbd12801..a3215cd8c6 100644 --- a/basis/alien/syntax/syntax-docs.factor +++ b/basis/alien/syntax/syntax-docs.factor @@ -1,5 +1,5 @@ IN: alien.syntax -USING: alien alien.c-types alien.structs alien.syntax.private +USING: alien alien.c-types alien.parser alien.structs help.markup help.syntax ; HELP: DLL" @@ -54,12 +54,6 @@ HELP: TYPEDEF: { $description "Aliases the C type " { $snippet "old" } " under the name " { $snippet "new" } " if ." } { $notes "This word differs from " { $link typedef } " in that it runs at parse time, to ensure correct ordering of operations when loading source files. Words defined in source files are compiled before top-level forms are run, so if a source file defines C binding words and uses " { $link typedef } ", the type alias won't be available at compile time." } ; -HELP: TYPEDEF-IF: -{ $syntax "TYPEDEF-IF: word old new" } -{ $values { "word" "a word with stack effect " { $snippet "( -- ? )" } } { "old" "a C type" } { "new" "a C type" } } -{ $description "Aliases the C type " { $snippet "old" } " under the name " { $snippet "new" } " if " { $snippet "word" } " evaluates to a true value." } -{ $notes "This word differs from " { $link typedef } " in that it runs at parse time, to ensure correct ordering of operations when loading source files. Words defined in source files are compiled before top-level forms are run, so if a source file defines C binding words and uses " { $link typedef } ", the type alias won't be available at compile time." } ; - HELP: C-STRUCT: { $syntax "C-STRUCT: name pairs... ;" } { $values { "name" "a new C type name" } { "pairs" "C type / field name string pairs" } } @@ -83,12 +77,17 @@ HELP: C-ENUM: { $code "C-ENUM: red green blue ;" ": red 0 ; : green 1 ; : blue 2 ;" } } ; +HELP: &: +{ $syntax "&: symbol" } +{ $values { "symbol" "A C library symbol name" } } +{ $description "Pushes the address of a symbol named " { $snippet "symbol" } " from the current library, set with " { $link POSTPONE: LIBRARY: } "." } ; + HELP: typedef { $values { "old" "a string" } { "new" "a string" } } { $description "Alises the C type " { $snippet "old" } " under the name " { $snippet "new" } "." } { $notes "Using this word in the same source file which defines C bindings can cause problems, because words are compiled before top-level forms are run. Use the " { $link POSTPONE: TYPEDEF: } " word instead." } ; -{ POSTPONE: TYPEDEF-IF: POSTPONE: TYPEDEF: typedef } related-words +{ POSTPONE: TYPEDEF: typedef } related-words HELP: c-struct? { $values { "type" "a string" } { "?" "a boolean" } } diff --git a/basis/alien/syntax/syntax.factor b/basis/alien/syntax/syntax.factor index 7629897fc0..15d82884f9 100644 --- a/basis/alien/syntax/syntax.factor +++ b/basis/alien/syntax/syntax.factor @@ -3,36 +3,10 @@ USING: accessors arrays alien alien.c-types alien.structs alien.arrays alien.strings kernel math namespaces parser sequences words quotations math.parser splitting grouping -effects prettyprint prettyprint.sections prettyprint.backend -assocs combinators lexer strings.parser ; +effects assocs combinators lexer strings.parser alien.parser +fry ; IN: alien.syntax - ; - -: function-quot ( type lib func types -- quot ) - [ alien-invoke ] 2curry 2curry ; - -: define-function ( return library function parameters -- ) - >r pick r> parse-arglist - pick create-in dup reset-generic - >r >r function-quot r> r> - -rot define-declared ; - -PRIVATE> - -: indirect-quot ( function-ptr-quot return types abi -- quot ) - [ alien-indirect ] 3curry compose ; - -: define-indirect ( abi return function-ptr-quot function-name parameters -- ) - >r pick r> parse-arglist - rot create-in dup reset-generic - >r >r swapd roll indirect-quot r> r> - -rot define-declared ; - : DLL" lexer get skip-blank parse-string dlopen parsed ; parsing : ALIEN: scan string>number parsed ; parsing @@ -49,29 +23,18 @@ PRIVATE> : TYPEDEF: scan scan typedef ; parsing -: TYPEDEF-IF: - scan-word execute scan scan rot [ typedef ] [ 2drop ] if ; parsing - : C-STRUCT: - scan in get - parse-definition - >r 2dup r> define-struct-early - define-struct ; parsing + scan in get parse-definition define-struct ; parsing : C-UNION: - scan in get parse-definition define-union ; parsing + scan parse-definition define-union ; parsing : C-ENUM: ";" parse-tokens dup length - [ >r create-in r> 1quotation define ] 2each ; + [ [ create-in ] dip 1quotation define ] 2each ; parsing -M: alien pprint* - { - { [ dup expired? ] [ drop \ BAD-ALIEN pprint-word ] } - { [ dup pinned-c-ptr? not ] [ drop "( displaced alien )" text ] } - [ \ ALIEN: [ alien-address pprint* ] pprint-prefix ] - } cond ; - -M: dll pprint* dll-path dup "DLL\" " "\"" pprint-string ; +: &: + scan "c-library" get + '[ _ _ load-library dlsym ] over push-all ; parsing diff --git a/basis/bit-arrays/bit-arrays.factor b/basis/bit-arrays/bit-arrays.factor index 11601f7b63..d407f0b84d 100644 --- a/basis/bit-arrays/bit-arrays.factor +++ b/basis/bit-arrays/bit-arrays.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: alien.c-types accessors math alien.accessors kernel kernel.private locals sequences sequences.private byte-arrays -parser prettyprint.backend ; +parser prettyprint.custom fry ; IN: bit-arrays TUPLE: bit-array @@ -24,9 +24,8 @@ TUPLE: bit-array : bits>bytes 7 + n>byte ; inline : (set-bits) ( bit-array n -- ) - [ [ length bits>cells ] keep ] dip - [ -rot underlying>> set-uint-nth ] 2curry - each ; inline + [ [ length bits>cells ] keep ] dip swap underlying>> + '[ [ _ _ ] dip set-alien-unsigned-4 ] each ; inline PRIVATE> @@ -74,19 +73,19 @@ M: bit-array byte-length length 7 + -3 shift ; :: integer>bit-array ( n -- bit-array ) n zero? [ 0 ] [ [let | out [ n log2 1+ ] i! [ 0 ] n'! [ n ] | - [ n' zero? not ] [ + [ n' zero? ] [ n' out underlying>> i set-alien-unsigned-1 n' -8 shift n'! i 1+ i! - ] [ ] while + ] [ ] until out ] ] if ; : bit-array>integer ( bit-array -- n ) - 0 swap underlying>> [ length ] keep [ - uchar-nth swap 8 shift bitor - ] curry each ; + 0 swap underlying>> dup length [ + alien-unsigned-1 swap 8 shift bitor + ] with each ; INSTANCE: bit-array sequence diff --git a/basis/bit-vectors/bit-vectors-tests.factor b/basis/bit-vectors/bit-vectors-tests.factor index dff9a8db37..31327999e7 100644 --- a/basis/bit-vectors/bit-vectors-tests.factor +++ b/basis/bit-vectors/bit-vectors-tests.factor @@ -4,7 +4,7 @@ USING: tools.test bit-vectors vectors sequences kernel math ; [ 0 ] [ 123 length ] unit-test : do-it - 1234 swap [ >r even? r> push ] curry each ; + 1234 swap [ [ even? ] dip push ] curry each ; [ t ] [ 3 dup do-it diff --git a/basis/bit-vectors/bit-vectors.factor b/basis/bit-vectors/bit-vectors.factor index 404b26829b..85bea80b2d 100644 --- a/basis/bit-vectors/bit-vectors.factor +++ b/basis/bit-vectors/bit-vectors.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: arrays kernel kernel.private math sequences -sequences.private growable bit-arrays prettyprint.backend +sequences.private growable bit-arrays prettyprint.custom parser accessors ; IN: bit-vectors diff --git a/basis/bootstrap/bootstrap-error.factor b/basis/bootstrap/bootstrap-error.factor new file mode 100644 index 0000000000..01eb002e44 --- /dev/null +++ b/basis/bootstrap/bootstrap-error.factor @@ -0,0 +1,8 @@ +USING: continuations kernel io debugger vocabs words system namespaces ; + +:c +:error +"listener" vocab +[ restarts. vocab-main execute ] +[ die ] if* +1 exit diff --git a/basis/bootstrap/compiler/compiler.factor b/basis/bootstrap/compiler/compiler.factor index dabdeea741..f0d9e8e131 100644 --- a/basis/bootstrap/compiler/compiler.factor +++ b/basis/bootstrap/compiler/compiler.factor @@ -5,17 +5,22 @@ sequences namespaces parser kernel kernel.private classes classes.private arrays hashtables vectors classes.tuple sbufs hashtables.private sequences.private math classes.tuple.private growable namespaces.private assocs words command-line vocabs io -io.encodings.string prettyprint libc splitting math.parser +io.encodings.string libc splitting math.parser compiler.units math.order compiler.tree.builder compiler.tree.optimizer compiler.cfg.optimizer ; IN: bootstrap.compiler ! Don't bring this in when deploying, since it will store a ! reference to 'eval' in a global variable -"deploy-vocab" get [ +"deploy-vocab" get "staging" get or [ "alien.remote-control" require ] unless +"prettyprint" vocab [ + "stack-checker.errors.prettyprint" require + "alien.prettyprint" require +] when + "cpu." cpu name>> append require enable-compiler @@ -60,7 +65,7 @@ nl "." write flush { - new-sequence nth push pop peek + new-sequence nth push pop peek flip } compile-uncompiled "." write flush @@ -86,7 +91,7 @@ nl "." write flush { - . malloc calloc free memcpy + malloc calloc free memcpy } compile-uncompiled "." write flush diff --git a/basis/bootstrap/finish-bootstrap.factor b/basis/bootstrap/finish-bootstrap.factor new file mode 100644 index 0000000000..133b64acaa --- /dev/null +++ b/basis/bootstrap/finish-bootstrap.factor @@ -0,0 +1,16 @@ +USING: init command-line debugger system continuations +namespaces eval kernel vocabs.loader io ; + +[ + boot + do-init-hooks + [ + (command-line) parse-command-line + load-vocab-roots + run-user-init + "e" get [ eval ] when* + ignore-cli-args? not script get and + [ run-script ] [ "run" get run ] if* + output-stream get [ stream-flush ] when* + ] [ print-error 1 exit ] recover +] set-boot-quot diff --git a/basis/bootstrap/finish-staging.factor b/basis/bootstrap/finish-staging.factor new file mode 100644 index 0000000000..a60ce04e15 --- /dev/null +++ b/basis/bootstrap/finish-staging.factor @@ -0,0 +1,10 @@ +USING: init command-line system namespaces kernel vocabs.loader +io ; + +[ + boot + do-init-hooks + (command-line) parse-command-line + "run" get run + output-stream get [ stream-flush ] when* +] set-boot-quot diff --git a/basis/bootstrap/help/help.factor b/basis/bootstrap/help/help.factor index e2a2288988..5b49ce2802 100644 --- a/basis/bootstrap/help/help.factor +++ b/basis/bootstrap/help/help.factor @@ -1,6 +1,6 @@ USING: help help.topics help.syntax help.crossref help.definitions io io.files kernel namespaces vocabs sequences -parser vocabs.loader ; +parser vocabs.loader vocabs.loader.private accessors assocs ; IN: bootstrap.help : load-help ( -- ) @@ -10,8 +10,8 @@ IN: bootstrap.help t load-help? set-global [ drop ] load-vocab-hook [ - vocabs - [ vocab-docs-loaded? not ] filter + dictionary get values + [ docs-loaded?>> not ] filter [ load-docs ] each ] with-variable ; diff --git a/basis/bootstrap/image/download/download.factor b/basis/bootstrap/image/download/download.factor index 71aa2e8adc..f9b7b56779 100644 --- a/basis/bootstrap/image/download/download.factor +++ b/basis/bootstrap/image/download/download.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: http.client checksums checksums.openssl splitting assocs +USING: http.client checksums checksums.md5 splitting assocs kernel io.files bootstrap.image sequences io urls ; IN: bootstrap.image.download @@ -13,7 +13,7 @@ IN: bootstrap.image.download : need-new-image? ( image -- ? ) dup exists? [ - [ openssl-md5 checksum-file hex-string ] + [ md5 checksum-file hex-string ] [ download-checksums at ] bi = not ] [ drop t ] if ; diff --git a/basis/bootstrap/image/image.factor b/basis/bootstrap/image/image.factor index c0fafdc0f5..c7d87776a1 100644 --- a/basis/bootstrap/image/image.factor +++ b/basis/bootstrap/image/image.factor @@ -23,7 +23,7 @@ IN: bootstrap.image os name>> cpu name>> arch ; : boot-image-name ( arch -- string ) - "boot." swap ".image" 3append ; + "boot." ".image" surround ; : my-boot-image-name ( -- string ) my-arch boot-image-name ; @@ -72,7 +72,7 @@ SYMBOL: objects : put-object ( n obj -- ) (objects) set-at ; : cache-object ( obj quot -- value ) - >r (objects) r> [ obj>> ] prepose cache ; inline + [ (objects) ] dip [ obj>> ] prepose cache ; inline ! Constants @@ -97,10 +97,10 @@ SYMBOL: sub-primitives { [ { } make ] [ ] [ ] [ ] } spread 4array ; inline : jit-define ( quot rc rt offset name -- ) - >r make-jit r> set ; inline + [ make-jit ] dip set ; inline : define-sub-primitive ( quot rc rt offset word -- ) - >r make-jit r> sub-primitives get set-at ; + [ make-jit ] dip sub-primitives get set-at ; ! The image being constructed; a vector of word-size integers SYMBOL: image @@ -124,12 +124,18 @@ SYMBOL: jit-primitive-word SYMBOL: jit-primitive SYMBOL: jit-word-jump SYMBOL: jit-word-call -SYMBOL: jit-push-literal SYMBOL: jit-push-immediate SYMBOL: jit-if-word -SYMBOL: jit-if-jump +SYMBOL: jit-if-1 +SYMBOL: jit-if-2 SYMBOL: jit-dispatch-word SYMBOL: jit-dispatch +SYMBOL: jit-dip-word +SYMBOL: jit-dip +SYMBOL: jit-2dip-word +SYMBOL: jit-2dip +SYMBOL: jit-3dip-word +SYMBOL: jit-3dip SYMBOL: jit-epilog SYMBOL: jit-return SYMBOL: jit-profiling @@ -139,8 +145,8 @@ SYMBOL: jit-save-stack ! Default definition for undefined words SYMBOL: undefined-quot -: userenv-offset ( symbol -- n ) - { +: userenvs ( -- assoc ) + H{ { bootstrap-boot-quot 20 } { bootstrap-global 21 } { jit-code-format 22 } @@ -149,9 +155,9 @@ SYMBOL: undefined-quot { jit-primitive 25 } { jit-word-jump 26 } { jit-word-call 27 } - { jit-push-literal 28 } - { jit-if-word 29 } - { jit-if-jump 30 } + { jit-if-word 28 } + { jit-if-1 29 } + { jit-if-2 30 } { jit-dispatch-word 31 } { jit-dispatch 32 } { jit-epilog 33 } @@ -160,8 +166,17 @@ SYMBOL: undefined-quot { jit-push-immediate 36 } { jit-declare-word 42 } { jit-save-stack 43 } + { jit-dip-word 44 } + { jit-dip 45 } + { jit-2dip-word 46 } + { jit-2dip 47 } + { jit-3dip-word 48 } + { jit-3dip 49 } { undefined-quot 60 } - } at header-size + ; + } ; inline + +: userenv-offset ( symbol -- n ) + userenvs at header-size + ; : emit ( cell -- ) image get push ; @@ -190,7 +205,7 @@ SYMBOL: undefined-quot : emit-fixnum ( n -- ) tag-fixnum emit ; : emit-object ( header tag quot -- addr ) - swap here-as >r swap tag-fixnum emit call align-here r> ; + swap here-as [ swap tag-fixnum emit call align-here ] dip ; inline ! Write an object to the image. @@ -336,7 +351,12 @@ M: wrapper ' : pad-bytes ( seq -- newseq ) dup length bootstrap-cell align 0 pad-right ; +: check-string ( string -- ) + [ 127 > ] contains? + [ "Bootstrap cannot emit non-ASCII strings" throw ] when ; + : emit-string ( string -- ptr ) + dup check-string string type-number object tag-number [ dup length emit-fixnum f ' emit @@ -443,6 +463,9 @@ M: quotation ' \ dispatch jit-dispatch-word set \ do-primitive jit-primitive-word set \ declare jit-declare-word set + \ dip jit-dip-word set + \ 2dip jit-2dip-word set + \ 3dip jit-3dip-word set [ undefined ] undefined-quot set { jit-code-format @@ -451,12 +474,18 @@ M: quotation ' jit-primitive jit-word-jump jit-word-call - jit-push-literal jit-push-immediate jit-if-word - jit-if-jump + jit-if-1 + jit-if-2 jit-dispatch-word jit-dispatch + jit-dip-word + jit-dip + jit-2dip-word + jit-2dip + jit-3dip-word + jit-3dip jit-epilog jit-return jit-profiling diff --git a/basis/bootstrap/math/math.factor b/basis/bootstrap/math/math.factor index a293efd33e..347969af0d 100644 --- a/basis/bootstrap/math/math.factor +++ b/basis/bootstrap/math/math.factor @@ -1,5 +1,7 @@ -USE: vocabs.loader +USING: vocabs vocabs.loader kernel ; "math.ratios" require "math.floats" require "math.complex" require + +"prettyprint" vocab [ "math.complex.prettyprint" require ] when diff --git a/basis/bootstrap/stage2.factor b/basis/bootstrap/stage2.factor index d25394e978..fb7292b989 100644 --- a/basis/bootstrap/stage2.factor +++ b/basis/bootstrap/stage2.factor @@ -2,10 +2,10 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors init namespaces words io kernel.private math memory continuations kernel io.files -io.backend system parser vocabs sequences prettyprint +io.backend system parser vocabs sequences vocabs.loader combinators splitting source-files strings definitions assocs compiler.errors compiler.units -math.parser generic sets debugger command-line ; +math.parser generic sets command-line ; IN: bootstrap.stage2 SYMBOL: core-bootstrap-time @@ -32,7 +32,7 @@ SYMBOL: bootstrap-time : count-words ( pred -- ) all-words swap count number>string write ; -: print-time ( time -- ) +: print-time ( ms -- ) 1000 /i 60 /mod swap number>string write @@ -59,15 +59,15 @@ SYMBOL: bootstrap-time "math compiler threads help io tools ui ui.tools unicode handbook" "include" set-global "" "exclude" set-global - parse-command-line + (command-line) parse-command-line - "-no-crossref" cli-args member? [ do-crossref ] unless + do-crossref ! Set dll paths os wince? [ "windows.ce" require ] when os winnt? [ "windows.nt" require ] when - "deploy-vocab" get [ + "staging" get "deploy-vocab" get or [ "stage2: deployment mode" print ] [ "listener" require @@ -86,30 +86,22 @@ SYMBOL: bootstrap-time f error set-global f error-continuation set-global + millis swap - bootstrap-time set-global + print-report + "deploy-vocab" get [ "tools.deploy.shaker" run ] [ - [ - boot - do-init-hooks - [ - parse-command-line - run-user-init - "run" get run - output-stream get [ stream-flush ] when* - ] [ print-error 1 exit ] recover - ] set-boot-quot - - millis swap - bootstrap-time set-global - print-report + "staging" get [ + "resource:basis/bootstrap/finish-staging.factor" run-file + ] [ + "resource:basis/bootstrap/finish-bootstrap.factor" run-file + ] if "output-image" get save-image-and-exit ] if ] [ - :c - dup print-error flush - "listener" vocab - [ restarts. vocab-main execute ] - [ die ] if* - 1 exit + drop + load-help? off + "resource:basis/bootstrap/bootstrap-error.factor" run-file ] recover diff --git a/basis/bootstrap/threads/threads.factor b/basis/bootstrap/threads/threads.factor index 6c30489bb4..8b751f8458 100644 --- a/basis/bootstrap/threads/threads.factor +++ b/basis/bootstrap/threads/threads.factor @@ -1,7 +1,11 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. +USING: vocabs vocabs.loader kernel ; IN: bootstrap.threads USE: io.thread USE: threads -USE: debugger.threads + +"debugger" vocab [ + "debugger.threads" require +] when diff --git a/basis/boxes/boxes.factor b/basis/boxes/boxes.factor index 9e2e8a4673..39f8eb44cc 100644 --- a/basis/boxes/boxes.factor +++ b/basis/boxes/boxes.factor @@ -23,4 +23,4 @@ ERROR: box-empty box ; dup occupied>> [ box> t ] [ drop f f ] if ; : if-box? ( box quot -- ) - >r ?box r> [ drop ] if ; inline + [ ?box ] dip [ drop ] if ; inline diff --git a/core/byte-vectors/byte-vectors-docs.factor b/basis/byte-vectors/byte-vectors-docs.factor similarity index 100% rename from core/byte-vectors/byte-vectors-docs.factor rename to basis/byte-vectors/byte-vectors-docs.factor diff --git a/core/byte-vectors/byte-vectors-tests.factor b/basis/byte-vectors/byte-vectors-tests.factor similarity index 100% rename from core/byte-vectors/byte-vectors-tests.factor rename to basis/byte-vectors/byte-vectors-tests.factor diff --git a/basis/byte-vectors/byte-vectors.factor b/basis/byte-vectors/byte-vectors.factor new file mode 100644 index 0000000000..d146017db0 --- /dev/null +++ b/basis/byte-vectors/byte-vectors.factor @@ -0,0 +1,51 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: arrays kernel kernel.private math sequences +sequences.private growable byte-arrays accessors parser +prettyprint.custom ; +IN: byte-vectors + +TUPLE: byte-vector +{ underlying byte-array } +{ length array-capacity } ; + +: ( n -- byte-vector ) + (byte-array) 0 byte-vector boa ; inline + +: >byte-vector ( seq -- byte-vector ) + T{ byte-vector f B{ } 0 } clone-like ; + +M: byte-vector like + drop dup byte-vector? [ + dup byte-array? + [ dup length byte-vector boa ] [ >byte-vector ] if + ] unless ; + +M: byte-vector new-sequence + drop [ (byte-array) ] [ >fixnum ] bi byte-vector boa ; + +M: byte-vector equal? + over byte-vector? [ sequence= ] [ 2drop f ] if ; + +M: byte-array like + #! If we have an byte-array, we're done. + #! If we have a byte-vector, and it's at full capacity, + #! we're done. Otherwise, call resize-byte-array, which is a + #! relatively fast primitive. + drop dup byte-array? [ + dup byte-vector? [ + [ length ] [ underlying>> ] bi + 2dup length eq? + [ nip ] [ resize-byte-array ] if + ] [ >byte-array ] if + ] unless ; + +M: byte-array new-resizable drop ; + +: BV{ \ } [ >byte-vector ] parse-literal ; parsing + +M: byte-vector pprint* pprint-object ; +M: byte-vector pprint-delims drop \ BV{ \ } ; +M: byte-vector >pprint-sequence ; + +INSTANCE: byte-vector growable diff --git a/core/byte-vectors/summary.txt b/basis/byte-vectors/summary.txt similarity index 100% rename from core/byte-vectors/summary.txt rename to basis/byte-vectors/summary.txt diff --git a/basis/float-arrays/tags.txt b/basis/byte-vectors/tags.txt similarity index 100% rename from basis/float-arrays/tags.txt rename to basis/byte-vectors/tags.txt diff --git a/basis/calendar/calendar-docs.factor b/basis/calendar/calendar-docs.factor index 64c74a494a..433459cb24 100644 --- a/basis/calendar/calendar-docs.factor +++ b/basis/calendar/calendar-docs.factor @@ -365,12 +365,12 @@ HELP: unix-1970 { $values { "timestamp" timestamp } } { $description "Outputs the beginning of UNIX time, or midnight, January 1, 1970." } ; -HELP: millis>timestamp +HELP: micros>timestamp { $values { "x" number } { "timestamp" timestamp } } -{ $description "Converts a number of milliseconds into a timestamp value in GMT time." } +{ $description "Converts a number of microseconds into a timestamp value in GMT time." } { $examples { $example "USING: accessors calendar prettyprint ;" - "1000 millis>timestamp year>> ." + "1000 micros>timestamp year>> ." "1970" } } ; diff --git a/basis/calendar/calendar-tests.factor b/basis/calendar/calendar-tests.factor index 995bd23c09..00d5730745 100644 --- a/basis/calendar/calendar-tests.factor +++ b/basis/calendar/calendar-tests.factor @@ -143,10 +143,10 @@ IN: calendar.tests [ +gt+ ] [ 2005 1 1 12 30 0 instant 2004 1 1 13 30 0 instant <=> ] unit-test -[ t ] [ now timestamp>millis millis - 1000 < ] unit-test -[ t ] [ 0 millis>timestamp unix-1970 = ] unit-test -[ t ] [ 123456789000 [ millis>timestamp timestamp>millis ] keep = ] unit-test -[ t ] [ 123456789123456 [ millis>timestamp timestamp>millis ] keep = ] unit-test +[ t ] [ now timestamp>micros micros - 1000000 < ] unit-test +[ t ] [ 0 micros>timestamp unix-1970 = ] unit-test +[ t ] [ 123456789000000 [ micros>timestamp timestamp>micros ] keep = ] unit-test +[ t ] [ 123456789123456000 [ micros>timestamp timestamp>micros ] keep = ] unit-test : checktime+ now dup clone [ rot time+ drop ] keep = ; diff --git a/basis/calendar/calendar.factor b/basis/calendar/calendar.factor index c002760748..793c771b64 100644 --- a/basis/calendar/calendar.factor +++ b/basis/calendar/calendar.factor @@ -173,7 +173,7 @@ M: real +year ( timestamp n -- timestamp ) 12 /rem dup zero? [ drop 1- 12 ] when swap ; inline M: integer +month ( timestamp n -- timestamp ) - [ over month>> + months/years >r >>month r> +year ] unless-zero ; + [ over month>> + months/years [ >>month ] dip +year ] unless-zero ; M: real +month ( timestamp n -- timestamp ) [ float>whole-part swapd average-month * +day swap +month ] unless-zero ; @@ -181,7 +181,7 @@ M: real +month ( timestamp n -- timestamp ) M: integer +day ( timestamp n -- timestamp ) [ over >date< julian-day-number + julian-day-number>date - >r >r >>year r> >>month r> >>day + [ >>year ] [ >>month ] [ >>day ] tri* ] unless-zero ; M: real +day ( timestamp n -- timestamp ) @@ -191,7 +191,7 @@ M: real +day ( timestamp n -- timestamp ) 24 /rem swap ; M: integer +hour ( timestamp n -- timestamp ) - [ over hour>> + hours/days >r >>hour r> +day ] unless-zero ; + [ over hour>> + hours/days [ >>hour ] dip +day ] unless-zero ; M: real +hour ( timestamp n -- timestamp ) float>whole-part swapd 60 * +minute swap +hour ; @@ -200,7 +200,7 @@ M: real +hour ( timestamp n -- timestamp ) 60 /rem swap ; M: integer +minute ( timestamp n -- timestamp ) - [ over minute>> + minutes/hours >r >>minute r> +hour ] unless-zero ; + [ over minute>> + minutes/hours [ >>minute ] dip +hour ] unless-zero ; M: real +minute ( timestamp n -- timestamp ) [ float>whole-part swapd 60 * +second swap +minute ] unless-zero ; @@ -209,7 +209,7 @@ M: real +minute ( timestamp n -- timestamp ) 60 /rem swap >integer ; M: number +second ( timestamp n -- timestamp ) - [ over second>> + seconds/minutes >r >>second r> +minute ] unless-zero ; + [ over second>> + seconds/minutes [ >>second ] dip +minute ] unless-zero ; : (time+) [ second>> +second ] keep @@ -226,7 +226,7 @@ PRIVATE> GENERIC# time+ 1 ( time1 time2 -- time3 ) M: timestamp time+ - >r clone r> (time+) drop ; + [ clone ] dip (time+) drop ; M: duration time+ dup timestamp? [ @@ -284,7 +284,7 @@ M: timestamp <=> ( ts1 ts2 -- n ) : (time-) ( timestamp timestamp -- n ) [ >gmt ] bi@ [ [ >date< julian-day-number ] bi@ - 86400 * ] 2keep - [ >time< >r >r 3600 * r> 60 * r> + + ] bi@ - + ; + [ >time< [ [ 3600 * ] [ 60 * ] bi* ] dip + + ] bi@ - + ; M: timestamp time- #! Exact calendar-time difference @@ -320,14 +320,20 @@ M: duration time- 1970 1 1 0 0 0 instant ; : millis>timestamp ( x -- timestamp ) - >r unix-1970 r> milliseconds time+ ; + [ unix-1970 ] dip milliseconds time+ ; : timestamp>millis ( timestamp -- n ) unix-1970 (time-) 1000 * >integer ; +: micros>timestamp ( x -- timestamp ) + [ unix-1970 ] dip microseconds time+ ; + +: timestamp>micros ( timestamp -- n ) + unix-1970 (time-) 1000000 * >integer ; + : gmt ( -- timestamp ) #! GMT time, right now - unix-1970 millis milliseconds time+ ; + unix-1970 micros microseconds time+ ; : now ( -- timestamp ) gmt >local-time ; : hence ( duration -- timestamp ) now swap time+ ; @@ -337,10 +343,11 @@ M: duration time- #! Zeller Congruence #! http://web.textfiles.com/computers/formulas.txt #! good for any date since October 15, 1582 - >r dup 2 <= [ 12 + >r 1- r> ] when - >r dup [ 4 /i + ] keep [ 100 /i - ] keep 400 /i + r> - [ 1+ 3 * 5 /i + ] keep 2 * + r> - 1+ + 7 mod ; + [ + dup 2 <= [ [ 1- ] [ 12 + ] bi* ] when + [ dup [ 4 /i + ] keep [ 100 /i - ] keep 400 /i + ] dip + [ 1+ 3 * 5 /i + ] keep 2 * + + ] dip 1+ + 7 mod ; GENERIC: days-in-year ( obj -- n ) @@ -404,7 +411,7 @@ PRIVATE> : since-1970 ( duration -- timestamp ) unix-1970 time+ >local-time ; -M: timestamp sleep-until timestamp>millis sleep-until ; +M: timestamp sleep-until timestamp>micros sleep-until ; M: duration sleep hence sleep-until ; diff --git a/basis/calendar/format/format.factor b/basis/calendar/format/format.factor index b15da42409..a7c4410aa5 100644 --- a/basis/calendar/format/format.factor +++ b/basis/calendar/format/format.factor @@ -1,7 +1,8 @@ -USING: math math.order math.parser math.functions kernel sequences io -accessors arrays io.streams.string splitting -combinators accessors debugger -calendar calendar.format.macros ; +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: math math.order math.parser math.functions kernel +sequences io accessors arrays io.streams.string splitting +combinators accessors calendar calendar.format.macros present ; IN: calendar.format : pad-00 ( n -- str ) number>string 2 CHAR: 0 pad-left ; @@ -138,11 +139,11 @@ M: timestamp year. ( timestamp -- ) : read-rfc3339-gmt-offset ( ch -- dt ) dup CHAR: Z = [ drop instant ] [ - >r - read-00 hours - read1 { { CHAR: : [ read-00 ] } { f [ 0 ] } } case minutes - time+ - r> signed-gmt-offset + [ + read-00 hours + read1 { { CHAR: : [ read-00 ] } { f [ 0 ] } } case minutes + time+ + ] dip signed-gmt-offset ] if ; : read-ymd ( -- y m d ) @@ -152,8 +153,9 @@ M: timestamp year. ( timestamp -- ) read-00 ":" expect read-00 ":" expect read-00 ; : read-rfc3339-seconds ( s -- s' ch ) - "+-Z" read-until >r - [ string>number ] [ length 10 swap ^ ] bi / + r> ; + "+-Z" read-until [ + [ string>number ] [ length 10 swap ^ ] bi / + + ] dip ; : (rfc3339>timestamp) ( -- timestamp ) read-ymd @@ -181,9 +183,9 @@ ERROR: invalid-timestamp-format ; : parse-rfc822-gmt-offset ( string -- dt ) dup "GMT" = [ drop instant ] [ - unclip >r - 2 cut [ string>number ] bi@ [ hours ] [ minutes ] bi* time+ - r> signed-gmt-offset + unclip [ + 2 cut [ string>number ] bi@ [ hours ] [ minutes ] bi* time+ + ] dip signed-gmt-offset ] if ; : (rfc822>timestamp) ( -- timestamp ) @@ -287,3 +289,5 @@ ERROR: invalid-timestamp-format ; ] } formatted ] with-string-writer ; + +M: timestamp present timestamp>string ; diff --git a/basis/calendar/model/model.factor b/basis/calendar/model/model.factor index 60a61c2026..8665cc22ce 100644 --- a/basis/calendar/model/model.factor +++ b/basis/calendar/model/model.factor @@ -7,7 +7,7 @@ SYMBOL: time : (time-thread) ( -- ) now time get set-model - 1000 sleep (time-thread) ; + 1 seconds sleep (time-thread) ; : time-thread ( -- ) [ diff --git a/basis/channels/remote/remote.factor b/basis/channels/remote/remote.factor index 1a7addac12..6e10b23407 100644 --- a/basis/channels/remote/remote.factor +++ b/basis/channels/remote/remote.factor @@ -14,7 +14,7 @@ IN: channels.remote PRIVATE> : publish ( channel -- id ) - 256 random-bits dup >r remote-channels set-at r> ; + 256 random-bits dup [ remote-channels set-at ] dip ; : get-channel ( id -- channel ) remote-channels at ; diff --git a/basis/checksums/common/common.factor b/basis/checksums/common/common.factor index 1f25efef24..7d5f34777d 100644 --- a/basis/checksums/common/common.factor +++ b/basis/checksums/common/common.factor @@ -18,4 +18,4 @@ SYMBOL: bytes-read ] "" make 64 group ; : update-old-new ( old new -- ) - [ get >r get r> ] 2keep >r >r w+ dup r> set r> set ; inline + [ [ get ] bi@ w+ dup ] 2keep [ set ] bi@ ; inline diff --git a/basis/checksums/md5/md5.factor b/basis/checksums/md5/md5.factor index 6158254f84..d919b0e313 100644 --- a/basis/checksums/md5/md5.factor +++ b/basis/checksums/md5/md5.factor @@ -4,7 +4,7 @@ USING: kernel io io.binary io.files io.streams.byte-array math math.functions math.parser namespaces splitting grouping strings sequences byte-arrays locals sequences.private io.encodings.binary symbols math.bitwise checksums -checksums.common ; +checksums.common checksums.stream ; IN: checksums.md5 ! See http://www.faqs.org/rfcs/rfc1321.html @@ -14,7 +14,7 @@ IN: checksums.md5 SYMBOLS: a b c d old-a old-b old-c old-d ; : T ( N -- Y ) - sin abs 4294967296 * >bignum ; foldable + sin abs 4294967296 * >integer ; foldable : initialize-md5 ( -- ) 0 bytes-read set @@ -180,7 +180,7 @@ PRIVATE> SINGLETON: md5 -INSTANCE: md5 checksum +INSTANCE: md5 stream-checksum M: md5 checksum-stream ( stream -- byte-array ) drop [ initialize-md5 stream>md5 get-md5 ] with-input-stream ; diff --git a/basis/checksums/openssl/openssl.factor b/basis/checksums/openssl/openssl.factor index d42febb541..4bc7a7964a 100644 --- a/basis/checksums/openssl/openssl.factor +++ b/basis/checksums/openssl/openssl.factor @@ -1,7 +1,8 @@ ! Copyright (C) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: accessors byte-arrays alien.c-types kernel continuations -destructors sequences io openssl openssl.libcrypto checksums ; +destructors sequences io openssl openssl.libcrypto checksums +checksums.stream ; IN: checksums.openssl ERROR: unknown-digest name ; @@ -12,7 +13,7 @@ TUPLE: openssl-checksum name ; : openssl-sha1 T{ openssl-checksum f "sha1" } ; -INSTANCE: openssl-checksum checksum +INSTANCE: openssl-checksum stream-checksum C: openssl-checksum @@ -28,7 +29,7 @@ M: evp-md-context dispose handle>> EVP_MD_CTX_cleanup drop ; : with-evp-md-context ( quot -- ) - maybe-init-ssl >r r> with-disposal ; inline + maybe-init-ssl [ ] dip with-disposal ; inline : digest-named ( name -- md ) dup EVP_get_digestbyname diff --git a/basis/checksums/sha1/sha1.factor b/basis/checksums/sha1/sha1.factor index bbae421b16..6cdc9270aa 100644 --- a/basis/checksums/sha1/sha1.factor +++ b/basis/checksums/sha1/sha1.factor @@ -3,7 +3,8 @@ USING: arrays combinators kernel io io.encodings.binary io.files io.streams.byte-array math.vectors strings sequences namespaces make math parser sequences assocs grouping vectors io.binary -hashtables symbols math.bitwise checksums checksums.common ; +hashtables symbols math.bitwise checksums checksums.common +checksums.stream ; IN: checksums.sha1 ! Implemented according to RFC 3174. @@ -41,9 +42,9 @@ SYMBOLS: h0 h1 h2 h3 h4 A B C D E w K ; : sha1-f ( B C D t -- f_tbcd ) 20 /i { - { 0 [ >r over bitnot r> bitand >r bitand r> bitor ] } + { 0 [ [ over bitnot ] dip bitand [ bitand ] dip bitor ] } { 1 [ bitxor bitxor ] } - { 2 [ 2dup bitand >r pick bitand >r bitand r> r> bitor bitor ] } + { 2 [ 2dup bitand [ pick bitand [ bitand ] dip ] dip bitor bitor ] } { 3 [ bitxor bitxor ] } } case ; @@ -113,7 +114,7 @@ SYMBOLS: h0 h1 h2 h3 h4 A B C D E w K ; SINGLETON: sha1 -INSTANCE: sha1 checksum +INSTANCE: sha1 stream-checksum M: sha1 checksum-stream ( stream -- sha1 ) drop [ initialize-sha1 stream>sha1 get-sha1 ] with-input-stream ; diff --git a/basis/checksums/sha2/sha2.factor b/basis/checksums/sha2/sha2.factor index 0a6d8c26ab..beb657bd3e 100644 --- a/basis/checksums/sha2/sha2.factor +++ b/basis/checksums/sha2/sha2.factor @@ -59,7 +59,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ; [ 15 - swap nth s0-256 ] 2keep [ 7 - swap nth ] 2keep [ 2 - swap nth s1-256 ] 2keep - >r >r + + w+ r> r> swap set-nth ; inline + [ + + w+ ] 2dip swap set-nth ; inline : prepare-message-schedule ( seq -- w-seq ) word-size get group [ be> ] map block-size get 0 pad-right @@ -71,7 +71,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ; [ bitxor bitand ] keep bitxor ; : maj ( x y z -- x' ) - >r [ bitand ] 2keep bitor r> bitand bitor ; + [ [ bitand ] 2keep bitor ] dip bitand bitor ; : S0-256 ( x -- x' ) [ -2 bitroll-32 ] keep @@ -83,7 +83,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ; [ -11 bitroll-32 ] keep -25 bitroll-32 bitxor bitxor ; inline -: slice3 ( n seq -- a b c ) >r dup 3 + r> first3 ; inline +: slice3 ( n seq -- a b c ) [ dup 3 + ] dip first3 ; inline : T1 ( W n -- T1 ) [ swap nth ] keep @@ -105,7 +105,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ; d c pick exchange c b pick exchange b a pick exchange - >r w+ a r> set-nth ; + [ w+ a ] dip set-nth ; : process-chunk ( M -- ) H get clone vars set @@ -118,7 +118,7 @@ SYMBOLS: vars M K H S0 S1 process-M word-size block-size ; : preprocess-plaintext ( string big-endian? -- padded-string ) #! pad 0x80 then 00 til 8 bytes left, then 64bit length in bits - >r >sbuf r> over [ + [ >sbuf ] dip over [ HEX: 80 , dup length HEX: 3f bitand calculate-pad-length 0 % diff --git a/basis/checksums/stream/stream.factor b/basis/checksums/stream/stream.factor new file mode 100644 index 0000000000..e753467323 --- /dev/null +++ b/basis/checksums/stream/stream.factor @@ -0,0 +1,12 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: io.encodings.binary io.streams.byte-array kernel +checksums ; +IN: checksums.stream + +MIXIN: stream-checksum + +M: stream-checksum checksum-bytes + [ binary ] dip checksum-stream ; + +INSTANCE: stream-checksum checksum diff --git a/basis/cocoa/application/application-docs.factor b/basis/cocoa/application/application-docs.factor index 791613e876..e12b6eb276 100644 --- a/basis/cocoa/application/application-docs.factor +++ b/basis/cocoa/application/application-docs.factor @@ -1,5 +1,5 @@ USING: debugger quotations help.markup help.syntax strings alien -core-foundation ; +core-foundation core-foundation.strings core-foundation.arrays ; IN: cocoa.application HELP: diff --git a/basis/cocoa/application/application.factor b/basis/cocoa/application/application.factor index 8f32782d76..a52aaedce2 100644 --- a/basis/cocoa/application/application.factor +++ b/basis/cocoa/application/application.factor @@ -1,8 +1,9 @@ -! Copyright (C) 2006, 2007 Slava Pestov +! Copyright (C) 2006, 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: alien alien.syntax io kernel namespaces core-foundation -core-foundation.run-loop cocoa.messages cocoa cocoa.classes -cocoa.runtime sequences threads debugger init summary +core-foundation.run-loop core-foundation.arrays +core-foundation.data core-foundation.strings cocoa.messages +cocoa cocoa.classes cocoa.runtime sequences threads init summary kernel.private assocs ; IN: cocoa.application @@ -27,35 +28,31 @@ IN: cocoa.application : NSApp ( -- app ) NSApplication -> sharedApplication ; +: NSAnyEventMask ( -- mask ) HEX: ffffffff ; inline + FUNCTION: void NSBeep ( ) ; : with-cocoa ( quot -- ) [ NSApp drop call ] with-autorelease-pool ; inline : next-event ( app -- event ) - 0 f CFRunLoopDefaultMode 1 + NSAnyEventMask f CFRunLoopDefaultMode 1 -> nextEventMatchingMask:untilDate:inMode:dequeue: ; : do-event ( app -- ? ) - dup next-event [ -> sendEvent: t ] [ drop f ] if* ; + dup next-event [ dupd -> sendEvent: -> updateWindows t ] [ drop f ] if* ; : add-observer ( observer selector name object -- ) - >r >r >r >r NSNotificationCenter -> defaultCenter - r> r> sel_registerName - r> r> -> addObserver:selector:name:object: ; + [ + [ NSNotificationCenter -> defaultCenter ] 2dip + sel_registerName + ] 2dip -> addObserver:selector:name:object: ; : remove-observer ( observer -- ) - >r NSNotificationCenter -> defaultCenter r> + [ NSNotificationCenter -> defaultCenter ] dip -> removeObserver: ; -: finish-launching ( -- ) NSApp -> finishLaunching ; - -: cocoa-app ( quot -- ) - [ - call - finish-launching - NSApp -> run - ] with-cocoa ; inline +: cocoa-app ( quot -- ) [ call NSApp -> run ] with-cocoa ; inline : install-delegate ( receiver delegate -- ) -> alloc -> init -> setDelegate: ; @@ -80,6 +77,6 @@ M: objc-error summary ( error -- ) running.app? [ drop ] [ - "The " swap " requires you to run Factor from an application bundle." - 3append throw + "The " " requires you to run Factor from an application bundle." + surround throw ] if ; diff --git a/basis/cocoa/cocoa-tests.factor b/basis/cocoa/cocoa-tests.factor index e1d6672872..59ea91c3cf 100644 --- a/basis/cocoa/cocoa-tests.factor +++ b/basis/cocoa/cocoa-tests.factor @@ -1,7 +1,7 @@ IN: cocoa.tests USING: cocoa cocoa.messages cocoa.subclassing cocoa.types compiler kernel namespaces cocoa.classes tools.test memory -compiler.units ; +compiler.units math ; CLASS: { { +superclass+ "NSObject" } @@ -45,3 +45,27 @@ Bar [ [ 2.0 ] [ "x" get NSRect-y ] unit-test [ 101.0 ] [ "x" get NSRect-w ] unit-test [ 102.0 ] [ "x" get NSRect-h ] unit-test + +! Make sure that we can add methods +CLASS: { + { +superclass+ "NSObject" } + { +name+ "Bar" } +} { + "bar" + "NSRect" + { "id" "SEL" } + [ 2drop test-foo "x" get ] +} { + "babb" + "int" + { "id" "SEL" "int" } + [ 2nip sq ] +} ; + +[ 144 ] [ + Bar [ + -> alloc -> init + dup 12 -> babb + swap -> release + ] compile-call +] unit-test diff --git a/basis/cocoa/cocoa.factor b/basis/cocoa/cocoa.factor index ab86796236..44252a3b19 100644 --- a/basis/cocoa/cocoa.factor +++ b/basis/cocoa/cocoa.factor @@ -2,8 +2,8 @@ ! See http://factorcode.org/license.txt for BSD license. USING: compiler io kernel cocoa.runtime cocoa.subclassing cocoa.messages cocoa.types sequences words vocabs parser -core-foundation namespaces assocs hashtables compiler.units -lexer init ; +core-foundation.bundles namespaces assocs hashtables +compiler.units lexer init ; IN: cocoa : (remember-send) ( selector variable -- ) diff --git a/basis/cocoa/dialogs/dialogs.factor b/basis/cocoa/dialogs/dialogs.factor index 606526a240..13f6f0b7d6 100644 --- a/basis/cocoa/dialogs/dialogs.factor +++ b/basis/cocoa/dialogs/dialogs.factor @@ -1,7 +1,8 @@ -! Copyright (C) 2006, 2007 Slava Pestov +! Copyright (C) 2006, 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. USING: kernel cocoa cocoa.messages cocoa.classes -cocoa.application sequences splitting core-foundation ; +cocoa.application sequences splitting core-foundation +core-foundation.strings ; IN: cocoa.dialogs : ( -- panel ) @@ -26,9 +27,9 @@ IN: cocoa.dialogs [ -> filenames CF>string-array ] [ drop f ] if ; : split-path ( path -- dir file ) - "/" last-split1 [ ] bi@ ; + "/" split1-last [ ] bi@ ; : save-panel ( path -- paths ) - dup - rot split-path -> runModalForDirectory:file: NSOKButton = + [ dup ] dip + split-path -> runModalForDirectory:file: NSOKButton = [ -> filename CF>string ] [ drop f ] if ; diff --git a/basis/cocoa/enumeration/enumeration.factor b/basis/cocoa/enumeration/enumeration.factor index 7de1f24a3c..7f5b777283 100644 --- a/basis/cocoa/enumeration/enumeration.factor +++ b/basis/cocoa/enumeration/enumeration.factor @@ -1,26 +1,31 @@ -USING: kernel cocoa cocoa.types alien.c-types locals math sequences -vectors fry libc ; +! Copyright (C) 2008 Joe Groff. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel cocoa cocoa.types alien.c-types locals math +sequences vectors fry libc destructors +specialized-arrays.direct.alien ; IN: cocoa.enumeration : NS-EACH-BUFFER-SIZE 16 ; inline -: (with-enumeration-buffers) ( quot -- ) - "NSFastEnumerationState" heap-size swap '[ - NS-EACH-BUFFER-SIZE "id" heap-size * [ - NS-EACH-BUFFER-SIZE @ - ] with-malloc - ] with-malloc ; inline +: with-enumeration-buffers ( quot -- ) + [ + [ + "NSFastEnumerationState" malloc-object &free + NS-EACH-BUFFER-SIZE "id" heap-size * malloc-object &free + NS-EACH-BUFFER-SIZE + ] dip call + ] with-destructors ; inline :: (NSFastEnumeration-each) ( object quot: ( elt -- ) state stackbuf count -- ) object state stackbuf count -> countByEnumeratingWithState:objects:count: - dup zero? [ drop ] [ + dup 0 = [ drop ] [ state NSFastEnumerationState-itemsPtr [ stackbuf ] unless* - '[ _ void*-nth quot call ] each + swap quot each object quot state stackbuf count (NSFastEnumeration-each) ] if ; inline recursive : NSFastEnumeration-each ( object quot -- ) - [ (NSFastEnumeration-each) ] (with-enumeration-buffers) ; inline + [ (NSFastEnumeration-each) ] with-enumeration-buffers ; inline : NSFastEnumeration-map ( object quot -- vector ) NS-EACH-BUFFER-SIZE diff --git a/basis/cocoa/messages/messages.factor b/basis/cocoa/messages/messages.factor index 09b2255913..ebe98a2df1 100644 --- a/basis/cocoa/messages/messages.factor +++ b/basis/cocoa/messages/messages.factor @@ -1,21 +1,18 @@ ! Copyright (C) 2006, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors alien alien.c-types alien.strings arrays assocs -combinators compiler compiler.alien kernel math namespaces make -parser prettyprint prettyprint.sections quotations sequences -strings words cocoa.runtime io macros memoize debugger -io.encodings.ascii effects libc libc.private parser lexer init -core-foundation fry ; +continuations combinators compiler compiler.alien kernel math +namespaces make parser quotations sequences strings words +cocoa.runtime io macros memoize io.encodings.utf8 +effects libc libc.private parser lexer init core-foundation fry +generalizations specialized-arrays.direct.alien ; IN: cocoa.messages : make-sender ( method function -- quot ) [ over first , f , , second , \ alien-invoke , ] [ ] make ; -: sender-stub-name ( method function -- string ) - [ % "_" % unparse % ] "" make ; - : sender-stub ( method function -- word ) - [ sender-stub-name f dup ] 2keep + [ "( sender-stub )" f dup ] 2dip over first large-struct? [ "_stret" append ] when make-sender define ; @@ -27,7 +24,7 @@ super-message-senders global [ H{ } assoc-like ] change-at : cache-stub ( method function hash -- ) [ - over get [ 2drop ] [ over >r sender-stub r> set ] if + over get [ 2drop ] [ over [ sender-stub ] dip set ] if ] bind ; : cache-stubs ( method -- ) @@ -37,7 +34,7 @@ super-message-senders global [ H{ } assoc-like ] change-at : ( receiver -- super ) "objc-super" [ - >r dup object_getClass class_getSuperclass r> + [ dup object_getClass class_getSuperclass ] dip set-objc-super-class ] keep [ set-objc-super-receiver ] keep ; @@ -62,36 +59,35 @@ objc-methods global [ H{ } assoc-like ] change-at dup objc-methods get at [ ] [ "No such method: " prepend throw ] ?if ; -: make-dip ( quot n -- quot' ) - dup - \ >r >quotation -rot - \ r> >quotation 3append ; - MEMO: make-prepare-send ( selector method super? -- quot ) [ [ \ , ] when swap , \ selector , ] [ ] make - swap second length 2 - make-dip ; + swap second length 2 - '[ _ _ ndip ] ; MACRO: (send) ( selector super? -- quot ) - >r dup lookup-method r> + [ dup lookup-method ] dip [ make-prepare-send ] 2keep super-message-senders message-senders ? get at - [ slip execute ] 2curry ; + '[ _ call _ execute ] ; : send ( receiver args... selector -- return... ) f (send) ; inline -\ send soft "break-after" set-word-prop - : super-send ( receiver args... selector -- return... ) t (send) ; inline -\ super-send soft "break-after" set-word-prop - ! Runtime introspection -: (objc-class) ( string word -- class ) - dupd execute - [ ] [ "No such class: " prepend throw ] ?if ; inline +SYMBOL: class-init-hooks + +class-init-hooks global [ H{ } clone or ] change-at + +: (objc-class) ( name word -- class ) + 2dup execute dup [ 2nip ] [ + drop over class-init-hooks get at [ assert-depth ] when* + 2dup execute dup [ 2nip ] [ + 2drop "No such class: " prepend throw + ] if + ] if ; inline : objc-class ( string -- class ) \ objc_getClass (objc-class) ; @@ -165,14 +161,14 @@ objc>alien-types get [ swap ] assoc-map assoc-union alien>objc-types set-global : objc-struct-type ( i string -- ctype ) - 2dup CHAR: = -rot index-from swap subseq + [ CHAR: = ] 2keep index-from swap subseq dup c-types get key? [ "Warning: no such C type: " write dup print drop "void*" ] unless ; : (parse-objc-type) ( i string -- ctype ) - 2dup nth >r >r 1+ r> r> { + [ [ 1+ ] dip ] [ nth ] 2bi { { [ dup "rnNoORV" member? ] [ drop (parse-objc-type) ] } { [ dup CHAR: ^ = ] [ 3drop "void*" ] } { [ dup CHAR: { = ] [ drop objc-struct-type ] } @@ -184,7 +180,7 @@ assoc-union alien>objc-types set-global : method-arg-type ( method i -- type ) method_copyArgumentType - [ ascii alien>string parse-objc-type ] keep + [ utf8 alien>string parse-objc-type ] keep (free) ; : method-arg-types ( method -- args ) @@ -193,7 +189,7 @@ assoc-union alien>objc-types set-global : method-return-type ( method -- ctype ) method_copyReturnType - [ ascii alien>string parse-objc-type ] keep + [ utf8 alien>string parse-objc-type ] keep (free) ; : register-objc-method ( method -- ) @@ -203,42 +199,28 @@ assoc-union alien>objc-types set-global objc-methods get set-at ; : each-method-in-class ( class quot -- ) - [ 0 [ class_copyMethodList ] keep *uint over ] dip - '[ _ void*-nth @ ] each (free) ; inline + [ 0 [ class_copyMethodList ] keep *uint ] dip + over 0 = [ 3drop ] [ + [ ] dip + [ each ] [ drop underlying>> (free) ] 2bi + ] if ; inline : register-objc-methods ( class -- ) [ register-objc-method ] each-method-in-class ; -: method. ( method -- ) - { - [ method_getName sel_getName ] - [ method-return-type ] - [ method-arg-types ] - [ method_getImplementation ] - } cleave 4array . ; - -: methods. ( class -- ) - [ method. ] each-method-in-class ; - : class-exists? ( string -- class ) objc_getClass >boolean ; -: unless-defined ( class quot -- ) - >r class-exists? r> unless ; inline - -: define-objc-class-word ( name quot -- ) +: define-objc-class-word ( quot name -- ) + [ class-init-hooks get set-at ] [ - over , , \ unless-defined , dup , \ objc-class , - ] [ ] make >r "cocoa.classes" create r> - (( -- class )) define-declared ; + [ "cocoa.classes" create ] [ '[ _ objc-class ] ] bi + (( -- class )) define-declared + ] bi ; : import-objc-class ( name quot -- ) - 2dup unless-defined - dupd define-objc-class-word - [ - dup - objc-class register-objc-methods - objc-meta-class register-objc-methods - ] curry try ; + over define-objc-class-word + [ objc-class register-objc-methods ] + [ objc-meta-class register-objc-methods ] bi ; : root-class ( class -- root ) dup class_getSuperclass [ root-class ] [ ] ?if ; diff --git a/basis/cocoa/nibs/nibs.factor b/basis/cocoa/nibs/nibs.factor index 31dac2531b..a39cc794d0 100644 --- a/basis/cocoa/nibs/nibs.factor +++ b/basis/cocoa/nibs/nibs.factor @@ -1,5 +1,8 @@ -USING: cocoa.application cocoa.messages cocoa.classes cocoa.runtime -kernel cocoa core-foundation alien.c-types ; +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: cocoa.application cocoa.messages cocoa.classes +cocoa.runtime kernel cocoa alien.c-types core-foundation +core-foundation.arrays ; IN: cocoa.nibs : load-nib ( name -- ) diff --git a/basis/cocoa/pasteboard/pasteboard.factor b/basis/cocoa/pasteboard/pasteboard.factor index d266c2452f..888f5452e2 100644 --- a/basis/cocoa/pasteboard/pasteboard.factor +++ b/basis/cocoa/pasteboard/pasteboard.factor @@ -1,8 +1,8 @@ -! Copyright (C) 2006, 2007 Slava Pestov. +! Copyright (C) 2006, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: alien.c-types arrays kernel cocoa.messages -cocoa.classes cocoa.application cocoa core-foundation -sequences ; +USING: alien.accessors arrays kernel cocoa.messages +cocoa.classes cocoa.application sequences cocoa core-foundation +core-foundation.strings core-foundation.arrays ; IN: cocoa.pasteboard : NSStringPboardType "NSStringPboardType" ; @@ -20,11 +20,11 @@ IN: cocoa.pasteboard : set-pasteboard-string ( str pasteboard -- ) NSStringPboardType dup 1array pick set-pasteboard-types - >r swap r> -> setString:forType: drop ; + [ swap ] dip -> setString:forType: drop ; : pasteboard-error ( error -- f ) "Pasteboard does not hold a string" - 0 spin set-void*-nth f ; + 0 set-alien-cell f ; : ?pasteboard-string ( pboard error -- str/f ) over pasteboard-string? [ diff --git a/basis/cocoa/plists/plists.factor b/basis/cocoa/plists/plists.factor index bb73b8fac3..cf68f9864a 100644 --- a/basis/cocoa/plists/plists.factor +++ b/basis/cocoa/plists/plists.factor @@ -3,7 +3,7 @@ USING: strings arrays hashtables assocs sequences cocoa.messages cocoa.classes cocoa.application cocoa kernel namespaces io.backend math cocoa.enumeration byte-arrays -combinators alien.c-types core-foundation ; +combinators alien.c-types core-foundation core-foundation.data ; IN: cocoa.plists GENERIC: >plist ( value -- plist ) diff --git a/basis/cocoa/subclassing/subclassing.factor b/basis/cocoa/subclassing/subclassing.factor index fd18c7fa89..be53364185 100644 --- a/basis/cocoa/subclassing/subclassing.factor +++ b/basis/cocoa/subclassing/subclassing.factor @@ -1,33 +1,35 @@ -! Copyright (C) 2006, 2008 Slava Pestov +! Copyright (C) 2006, 2008 Slava Pestov, Joe Groff. ! See http://factorcode.org/license.txt for BSD license. USING: alien alien.c-types alien.strings arrays assocs combinators compiler hashtables kernel libc math namespaces -parser sequences words cocoa.messages cocoa.runtime -compiler.units io.encodings.ascii generalizations -continuations make ; +parser sequences words cocoa.messages cocoa.runtime locals +compiler.units io.encodings.utf8 continuations make fry ; IN: cocoa.subclassing : init-method ( method -- sel imp types ) first3 swap - [ sel_registerName ] [ execute ] [ ascii string>alien ] + [ sel_registerName ] [ execute ] [ utf8 string>alien ] tri* ; -: throw-if-false ( YES/NO -- ) - zero? [ "Failed to add method or protocol to class" throw ] - when ; +: throw-if-false ( obj what -- ) + swap { f 0 } member? + [ "Failed to " prepend throw ] [ drop ] if ; + +: add-method ( class sel imp types -- ) + class_addMethod "add method to class" throw-if-false ; : add-methods ( methods class -- ) - swap - [ init-method class_addMethod throw-if-false ] with each ; + '[ [ _ ] dip init-method add-method ] each ; + +: add-protocol ( class protocol -- ) + class_addProtocol "add protocol to class" throw-if-false ; : add-protocols ( protocols class -- ) - swap [ objc-protocol class_addProtocol throw-if-false ] - with each ; + '[ [ _ ] dip objc-protocol add-protocol ] each ; -: (define-objc-class) ( protocols superclass name imeth -- ) - -rot +: (define-objc-class) ( imeth protocols superclass name -- ) [ objc-class ] dip 0 objc_allocateClassPair - [ add-methods ] [ add-protocols ] [ objc_registerClassPair ] + [ add-protocols ] [ add-methods ] [ objc_registerClassPair ] tri ; : encode-types ( return types -- encoding ) @@ -36,7 +38,7 @@ IN: cocoa.subclassing ] map concat ; : prepare-method ( ret types quot -- type imp ) - >r [ encode-types ] 2keep r> [ + [ [ encode-types ] 2keep ] dip [ "cdecl" swap 4array % \ alien-callback , ] [ ] make define-temp ; @@ -45,28 +47,19 @@ IN: cocoa.subclassing [ first4 prepare-method 3array ] map ] with-compilation-unit ; -: types= ( a b -- ? ) - [ ascii alien>string ] bi@ = ; - -: (verify-method-type) ( class sel types -- ) - [ class_getInstanceMethod method_getTypeEncoding ] - dip types= - [ "Objective-C method types cannot be changed once defined" throw ] - unless ; -: verify-method-type ( class sel imp types -- class sel imp types ) - 4 ndup nip (verify-method-type) ; - -: (redefine-objc-method) ( class method -- ) - init-method ! verify-method-type - drop - [ class_getInstanceMethod ] dip method_setImplementation drop ; +:: (redefine-objc-method) ( class method -- ) + method init-method [| sel imp types | + class sel class_getInstanceMethod [ + imp method_setImplementation drop + ] [ + class sel imp types add-method + ] if* + ] call ; : redefine-objc-methods ( imeth name -- ) dup class-exists? [ - objc_getClass swap [ (redefine-objc-method) ] with each - ] [ - 2drop - ] if ; + objc_getClass '[ [ _ ] dip (redefine-objc-method) ] each + ] [ 2drop ] if ; SYMBOL: +name+ SYMBOL: +protocols+ @@ -76,10 +69,10 @@ SYMBOL: +superclass+ clone [ prepare-methods +name+ get "cocoa.classes" create drop - +name+ get 2dup redefine-objc-methods swap [ - +protocols+ get , +superclass+ get , +name+ get , , - \ (define-objc-class) , - ] [ ] make import-objc-class + +name+ get 2dup redefine-objc-methods swap + +protocols+ get +superclass+ get +name+ get + '[ _ _ _ _ (define-objc-class) ] + import-objc-class ] bind ; : CLASS: diff --git a/basis/cocoa/views/views.factor b/basis/cocoa/views/views.factor index d03688b2be..03cafd0a0a 100644 --- a/basis/cocoa/views/views.factor +++ b/basis/cocoa/views/views.factor @@ -1,8 +1,8 @@ -! Copyright (C) 2006, 2007 Slava Pestov +! Copyright (C) 2006, 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. -USING: alien.c-types arrays kernel math namespaces make cocoa -cocoa.messages cocoa.classes cocoa.types sequences -continuations ; +USING: specialized-arrays.int arrays kernel math namespaces make +cocoa cocoa.messages cocoa.classes cocoa.types sequences +continuations accessors ; IN: cocoa.views : NSOpenGLPFAAllRenderers 1 ; @@ -55,10 +55,9 @@ PRIVATE> : with-multisample ( quot -- ) t +multisample+ pick with-variable ; inline -: ( -- pixelfmt ) - NSOpenGLPixelFormat -> alloc [ - NSOpenGLPFAWindow , - NSOpenGLPFADoubleBuffer , +: ( attributes -- pixelfmt ) + NSOpenGLPixelFormat -> alloc swap [ + % NSOpenGLPFADepthSize , 16 , +software-renderer+ get [ NSOpenGLPFARendererID , kCGLRendererGenericFloatID , @@ -69,12 +68,13 @@ PRIVATE> NSOpenGLPFASamples , 8 , ] when 0 , - ] { } make >c-int-array + ] int-array{ } make underlying>> -> initWithAttributes: -> autorelease ; : ( class dim -- view ) - >r -> alloc 0 0 r> first2 + [ -> alloc 0 0 ] dip first2 + NSOpenGLPFAWindow NSOpenGLPFADoubleBuffer 2array -> initWithFrame:pixelFormat: dup 1 -> setPostsBoundsChangedNotifications: dup 1 -> setPostsFrameChangedNotifications: ; @@ -85,10 +85,11 @@ PRIVATE> swap NSRect-h >fixnum 2array ; : mouse-location ( view event -- loc ) - over >r - -> locationInWindow f -> convertPoint:fromView: - dup NSPoint-x swap NSPoint-y - r> -> frame NSRect-h swap - 2array ; + [ + -> locationInWindow f -> convertPoint:fromView: + [ NSPoint-x ] [ NSPoint-y ] bi + ] [ drop -> frame NSRect-h ] 2bi + swap - 2array ; USE: opengl.gl USE: alien.syntax diff --git a/basis/cocoa/windows/windows.factor b/basis/cocoa/windows/windows.factor index dd2d1bfd41..3a53a1cc3c 100644 --- a/basis/cocoa/windows/windows.factor +++ b/basis/cocoa/windows/windows.factor @@ -34,5 +34,6 @@ IN: cocoa.windows dup 0 -> setReleasedWhenClosed: ; : window-content-rect ( window -- rect ) - NSWindow over -> frame rot -> styleMask + [ NSWindow ] dip + [ -> frame ] [ -> styleMask ] bi -> contentRectForFrameRect:styleMask: ; diff --git a/basis/combinators/short-circuit/short-circuit-docs.factor b/basis/combinators/short-circuit/short-circuit-docs.factor index 54fc3aac43..6cd18201fe 100644 --- a/basis/combinators/short-circuit/short-circuit-docs.factor +++ b/basis/combinators/short-circuit/short-circuit-docs.factor @@ -52,17 +52,17 @@ HELP: 3|| { "quot" quotation } } { $description "Returns true if any quotation in the sequence returns true. Each quotation takes the same three elements from the datastack and must return a boolean." } ; -HELP: n&&-rewrite +HELP: n&& { $values { "quots" "a sequence of quotations" } { "N" integer } { "quot" quotation } } -{ $description "A macro that reqrites the code to pass " { $snippet "N" } " parameters from the stack to each AND quotation." } ; +{ $description "A macro that rewrites the code to pass " { $snippet "n" } " parameters from the stack to each AND quotation." } ; -HELP: n||-rewrite +HELP: n|| { $values - { "quots" "a sequence of quotations" } { "N" integer } + { "quots" "a sequence of quotations" } { "n" integer } { "quot" quotation } } -{ $description "A macro that reqrites the code to pass " { $snippet "N" } " parameters from the stack to each OR quotation." } ; +{ $description "A macro that rewrites the code to pass " { $snippet "n" } " parameters from the stack to each OR quotation." } ; ARTICLE: "combinators.short-circuit" "Short-circuit combinators" "The " { $vocab-link "combinators.short-circuit" } " vocabulary stops a computation early once a condition is met." $nl @@ -77,8 +77,8 @@ ARTICLE: "combinators.short-circuit" "Short-circuit combinators" { $subsection 2|| } { $subsection 3|| } "Generalized combinators:" -{ $subsection n&&-rewrite } -{ $subsection n||-rewrite } +{ $subsection n&& } +{ $subsection n|| } ; ABOUT: "combinators.short-circuit" diff --git a/basis/combinators/short-circuit/short-circuit.factor b/basis/combinators/short-circuit/short-circuit.factor index 7b6c1d126d..d8bab4dd34 100644 --- a/basis/combinators/short-circuit/short-circuit.factor +++ b/basis/combinators/short-circuit/short-circuit.factor @@ -1,35 +1,33 @@ - USING: kernel combinators quotations arrays sequences assocs - locals generalizations macros fry ; - +locals generalizations macros fry ; IN: combinators.short-circuit -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +MACRO:: n&& ( quots n -- quot ) + [ f ] quots [| q | + n + [ q '[ drop _ ndup @ dup not ] ] + [ '[ drop _ ndrop f ] ] + bi 2array + ] map + n '[ _ nnip ] suffix 1array + [ cond ] 3append ; -:: n&&-rewrite ( quots N -- quot ) - quots - [ '[ drop N ndup @ dup not ] [ drop N ndrop f ] 2array ] - map - [ t ] [ N nnip ] 2array suffix - '[ f _ cond ] ; +MACRO: 0&& ( quots -- quot ) '[ _ 0 n&& ] ; +MACRO: 1&& ( quots -- quot ) '[ _ 1 n&& ] ; +MACRO: 2&& ( quots -- quot ) '[ _ 2 n&& ] ; +MACRO: 3&& ( quots -- quot ) '[ _ 3 n&& ] ; -MACRO: 0&& ( quots -- quot ) 0 n&&-rewrite ; -MACRO: 1&& ( quots -- quot ) 1 n&&-rewrite ; -MACRO: 2&& ( quots -- quot ) 2 n&&-rewrite ; -MACRO: 3&& ( quots -- quot ) 3 n&&-rewrite ; +MACRO:: n|| ( quots n -- quot ) + [ f ] quots [| q | + n + [ q '[ drop _ ndup @ dup ] ] + [ '[ _ nnip ] ] + bi 2array + ] map + n '[ drop _ ndrop t ] [ f ] 2array suffix 1array + [ cond ] 3append ; -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -:: n||-rewrite ( quots N -- quot ) - quots - [ '[ drop N ndup @ dup ] [ N nnip ] 2array ] - map - [ drop N ndrop t ] [ f ] 2array suffix - '[ f _ cond ] ; - -MACRO: 0|| ( quots -- quot ) 0 n||-rewrite ; -MACRO: 1|| ( quots -- quot ) 1 n||-rewrite ; -MACRO: 2|| ( quots -- quot ) 2 n||-rewrite ; -MACRO: 3|| ( quots -- quot ) 3 n||-rewrite ; - -! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +MACRO: 0|| ( quots -- quot ) '[ _ 0 n|| ] ; +MACRO: 1|| ( quots -- quot ) '[ _ 1 n|| ] ; +MACRO: 2|| ( quots -- quot ) '[ _ 2 n|| ] ; +MACRO: 3|| ( quots -- quot ) '[ _ 3 n|| ] ; diff --git a/basis/combinators/short-circuit/smart/smart.factor b/basis/combinators/short-circuit/smart/smart.factor index ca659cacbe..b80e7294d1 100644 --- a/basis/combinators/short-circuit/smart/smart.factor +++ b/basis/combinators/short-circuit/smart/smart.factor @@ -1,7 +1,5 @@ - USING: kernel sequences math stack-checker effects accessors macros - combinators.short-circuit ; - +fry combinators.short-circuit ; IN: combinators.short-circuit.smart -MACRO: && ( quots -- quot ) dup arity n&&-rewrite ; +MACRO: && ( quots -- quot ) dup arity '[ _ _ n&& ] ; -MACRO: || ( quots -- quot ) dup arity n||-rewrite ; +MACRO: || ( quots -- quot ) dup arity '[ _ _ n|| ] ; diff --git a/basis/command-line/command-line-docs.factor b/basis/command-line/command-line-docs.factor index 65d290df3a..3d06bd97b7 100644 --- a/basis/command-line/command-line-docs.factor +++ b/basis/command-line/command-line-docs.factor @@ -1,4 +1,5 @@ -USING: help.markup help.syntax parser vocabs.loader strings ; +USING: help.markup help.syntax parser vocabs.loader strings +command-line.private ; IN: command-line HELP: run-bootstrap-init @@ -7,7 +8,10 @@ HELP: run-bootstrap-init HELP: run-user-init { $description "Runs the startup initialization file in the user's home directory, unless the " { $snippet "-no-user-init" } " command line switch was given. This file is named " { $snippet ".factor-rc" } " on Unix and " { $snippet "factor-rc" } " on Windows." } ; -HELP: cli-param +HELP: load-vocab-roots +{ $description "Loads the newline-separated list of additional vocabulary roots from the file named " { $snippet ".factor-roots" } " on Unix and " { $snippet "factor-roots" } " on Windows." } ; + +HELP: param { $values { "param" string } } { $description "Process a command-line switch." $nl @@ -17,10 +21,13 @@ $nl $nl "Otherwise, sets the global variable named by the parameter to " { $link t } "." } ; -HELP: cli-args +HELP: (command-line) { $values { "args" "a sequence of strings" } } { $description "Outputs the command line parameters which were passed to the Factor VM on startup." } ; +HELP: command-line +{ $var-description "The command line parameters which follow the name of the script on the command line." } ; + HELP: main-vocab-hook { $var-description "Global variable holding a quotation which outputs a vocabulary name. UI backends set this so that the UI can automatically start if the prerequisites are met (for example, " { $snippet "$DISPLAY" } " being set on X11)." } ; @@ -35,9 +42,6 @@ HELP: ignore-cli-args? { $values { "?" "a boolean" } } { $description "On Mac OS X, source files to run are supplied by the Cocoa API, so to avoid running them twice the startup code has to call this word." } ; -HELP: parse-command-line -{ $description "Called on startup to process command line arguments. This sets global variables with " { $link cli-param } ", runs source files, and evaluates the string given by the " { $snippet "-e" } " switch, if there is one." } ; - ARTICLE: "runtime-cli-args" "Command line switches for the VM" "A handful of command line switches are processed by the VM and not the library. They control low-level features." { $table @@ -64,9 +68,12 @@ ARTICLE: "bootstrap-cli-args" "Command line switches for bootstrap" } "Bootstrap can load various optional components:" { $table + { { $snippet "math" } "Rational and complex number support." } + { { $snippet "threads" } "Thread support." } { { $snippet "compiler" } "The compiler." } { { $snippet "tools" } "Terminal-based developer tools." } { { $snippet "help" } "The help system." } + { { $snippet "help.handbook" } "The help handbook." } { { $snippet "ui" } "The graphical user interface." } { { $snippet "ui.tools" } "Graphical developer tools." } { { $snippet "io" } "Non-blocking I/O and networking." } @@ -86,7 +93,6 @@ ARTICLE: "standard-cli-args" "Command line switches for general usage" { { $snippet "-run=" { $emphasis "vocab" } } { { $snippet { $emphasis "vocab" } } " is the name of a vocabulary with a " { $link POSTPONE: MAIN: } " hook to run on startup, for example " { $vocab-link "listener" } ", " { $vocab-link "ui" } " or " { $vocab-link "none" } "." } } { { $snippet "-no-user-init" } { "Inhibits the running of user initialization files on startup. See " { $link "rc-files" } "." } } { { $snippet "-quiet" } { "If set, " { $link run-file } " and " { $link require } " will not print load messages." } } - { { $snippet "-script" } { "Equivalent to " { $snippet "-quiet -run=none" } "." $nl "On Unix systems, Factor can be used for scripting - just create an executable text file whose first line is:" { $code "#! /usr/local/bin/factor -script" } "The space after " { $snippet "#!" } " is necessary because of Factor syntax." } } } ; ARTICLE: "factor-boot-rc" "Bootstrap initialization file" @@ -102,11 +108,18 @@ $nl "A word to run this file from an existing Factor session:" { $subsection run-user-init } ; +ARTICLE: "factor-roots" "Additional vocabulary roots file" +"The vocabulary roots file is named " { $snippet "factor-roots" } " on Windows and " { $snippet ".factor-roots" } " on Unix. If it exists, it is loaded every time Factor starts. It contains a newline-separated list of " { $link "vocabs.roots" } "." +$nl +"A word to run this file from an existing Factor session:" +{ $subsection load-vocab-roots } ; + ARTICLE: "rc-files" "Running code on startup" -"Factor looks for two files in your home directory." +"Factor looks for three optional files in your home directory." { $subsection "factor-boot-rc" } { $subsection "factor-rc" } -"The " { $snippet "-no-user-init" } " command line switch will inhibit the running of these files." +{ $subsection "factor-roots" } +"The " { $snippet "-no-user-init" } " command line switch will inhibit loading running of these files." $nl "If you are unsure where the files should be located, evaluate the following code:" { $code @@ -122,8 +135,16 @@ $nl "100 dpi set-global" } ; -ARTICLE: "cli" "Command line usage" -"Zero or more command line arguments may be passed to the Factor runtime. Command line arguments starting with a dash (" { $snippet "-" } ") is interpreted as switches. All other arguments are taken to be file names to be run by " { $link run-file } "." +ARTICLE: "cli" "Command line arguments" +"Factor command line usage:" +{ $code "factor [system switches...] [script args...]" } +"Zero or more system switches can be passed in, followed by an optional script file name. If the script file is specified, it will be run on startup, any arguments after the script file are stored in a variable, with no further processing by Factor itself:" +{ $subsection command-line } +"Instead of running a script, it is also possible to run a vocabulary; this invokes the vocabulary's " { $link POSTPONE: MAIN: } " word:" +{ $code "factor [system switches...] -run=" } +"If no script file or " { $snippet "-run=" } " switch is specified, Factor will start " { $link "listener" } " or " { $link "ui-tools" } ", depending on the operating system." +$nl +"As stated above, arguments in the first part of the command line, before the optional script name, are interpreted by to the Factor system. These arguments all start with a dash (" { $snippet "-" } ")." $nl "Switches can take one of the following three forms:" { $list @@ -134,9 +155,9 @@ $nl { $subsection "runtime-cli-args" } { $subsection "bootstrap-cli-args" } { $subsection "standard-cli-args" } -"The list of command line arguments can be obtained and inspected directly:" -{ $subsection cli-args } -"There is a way to override the default vocabulary to run on startup:" +"The raw list of command line arguments can also be obtained and inspected directly:" +{ $subsection (command-line) } +"There is a way to override the default vocabulary to run on startup, if no script name or " { $snippet "-run" } " switch is specified:" { $subsection main-vocab-hook } ; ABOUT: "cli" diff --git a/basis/command-line/command-line-tests.factor b/basis/command-line/command-line-tests.factor deleted file mode 100644 index 226765bafe..0000000000 --- a/basis/command-line/command-line-tests.factor +++ /dev/null @@ -1,12 +0,0 @@ -USING: namespaces tools.test kernel command-line ; -IN: command-line.tests - -[ - [ f ] [ "-no-user-init" cli-arg ] unit-test - [ f ] [ "user-init" get ] unit-test - - [ f ] [ "-user-init" cli-arg ] unit-test - [ t ] [ "user-init" get ] unit-test - - [ "sdl.factor" ] [ "sdl.factor" cli-arg ] unit-test -] with-scope diff --git a/basis/command-line/command-line.factor b/basis/command-line/command-line.factor index 7691f6877b..7d5a041951 100644 --- a/basis/command-line/command-line.factor +++ b/basis/command-line/command-line.factor @@ -1,10 +1,15 @@ ! Copyright (C) 2003, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: init continuations debugger hashtables io kernel -kernel.private namespaces parser sequences strings system -splitting io.files eval ; +USING: init continuations hashtables io io.encodings.utf8 +io.files kernel kernel.private namespaces parser sequences +strings system splitting vocabs.loader ; IN: command-line +SYMBOL: script +SYMBOL: command-line + +: (command-line) ( -- args ) 10 getenv sift ; + : rc-path ( name -- path ) os windows? [ "." prepend ] unless home prepend-path ; @@ -19,17 +24,29 @@ IN: command-line "factor-rc" rc-path ?run-file ] when ; -: cli-var-param ( name value -- ) swap set-global ; +: load-vocab-roots ( -- ) + "user-init" get [ + "factor-roots" rc-path dup exists? [ + utf8 file-lines [ add-vocab-root ] each + ] [ drop ] if + ] when ; -: cli-bool-param ( name -- ) "no-" ?head not cli-var-param ; +: var-param ( name value -- ) swap set-global ; -: cli-param ( param -- ) - "=" split1 [ cli-var-param ] [ cli-bool-param ] if* ; +: bool-param ( name -- ) "no-" ?head not var-param ; -: cli-arg ( argument -- argument ) - "-" ?head [ cli-param f ] when ; +: param ( param -- ) + "=" split1 [ var-param ] [ bool-param ] if* ; -: cli-args ( -- args ) 10 getenv ; +: run-script ( file -- ) + t "quiet" set-global run-file ; + +: parse-command-line ( args -- ) + [ command-line off script off ] [ + unclip "-" ?head + [ param parse-command-line ] + [ script set command-line set ] if + ] if-empty ; SYMBOL: main-vocab-hook @@ -53,14 +70,6 @@ SYMBOL: main-vocab-hook : ignore-cli-args? ( -- ? ) os macosx? "run" get "ui" = and ; -: script-mode ( -- ) - t "quiet" set-global - "none" "run" set-global ; - -: parse-command-line ( -- ) - cli-args [ cli-arg ] filter - "script" get [ script-mode ] when - ignore-cli-args? [ drop ] [ [ run-file ] each ] if - "e" get [ eval ] when* ; +: script-mode ( -- ) ; [ default-cli-args ] "command-line" add-init-hook diff --git a/basis/compiler/alien/alien.factor b/basis/compiler/alien/alien.factor index e414d6e29b..4a41014ab2 100644 --- a/basis/compiler/alien/alien.factor +++ b/basis/compiler/alien/alien.factor @@ -18,7 +18,7 @@ IN: compiler.alien dup c-type-stack-align? [ c-type-align ] [ drop cell ] if ; : parameter-align ( n type -- n delta ) - over >r c-type-stack-align align dup r> - ; + [ c-type-stack-align align dup ] [ drop ] 2bi - ; : parameter-sizes ( types -- total offsets ) #! Compute stack frame locations. diff --git a/basis/compiler/cfg/alias-analysis/alias-analysis-tests.factor b/basis/compiler/cfg/alias-analysis/alias-analysis-tests.factor index c7094c8c36..d8bad5ec41 100644 --- a/basis/compiler/cfg/alias-analysis/alias-analysis-tests.factor +++ b/basis/compiler/cfg/alias-analysis/alias-analysis-tests.factor @@ -1,6 +1,6 @@ USING: compiler.cfg.instructions compiler.cfg.registers -compiler.cfg.alias-analysis cpu.architecture tools.test -kernel ; +compiler.cfg.alias-analysis compiler.cfg.debugger +cpu.architecture tools.test kernel ; IN: compiler.cfg.alias-analysis.tests [ ] [ diff --git a/basis/compiler/cfg/alias-analysis/alias-analysis.factor b/basis/compiler/cfg/alias-analysis/alias-analysis.factor index 98569d868c..90227bb5da 100644 --- a/basis/compiler/cfg/alias-analysis/alias-analysis.factor +++ b/basis/compiler/cfg/alias-analysis/alias-analysis.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel math namespaces assocs hashtables sequences +USING: kernel math namespaces assocs hashtables sequences arrays accessors vectors combinators sets classes compiler.cfg compiler.cfg.registers compiler.cfg.instructions compiler.cfg.copy-prop ; @@ -194,6 +194,7 @@ M: ##slot insn-slot# slot>> constant ; M: ##slot-imm insn-slot# slot>> ; M: ##set-slot insn-slot# slot>> constant ; M: ##set-slot-imm insn-slot# slot>> ; +M: ##alien-global insn-slot# [ library>> ] [ symbol>> ] bi 2array ; M: ##peek insn-object loc>> class ; M: ##replace insn-object loc>> class ; @@ -201,6 +202,7 @@ M: ##slot insn-object obj>> resolve ; M: ##slot-imm insn-object obj>> resolve ; M: ##set-slot insn-object obj>> resolve ; M: ##set-slot-imm insn-object obj>> resolve ; +M: ##alien-global insn-object drop \ ##alien-global ; : init-alias-analysis ( -- ) H{ } clone histories set @@ -224,6 +226,9 @@ M: ##load-immediate analyze-aliases* M: ##load-indirect analyze-aliases* dup dst>> set-heap-ac ; +M: ##alien-global analyze-aliases* + dup dst>> set-heap-ac ; + M: ##allot analyze-aliases* #! A freshly allocated object is distinct from any other #! object. diff --git a/basis/compiler/cfg/builder/builder.factor b/basis/compiler/cfg/builder/builder.factor index 7bad44f7a6..9ffe4a6aa0 100755 --- a/basis/compiler/cfg/builder/builder.factor +++ b/basis/compiler/cfg/builder/builder.factor @@ -21,8 +21,6 @@ IN: compiler.cfg.builder ! Convert tree SSA IR to CFG SSA IR. -: stop-iterating ( -- next ) end-basic-block f ; - SYMBOL: procedures SYMBOL: current-word SYMBOL: current-label @@ -211,7 +209,7 @@ M: #dispatch emit-node ! #call M: #call emit-node dup word>> dup "intrinsic" word-prop - [ emit-intrinsic iterate-next ] [ nip emit-call ] if ; + [ emit-intrinsic ] [ nip emit-call ] if ; ! #call-recursive M: #call-recursive emit-node label>> id>> emit-call ; @@ -262,7 +260,7 @@ M: #terminate emit-node drop stop-iterating ; : emit-alien-node ( node quot -- next ) [ params>> ] dip [ drop alien-stack-frame ] [ call ] 2bi - begin-basic-block iterate-next ; inline + ##branch begin-basic-block iterate-next ; inline M: #alien-invoke emit-node [ ##alien-invoke ] emit-alien-node ; diff --git a/basis/compiler/cfg/dead-code/dead-code-tests.factor b/basis/compiler/cfg/dead-code/dead-code-tests.factor index b9c3af5215..ee7d8d2a43 100644 --- a/basis/compiler/cfg/dead-code/dead-code-tests.factor +++ b/basis/compiler/cfg/dead-code/dead-code-tests.factor @@ -1,5 +1,6 @@ USING: compiler.cfg.dead-code compiler.cfg.instructions -compiler.cfg.registers cpu.architecture tools.test ; +compiler.cfg.registers compiler.cfg.debugger +cpu.architecture tools.test ; IN: compiler.cfg.dead-code.tests [ { } ] [ diff --git a/basis/compiler/cfg/debugger/debugger.factor b/basis/compiler/cfg/debugger/debugger.factor index 7b1b9100c4..ba58e60a4a 100644 --- a/basis/compiler/cfg/debugger/debugger.factor +++ b/basis/compiler/cfg/debugger/debugger.factor @@ -2,10 +2,12 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel words sequences quotations namespaces io classes.tuple accessors prettyprint prettyprint.config -compiler.tree.builder compiler.tree.optimizer +prettyprint.backend prettyprint.custom prettyprint.sections +parser compiler.tree.builder compiler.tree.optimizer compiler.cfg.builder compiler.cfg.linearization -compiler.cfg.stack-frame compiler.cfg.linear-scan -compiler.cfg.two-operand compiler.cfg.optimizer ; +compiler.cfg.registers compiler.cfg.stack-frame +compiler.cfg.linear-scan compiler.cfg.two-operand +compiler.cfg.optimizer ; IN: compiler.cfg.debugger GENERIC: test-cfg ( quot -- cfgs ) @@ -40,3 +42,15 @@ SYMBOL: allocate-registers? instructions>> [ insn. ] each nl ] each ; + +! Prettyprinting +M: vreg pprint* + > pprint* ] [ n>> pprint* ] bi + block> ; + +: pprint-loc ( loc word -- ) > pprint* block> ; + +M: ds-loc pprint* \ D pprint-loc ; + +M: rs-loc pprint* \ R pprint-loc ; diff --git a/basis/compiler/cfg/def-use/def-use.factor b/basis/compiler/cfg/def-use/def-use.factor index 7553407e00..068a6a6377 100644 --- a/basis/compiler/cfg/def-use/def-use.factor +++ b/basis/compiler/cfg/def-use/def-use.factor @@ -12,9 +12,15 @@ M: ##write-barrier defs-vregs [ card#>> ] [ table>> ] bi 2array ; M: ##unary/temp defs-vregs dst/tmp-vregs ; M: ##allot defs-vregs dst/tmp-vregs ; M: ##dispatch defs-vregs temp>> 1array ; -M: ##slot defs-vregs [ dst>> ] [ temp>> ] bi 2array ; +M: ##slot defs-vregs dst/tmp-vregs ; M: ##set-slot defs-vregs temp>> 1array ; -M: ##string-nth defs-vregs [ dst>> ] [ temp>> ] bi 2array ; +M: ##string-nth defs-vregs dst/tmp-vregs ; +M: ##set-string-nth-fast defs-vregs temp>> 1array ; +M: ##compare defs-vregs dst/tmp-vregs ; +M: ##compare-imm defs-vregs dst/tmp-vregs ; +M: ##compare-float defs-vregs dst/tmp-vregs ; +M: ##fixnum-mul defs-vregs [ temp1>> ] [ temp2>> ] bi 2array ; +M: ##fixnum-mul-tail defs-vregs [ temp1>> ] [ temp2>> ] bi 2array ; M: insn defs-vregs drop f ; M: ##unary uses-vregs src>> 1array ; @@ -26,11 +32,13 @@ M: ##slot-imm uses-vregs obj>> 1array ; M: ##set-slot uses-vregs [ src>> ] [ obj>> ] [ slot>> ] tri 3array ; M: ##set-slot-imm uses-vregs [ src>> ] [ obj>> ] bi 2array ; M: ##string-nth uses-vregs [ obj>> ] [ index>> ] bi 2array ; +M: ##set-string-nth-fast uses-vregs [ src>> ] [ obj>> ] [ index>> ] tri 3array ; M: ##conditional-branch uses-vregs [ src1>> ] [ src2>> ] bi 2array ; M: ##compare-imm-branch uses-vregs src1>> 1array ; M: ##dispatch uses-vregs src>> 1array ; M: ##alien-getter uses-vregs src>> 1array ; M: ##alien-setter uses-vregs [ src>> ] [ value>> ] bi 2array ; +M: ##fixnum-overflow uses-vregs [ src1>> ] [ src2>> ] bi 2array ; M: _conditional-branch uses-vregs [ src1>> ] [ src2>> ] bi 2array ; M: _compare-imm-branch uses-vregs src1>> 1array ; M: insn uses-vregs drop f ; @@ -40,6 +48,7 @@ UNION: vreg-insn ##write-barrier ##dispatch ##effect +##fixnum-overflow ##conditional-branch ##compare-imm-branch _conditional-branch diff --git a/basis/compiler/cfg/hats/hats.factor b/basis/compiler/cfg/hats/hats.factor index e6e05abbd5..c0d5bf79a6 100644 --- a/basis/compiler/cfg/hats/hats.factor +++ b/basis/compiler/cfg/hats/hats.factor @@ -39,6 +39,7 @@ IN: compiler.cfg.hats : ^^shr-imm ( src1 src2 -- dst ) ^^i2 ##shr-imm ; inline : ^^sar-imm ( src1 src2 -- dst ) ^^i2 ##sar-imm ; inline : ^^not ( src -- dst ) ^^i1 ##not ; inline +: ^^log2 ( src -- dst ) ^^i1 ##log2 ; inline : ^^bignum>integer ( src -- dst ) ^^i1 i ##bignum>integer ; inline : ^^integer>bignum ( src -- dst ) ^^i1 i ##integer>bignum ; inline : ^^add-float ( src1 src2 -- dst ) ^^d2 ##add-float ; inline @@ -65,9 +66,10 @@ IN: compiler.cfg.hats : ^^alien-cell ( src -- dst ) ^^i1 ##alien-cell ; inline : ^^alien-float ( src -- dst ) ^^d1 ##alien-float ; inline : ^^alien-double ( src -- dst ) ^^d1 ##alien-double ; inline -: ^^compare ( src1 src2 cc -- dst ) ^^i3 ##compare ; inline -: ^^compare-imm ( src1 src2 cc -- dst ) ^^i3 ##compare-imm ; inline -: ^^compare-float ( src1 src2 cc -- dst ) ^^i3 ##compare-float ; inline +: ^^alien-global ( symbol library -- dst ) ^^i2 ##alien-global ; inline +: ^^compare ( src1 src2 cc -- dst ) ^^i3 i ##compare ; inline +: ^^compare-imm ( src1 src2 cc -- dst ) ^^i3 i ##compare-imm ; inline +: ^^compare-float ( src1 src2 cc -- dst ) ^^i3 i ##compare-float ; inline : ^^offset>slot ( vreg -- vreg' ) cell 4 = [ 1 ^^shr-imm ] when ; inline : ^^tag-fixnum ( src -- dst ) ^^i1 ##tag-fixnum ; inline : ^^untag-fixnum ( src -- dst ) ^^i1 ##untag-fixnum ; inline diff --git a/basis/compiler/cfg/instructions/instructions.factor b/basis/compiler/cfg/instructions/instructions.factor index b2c752e612..5619a70740 100644 --- a/basis/compiler/cfg/instructions/instructions.factor +++ b/basis/compiler/cfg/instructions/instructions.factor @@ -73,6 +73,7 @@ INSN: ##set-slot-imm < ##write { obj vreg } { slot integer } { tag integer } ; ! String element access INSN: ##string-nth < ##flushable { obj vreg } { index vreg } { temp vreg } ; +INSN: ##set-string-nth-fast < ##effect { obj vreg } { index vreg } { temp vreg } ; ! Integer arithmetic INSN: ##add < ##commutative ; @@ -91,6 +92,16 @@ INSN: ##shl-imm < ##binary-imm ; INSN: ##shr-imm < ##binary-imm ; INSN: ##sar-imm < ##binary-imm ; INSN: ##not < ##unary ; +INSN: ##log2 < ##unary ; + +! Overflowing arithmetic +TUPLE: ##fixnum-overflow < insn src1 src2 ; +INSN: ##fixnum-add < ##fixnum-overflow ; +INSN: ##fixnum-add-tail < ##fixnum-overflow ; +INSN: ##fixnum-sub < ##fixnum-overflow ; +INSN: ##fixnum-sub-tail < ##fixnum-overflow ; +INSN: ##fixnum-mul < ##fixnum-overflow temp1 temp2 ; +INSN: ##fixnum-mul-tail < ##fixnum-overflow temp1 temp2 ; : ##tag-fixnum ( dst src -- ) tag-bits get ##shl-imm ; inline : ##untag-fixnum ( dst src -- ) tag-bits get ##sar-imm ; inline @@ -151,6 +162,8 @@ INSN: ##set-alien-double < ##alien-setter ; INSN: ##allot < ##flushable size class { temp vreg } ; INSN: ##write-barrier < ##effect card# table ; +INSN: ##alien-global < ##read symbol library ; + ! FFI INSN: ##alien-invoke params ; INSN: ##alien-indirect params ; @@ -198,11 +211,11 @@ TUPLE: ##conditional-branch < insn { src1 vreg } { src2 vreg } cc ; INSN: ##compare-branch < ##conditional-branch ; INSN: ##compare-imm-branch { src1 vreg } { src2 integer } cc ; -INSN: ##compare < ##binary cc ; -INSN: ##compare-imm < ##binary-imm cc ; +INSN: ##compare < ##binary cc temp ; +INSN: ##compare-imm < ##binary-imm cc temp ; INSN: ##compare-float-branch < ##conditional-branch ; -INSN: ##compare-float < ##binary cc ; +INSN: ##compare-float < ##binary cc temp ; ! Instructions used by machine IR only. INSN: _prologue stack-frame ; diff --git a/basis/compiler/cfg/intrinsics/allot/allot.factor b/basis/compiler/cfg/intrinsics/allot/allot.factor index ceac5e960c..3a4c702bc5 100644 --- a/basis/compiler/cfg/intrinsics/allot/allot.factor +++ b/basis/compiler/cfg/intrinsics/allot/allot.factor @@ -54,15 +54,19 @@ IN: compiler.cfg.intrinsics.allot : bytes>cells ( m -- n ) cell align cell /i ; -:: emit- ( node -- ) - [let | len [ node node-input-infos first literal>> ] | - len expand-? [ - [let | elt [ 0 ^^load-literal ] - reg [ len ^^allot-byte-array ] | - ds-drop - len reg store-length - elt reg len bytes>cells store-initial-element - reg ds-push - ] - ] [ node emit-primitive ] if - ] ; +: emit-allot-byte-array ( len -- dst ) + ds-drop + dup ^^allot-byte-array + [ store-length ] [ ds-push ] [ ] tri ; + +: emit-(byte-array) ( node -- ) + dup node-input-infos first literal>> dup expand-? + [ nip emit-allot-byte-array drop ] [ drop emit-primitive ] if ; + +: emit- ( node -- ) + dup node-input-infos first literal>> dup expand-? [ + nip + [ 0 ^^load-literal ] dip + [ emit-allot-byte-array ] keep + bytes>cells store-initial-element + ] [ drop emit-primitive ] if ; diff --git a/basis/compiler/cfg/intrinsics/fixnum/fixnum.factor b/basis/compiler/cfg/intrinsics/fixnum/fixnum.factor index 04c9097725..3ad716d847 100644 --- a/basis/compiler/cfg/intrinsics/fixnum/fixnum.factor +++ b/basis/compiler/cfg/intrinsics/fixnum/fixnum.factor @@ -3,10 +3,21 @@ USING: sequences accessors layouts kernel math namespaces combinators fry locals compiler.tree.propagation.info -compiler.cfg.stacks compiler.cfg.hats compiler.cfg.instructions -compiler.cfg.utilities ; +compiler.cfg.hats +compiler.cfg.stacks +compiler.cfg.iterator +compiler.cfg.instructions +compiler.cfg.utilities +compiler.cfg.registers ; IN: compiler.cfg.intrinsics.fixnum +: emit-both-fixnums? ( -- ) + 2inputs + ^^or + tag-mask get ^^and-imm + 0 cc= ^^compare-imm + ds-push ; + : (emit-fixnum-imm-op) ( infos insn -- dst ) ds-drop [ ds-pop ] @@ -42,6 +53,9 @@ IN: compiler.cfg.intrinsics.fixnum : emit-fixnum-bitnot ( -- ) ds-pop ^^not tag-mask get ^^xor-imm ds-push ; +: emit-fixnum-log2 ( -- ) + ds-pop ^^log2 tag-bits get ^^sub-imm ^^tag-fixnum ds-push ; + : (emit-fixnum*fast) ( -- dst ) 2inputs ^^untag-fixnum ^^mul ; @@ -64,3 +78,16 @@ IN: compiler.cfg.intrinsics.fixnum : emit-fixnum>bignum ( -- ) ds-pop ^^untag-fixnum ^^integer>bignum ds-push ; + +: emit-fixnum-overflow-op ( quot quot-tail -- next ) + [ 2inputs 1 ##inc-d ] 2dip + tail-call? [ + ##epilogue + nip call + stop-iterating + ] [ + drop call + ##branch + begin-basic-block + iterate-next + ] if ; inline diff --git a/basis/compiler/cfg/intrinsics/intrinsics.factor b/basis/compiler/cfg/intrinsics/intrinsics.factor index ef1cde337a..5f75330865 100644 --- a/basis/compiler/cfg/intrinsics/intrinsics.factor +++ b/basis/compiler/cfg/intrinsics/intrinsics.factor @@ -8,7 +8,9 @@ compiler.cfg.intrinsics.alien compiler.cfg.intrinsics.allot compiler.cfg.intrinsics.fixnum compiler.cfg.intrinsics.float -compiler.cfg.intrinsics.slots ; +compiler.cfg.intrinsics.slots +compiler.cfg.intrinsics.misc +compiler.cfg.iterator ; QUALIFIED: kernel QUALIFIED: arrays QUALIFIED: byte-arrays @@ -17,11 +19,17 @@ QUALIFIED: slots.private QUALIFIED: strings.private QUALIFIED: classes.tuple.private QUALIFIED: math.private +QUALIFIED: math.integers.private QUALIFIED: alien.accessors IN: compiler.cfg.intrinsics { kernel.private:tag + kernel.private:getenv + math.private:both-fixnums? + math.private:fixnum+ + math.private:fixnum- + math.private:fixnum* math.private:fixnum+fast math.private:fixnum-fast math.private:fixnum-bitand @@ -40,9 +48,11 @@ IN: compiler.cfg.intrinsics slots.private:slot slots.private:set-slot strings.private:string-nth + strings.private:set-string-nth-fast classes.tuple.private: arrays: byte-arrays: + byte-arrays:(byte-array) math.private: math.private: kernel: @@ -85,60 +95,71 @@ IN: compiler.cfg.intrinsics alien.accessors:set-alien-double } [ t "intrinsic" set-word-prop ] each ; -: emit-intrinsic ( node word -- ) +: enable-fixnum-log2 ( -- ) + \ math.integers.private:fixnum-log2 t "intrinsic" set-word-prop ; + +: emit-intrinsic ( node word -- node/f ) { - { \ kernel.private:tag [ drop emit-tag ] } - { \ math.private:fixnum+fast [ [ ^^add ] [ ^^add-imm ] emit-fixnum-op ] } - { \ math.private:fixnum-fast [ [ ^^sub ] [ ^^sub-imm ] emit-fixnum-op ] } - { \ math.private:fixnum-bitand [ [ ^^and ] [ ^^and-imm ] emit-fixnum-op ] } - { \ math.private:fixnum-bitor [ [ ^^or ] [ ^^or-imm ] emit-fixnum-op ] } - { \ math.private:fixnum-bitxor [ [ ^^xor ] [ ^^xor-imm ] emit-fixnum-op ] } - { \ math.private:fixnum-shift-fast [ emit-fixnum-shift-fast ] } - { \ math.private:fixnum-bitnot [ drop emit-fixnum-bitnot ] } - { \ math.private:fixnum*fast [ emit-fixnum*fast ] } - { \ math.private:fixnum< [ cc< emit-fixnum-comparison ] } - { \ math.private:fixnum<= [ cc<= emit-fixnum-comparison ] } - { \ math.private:fixnum>= [ cc>= emit-fixnum-comparison ] } - { \ math.private:fixnum> [ cc> emit-fixnum-comparison ] } - { \ kernel:eq? [ cc= emit-fixnum-comparison ] } - { \ math.private:bignum>fixnum [ drop emit-bignum>fixnum ] } - { \ math.private:fixnum>bignum [ drop emit-fixnum>bignum ] } - { \ math.private:float+ [ drop [ ^^add-float ] emit-float-op ] } - { \ math.private:float- [ drop [ ^^sub-float ] emit-float-op ] } - { \ math.private:float* [ drop [ ^^mul-float ] emit-float-op ] } - { \ math.private:float/f [ drop [ ^^div-float ] emit-float-op ] } - { \ math.private:float< [ drop cc< emit-float-comparison ] } - { \ math.private:float<= [ drop cc<= emit-float-comparison ] } - { \ math.private:float>= [ drop cc>= emit-float-comparison ] } - { \ math.private:float> [ drop cc> emit-float-comparison ] } - { \ math.private:float= [ drop cc= emit-float-comparison ] } - { \ math.private:float>fixnum [ drop emit-float>fixnum ] } - { \ math.private:fixnum>float [ drop emit-fixnum>float ] } - { \ slots.private:slot [ emit-slot ] } - { \ slots.private:set-slot [ emit-set-slot ] } - { \ strings.private:string-nth [ drop emit-string-nth ] } - { \ classes.tuple.private: [ emit- ] } - { \ arrays: [ emit- ] } - { \ byte-arrays: [ emit- ] } - { \ math.private: [ emit-simple-allot ] } - { \ math.private: [ emit-simple-allot ] } - { \ kernel: [ emit-simple-allot ] } - { \ alien.accessors:alien-unsigned-1 [ 1 emit-alien-unsigned-getter ] } - { \ alien.accessors:set-alien-unsigned-1 [ 1 emit-alien-integer-setter ] } - { \ alien.accessors:alien-signed-1 [ 1 emit-alien-signed-getter ] } - { \ alien.accessors:set-alien-signed-1 [ 1 emit-alien-integer-setter ] } - { \ alien.accessors:alien-unsigned-2 [ 2 emit-alien-unsigned-getter ] } - { \ alien.accessors:set-alien-unsigned-2 [ 2 emit-alien-integer-setter ] } - { \ alien.accessors:alien-signed-2 [ 2 emit-alien-signed-getter ] } - { \ alien.accessors:set-alien-signed-2 [ 2 emit-alien-integer-setter ] } - { \ alien.accessors:alien-unsigned-4 [ 4 emit-alien-unsigned-getter ] } - { \ alien.accessors:set-alien-unsigned-4 [ 4 emit-alien-integer-setter ] } - { \ alien.accessors:alien-signed-4 [ 4 emit-alien-signed-getter ] } - { \ alien.accessors:set-alien-signed-4 [ 4 emit-alien-integer-setter ] } - { \ alien.accessors:alien-cell [ emit-alien-cell-getter ] } - { \ alien.accessors:set-alien-cell [ emit-alien-cell-setter ] } - { \ alien.accessors:alien-float [ single-float-regs emit-alien-float-getter ] } - { \ alien.accessors:set-alien-float [ single-float-regs emit-alien-float-setter ] } - { \ alien.accessors:alien-double [ double-float-regs emit-alien-float-getter ] } - { \ alien.accessors:set-alien-double [ double-float-regs emit-alien-float-setter ] } + { \ kernel.private:tag [ drop emit-tag iterate-next ] } + { \ kernel.private:getenv [ emit-getenv iterate-next ] } + { \ math.private:both-fixnums? [ drop emit-both-fixnums? iterate-next ] } + { \ math.private:fixnum+ [ drop [ ##fixnum-add ] [ ##fixnum-add-tail ] emit-fixnum-overflow-op ] } + { \ math.private:fixnum- [ drop [ ##fixnum-sub ] [ ##fixnum-sub-tail ] emit-fixnum-overflow-op ] } + { \ math.private:fixnum* [ drop [ i i ##fixnum-mul ] [ i i ##fixnum-mul-tail ] emit-fixnum-overflow-op ] } + { \ math.private:fixnum+fast [ [ ^^add ] [ ^^add-imm ] emit-fixnum-op iterate-next ] } + { \ math.private:fixnum-fast [ [ ^^sub ] [ ^^sub-imm ] emit-fixnum-op iterate-next ] } + { \ math.private:fixnum-bitand [ [ ^^and ] [ ^^and-imm ] emit-fixnum-op iterate-next ] } + { \ math.private:fixnum-bitor [ [ ^^or ] [ ^^or-imm ] emit-fixnum-op iterate-next ] } + { \ math.private:fixnum-bitxor [ [ ^^xor ] [ ^^xor-imm ] emit-fixnum-op iterate-next ] } + { \ math.private:fixnum-shift-fast [ emit-fixnum-shift-fast iterate-next ] } + { \ math.private:fixnum-bitnot [ drop emit-fixnum-bitnot iterate-next ] } + { \ math.integers.private:fixnum-log2 [ drop emit-fixnum-log2 iterate-next ] } + { \ math.private:fixnum*fast [ emit-fixnum*fast iterate-next ] } + { \ math.private:fixnum< [ cc< emit-fixnum-comparison iterate-next ] } + { \ math.private:fixnum<= [ cc<= emit-fixnum-comparison iterate-next ] } + { \ math.private:fixnum>= [ cc>= emit-fixnum-comparison iterate-next ] } + { \ math.private:fixnum> [ cc> emit-fixnum-comparison iterate-next ] } + { \ kernel:eq? [ cc= emit-fixnum-comparison iterate-next ] } + { \ math.private:bignum>fixnum [ drop emit-bignum>fixnum iterate-next ] } + { \ math.private:fixnum>bignum [ drop emit-fixnum>bignum iterate-next ] } + { \ math.private:float+ [ drop [ ^^add-float ] emit-float-op iterate-next ] } + { \ math.private:float- [ drop [ ^^sub-float ] emit-float-op iterate-next ] } + { \ math.private:float* [ drop [ ^^mul-float ] emit-float-op iterate-next ] } + { \ math.private:float/f [ drop [ ^^div-float ] emit-float-op iterate-next ] } + { \ math.private:float< [ drop cc< emit-float-comparison iterate-next ] } + { \ math.private:float<= [ drop cc<= emit-float-comparison iterate-next ] } + { \ math.private:float>= [ drop cc>= emit-float-comparison iterate-next ] } + { \ math.private:float> [ drop cc> emit-float-comparison iterate-next ] } + { \ math.private:float= [ drop cc= emit-float-comparison iterate-next ] } + { \ math.private:float>fixnum [ drop emit-float>fixnum iterate-next ] } + { \ math.private:fixnum>float [ drop emit-fixnum>float iterate-next ] } + { \ slots.private:slot [ emit-slot iterate-next ] } + { \ slots.private:set-slot [ emit-set-slot iterate-next ] } + { \ strings.private:string-nth [ drop emit-string-nth iterate-next ] } + { \ strings.private:set-string-nth-fast [ drop emit-set-string-nth-fast iterate-next ] } + { \ classes.tuple.private: [ emit- iterate-next ] } + { \ arrays: [ emit- iterate-next ] } + { \ byte-arrays: [ emit- iterate-next ] } + { \ byte-arrays:(byte-array) [ emit-(byte-array) iterate-next ] } + { \ math.private: [ emit-simple-allot iterate-next ] } + { \ math.private: [ emit-simple-allot iterate-next ] } + { \ kernel: [ emit-simple-allot iterate-next ] } + { \ alien.accessors:alien-unsigned-1 [ 1 emit-alien-unsigned-getter iterate-next ] } + { \ alien.accessors:set-alien-unsigned-1 [ 1 emit-alien-integer-setter iterate-next ] } + { \ alien.accessors:alien-signed-1 [ 1 emit-alien-signed-getter iterate-next ] } + { \ alien.accessors:set-alien-signed-1 [ 1 emit-alien-integer-setter iterate-next ] } + { \ alien.accessors:alien-unsigned-2 [ 2 emit-alien-unsigned-getter iterate-next ] } + { \ alien.accessors:set-alien-unsigned-2 [ 2 emit-alien-integer-setter iterate-next ] } + { \ alien.accessors:alien-signed-2 [ 2 emit-alien-signed-getter iterate-next ] } + { \ alien.accessors:set-alien-signed-2 [ 2 emit-alien-integer-setter iterate-next ] } + { \ alien.accessors:alien-unsigned-4 [ 4 emit-alien-unsigned-getter iterate-next ] } + { \ alien.accessors:set-alien-unsigned-4 [ 4 emit-alien-integer-setter iterate-next ] } + { \ alien.accessors:alien-signed-4 [ 4 emit-alien-signed-getter iterate-next ] } + { \ alien.accessors:set-alien-signed-4 [ 4 emit-alien-integer-setter iterate-next ] } + { \ alien.accessors:alien-cell [ emit-alien-cell-getter iterate-next ] } + { \ alien.accessors:set-alien-cell [ emit-alien-cell-setter iterate-next ] } + { \ alien.accessors:alien-float [ single-float-regs emit-alien-float-getter iterate-next ] } + { \ alien.accessors:set-alien-float [ single-float-regs emit-alien-float-setter iterate-next ] } + { \ alien.accessors:alien-double [ double-float-regs emit-alien-float-getter iterate-next ] } + { \ alien.accessors:set-alien-double [ double-float-regs emit-alien-float-setter iterate-next ] } } case ; diff --git a/basis/compiler/cfg/intrinsics/misc/misc.factor b/basis/compiler/cfg/intrinsics/misc/misc.factor new file mode 100644 index 0000000000..f9f2182a4e --- /dev/null +++ b/basis/compiler/cfg/intrinsics/misc/misc.factor @@ -0,0 +1,16 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: namespaces layouts sequences kernel +accessors compiler.tree.propagation.info +compiler.cfg.stacks compiler.cfg.hats +compiler.cfg.instructions compiler.cfg.utilities ; +IN: compiler.cfg.intrinsics.misc + +: emit-tag ( -- ) + ds-pop tag-mask get ^^and-imm ^^tag-fixnum ds-push ; + +: emit-getenv ( node -- ) + "userenv" f ^^alien-global + swap node-input-infos first literal>> + [ ds-drop 0 ^^slot-imm ] [ ds-pop ^^offset>slot 0 ^^slot ] if* + ds-push ; diff --git a/basis/compiler/cfg/intrinsics/slots/slots.factor b/basis/compiler/cfg/intrinsics/slots/slots.factor index fec234a576..bc46e6149c 100644 --- a/basis/compiler/cfg/intrinsics/slots/slots.factor +++ b/basis/compiler/cfg/intrinsics/slots/slots.factor @@ -6,9 +6,6 @@ compiler.cfg.stacks compiler.cfg.hats compiler.cfg.instructions compiler.cfg.utilities ; IN: compiler.cfg.intrinsics.slots -: emit-tag ( -- ) - ds-pop tag-mask get ^^and-imm ^^tag-fixnum ds-push ; - : value-tag ( info -- n ) class>> class-tag ; inline : (emit-slot) ( infos -- dst ) @@ -54,3 +51,7 @@ IN: compiler.cfg.intrinsics.slots : emit-string-nth ( -- ) 2inputs swap ^^untag-fixnum ^^string-nth ^^tag-fixnum ds-push ; + +: emit-set-string-nth-fast ( -- ) + 3inputs [ ^^untag-fixnum ] [ ^^untag-fixnum ] [ ] tri* + swap i ##set-string-nth-fast ; diff --git a/basis/compiler/cfg/registers/registers.factor b/basis/compiler/cfg/registers/registers.factor index 21572ec615..2b9d3df6f6 100644 --- a/basis/compiler/cfg/registers/registers.factor +++ b/basis/compiler/cfg/registers/registers.factor @@ -1,7 +1,6 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors namespaces kernel arrays -parser prettyprint.backend prettyprint.sections ; +USING: accessors namespaces kernel arrays parser ; IN: compiler.cfg.registers ! Virtual registers, used by CFG and machine IRs @@ -18,20 +17,6 @@ C: ds-loc TUPLE: rs-loc < loc ; C: rs-loc -! Prettyprinting : V scan-word scan-word vreg boa parsed ; parsing - -M: vreg pprint* - > pprint* ] [ n>> pprint* ] bi - block> ; - -: pprint-loc ( loc word -- ) > pprint* block> ; - : D scan-word parsed ; parsing - -M: ds-loc pprint* \ D pprint-loc ; - : R scan-word parsed ; parsing - -M: rs-loc pprint* \ R pprint-loc ; diff --git a/basis/compiler/cfg/stack-frame/stack-frame.factor b/basis/compiler/cfg/stack-frame/stack-frame.factor index ec9ffaba49..d545b6d15c 100644 --- a/basis/compiler/cfg/stack-frame/stack-frame.factor +++ b/basis/compiler/cfg/stack-frame/stack-frame.factor @@ -34,6 +34,12 @@ M: insn compute-stack-frame* \ _gc t frame-required? set-word-prop \ _spill t frame-required? set-word-prop +\ ##fixnum-add t frame-required? set-word-prop +\ ##fixnum-sub t frame-required? set-word-prop +\ ##fixnum-mul t frame-required? set-word-prop +\ ##fixnum-add-tail f frame-required? set-word-prop +\ ##fixnum-sub-tail f frame-required? set-word-prop +\ ##fixnum-mul-tail f frame-required? set-word-prop : compute-stack-frame ( insns -- ) frame-required? off diff --git a/basis/compiler/cfg/two-operand/two-operand.factor b/basis/compiler/cfg/two-operand/two-operand.factor index e943fb4828..dabecaeec4 100644 --- a/basis/compiler/cfg/two-operand/two-operand.factor +++ b/basis/compiler/cfg/two-operand/two-operand.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors arrays kernel sequences sequences.deep +USING: accessors arrays kernel sequences compiler.utilities compiler.cfg.instructions cpu.architecture ; IN: compiler.cfg.two-operand @@ -55,6 +55,6 @@ M: insn convert-two-operand* ; : convert-two-operand ( mr -- mr' ) [ two-operand? [ - [ convert-two-operand* ] map flatten + [ convert-two-operand* ] map-flat ] when ] change-instructions ; diff --git a/basis/compiler/cfg/utilities/utilities.factor b/basis/compiler/cfg/utilities/utilities.factor index cef14d06e4..99a138a763 100644 --- a/basis/compiler/cfg/utilities/utilities.factor +++ b/basis/compiler/cfg/utilities/utilities.factor @@ -33,5 +33,7 @@ IN: compiler.cfg.utilities building off basic-block off ; +: stop-iterating ( -- next ) end-basic-block f ; + : emit-primitive ( node -- ) word>> ##call ##branch begin-basic-block ; diff --git a/basis/compiler/cfg/value-numbering/propagate/propagate.factor b/basis/compiler/cfg/value-numbering/propagate/propagate.factor index a3c9725838..d5c9830c0b 100644 --- a/basis/compiler/cfg/value-numbering/propagate/propagate.factor +++ b/basis/compiler/cfg/value-numbering/propagate/propagate.factor @@ -62,4 +62,8 @@ M: ##compare-imm-branch propagate M: ##dispatch propagate [ resolve ] change-src ; +M: ##fixnum-overflow propagate + [ resolve ] change-src1 + [ resolve ] change-src2 ; + M: insn propagate ; diff --git a/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor b/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor index 5f67f8097e..990543ed7a 100644 --- a/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor +++ b/basis/compiler/cfg/value-numbering/rewrite/rewrite.factor @@ -2,6 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel sequences layouts accessors combinators namespaces math fry +compiler.cfg.hats compiler.cfg.instructions compiler.cfg.value-numbering.graph compiler.cfg.value-numbering.simplify @@ -63,7 +64,7 @@ M: ##compare-imm-branch rewrite-tagged-comparison M: ##compare-imm rewrite-tagged-comparison [ dst>> ] [ (rewrite-tagged-comparison) ] bi - f \ ##compare-imm boa ; + i f \ ##compare-imm boa ; M: ##compare-imm-branch rewrite dup rewrite-boolean-comparison? [ rewrite-boolean-comparison ] when @@ -78,7 +79,7 @@ M: ##compare-imm-branch rewrite [ dst>> ] [ src2>> ] [ src1>> vreg>vn vn>constant ] tri - cc= f \ ##compare-imm boa ; + cc= f i \ ##compare-imm boa ; M: ##compare rewrite dup flip-comparison? [ @@ -95,9 +96,9 @@ M: ##compare rewrite : rewrite-redundant-comparison ( insn -- insn' ) [ cc>> ] [ dst>> ] [ src1>> vreg>expr dup op>> ] tri { - { \ ##compare [ >compare-expr< f \ ##compare boa ] } - { \ ##compare-imm [ >compare-imm-expr< f \ ##compare-imm boa ] } - { \ ##compare-float [ >compare-expr< f \ ##compare-float boa ] } + { \ ##compare [ >compare-expr< i f \ ##compare boa ] } + { \ ##compare-imm [ >compare-imm-expr< i f \ ##compare-imm boa ] } + { \ ##compare-float [ >compare-expr< i f \ ##compare-float boa ] } } case swap cc= eq? [ [ negate-cc ] change-cc ] when ; diff --git a/basis/compiler/cfg/value-numbering/value-numbering-tests.factor b/basis/compiler/cfg/value-numbering/value-numbering-tests.factor index b73736ed14..641ccceb5d 100644 --- a/basis/compiler/cfg/value-numbering/value-numbering-tests.factor +++ b/basis/compiler/cfg/value-numbering/value-numbering-tests.factor @@ -1,6 +1,18 @@ IN: compiler.cfg.value-numbering.tests USING: compiler.cfg.value-numbering compiler.cfg.instructions -compiler.cfg.registers cpu.architecture tools.test kernel math ; +compiler.cfg.registers compiler.cfg.debugger cpu.architecture +tools.test kernel math combinators.short-circuit accessors +sequences ; + +: trim-temps ( insns -- insns ) + [ + dup { + [ ##compare? ] + [ ##compare-imm? ] + [ ##compare-float? ] + } 1|| [ f >>temp ] when + ] map ; + [ { T{ ##peek f V int-regs 45 D 1 } @@ -82,7 +94,7 @@ compiler.cfg.registers cpu.architecture tools.test kernel math ; T{ ##compare f V int-regs 4 V int-regs 2 V int-regs 1 cc> } T{ ##compare-imm f V int-regs 6 V int-regs 4 7 cc/= } T{ ##replace f V int-regs 6 D 0 } - } value-numbering + } value-numbering trim-temps ] unit-test [ @@ -100,7 +112,7 @@ compiler.cfg.registers cpu.architecture tools.test kernel math ; T{ ##compare f V int-regs 4 V int-regs 2 V int-regs 1 cc<= } T{ ##compare-imm f V int-regs 6 V int-regs 4 7 cc= } T{ ##replace f V int-regs 6 D 0 } - } value-numbering + } value-numbering trim-temps ] unit-test [ @@ -122,7 +134,7 @@ compiler.cfg.registers cpu.architecture tools.test kernel math ; T{ ##compare-float f V int-regs 12 V double-float-regs 10 V double-float-regs 11 cc< } T{ ##compare-imm f V int-regs 14 V int-regs 12 7 cc= } T{ ##replace f V int-regs 14 D 0 } - } value-numbering + } value-numbering trim-temps ] unit-test [ @@ -138,5 +150,5 @@ compiler.cfg.registers cpu.architecture tools.test kernel math ; T{ ##peek f V int-regs 30 D -2 } T{ ##compare f V int-regs 33 V int-regs 29 V int-regs 30 cc<= } T{ ##compare-imm-branch f V int-regs 33 7 cc/= } - } value-numbering + } value-numbering trim-temps ] unit-test diff --git a/basis/compiler/cfg/write-barrier/write-barrier-tests.factor b/basis/compiler/cfg/write-barrier/write-barrier-tests.factor index 7a4b1c488f..73748dbc37 100644 --- a/basis/compiler/cfg/write-barrier/write-barrier-tests.factor +++ b/basis/compiler/cfg/write-barrier/write-barrier-tests.factor @@ -1,5 +1,6 @@ USING: compiler.cfg.write-barrier compiler.cfg.instructions -compiler.cfg.registers cpu.architecture arrays tools.test ; +compiler.cfg.registers compiler.cfg.debugger cpu.architecture +arrays tools.test ; IN: compiler.cfg.write-barrier.tests [ diff --git a/basis/compiler/codegen/codegen.factor b/basis/compiler/codegen/codegen.factor index 0d45b28126..9f134c02d7 100644 --- a/basis/compiler/codegen/codegen.factor +++ b/basis/compiler/codegen/codegen.factor @@ -131,6 +131,14 @@ M: ##string-nth generate-insn [ temp>> register ] } cleave %string-nth ; +M: ##set-string-nth-fast generate-insn + { + [ src>> register ] + [ obj>> register ] + [ index>> register ] + [ temp>> register ] + } cleave %set-string-nth-fast ; + : dst/src ( insn -- dst src ) [ dst>> register ] [ src>> register ] bi ; inline @@ -155,6 +163,20 @@ M: ##shl-imm generate-insn dst/src1/src2 %shl-imm ; M: ##shr-imm generate-insn dst/src1/src2 %shr-imm ; M: ##sar-imm generate-insn dst/src1/src2 %sar-imm ; M: ##not generate-insn dst/src %not ; +M: ##log2 generate-insn dst/src %log2 ; + +: src1/src2 ( insn -- src1 src2 ) + [ src1>> register ] [ src2>> register ] bi ; inline + +: src1/src2/temp1/temp2 ( insn -- src1 src2 temp1 temp2 ) + [ src1/src2 ] [ temp1>> register ] [ temp2>> register ] tri ; inline + +M: ##fixnum-add generate-insn src1/src2 %fixnum-add ; +M: ##fixnum-add-tail generate-insn src1/src2 %fixnum-add-tail ; +M: ##fixnum-sub generate-insn src1/src2 %fixnum-sub ; +M: ##fixnum-sub-tail generate-insn src1/src2 %fixnum-sub-tail ; +M: ##fixnum-mul generate-insn src1/src2/temp1/temp2 %fixnum-mul ; +M: ##fixnum-mul-tail generate-insn src1/src2/temp1/temp2 %fixnum-mul-tail ; : dst/src/temp ( insn -- dst src temp ) [ dst/src ] [ temp>> register ] bi ; inline @@ -215,6 +237,10 @@ M: _gc generate-insn drop %gc ; M: ##loop-entry generate-insn drop %loop-entry ; +M: ##alien-global generate-insn + [ dst>> register ] [ symbol>> ] [ library>> ] tri + %alien-global ; + ! ##alien-invoke GENERIC: reg-size ( register-class -- n ) @@ -235,7 +261,7 @@ M: float-regs reg-class-variable drop float-regs ; GENERIC: inc-reg-class ( register-class -- ) : ?dummy-stack-params ( reg-class -- ) - dummy-stack-params? [ reg-size stack-params +@ ] [ drop ] if ; + dummy-stack-params? [ reg-size cell align stack-params +@ ] [ drop ] if ; : ?dummy-int-params ( reg-class -- ) dummy-int-params? [ reg-size cell /i 1 max int-regs +@ ] [ drop ] if ; @@ -264,7 +290,7 @@ M: object reg-class-full? : spill-param ( reg-class -- n reg-class ) stack-params get - >r reg-size stack-params +@ r> + [ reg-size cell align stack-params +@ ] dip stack-params ; : fastcall-param ( reg-class -- n reg-class ) @@ -300,10 +326,10 @@ M: long-long-type flatten-value-type ( type -- types ) ] { } make ; : each-parameter ( parameters quot -- ) - >r [ parameter-sizes nip ] keep r> 2each ; inline + [ [ parameter-sizes nip ] keep ] dip 2each ; inline : reverse-each-parameter ( parameters quot -- ) - >r [ parameter-sizes nip ] keep r> 2reverse-each ; inline + [ [ parameter-sizes nip ] keep ] dip 2reverse-each ; inline : reset-freg-counts ( -- ) { int-regs float-regs stack-params } [ 0 swap set ] each ; @@ -316,15 +342,13 @@ M: long-long-type flatten-value-type ( type -- types ) #! Moves values from C stack to registers (if word is #! %load-param-reg) and registers to C stack (if word is #! %save-param-reg). - >r - alien-parameters - flatten-value-types - r> '[ alloc-parameter _ execute ] each-parameter ; - inline + [ alien-parameters flatten-value-types ] + [ '[ alloc-parameter _ execute ] ] + bi* each-parameter ; inline : unbox-parameters ( offset node -- ) parameters>> [ - %prepare-unbox >r over + r> unbox-parameter + %prepare-unbox [ over + ] dip unbox-parameter ] reverse-each-parameter drop ; : prepare-box-struct ( node -- offset ) @@ -432,7 +456,7 @@ M: ##alien-indirect generate-insn TUPLE: callback-context ; -: current-callback 2 getenv ; +: current-callback ( -- id ) 2 getenv ; : wait-to-return ( token -- ) dup current-callback eq? [ @@ -491,9 +515,10 @@ M: _label generate-insn M: _branch generate-insn label>> lookup-label %jump-label ; -: >compare< ( insn -- label cc src1 src2 ) +: >compare< ( insn -- dst temp cc src1 src2 ) { [ dst>> register ] + [ temp>> register ] [ cc>> ] [ src1>> register ] [ src2>> ?register ] diff --git a/basis/compiler/codegen/fixup/fixup.factor b/basis/compiler/codegen/fixup/fixup.factor index b25f1fa8fe..e0f391deb5 100755 --- a/basis/compiler/codegen/fixup/fixup.factor +++ b/basis/compiler/codegen/fixup/fixup.factor @@ -1,15 +1,15 @@ ! Copyright (C) 2007, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: arrays byte-arrays generic assocs hashtables io.binary -kernel kernel.private math namespaces make sequences words -quotations strings alien.accessors alien.strings layouts system -combinators math.bitwise words.private math.order accessors -growable cpu.architecture compiler.constants ; +USING: arrays byte-arrays byte-vectors generic assocs hashtables +io.binary kernel kernel.private math namespaces make sequences +words quotations strings alien.accessors alien.strings layouts +system combinators math.bitwise words.private math.order +accessors growable cpu.architecture compiler.constants ; IN: compiler.codegen.fixup GENERIC: fixup* ( obj -- ) -: code-format 22 getenv ; +: code-format ( -- n ) 22 getenv ; : compiled-offset ( -- n ) building get length code-format * ; @@ -46,28 +46,27 @@ M: integer fixup* , ; : indq ( elt seq -- n ) [ eq? ] with find drop ; : adjoin* ( obj table -- n ) - 2dup indq [ 2nip ] [ dup length >r push r> ] if* ; + 2dup indq [ 2nip ] [ dup length [ push ] dip ] if* ; SYMBOL: literal-table : add-literal ( obj -- n ) literal-table get adjoin* ; : add-dlsym-literals ( symbol dll -- ) - >r string>symbol r> 2array literal-table get push-all ; + [ string>symbol ] dip 2array literal-table get push-all ; : rel-dlsym ( name dll class -- ) - >r literal-table get length >r - add-dlsym-literals - r> r> rt-dlsym rel-fixup ; + [ literal-table get length [ add-dlsym-literals ] dip ] dip + rt-dlsym rel-fixup ; : rel-word ( word class -- ) - >r add-literal r> rt-xt rel-fixup ; + [ add-literal ] dip rt-xt rel-fixup ; : rel-primitive ( word class -- ) - >r def>> first r> rt-primitive rel-fixup ; + [ def>> first ] dip rt-primitive rel-fixup ; -: rel-literal ( literal class -- ) - >r add-literal r> rt-literal rel-fixup ; +: rel-immediate ( literal class -- ) + [ add-literal ] dip rt-immediate rel-fixup ; : rel-this ( class -- ) 0 swap rt-label rel-fixup ; diff --git a/basis/compiler/compiler-docs.factor b/basis/compiler/compiler-docs.factor index 6cb860d33f..512d26f4bf 100644 --- a/basis/compiler/compiler-docs.factor +++ b/basis/compiler/compiler-docs.factor @@ -6,7 +6,7 @@ HELP: enable-compiler { $description "Enables the optimizing compiler." } ; HELP: disable-compiler -{ $description "Enables the optimizing compiler." } ; +{ $description "Disable the optimizing compiler." } ; ARTICLE: "compiler-usage" "Calling the optimizing compiler" "Normally, new word definitions are recompiled automatically. This can be changed:" diff --git a/basis/compiler/compiler.factor b/basis/compiler/compiler.factor index a6afc4b243..0d24daef71 100644 --- a/basis/compiler/compiler.factor +++ b/basis/compiler/compiler.factor @@ -1,15 +1,14 @@ ! Copyright (C) 2004, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel namespaces arrays sequences io debugger -words fry continuations vocabs assocs dlists definitions -math threads graphs generic combinators deques search-deques -prettyprint io stack-checker stack-checker.state -stack-checker.inlining compiler.errors compiler.units -compiler.tree.builder compiler.tree.optimizer -compiler.cfg.builder compiler.cfg.optimizer -compiler.cfg.linearization compiler.cfg.two-operand -compiler.cfg.linear-scan compiler.cfg.stack-frame -compiler.codegen ; +USING: accessors kernel namespaces arrays sequences io +words fry continuations vocabs assocs dlists definitions math +threads graphs generic combinators deques search-deques io +stack-checker stack-checker.state stack-checker.inlining +compiler.errors compiler.units compiler.tree.builder +compiler.tree.optimizer compiler.cfg.builder +compiler.cfg.optimizer compiler.cfg.linearization +compiler.cfg.two-operand compiler.cfg.linear-scan +compiler.cfg.stack-frame compiler.codegen ; IN: compiler SYMBOL: compile-queue @@ -45,7 +44,7 @@ SYMBOL: +failed+ 2bi ; : start ( word -- ) - "trace-compilation" get [ dup . flush ] when + "trace-compilation" get [ dup name>> print flush ] when H{ } clone dependencies set H{ } clone generic-dependencies set f swap compiler-error ; @@ -91,8 +90,8 @@ t compile-dependencies? set-global [ dup crossref? [ - dependencies get >alist - generic-dependencies get >alist + dependencies get + generic-dependencies get compiled-xref ] [ drop ] if ] tri ; diff --git a/basis/compiler/constants/constants.factor b/basis/compiler/constants/constants.factor index 86c1f65049..48ea958818 100644 --- a/basis/compiler/constants/constants.factor +++ b/basis/compiler/constants/constants.factor @@ -39,13 +39,12 @@ IN: compiler.constants ! Relocation types : rt-primitive 0 ; inline : rt-dlsym 1 ; inline -: rt-literal 2 ; inline -: rt-dispatch 3 ; inline -: rt-xt 4 ; inline -: rt-here 5 ; inline -: rt-label 6 ; inline -: rt-immediate 7 ; inline -: rt-stack-chain 8 ; inline +: rt-dispatch 2 ; inline +: rt-xt 3 ; inline +: rt-here 4 ; inline +: rt-label 5 ; inline +: rt-immediate 6 ; inline +: rt-stack-chain 7 ; inline : rc-absolute? ( n -- ? ) [ rc-absolute-ppc-2/2 = ] diff --git a/basis/compiler/tests/alien.factor b/basis/compiler/tests/alien.factor index d7e82402d5..1b21e40bac 100644 --- a/basis/compiler/tests/alien.factor +++ b/basis/compiler/tests/alien.factor @@ -3,7 +3,8 @@ USING: alien alien.c-types alien.syntax compiler kernel namespaces namespaces tools.test sequences stack-checker stack-checker.errors words arrays parser quotations continuations effects namespaces.private io io.streams.string -memory system threads tools.test math accessors combinators ; +memory system threads tools.test math accessors combinators +specialized-arrays.float ; FUNCTION: void ffi_test_0 ; [ ] [ ffi_test_0 ] unit-test @@ -82,14 +83,14 @@ FUNCTION: tiny ffi_test_17 int x ; { 1 1 } [ indirect-test-1 ] must-infer-as -[ 3 ] [ "ffi_test_1" f dlsym indirect-test-1 ] unit-test +[ 3 ] [ &: ffi_test_1 indirect-test-1 ] unit-test : indirect-test-1' ( ptr -- ) "int" { } "cdecl" alien-indirect drop ; { 1 0 } [ indirect-test-1' ] must-infer-as -[ ] [ "ffi_test_1" f dlsym indirect-test-1' ] unit-test +[ ] [ &: ffi_test_1 indirect-test-1' ] unit-test [ -1 indirect-test-1 ] must-fail @@ -99,7 +100,7 @@ FUNCTION: tiny ffi_test_17 int x ; { 3 1 } [ indirect-test-2 ] must-infer-as [ 5 ] -[ 2 3 "ffi_test_2" f dlsym indirect-test-2 ] +[ 2 3 &: ffi_test_2 indirect-test-2 ] unit-test : indirect-test-3 ( a b c d ptr -- result ) @@ -146,13 +147,21 @@ FUNCTION: void ffi_test_20 double x1, double x2, double x3, ! Make sure XT doesn't get clobbered in stack frame -: ffi_test_31 ( a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a ptr -- result y ) - "void" +: ffi_test_31 ( a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a -- result y ) + "int" f "ffi_test_31" { "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" "int" } alien-invoke gc 3 ; -[ 3 ] [ 42 [ ] each ffi_test_31 ] unit-test +[ 861 3 ] [ 42 [ ] each ffi_test_31 ] unit-test + +: ffi_test_31_point_5 ( a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a -- result ) + "float" + f "ffi_test_31_point_5" + { "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" "float" } + alien-invoke ; + +[ 861.0 ] [ 42 [ >float ] each ffi_test_31_point_5 ] unit-test FUNCTION: longlong ffi_test_21 long x long y ; @@ -188,7 +197,11 @@ FUNCTION: int ffi_test_12 int a int b rect c int d int e int f ; FUNCTION: float ffi_test_23 ( float[3] x, float[3] y ) ; -[ 32.0 ] [ { 1.0 2.0 3.0 } >c-float-array { 4.0 5.0 6.0 } >c-float-array ffi_test_23 ] unit-test +[ 32.0 ] [ + { 1.0 2.0 3.0 } >float-array underlying>> + { 4.0 5.0 6.0 } >float-array underlying>> + ffi_test_23 +] unit-test ! Test odd-size structs C-STRUCT: test-struct-1 { { "char" 1 } "x" } ; @@ -353,7 +366,7 @@ FUNCTION: ulonglong ffi_test_38 ( ulonglong x, ulonglong y ) ; [ 1 2 3 ] [ callback-6 callback_test_1 1 2 3 ] unit-test : callback-7 ( -- callback ) - "void" { } "cdecl" [ 1000 sleep ] alien-callback ; + "void" { } "cdecl" [ 1000000 sleep ] alien-callback ; [ 1 2 3 ] [ callback-7 callback_test_1 1 2 3 ] unit-test diff --git a/basis/compiler/tests/codegen.factor b/basis/compiler/tests/codegen.factor index a56ee55c82..e743c8484b 100644 --- a/basis/compiler/tests/codegen.factor +++ b/basis/compiler/tests/codegen.factor @@ -3,7 +3,7 @@ kernel.private math hashtables.private math.private namespaces sequences sequences.private tools.test namespaces.private slots.private sequences.private byte-arrays alien alien.accessors layouts words definitions compiler.units io -combinators vectors float-arrays ; +combinators vectors grouping make ; IN: compiler.tests ! Originally, this file did black box testing of templating @@ -241,3 +241,38 @@ TUPLE: id obj ; [ "a" ] [ 1 test-2 ] unit-test [ "b" ] [ 2 test-2 ] unit-test + +! I accidentally fixnum/i-fast on PowerPC +[ { { 1 2 } { 3 4 } } ] [ + { 1 2 3 4 } + [ + [ { array } declare 2 [ , ] each ] compile-call + ] { } make +] unit-test + +[ 2 ] [ + { 1 2 3 4 } + [ { array } declare 2 length ] compile-call +] unit-test + +! Oops with new intrinsics +: fixnum-overflow-control-flow-test ( a b -- c ) + [ 1 fixnum- ] [ 2 fixnum- ] if 3 fixnum+fast ; + +[ 3 ] [ 1 t fixnum-overflow-control-flow-test ] unit-test +[ 2 ] [ 1 f fixnum-overflow-control-flow-test ] unit-test + +! LOL +: blah ( a -- b ) + { float } declare dup 0 = + [ drop 1 ] [ + dup 0 >= + [ 2 "double" "libm" "pow" { "double" "double" } alien-invoke ] + [ -0.5 "double" "libm" "pow" { "double" "double" } alien-invoke ] + if + ] if ; + +[ 4.0 ] [ 2.0 blah ] unit-test + +[ 4 ] [ 2 [ dup fixnum* ] compile-call ] unit-test +[ 7 ] [ 2 [ dup fixnum* 3 fixnum+fast ] compile-call ] unit-test diff --git a/basis/compiler/tests/intrinsics.factor b/basis/compiler/tests/intrinsics.factor index c90a31fc61..df5f484952 100644 --- a/basis/compiler/tests/intrinsics.factor +++ b/basis/compiler/tests/intrinsics.factor @@ -160,6 +160,11 @@ IN: compiler.tests [ -2 ] [ 4 [ -2 fixnum/i ] compile-call ] unit-test [ 3 1 ] [ 10 3 [ fixnum/mod ] compile-call ] unit-test +[ 2 ] [ 4 2 [ fixnum/i-fast ] compile-call ] unit-test +[ 2 ] [ 4 [ 2 fixnum/i-fast ] compile-call ] unit-test +[ -2 ] [ 4 [ -2 fixnum/i-fast ] compile-call ] unit-test +[ 3 1 ] [ 10 3 [ fixnum/mod-fast ] compile-call ] unit-test + [ 4 ] [ 1 3 [ fixnum+ ] compile-call ] unit-test [ 4 ] [ 1 [ 3 fixnum+ ] compile-call ] unit-test [ 4 ] [ [ 1 3 fixnum+ ] compile-call ] unit-test @@ -208,6 +213,7 @@ IN: compiler.tests [ -1 ] [ [ -123 -64 fixnum-shift ] compile-call ] unit-test [ -1 ] [ -123 -64 [ fixnum-shift ] compile-call ] unit-test +[ HEX: 10000000 ] [ HEX: 1000000 HEX: 10 [ fixnum* ] compile-call ] unit-test [ HEX: 10000000 ] [ HEX: -10000000 >fixnum [ 0 swap fixnum- ] compile-call ] unit-test [ HEX: 10000000 ] [ HEX: -fffffff >fixnum [ 1 swap fixnum- ] compile-call ] unit-test diff --git a/basis/compiler/tests/optimizer.factor b/basis/compiler/tests/optimizer.factor index f1b3e32eed..fa6a3c7b21 100644 --- a/basis/compiler/tests/optimizer.factor +++ b/basis/compiler/tests/optimizer.factor @@ -286,9 +286,7 @@ HINTS: recursive-inline-hang-2 array ; HINTS: recursive-inline-hang-3 array ; ! Regression -USE: sequences.private - -[ ] [ { (3append) } compile ] unit-test +[ ] [ { 3append-as } compile ] unit-test ! Wow : counter-example ( a b c d -- a' b' c' d' ) @@ -377,3 +375,9 @@ DEFER: loop-bbb : loop-ccc ( -- ) loop-bbb ; [ 0 ] [ 0 counter set loop-ccc counter get ] unit-test + +! Type inference issue +[ 4 3 ] [ + 1 >bignum 2 >bignum + [ { bignum integer } declare [ shift ] keep 1+ ] compile-call +] unit-test diff --git a/basis/compiler/tests/redefine13.factor b/basis/compiler/tests/redefine13.factor new file mode 100644 index 0000000000..d092cd4ee1 --- /dev/null +++ b/basis/compiler/tests/redefine13.factor @@ -0,0 +1,14 @@ +USING: math fry macros eval tools.test ; +IN: compiler.tests.redefine13 + +: breakage-word ( a b -- c ) + ; + +MACRO: breakage-macro ( a -- ) '[ _ breakage-word ] ; + +GENERIC: breakage-caller ( a -- c ) + +M: fixnum breakage-caller 2 breakage-macro ; + +: breakage ( -- obj ) 2 breakage-caller ; + +! [ ] [ "IN: compiler.tests.redefine13 : breakage-word ( a b -- c ) ;" eval ] unit-test diff --git a/basis/compiler/tests/redefine14.factor b/basis/compiler/tests/redefine14.factor new file mode 100644 index 0000000000..807f3ed2c7 --- /dev/null +++ b/basis/compiler/tests/redefine14.factor @@ -0,0 +1,8 @@ +USING: compiler.units definitions tools.test sequences ; +IN: compiler.tests.redefine14 + +! TUPLE: bad ; +! +! M: bad length 1 2 3 ; +! +! [ ] [ [ { bad length } forget ] with-compilation-unit ] unit-test diff --git a/basis/compiler/tests/spilling.factor b/basis/compiler/tests/spilling.factor index 156fdfff02..ee8c2f056a 100644 --- a/basis/compiler/tests/spilling.factor +++ b/basis/compiler/tests/spilling.factor @@ -1,5 +1,5 @@ USING: math.private kernel combinators accessors arrays -generalizations float-arrays tools.test ; +generalizations tools.test ; IN: compiler.tests : float-spill-bug ( a -- b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b b ) diff --git a/basis/compiler/tree/builder/builder.factor b/basis/compiler/tree/builder/builder.factor index 4e79c4cd2d..b715223445 100644 --- a/basis/compiler/tree/builder/builder.factor +++ b/basis/compiler/tree/builder/builder.factor @@ -21,7 +21,7 @@ IN: compiler.tree.builder : build-tree-with ( in-stack quot -- nodes out-stack ) #! Not safe to call from inference transforms. [ - [ >vector meta-d set ] + [ >vector \ meta-d set ] [ f initial-recursive-state infer-quot ] bi* ] with-tree-builder nip unclip-last in-d>> ; diff --git a/basis/compiler/tree/cleanup/cleanup-tests.factor b/basis/compiler/tree/cleanup/cleanup-tests.factor index 4a6198db37..71c6fb5675 100644 --- a/basis/compiler/tree/cleanup/cleanup-tests.factor +++ b/basis/compiler/tree/cleanup/cleanup-tests.factor @@ -71,7 +71,7 @@ M: object xyz ; 2over fixnum>= [ 3drop ] [ - [ swap >r call 1 fixnum+fast r> ] keep (fx-repeat) + [ swap [ call 1 fixnum+fast ] dip ] keep (fx-repeat) ] if ; inline recursive : fx-repeat ( n quot -- ) @@ -87,10 +87,10 @@ M: object xyz ; 2over dup xyz drop >= [ 3drop ] [ - [ swap >r call 1+ r> ] keep (i-repeat) + [ swap [ call 1+ ] dip ] keep (i-repeat) ] if ; inline recursive -: i-repeat >r { integer } declare r> 0 -rot (i-repeat) ; inline +: i-repeat [ { integer } declare ] dip 0 -rot (i-repeat) ; inline [ t ] [ [ [ dup xyz drop ] i-repeat ] \ xyz inlined? @@ -194,7 +194,7 @@ M: fixnum annotate-entry-test-1 drop ; 2dup >= [ 2drop ] [ - >r dup annotate-entry-test-1 1+ r> (annotate-entry-test-2) + [ dup annotate-entry-test-1 1+ ] dip (annotate-entry-test-2) ] if ; inline recursive : annotate-entry-test-2 0 -rot (annotate-entry-test-2) ; inline @@ -448,7 +448,7 @@ cell-bits 32 = [ ] unit-test [ ] [ - [ [ >r "A" throw r> ] [ "B" throw ] if ] + [ [ [ "A" throw ] dip ] [ "B" throw ] if ] cleaned-up-tree drop ] unit-test @@ -463,7 +463,7 @@ cell-bits 32 = [ : buffalo-wings ( i seq -- ) 2dup < [ 2dup chicken-fingers - >r 1+ r> buffalo-wings + [ 1+ ] dip buffalo-wings ] [ 2drop ] if ; inline recursive @@ -482,7 +482,7 @@ cell-bits 32 = [ : ribs ( i seq -- ) 2dup < [ steak - >r 1+ r> ribs + [ 1+ ] dip ribs ] [ 2drop ] if ; inline recursive diff --git a/basis/compiler/tree/cleanup/cleanup.factor b/basis/compiler/tree/cleanup/cleanup.factor index becac01cd5..1b0343faa9 100644 --- a/basis/compiler/tree/cleanup/cleanup.factor +++ b/basis/compiler/tree/cleanup/cleanup.factor @@ -1,10 +1,11 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel accessors sequences sequences.deep combinators fry +USING: kernel accessors sequences combinators fry classes.algebra namespaces assocs words math math.private math.partial-dispatch math.intervals classes classes.tuple classes.tuple.private layouts definitions stack-checker.state stack-checker.branches +compiler.utilities compiler.tree compiler.tree.combinators compiler.tree.propagation.info @@ -33,7 +34,7 @@ GENERIC: cleanup* ( node -- node/nodes ) : cleanup ( nodes -- nodes' ) #! We don't recurse into children here, instead the methods #! do it since the logic is a bit more involved - [ cleanup* ] map flatten ; + [ cleanup* ] map-flat ; : cleanup-folding? ( #call -- ? ) node-output-infos diff --git a/basis/compiler/tree/combinators/combinators.factor b/basis/compiler/tree/combinators/combinators.factor index 40bbf81a03..030df8484f 100644 --- a/basis/compiler/tree/combinators/combinators.factor +++ b/basis/compiler/tree/combinators/combinators.factor @@ -1,7 +1,8 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: assocs fry kernel accessors sequences sequences.deep arrays -stack-checker.inlining namespaces compiler.tree ; +USING: assocs fry kernel accessors sequences compiler.utilities +arrays stack-checker.inlining namespaces compiler.tree +math.order ; IN: compiler.tree.combinators : each-node ( nodes quot: ( node -- ) -- ) @@ -27,7 +28,7 @@ IN: compiler.tree.combinators [ _ map-nodes ] change-child ] when ] if - ] map flatten ; inline recursive + ] map-flat ; inline recursive : contains-node? ( nodes quot: ( node -- ? ) -- ? ) dup dup '[ @@ -48,12 +49,6 @@ IN: compiler.tree.combinators : sift-children ( seq flags -- seq' ) zip [ nip ] assoc-filter keys ; -: (3each) [ 3array flip ] dip '[ first3 @ ] ; inline - -: 3each ( seq1 seq2 seq3 quot -- seq ) (3each) each ; inline - -: 3map ( seq1 seq2 seq3 quot -- seq ) (3each) map ; inline - : until-fixed-point ( #recursive quot: ( node -- ) -- ) over label>> t >>fixed-point drop [ with-scope ] 2keep diff --git a/basis/compiler/tree/dead-code/dead-code-tests.factor b/basis/compiler/tree/dead-code/dead-code-tests.factor index 7b15fdf856..b64e30d8f9 100644 --- a/basis/compiler/tree/dead-code/dead-code-tests.factor +++ b/basis/compiler/tree/dead-code/dead-code-tests.factor @@ -75,9 +75,9 @@ IN: compiler.tree.dead-code.tests remove-dead-code "no-check" get [ dup check-nodes ] unless nodes>quot ; -[ [ drop 1 ] ] [ [ >r 1 r> drop ] optimize-quot ] unit-test +[ [ drop 1 ] ] [ [ [ 1 ] dip drop ] optimize-quot ] unit-test -[ [ read drop 1 2 ] ] [ [ read >r 1 2 r> drop ] optimize-quot ] unit-test +[ [ read drop 1 2 ] ] [ [ read [ 1 2 ] dip drop ] optimize-quot ] unit-test [ [ over >r + r> ] ] [ [ [ + ] [ drop ] 2bi ] optimize-quot ] unit-test diff --git a/basis/compiler/tree/dead-code/liveness/liveness.factor b/basis/compiler/tree/dead-code/liveness/liveness.factor index 44b71935c8..9ece5d340b 100644 --- a/basis/compiler/tree/dead-code/liveness/liveness.factor +++ b/basis/compiler/tree/dead-code/liveness/liveness.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: fry accessors namespaces assocs deques search-deques -dlists kernel sequences sequences.deep words sets +dlists kernel sequences compiler.utilities words sets stack-checker.branches compiler.tree compiler.tree.def-use compiler.tree.combinators ; IN: compiler.tree.dead-code.liveness @@ -49,4 +49,4 @@ GENERIC: remove-dead-code* ( node -- node' ) M: node remove-dead-code* ; : (remove-dead-code) ( nodes -- nodes' ) - [ remove-dead-code* ] map flatten ; + [ remove-dead-code* ] map-flat ; diff --git a/basis/compiler/tree/dead-code/recursive/recursive.factor b/basis/compiler/tree/dead-code/recursive/recursive.factor index 02dc42f058..71830d07e7 100644 --- a/basis/compiler/tree/dead-code/recursive/recursive.factor +++ b/basis/compiler/tree/dead-code/recursive/recursive.factor @@ -22,14 +22,11 @@ M: #call-recursive compute-live-values* [ out-d>> ] [ label>> return>> in-d>> ] bi look-at-mapping ; :: drop-dead-inputs ( inputs outputs -- #shuffle ) - [let* | live-inputs [ inputs filter-live ] - new-live-inputs [ outputs inputs filter-corresponding make-values ] | - live-inputs - new-live-inputs - outputs - inputs - drop-values - ] ; + inputs filter-live + outputs inputs filter-corresponding make-values + outputs + inputs + drop-values ; M: #enter-recursive remove-dead-code* [ filter-live ] change-out-d ; @@ -79,12 +76,12 @@ M: #call-recursive remove-dead-code* bi ] ; -M:: #recursive remove-dead-code* ( node -- nodes ) - [let* | drop-inputs [ node drop-recursive-inputs ] - drop-outputs [ node drop-recursive-outputs ] | - node [ (remove-dead-code) ] change-child drop - node label>> [ filter-live ] change-enter-out drop - { drop-inputs node drop-outputs } - ] ; +M: #recursive remove-dead-code* ( node -- nodes ) + [ drop-recursive-inputs ] + [ + [ (remove-dead-code) ] change-child + dup label>> [ filter-live ] change-enter-out drop + ] + [ drop-recursive-outputs ] tri 3array ; M: #return-recursive remove-dead-code* ; diff --git a/basis/compiler/tree/debugger/debugger.factor b/basis/compiler/tree/debugger/debugger.factor index a1d8773484..e75e7f6046 100644 --- a/basis/compiler/tree/debugger/debugger.factor +++ b/basis/compiler/tree/debugger/debugger.factor @@ -2,8 +2,9 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel assocs match fry accessors namespaces make effects sequences sequences.private quotations generic macros arrays -prettyprint prettyprint.backend prettyprint.sections math words -combinators combinators.short-circuit io sorting hints qualified +prettyprint prettyprint.backend prettyprint.custom +prettyprint.sections math words combinators +combinators.short-circuit io sorting hints qualified compiler.tree compiler.tree.recursive compiler.tree.normalization @@ -93,7 +94,7 @@ M: #shuffle node>quot [ drop "COMPLEX SHUFFLE" , ] } cond ; -M: #push node>quot literal>> , ; +M: #push node>quot literal>> literalize , ; M: #call node>quot word>> , ; @@ -125,9 +126,13 @@ M: node node>quot drop ; : nodes>quot ( node -- quot ) [ [ node>quot ] each ] [ ] make ; -: optimized. ( quot/word -- ) - dup word? [ specialized-def ] when - build-tree optimize-tree nodes>quot . ; +GENERIC: optimized. ( quot/word -- ) + +M: method-spec optimized. first2 method optimized. ; + +M: word optimized. specialized-def optimized. ; + +M: callable optimized. build-tree optimize-tree nodes>quot . ; SYMBOL: words-called SYMBOL: generics-called @@ -146,14 +151,14 @@ SYMBOL: node-count H{ } clone intrinsics-called set 0 swap [ - >r 1+ r> + [ 1+ ] dip dup #call? [ word>> { { [ dup "intrinsics" word-prop over "if-intrinsics" word-prop or ] [ intrinsics-called ] } { [ dup generic? ] [ generics-called ] } { [ dup method-body? ] [ methods-called ] } [ words-called ] - } cond 1 -rot get at+ + } cond inc-at ] [ drop ] if ] each-node node-count set diff --git a/basis/compiler/tree/def-use/simplified/simplified.factor b/basis/compiler/tree/def-use/simplified/simplified.factor index edfe633057..9b2a2038da 100644 --- a/basis/compiler/tree/def-use/simplified/simplified.factor +++ b/basis/compiler/tree/def-use/simplified/simplified.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: sequences sequences.deep kernel +USING: sequences kernel fry vectors compiler.tree compiler.tree.def-use ; IN: compiler.tree.def-use.simplified @@ -9,8 +9,6 @@ IN: compiler.tree.def-use.simplified ! A 'real' usage is a usage of a value that is not a #renaming. TUPLE: real-usage value node ; -GENERIC: actually-used-by* ( value node -- real-usages ) - ! Def GENERIC: actually-defined-by* ( value node -- real-usage ) @@ -25,16 +23,18 @@ M: #return-recursive actually-defined-by* real-usage boa ; M: node actually-defined-by* real-usage boa ; ! Use -: (actually-used-by) ( value -- real-usages ) - dup used-by [ actually-used-by* ] with map ; +GENERIC# actually-used-by* 1 ( value node accum -- ) + +: (actually-used-by) ( value accum -- ) + [ [ used-by ] keep ] dip '[ _ swap _ actually-used-by* ] each ; M: #renaming actually-used-by* - inputs/outputs [ indices ] dip nths - [ (actually-used-by) ] map ; + [ inputs/outputs [ indices ] dip nths ] dip + '[ _ (actually-used-by) ] each ; -M: #return-recursive actually-used-by* real-usage boa ; +M: #return-recursive actually-used-by* [ real-usage boa ] dip push ; -M: node actually-used-by* real-usage boa ; +M: node actually-used-by* [ real-usage boa ] dip push ; : actually-used-by ( value -- real-usages ) - (actually-used-by) flatten ; + 10 [ (actually-used-by) ] keep ; diff --git a/basis/compiler/tree/escape-analysis/branches/branches.factor b/basis/compiler/tree/escape-analysis/branches/branches.factor index b728e9a1ba..2eee3e698b 100644 --- a/basis/compiler/tree/escape-analysis/branches/branches.factor +++ b/basis/compiler/tree/escape-analysis/branches/branches.factor @@ -33,4 +33,4 @@ M: #branch escape-analysis* 2bi ; M: #phi escape-analysis* - [ phi-in-d>> ] [ out-d>> ] bi merge-allocations ; + [ phi-in-d>> flip ] [ out-d>> ] bi merge-allocations ; diff --git a/basis/compiler/tree/escape-analysis/check/check.factor b/basis/compiler/tree/escape-analysis/check/check.factor new file mode 100644 index 0000000000..333b3fa636 --- /dev/null +++ b/basis/compiler/tree/escape-analysis/check/check.factor @@ -0,0 +1,23 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: classes classes.tuple math math.private accessors +combinators kernel compiler.tree compiler.tree.combinators +compiler.tree.propagation.info ; +IN: compiler.tree.escape-analysis.check + +GENERIC: run-escape-analysis* ( node -- ? ) + +M: #push run-escape-analysis* + literal>> [ class immutable-tuple-class? ] [ complex? ] bi or ; + +M: #call run-escape-analysis* + { + { [ dup word>> \ eq? ] [ t ] } + { [ dup immutable-tuple-boa? ] [ t ] } + [ f ] + } cond nip ; + +M: node run-escape-analysis* drop f ; + +: run-escape-analysis? ( nodes -- ? ) + [ run-escape-analysis* ] contains-node? ; diff --git a/basis/compiler/tree/finalization/finalization.factor b/basis/compiler/tree/finalization/finalization.factor index 16a27e020a..ecd5429baf 100644 --- a/basis/compiler/tree/finalization/finalization.factor +++ b/basis/compiler/tree/finalization/finalization.factor @@ -1,6 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel accessors sequences words memoize classes.builtin +USING: kernel accessors sequences words memoize combinators +classes classes.builtin classes.tuple math.partial-dispatch fry assocs compiler.tree compiler.tree.combinators @@ -12,7 +13,7 @@ IN: compiler.tree.finalization ! See the comment in compiler.tree.late-optimizations. ! This pass runs after propagation, so that it can expand -! built-in type predicates; these cannot be expanded before +! type predicates; these cannot be expanded before ! propagation since we need to see 'fixnum?' instead of ! 'tag 0 eq?' and so on, for semantic reasoning. @@ -33,16 +34,24 @@ M: #shuffle finalize* [ [ in-r>> ] [ out-r>> ] [ mapping>> ] tri '[ _ at ] map sequence= ] bi and [ drop f ] when ; -: builtin-predicate? ( #call -- ? ) - word>> "predicating" word-prop builtin-class? ; - -MEMO: builtin-predicate-expansion ( word -- nodes ) +MEMO: cached-expansion ( word -- nodes ) def>> splice-final ; -: expand-builtin-predicate ( #call -- nodes ) - word>> builtin-predicate-expansion ; +GENERIC: finalize-word ( #call word -- nodes ) + +M: predicate finalize-word + "predicating" word-prop { + { [ dup builtin-class? ] [ drop word>> cached-expansion ] } + { [ dup tuple-class? ] [ drop word>> def>> splice-final ] } + [ drop ] + } cond ; + +! M: math-partial finalize-word +! dup primitive? [ drop ] [ nip cached-expansion ] if ; + +M: word finalize-word drop ; M: #call finalize* - dup builtin-predicate? [ expand-builtin-predicate ] when ; + dup word>> finalize-word ; M: node finalize* ; diff --git a/basis/compiler/tree/normalization/normalization-tests.factor b/basis/compiler/tree/normalization/normalization-tests.factor index c4a97fcc92..5ac3c57abe 100644 --- a/basis/compiler/tree/normalization/normalization-tests.factor +++ b/basis/compiler/tree/normalization/normalization-tests.factor @@ -34,8 +34,8 @@ sequences accessors tools.test kernel math ; [ ] [ [ [ 1 ] [ 2 ] if + * ] test-normalization ] unit-test DEFER: bbb -: aaa ( x -- ) dup [ dup >r bbb r> aaa ] [ drop ] if ; inline recursive -: bbb ( x -- ) >r drop 0 r> aaa ; inline recursive +: aaa ( x -- ) dup [ dup [ bbb ] dip aaa ] [ drop ] if ; inline recursive +: bbb ( x -- ) [ drop 0 ] dip aaa ; inline recursive [ ] [ [ bbb ] test-normalization ] unit-test diff --git a/basis/compiler/tree/normalization/normalization.factor b/basis/compiler/tree/normalization/normalization.factor index bebe2e91b6..8c13de296a 100644 --- a/basis/compiler/tree/normalization/normalization.factor +++ b/basis/compiler/tree/normalization/normalization.factor @@ -1,10 +1,11 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: fry namespaces sequences math accessors kernel arrays -combinators sequences.deep assocs +combinators compiler.utilities assocs stack-checker.backend stack-checker.branches stack-checker.inlining +compiler.utilities compiler.tree compiler.tree.combinators compiler.tree.normalization.introductions @@ -46,7 +47,7 @@ M: #branch normalize* [ [ [ - [ normalize* ] map flatten + [ normalize* ] map-flat introduction-stack get 2array ] with-scope @@ -70,7 +71,7 @@ M: #phi normalize* : (normalize) ( nodes introductions -- nodes ) introduction-stack [ - [ normalize* ] map flatten + [ normalize* ] map-flat ] with-variable ; M: #recursive normalize* diff --git a/basis/compiler/tree/optimizer/optimizer.factor b/basis/compiler/tree/optimizer/optimizer.factor index e37323a2ec..54c6c2c117 100644 --- a/basis/compiler/tree/optimizer/optimizer.factor +++ b/basis/compiler/tree/optimizer/optimizer.factor @@ -6,6 +6,7 @@ compiler.tree.normalization compiler.tree.propagation compiler.tree.cleanup compiler.tree.escape-analysis +compiler.tree.escape-analysis.check compiler.tree.tuple-unboxing compiler.tree.identities compiler.tree.def-use @@ -22,8 +23,10 @@ SYMBOL: check-optimizer? normalize propagate cleanup - escape-analysis - unbox-tuples + dup run-escape-analysis? [ + escape-analysis + unbox-tuples + ] when apply-identities compute-def-use remove-dead-code diff --git a/basis/compiler/tree/propagation/branches/branches.factor b/basis/compiler/tree/propagation/branches/branches.factor index 424cd8a01c..f2613022fc 100644 --- a/basis/compiler/tree/propagation/branches/branches.factor +++ b/basis/compiler/tree/propagation/branches/branches.factor @@ -3,6 +3,7 @@ USING: fry kernel sequences assocs accessors namespaces math.intervals arrays classes.algebra combinators columns stack-checker.branches +compiler.utilities compiler.tree compiler.tree.combinators compiler.tree.propagation.info @@ -78,7 +79,7 @@ SYMBOL: condition-value M: #phi propagate-before ( #phi -- ) [ annotate-phi-inputs ] - [ [ phi-info-d>> ] [ out-d>> ] bi merge-value-infos ] + [ [ phi-info-d>> flip ] [ out-d>> ] bi merge-value-infos ] bi ; : branch-phi-constraints ( output values booleans -- ) @@ -137,8 +138,8 @@ M: #phi propagate-before ( #phi -- ) M: #phi propagate-after ( #phi -- ) condition-value get [ [ out-d>> ] - [ phi-in-d>> ] - [ phi-info-d>> ] tri + [ phi-in-d>> flip ] + [ phi-info-d>> flip ] tri [ [ possible-boolean-values ] map branch-phi-constraints diff --git a/basis/compiler/tree/propagation/copy/copy.factor b/basis/compiler/tree/propagation/copy/copy.factor index 2452aba4aa..53b7d17326 100644 --- a/basis/compiler/tree/propagation/copy/copy.factor +++ b/basis/compiler/tree/propagation/copy/copy.factor @@ -49,7 +49,7 @@ M: #renaming compute-copy-equiv* inputs/outputs are-copies-of ; ] 2each ; M: #phi compute-copy-equiv* - [ phi-in-d>> ] [ out-d>> ] bi compute-phi-equiv ; + [ phi-in-d>> flip ] [ out-d>> ] bi compute-phi-equiv ; M: node compute-copy-equiv* drop ; diff --git a/basis/compiler/tree/propagation/info/info.factor b/basis/compiler/tree/propagation/info/info.factor index e89a9c6211..771d3800df 100644 --- a/basis/compiler/tree/propagation/info/info.factor +++ b/basis/compiler/tree/propagation/info/info.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: assocs classes classes.algebra classes.tuple classes.tuple.private kernel accessors math math.intervals -namespaces sequences words combinators combinators.short-circuit +namespaces sequences words combinators arrays compiler.tree.propagation.copy ; IN: compiler.tree.propagation.info @@ -253,12 +253,13 @@ DEFER: (value-info-union) { [ over not ] [ 2drop f ] } [ { - [ [ class>> ] bi@ class<= ] - [ [ interval>> ] bi@ interval-subset? ] - [ literals<= ] - [ [ length>> ] bi@ value-info<= ] - [ [ slots>> ] bi@ [ value-info<= ] 2all? ] - } 2&& + { [ 2dup [ class>> ] bi@ class<= not ] [ f ] } + { [ 2dup [ interval>> ] bi@ interval-subset? not ] [ f ] } + { [ 2dup literals<= not ] [ f ] } + { [ 2dup [ length>> ] bi@ value-info<= not ] [ f ] } + { [ 2dup [ slots>> ] bi@ [ value-info<= ] 2all? not ] [ f ] } + [ t ] + } cond 2nip ] } cond ; diff --git a/basis/compiler/tree/propagation/inlining/inlining.factor b/basis/compiler/tree/propagation/inlining/inlining.factor index 8397a5fdbb..bd6d657442 100644 --- a/basis/compiler/tree/propagation/inlining/inlining.factor +++ b/basis/compiler/tree/propagation/inlining/inlining.factor @@ -3,7 +3,7 @@ USING: accessors kernel arrays sequences math math.order math.partial-dispatch generic generic.standard generic.math classes.algebra classes.union sets quotations assocs combinators -words namespaces continuations +words namespaces continuations classes fry compiler.tree compiler.tree.builder compiler.tree.recursive @@ -20,13 +20,17 @@ SYMBOL: node-count : count-nodes ( nodes -- ) 0 swap [ drop 1+ ] each-node node-count set ; +! We try not to inline the same word too many times, to avoid +! combinatorial explosion +SYMBOL: inlining-count + ! Splicing nodes GENERIC: splicing-nodes ( #call word/quot/f -- nodes ) M: word splicing-nodes [ [ in-d>> ] [ out-d>> ] bi ] dip #call 1array ; -M: quotation splicing-nodes +M: callable splicing-nodes build-sub-tree analyze-recursive normalize ; : propagate-body ( #call -- ) @@ -44,9 +48,11 @@ M: quotation splicing-nodes ] [ 2drop f >>method f >>body f >>class drop f ] if ; : inlining-standard-method ( #call word -- class/f method/f ) - [ in-d>> ] [ [ dispatch# ] keep ] bi* - [ swap nth value-info class>> dup ] dip - specific-method ; + dup "methods" word-prop assoc-empty? [ 2drop f f ] [ + [ in-d>> ] [ [ dispatch# ] keep ] bi* + [ swap nth value-info class>> dup ] dip + specific-method + ] if ; : inline-standard-method ( #call word -- ? ) dupd inlining-standard-method eliminate-dispatch ; @@ -85,6 +91,8 @@ DEFER: (flat-length) : word-flat-length ( word -- n ) { + ! special-case + { [ dup { dip 2dip 3dip } memq? ] [ drop 1 ] } ! not inline { [ dup inline? not ] [ drop 1 ] } ! recursive and inline @@ -118,17 +126,25 @@ DEFER: (flat-length) bi and ] contains? ; +: node-count-bias ( -- n ) + 45 node-count get [-] 8 /i ; + +: body-length-bias ( word -- n ) + [ flat-length ] [ inlining-count get at 0 or ] bi + over 2 <= [ drop ] [ 2/ 1+ * ] if 24 swap [-] 4 /i ; + : inlining-rank ( #call word -- n ) [ classes-known? 2 0 ? ] [ { - [ drop node-count get 45 swap [-] 8 /i ] - [ flat-length 24 swap [-] 4 /i ] + [ body-length-bias ] [ "default" word-prop -4 0 ? ] [ "specializer" word-prop 1 0 ? ] [ method-body? 1 0 ? ] } cleave - ] bi* + + + + + ; + node-count-bias + loop-nesting get 0 or 2 * + ] bi* + + + + + + ; : should-inline? ( #call word -- ? ) dup "inline" word-prop [ 2drop t ] [ inlining-rank 5 >= ] if ; @@ -136,20 +152,23 @@ DEFER: (flat-length) SYMBOL: history : remember-inlining ( word -- ) - history [ swap suffix ] change ; + [ inlining-count get inc-at ] + [ history [ swap suffix ] change ] + bi ; -: inline-word ( #call word -- ? ) - dup history get memq? [ - 2drop f - ] [ +: inline-word-def ( #call word quot -- ? ) + over history get memq? [ 3drop f ] [ [ - dup remember-inlining - dupd def>> splicing-nodes >>body + swap remember-inlining + dupd splicing-nodes >>body propagate-body ] with-scope t ] if ; +: inline-word ( #call word -- ? ) + dup def>> inline-word-def ; + : inline-method-body ( #call word -- ? ) 2dup should-inline? [ inline-word ] [ 2drop f ] if ; @@ -163,7 +182,11 @@ SYMBOL: history [ dup 1array ] [ "custom-inlining" word-prop ] bi* with-datastack first object swap eliminate-dispatch ; -: do-inlining ( #call word -- ? ) +: inline-instance-check ( #call word -- ? ) + over in-d>> second value-info literal>> dup class? + [ "predicate" word-prop '[ drop @ ] inline-word-def ] [ 3drop f ] if ; + +: (do-inlining) ( #call word -- ? ) #! If the generic was defined in an outer compilation unit, #! then it doesn't have a definition yet; the definition #! is built at the end of the compilation unit. We do not @@ -174,10 +197,17 @@ SYMBOL: history #! discouraged, but it should still work.) { { [ dup deferred? ] [ 2drop f ] } - { [ dup custom-inlining? ] [ inline-custom ] } + { [ dup \ instance? eq? ] [ inline-instance-check ] } { [ dup always-inline-word? ] [ inline-word ] } { [ dup standard-generic? ] [ inline-standard-method ] } { [ dup math-generic? ] [ inline-math-method ] } { [ dup method-body? ] [ inline-method-body ] } [ 2drop f ] } cond ; + +: do-inlining ( #call word -- ? ) + #! Note the logic here: if there's a custom inlining hook, + #! it is permitted to return f, which means that we try the + #! normal inlining heuristic. + dup custom-inlining? [ 2dup inline-custom ] [ f ] if + [ 2drop t ] [ (do-inlining) ] if ; diff --git a/basis/compiler/tree/propagation/known-words/known-words.factor b/basis/compiler/tree/propagation/known-words/known-words.factor index 3b698e0001..4d8d935477 100644 --- a/basis/compiler/tree/propagation/known-words/known-words.factor +++ b/basis/compiler/tree/propagation/known-words/known-words.factor @@ -1,11 +1,12 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel effects accessors math math.private math.libm -math.partial-dispatch math.intervals math.parser math.order -layouts words sequences sequences.private arrays assocs classes -classes.algebra combinators generic.math splitting fry locals -classes.tuple alien.accessors classes.tuple.private slots.private -definitions +USING: kernel effects accessors math math.private +math.integers.private math.partial-dispatch math.intervals +math.parser math.order layouts words sequences sequences.private +arrays assocs classes classes.algebra combinators generic.math +splitting fry locals classes.tuple alien.accessors +classes.tuple.private slots.private definitions strings.private +vectors hashtables stack-checker.state compiler.tree.comparisons compiler.tree.propagation.info @@ -37,31 +38,6 @@ most-negative-fixnum most-positive-fixnum [a,b] \ bitnot { integer } "input-classes" set-word-prop -{ - fcosh - flog - fsinh - fexp - fasin - facosh - fasinh - ftanh - fatanh - facos - fpow - fatan - fatan2 - fcos - ftan - fsin - fsqrt -} [ - dup stack-effect - [ in>> length real "input-classes" set-word-prop ] - [ out>> length float "default-output-classes" set-word-prop ] - 2bi -] each - : ?change-interval ( info quot -- quot' ) over interval>> [ [ clone ] dip change-interval ] [ 2drop ] if ; inline @@ -101,14 +77,17 @@ most-negative-fixnum most-positive-fixnum [a,b] [ rational math-class-max ] dip ] unless ; +: ensure-math-class ( class must-be -- class' ) + [ class<= ] 2keep ? ; + : number-valued ( class interval -- class' interval' ) - [ number math-class-min ] dip ; + [ number ensure-math-class ] dip ; : integer-valued ( class interval -- class' interval' ) - [ integer math-class-min ] dip ; + [ integer ensure-math-class ] dip ; : real-valued ( class interval -- class' interval' ) - [ real math-class-min ] dip ; + [ real ensure-math-class ] dip ; : float-valued ( class interval -- class' interval' ) over null-class? [ @@ -138,6 +117,12 @@ most-negative-fixnum most-positive-fixnum [a,b] \ mod [ [ interval-mod ] [ real-valued ] binary-op ] each-derived-op \ rem [ [ interval-rem ] [ may-overflow real-valued ] binary-op ] each-derived-op +{ /mod fixnum/mod } [ + \ /i \ mod + [ "outputs" word-prop ] bi@ + '[ _ _ 2bi ] "outputs" set-word-prop +] each + \ shift [ [ interval-shift-safe ] [ may-overflow integer-valued ] binary-op ] each-derived-op \ shift [ [ interval-shift-safe ] [ integer-valued ] binary-op ] each-fast-derived-op @@ -163,10 +148,9 @@ most-negative-fixnum most-positive-fixnum [a,b] comparison-ops [ dup '[ _ define-comparison-constraints ] each-derived-op ] each -generic-comparison-ops [ - dup specific-comparison - '[ _ _ define-comparison-constraints ] each-derived-op -] each +! generic-comparison-ops [ +! dup specific-comparison define-comparison-constraints +! ] each ! Remove redundant comparisons : fold-comparison ( info1 info2 word -- info ) @@ -214,10 +198,22 @@ generic-comparison-ops [ 2bi and maybe-or-never ] "outputs" set-word-prop +\ both-fixnums? [ + [ class>> fixnum classes-intersect? not ] either? + f object-info ? +] "outputs" set-word-prop + { { >fixnum fixnum } + { bignum>fixnum fixnum } + { >bignum bignum } + { fixnum>bignum bignum } + { float>bignum bignum } + { >float float } + { fixnum>float float } + { bignum>float float } } [ '[ _ @@ -238,7 +234,7 @@ generic-comparison-ops [ } [ [ in-d>> second value-info >literal< - [ power-of-2? [ 1- bitand ] f ? ] when + [ dup integer? [ power-of-2? [ 1- bitand ] f ? ] [ drop f ] if ] when ] "custom-inlining" set-word-prop ] each @@ -255,6 +251,19 @@ generic-comparison-ops [ ] "custom-inlining" set-word-prop ] each +{ numerator denominator } +[ [ drop integer ] "outputs" set-word-prop ] each + +{ (log2) fixnum-log2 bignum-log2 } [ + [ + [ class>> ] [ interval>> interval-log2 ] bi + ] "outputs" set-word-prop +] each + +\ string-nth [ + 2drop fixnum 0 23 2^ [a,b] +] "outputs" set-word-prop + { alien-signed-1 alien-unsigned-1 @@ -296,6 +305,15 @@ generic-comparison-ops [ "outputs" set-word-prop ] each +! Generate more efficient code for common idiom +\ clone [ + in-d>> first value-info literal>> { + { V{ } [ [ drop { } 0 vector boa ] ] } + { H{ } [ [ drop hashtable new ] ] } + [ drop f ] + } case +] "custom-inlining" set-word-prop + \ slot [ dup literal?>> [ literal>> swap value-info-slot ] [ 2drop object-info ] if diff --git a/basis/compiler/tree/propagation/nodes/nodes.factor b/basis/compiler/tree/propagation/nodes/nodes.factor index 9e4d99e462..d676102bde 100644 --- a/basis/compiler/tree/propagation/nodes/nodes.factor +++ b/basis/compiler/tree/propagation/nodes/nodes.factor @@ -6,6 +6,8 @@ compiler.tree.propagation.copy compiler.tree.propagation.info ; IN: compiler.tree.propagation.nodes +SYMBOL: loop-nesting + GENERIC: propagate-before ( node -- ) GENERIC: propagate-after ( node -- ) diff --git a/basis/compiler/tree/propagation/propagation-tests.factor b/basis/compiler/tree/propagation/propagation-tests.factor index 760ff167aa..d95245fe83 100644 --- a/basis/compiler/tree/propagation/propagation-tests.factor +++ b/basis/compiler/tree/propagation/propagation-tests.factor @@ -8,7 +8,8 @@ math.functions math.private strings layouts compiler.tree.propagation.info compiler.tree.def-use compiler.tree.debugger compiler.tree.checker slots.private words hashtables classes assocs locals -float-arrays system sorting ; +specialized-arrays.double system sorting math.libm +math.intervals ; IN: compiler.tree.propagation.tests \ propagate must-infer @@ -33,17 +34,57 @@ IN: compiler.tree.propagation.tests [ V{ fixnum } ] [ [ { fixnum } declare bitnot ] final-classes ] unit-test -[ V{ number } ] [ [ + ] final-classes ] unit-test +! Test type propagation for math ops +: cleanup-math-class ( obj -- class ) + { null fixnum bignum integer ratio rational float real complex number } + [ class= ] with find nip ; -[ V{ float } ] [ [ { float integer } declare + ] final-classes ] unit-test +: final-math-class ( quot -- class ) + final-classes first cleanup-math-class ; -[ V{ float } ] [ [ /f ] final-classes ] unit-test +[ number ] [ [ + ] final-math-class ] unit-test -[ V{ integer } ] [ [ /i ] final-classes ] unit-test +[ bignum ] [ [ { fixnum bignum } declare + ] final-math-class ] unit-test -[ V{ integer } ] [ - [ { integer } declare bitnot ] final-classes -] unit-test +[ integer ] [ [ { fixnum integer } declare + ] final-math-class ] unit-test + +[ bignum ] [ [ { integer bignum } declare + ] final-math-class ] unit-test + +[ integer ] [ [ { fixnum fixnum } declare + ] final-math-class ] unit-test + +[ float ] [ [ { float integer } declare + ] final-math-class ] unit-test + +[ float ] [ [ { real float } declare + ] final-math-class ] unit-test + +[ float ] [ [ { float real } declare + ] final-math-class ] unit-test + +[ rational ] [ [ { ratio ratio } declare + ] final-math-class ] unit-test + +[ rational ] [ [ { rational ratio } declare + ] final-math-class ] unit-test + +[ number ] [ [ { complex complex } declare + ] final-math-class ] unit-test + +[ float ] [ [ /f ] final-math-class ] unit-test + +[ float ] [ [ { real real } declare /f ] final-math-class ] unit-test + +[ integer ] [ [ /i ] final-math-class ] unit-test + +[ integer ] [ [ { integer float } declare /i ] final-math-class ] unit-test + +[ integer ] [ [ { float float } declare /i ] final-math-class ] unit-test + +[ integer ] [ [ { integer } declare bitnot ] final-math-class ] unit-test + +[ null ] [ [ { null null } declare + ] final-math-class ] unit-test + +[ null ] [ [ { null fixnum } declare + ] final-math-class ] unit-test + +[ float ] [ [ { float fixnum } declare + ] final-math-class ] unit-test + +[ bignum ] [ [ { bignum bignum } declare bitxor ] final-math-class ] unit-test + +[ float ] [ [ { float float } declare mod ] final-math-class ] unit-test [ V{ integer } ] [ [ 255 bitand ] final-classes ] unit-test @@ -65,18 +106,6 @@ IN: compiler.tree.propagation.tests [ { fixnum } declare 615949 * ] final-classes ] unit-test -[ V{ null } ] [ - [ { null null } declare + ] final-classes -] unit-test - -[ V{ null } ] [ - [ { null fixnum } declare + ] final-classes -] unit-test - -[ V{ float } ] [ - [ { float fixnum } declare + ] final-classes -] unit-test - [ V{ fixnum } ] [ [ 255 bitand >fixnum 3 bitor ] final-classes ] unit-test @@ -167,7 +196,8 @@ IN: compiler.tree.propagation.tests [ V{ fixnum } ] [ [ - [ uchar-nth ] 2keep [ uchar-nth ] 2keep uchar-nth + { fixnum byte-array } declare + [ nth-unsafe ] 2keep [ nth-unsafe ] 2keep nth-unsafe >r >r 298 * r> 100 * - r> 208 * - 128 + -8 shift 255 min 0 max ] final-classes @@ -277,14 +307,6 @@ IN: compiler.tree.propagation.tests ] final-classes ] unit-test -[ V{ float } ] [ - [ { real float } declare + ] final-classes -] unit-test - -[ V{ float } ] [ - [ { float real } declare + ] final-classes -] unit-test - [ V{ fixnum } ] [ [ { fixnum fixnum } declare 7 bitand neg shift ] final-classes ] unit-test @@ -434,7 +456,7 @@ TUPLE: mixed-mutable-immutable { x integer } { y sequence read-only } ; ] unit-test : recursive-test-4 ( i n -- ) - 2dup < [ >r 1+ r> recursive-test-4 ] [ 2drop ] if ; inline recursive + 2dup < [ [ 1+ ] dip recursive-test-4 ] [ 2drop ] if ; inline recursive [ ] [ [ recursive-test-4 ] final-info drop ] unit-test @@ -588,12 +610,36 @@ MIXIN: empty-mixin [ { fixnum integer } declare bitand ] final-classes ] unit-test -[ V{ float-array } ] [ [| | F{ } ] final-classes ] unit-test +[ V{ double-array } ] [ [| | double-array{ } ] final-classes ] unit-test [ V{ t } ] [ [ netbsd unix? ] final-literals ] unit-test [ V{ array } ] [ [ [ <=> ] sort [ <=> ] sort ] final-classes ] unit-test +[ V{ float } ] [ [ fsqrt ] final-classes ] unit-test + +[ V{ t } ] [ [ { fixnum } declare 10 mod >float -20 > ] final-literals ] unit-test + +[ T{ interval f { 0 t } { 127 t } } ] [ + [ { integer } declare 127 bitand ] final-info first interval>> +] unit-test + +[ V{ bignum } ] [ + [ { bignum } declare dup 1- bitxor ] final-classes +] unit-test + +[ V{ bignum integer } ] [ + [ { bignum integer } declare [ shift ] keep ] final-classes +] unit-test + +[ V{ fixnum } ] [ + [ { fixnum } declare log2 ] final-classes +] unit-test + +[ V{ word } ] [ + [ { fixnum } declare log2 0 >= ] final-classes +] unit-test + ! [ V{ string } ] [ ! [ dup string? t xor [ "A" throw ] [ ] if ] final-classes ! ] unit-test diff --git a/basis/compiler/tree/propagation/propagation.factor b/basis/compiler/tree/propagation/propagation.factor index b9822d2c6b..2a9825e3f1 100644 --- a/basis/compiler/tree/propagation/propagation.factor +++ b/basis/compiler/tree/propagation/propagation.factor @@ -19,5 +19,6 @@ IN: compiler.tree.propagation H{ } clone copies set H{ } clone 1array value-infos set H{ } clone 1array constraints set + H{ } clone inlining-count set dup count-nodes dup (propagate) ; diff --git a/basis/compiler/tree/propagation/recursive/recursive.factor b/basis/compiler/tree/propagation/recursive/recursive.factor index 7f10f87016..ff9f262d28 100644 --- a/basis/compiler/tree/propagation/recursive/recursive.factor +++ b/basis/compiler/tree/propagation/recursive/recursive.factor @@ -55,6 +55,8 @@ IN: compiler.tree.propagation.recursive M: #recursive propagate-around ( #recursive -- ) constraints [ H{ } clone suffix ] change [ + loop-nesting inc + constraints [ but-last H{ } clone suffix ] change child>> @@ -62,6 +64,8 @@ M: #recursive propagate-around ( #recursive -- ) [ first propagate-recursive-phi ] [ (propagate) ] tri + + loop-nesting dec ] until-fixed-point ; : recursive-phi-infos ( node -- infos ) diff --git a/basis/compiler/tree/propagation/simple/simple.factor b/basis/compiler/tree/propagation/simple/simple.factor index d586ff398f..9937c6b9c4 100644 --- a/basis/compiler/tree/propagation/simple/simple.factor +++ b/basis/compiler/tree/propagation/simple/simple.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: fry accessors kernel sequences sequences.private assocs words namespaces classes.algebra combinators classes classes.tuple -classes.tuple.private continuations arrays +classes.tuple.private continuations arrays alien.c-types math math.private slots generic definitions stack-checker.state compiler.tree @@ -137,11 +137,12 @@ M: #call propagate-after dup word>> "input-classes" word-prop dup [ propagate-input-classes ] [ 2drop ] if ; -M: #alien-invoke propagate-before - out-d>> [ object-info swap set-value-info ] each ; +: propagate-alien-invoke ( node -- ) + [ out-d>> ] [ params>> return>> ] bi + [ drop ] [ c-type-class swap first set-value-info ] if-void ; -M: #alien-indirect propagate-before - out-d>> [ object-info swap set-value-info ] each ; +M: #alien-invoke propagate-before propagate-alien-invoke ; -M: #return annotate-node - dup in-d>> (annotate-node) ; +M: #alien-indirect propagate-before propagate-alien-invoke ; + +M: #return annotate-node dup in-d>> (annotate-node) ; diff --git a/basis/compiler/tree/propagation/slots/slots.factor b/basis/compiler/tree/propagation/slots/slots.factor index 83e71c3363..8192b1c520 100644 --- a/basis/compiler/tree/propagation/slots/slots.factor +++ b/basis/compiler/tree/propagation/slots/slots.factor @@ -14,12 +14,13 @@ IN: compiler.tree.propagation.slots UNION: fixed-length-sequence array byte-array string ; : sequence-constructor? ( word -- ? ) - { } memq? ; + { (byte-array) } memq? ; : constructor-output-class ( word -- class ) { { array } { byte-array } + { (byte-array) byte-array } { string } } at ; diff --git a/basis/compiler/tree/tuple-unboxing/tuple-unboxing.factor b/basis/compiler/tree/tuple-unboxing/tuple-unboxing.factor index 52903fce8d..f6726e4404 100644 --- a/basis/compiler/tree/tuple-unboxing/tuple-unboxing.factor +++ b/basis/compiler/tree/tuple-unboxing/tuple-unboxing.factor @@ -1,9 +1,10 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: namespaces assocs accessors kernel combinators -classes.algebra sequences sequences.deep slots.private +classes.algebra sequences slots.private fry vectors classes.tuple.private math math.private arrays stack-checker.branches +compiler.utilities compiler.tree compiler.tree.combinators compiler.tree.propagation.info @@ -21,7 +22,7 @@ GENERIC: unbox-tuples* ( node -- node/nodes ) : (expand-#push) ( object value -- nodes ) dup unboxed-allocation dup [ [ object-slots ] [ drop ] [ ] tri* - [ (expand-#push) ] 2map + [ (expand-#push) ] 2map-flat ] [ drop #push ] if ; @@ -38,11 +39,16 @@ M: #push unbox-tuples* ( #push -- nodes ) : unbox- ( #call -- nodes ) dup unbox-output? [ drop { } ] when ; -: (flatten-values) ( values -- values' ) - [ dup unboxed-allocation [ (flatten-values) ] [ ] ?if ] map ; +: (flatten-values) ( values accum -- ) + dup '[ + dup unboxed-allocation + [ _ (flatten-values) ] [ _ push ] ?if + ] each ; : flatten-values ( values -- values' ) - dup empty? [ (flatten-values) flatten ] unless ; + dup empty? [ + 10 [ (flatten-values) ] keep + ] unless ; : prepare-slot-access ( #call -- tuple-values outputs slot-values ) [ in-d>> flatten-values ] diff --git a/basis/compiler/utilities/utilities.factor b/basis/compiler/utilities/utilities.factor new file mode 100644 index 0000000000..1f488b3dde --- /dev/null +++ b/basis/compiler/utilities/utilities.factor @@ -0,0 +1,31 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel sequences sequences.private arrays vectors fry +math.order ; +IN: compiler.utilities + +: flattener ( seq quot -- seq vector quot' ) + over length [ + dup + '[ + @ [ + dup array? + [ _ push-all ] [ _ push ] if + ] when* + ] + ] keep ; inline + +: flattening ( seq quot combinator -- seq' ) + [ flattener ] dip dip { } like ; inline + +: map-flat ( seq quot -- seq' ) [ each ] flattening ; inline + +: 2map-flat ( seq quot -- seq' ) [ 2each ] flattening ; inline + +: (3each) ( seq1 seq2 seq3 quot -- n quot' ) + [ [ [ length ] tri@ min min ] 3keep ] dip + '[ [ _ nth-unsafe ] [ _ nth-unsafe ] [ _ nth-unsafe ] tri @ ] ; inline + +: 3each ( seq1 seq2 seq3 quot -- seq ) (3each) each ; inline + +: 3map ( seq1 seq2 seq3 quot -- seq ) (3each) map ; inline diff --git a/basis/concurrency/combinators/combinators-docs.factor b/basis/concurrency/combinators/combinators-docs.factor index cb07e5a8d6..c61967fc8a 100644 --- a/basis/concurrency/combinators/combinators-docs.factor +++ b/basis/concurrency/combinators/combinators-docs.factor @@ -27,11 +27,17 @@ HELP: parallel-filter { $errors "Throws an error if one of the iterations throws an error." } ; ARTICLE: "concurrency.combinators" "Concurrent combinators" -"The " { $vocab-link "concurrency.combinators" } " vocabulary provides concurrent variants of " { $link each } ", " { $link map } " and " { $link filter } ":" +"The " { $vocab-link "concurrency.combinators" } " vocabulary provides concurrent variants of various combinators." +$nl +"Concurrent sequence combinators:" { $subsection parallel-each } { $subsection 2parallel-each } { $subsection parallel-map } { $subsection 2parallel-map } -{ $subsection parallel-filter } ; +{ $subsection parallel-filter } +"Concurrent cleave combinators:" +{ $subsection parallel-cleave } +{ $subsection parallel-spread } +{ $subsection parallel-napply } ; ABOUT: "concurrency.combinators" diff --git a/basis/concurrency/combinators/combinators-tests.factor b/basis/concurrency/combinators/combinators-tests.factor index 562111242d..1c2dea2d79 100644 --- a/basis/concurrency/combinators/combinators-tests.factor +++ b/basis/concurrency/combinators/combinators-tests.factor @@ -1,6 +1,7 @@ IN: concurrency.combinators.tests USING: concurrency.combinators tools.test random kernel math -concurrency.mailboxes threads sequences accessors arrays ; +concurrency.mailboxes threads sequences accessors arrays +math.parser ; [ [ drop ] parallel-each ] must-infer { 2 0 } [ [ 2drop ] 2parallel-each ] must-infer-as @@ -10,7 +11,7 @@ concurrency.mailboxes threads sequences accessors arrays ; [ { 1 4 9 } ] [ { 1 2 3 } [ sq ] parallel-map ] unit-test -[ { 1 4 9 } ] [ { 1 2 3 } [ 1000 random sleep sq ] parallel-map ] unit-test +[ { 1 4 9 } ] [ { 1 2 3 } [ 1000000 random sleep sq ] parallel-map ] unit-test [ { 1 2 3 } [ dup 2 mod 0 = [ "Even" throw ] when ] parallel-map ] [ error>> "Even" = ] must-fail-with @@ -45,3 +46,10 @@ concurrency.mailboxes threads sequences accessors arrays ; ] unit-test [ { f } [ "OOPS" throw ] parallel-each ] must-fail + +[ "1a" "4b" "3c" ] [ + 2 + { [ 1- ] [ sq ] [ 1+ ] } parallel-cleave + [ number>string ] 3 parallel-napply + { [ "a" append ] [ "b" append ] [ "c" append ] } parallel-spread +] unit-test diff --git a/basis/concurrency/combinators/combinators.factor b/basis/concurrency/combinators/combinators.factor index ab3ca7ed4a..932605fc36 100644 --- a/basis/concurrency/combinators/combinators.factor +++ b/basis/concurrency/combinators/combinators.factor @@ -1,34 +1,58 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: concurrency.futures concurrency.count-downs sequences -kernel ; +kernel macros fry combinators generalizations ; IN: concurrency.combinators r r> keep await ; inline + [ ] dip keep await ; inline + PRIVATE> : parallel-each ( seq quot -- ) over length [ - [ >r curry r> spawn-stage ] 2curry each + '[ _ curry _ spawn-stage ] each ] (parallel-each) ; inline : 2parallel-each ( seq1 seq2 quot -- ) 2over min-length [ - [ >r 2curry r> spawn-stage ] 2curry 2each + '[ _ 2curry _ spawn-stage ] 2each ] (parallel-each) ; inline : parallel-filter ( seq quot -- newseq ) - over >r pusher >r each r> r> like ; inline + over [ pusher [ parallel-each ] dip ] dip like ; inline : parallel-map ( seq quot -- newseq ) - [ curry future ] curry map future-values ; - inline + [future] map future-values ; inline : 2parallel-map ( seq1 seq2 quot -- newseq ) - [ 2curry future ] curry 2map future-values ; + '[ _ 2curry future ] 2map future-values ; + + ; inline + +: (parallel-cleave) ( quots -- quot-array spread-array ) + [ [future] ] map dup length (parallel-spread) ; inline + +PRIVATE> + +MACRO: parallel-cleave ( quots -- ) + (parallel-cleave) '[ _ cleave _ spread ] ; + +MACRO: parallel-spread ( quots -- ) + (parallel-cleave) '[ _ spread _ spread ] ; + +MACRO: parallel-napply ( quot n -- ) + [ [future] ] dip dup (parallel-spread) '[ _ _ napply _ spread ] ; diff --git a/basis/concurrency/conditions/conditions.factor b/basis/concurrency/conditions/conditions.factor index 43374d3127..11e624110c 100644 --- a/basis/concurrency/conditions/conditions.factor +++ b/basis/concurrency/conditions/conditions.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: deques threads kernel arrays sequences alarms ; +USING: deques threads kernel arrays sequences alarms fry ; IN: concurrency.conditions : notify-1 ( deque -- ) @@ -12,15 +12,18 @@ IN: concurrency.conditions : queue-timeout ( queue timeout -- alarm ) #! Add an alarm which removes the current thread from the #! queue, and resumes it, passing it a value of t. - >r [ self swap push-front* ] keep [ - [ delete-node ] [ drop node-value ] 2bi - t swap resume-with - ] 2curry r> later ; + [ + [ self swap push-front* ] keep '[ + _ _ + [ delete-node ] [ drop node-value ] 2bi + t swap resume-with + ] + ] dip later ; : wait ( queue timeout status -- ) over [ - >r queue-timeout [ drop ] r> suspend + [ queue-timeout [ drop ] ] dip suspend [ "Timeout" throw ] [ cancel-alarm ] if ] [ - >r drop [ push-front ] curry r> suspend drop + [ drop '[ _ push-front ] ] dip suspend drop ] if ; diff --git a/basis/concurrency/count-downs/count-downs.factor b/basis/concurrency/count-downs/count-downs.factor index c4bc92c688..d79cfbf1c9 100644 --- a/basis/concurrency/count-downs/count-downs.factor +++ b/basis/concurrency/count-downs/count-downs.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: dlists kernel math concurrency.promises -concurrency.mailboxes debugger accessors ; +concurrency.mailboxes debugger accessors fry ; IN: concurrency.count-downs ! http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CountDownLatch.html @@ -26,12 +26,12 @@ ERROR: count-down-already-done ; [ 1- >>n count-down-check ] if ; : await-timeout ( count-down timeout -- ) - >r promise>> r> ?promise-timeout ?linked t assert= ; + [ promise>> ] dip ?promise-timeout ?linked t assert= ; : await ( count-down -- ) f await-timeout ; : spawn-stage ( quot count-down -- ) - [ [ count-down ] curry compose ] keep + [ '[ @ _ count-down ] ] keep "Count down stage" swap promise>> mailbox>> spawn-linked-to drop ; diff --git a/basis/concurrency/distributed/distributed-tests.factor b/basis/concurrency/distributed/distributed-tests.factor index 528e1956b8..1087823aa0 100644 --- a/basis/concurrency/distributed/distributed-tests.factor +++ b/basis/concurrency/distributed/distributed-tests.factor @@ -15,7 +15,7 @@ concurrency.messaging continuations accessors prettyprint ; [ ] [ [ - receive first2 >r 3 + r> send + receive first2 [ 3 + ] dip send "thread-a" unregister-process ] "Thread A" spawn "thread-a" swap register-process diff --git a/basis/concurrency/exchangers/exchangers.factor b/basis/concurrency/exchangers/exchangers.factor index 6b44886eda..97b3c14fe4 100644 --- a/basis/concurrency/exchangers/exchangers.factor +++ b/basis/concurrency/exchangers/exchangers.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel threads boxes accessors ; +USING: kernel threads boxes accessors fry ; IN: concurrency.exchangers ! Motivated by @@ -14,8 +14,8 @@ TUPLE: exchanger thread object ; : exchange ( obj exchanger -- newobj ) dup thread>> occupied>> [ dup object>> box> - >r thread>> box> resume-with r> + [ thread>> box> resume-with ] dip ] [ [ object>> >box ] keep - [ thread>> >box ] curry "exchange" suspend + '[ _ thread>> >box ] "exchange" suspend ] if ; diff --git a/basis/concurrency/flags/flags-tests.factor b/basis/concurrency/flags/flags-tests.factor index 9d3f6de98c..a666293316 100644 --- a/basis/concurrency/flags/flags-tests.factor +++ b/basis/concurrency/flags/flags-tests.factor @@ -1,8 +1,8 @@ IN: concurrency.flags.tests USING: tools.test concurrency.flags concurrency.combinators -kernel threads locals accessors ; +kernel threads locals accessors calendar ; -:: flag-test-1 ( -- ) +:: flag-test-1 ( -- val ) [let | f [ ] | [ f raise-flag ] "Flag test" spawn drop f lower-flag @@ -13,14 +13,14 @@ kernel threads locals accessors ; :: flag-test-2 ( -- ) [let | f [ ] | - [ 1000 sleep f raise-flag ] "Flag test" spawn drop + [ 1 seconds sleep f raise-flag ] "Flag test" spawn drop f lower-flag f value>> ] ; [ f ] [ flag-test-2 ] unit-test -:: flag-test-3 ( -- ) +:: flag-test-3 ( -- val ) [let | f [ ] | f raise-flag f value>> @@ -28,7 +28,7 @@ kernel threads locals accessors ; [ t ] [ flag-test-3 ] unit-test -:: flag-test-4 ( -- ) +:: flag-test-4 ( -- val ) [let | f [ ] | [ f raise-flag ] "Flag test" spawn drop f wait-for-flag @@ -37,9 +37,9 @@ kernel threads locals accessors ; [ t ] [ flag-test-4 ] unit-test -:: flag-test-5 ( -- ) +:: flag-test-5 ( -- val ) [let | f [ ] | - [ 1000 sleep f raise-flag ] "Flag test" spawn drop + [ 1 seconds sleep f raise-flag ] "Flag test" spawn drop f wait-for-flag f value>> ] ; @@ -48,6 +48,6 @@ kernel threads locals accessors ; [ ] [ { 1 2 } - [ [ 1000 sleep raise-flag ] curry "Flag test" spawn drop ] + [ [ 1 seconds sleep raise-flag ] curry "Flag test" spawn drop ] [ [ wait-for-flag drop ] curry parallel-each ] bi ] unit-test diff --git a/basis/concurrency/flags/flags.factor b/basis/concurrency/flags/flags.factor index ec260961d0..c65171a3f0 100644 --- a/basis/concurrency/flags/flags.factor +++ b/basis/concurrency/flags/flags.factor @@ -11,7 +11,7 @@ TUPLE: flag value threads ; dup value>> [ drop ] [ t >>value threads>> notify-all ] if ; : wait-for-flag-timeout ( flag timeout -- ) - over value>> [ 2drop ] [ >r threads>> r> "flag" wait ] if ; + over value>> [ 2drop ] [ [ threads>> ] dip "flag" wait ] if ; : wait-for-flag ( flag -- ) f wait-for-flag-timeout ; diff --git a/basis/concurrency/futures/futures-docs.factor b/basis/concurrency/futures/futures-docs.factor index 22549c1720..3d2ac552de 100644 --- a/basis/concurrency/futures/futures-docs.factor +++ b/basis/concurrency/futures/futures-docs.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2005, 2008 Chris Double, Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: concurrency.promises concurrency.messaging kernel arrays -continuations help.markup help.syntax quotations ; +continuations help.markup help.syntax quotations calendar ; IN: concurrency.futures HELP: future @@ -11,8 +11,8 @@ $nl "The quotation begins with an empty data stack, an empty catch stack, and a name stack containing the global namespace only. This means that the only way to pass data to the quotation is to partially apply the data, for example using " { $link curry } " or " { $link compose } "." } ; HELP: ?future-timeout -{ $values { "future" future } { "timeout" "a timeout in milliseconds or " { $link f } } { "value" object } } -{ $description "Waits for a deferred computation to complete, blocking indefinitely if " { $snippet "timeout" } " is " { $link f } ", otherwise waiting up to " { $snippet "timeout" } " milliseconds." } +{ $values { "future" future } { "timeout" { $maybe duration } } { "value" object } } +{ $description "Waits for a deferred computation to complete, blocking indefinitely if " { $snippet "timeout" } " is " { $link f } ", otherwise waiting up to the " { $snippet "timeout" } " before throwing an error." } { $errors "Throws an error if the timeout expires before the computation completes. Also throws an error if the future quotation threw an error." } ; HELP: ?future diff --git a/basis/concurrency/futures/futures.factor b/basis/concurrency/futures/futures.factor index 132342aff1..a1f4f57af6 100644 --- a/basis/concurrency/futures/futures.factor +++ b/basis/concurrency/futures/futures.factor @@ -1,12 +1,12 @@ ! Copyright (C) 2005, 2008 Chris Double, Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: concurrency.promises concurrency.mailboxes kernel arrays -continuations accessors ; +continuations accessors fry ; IN: concurrency.futures : future ( quot -- future ) [ - [ [ >r call r> fulfill ] 2curry "Future" ] keep + [ '[ @ _ fulfill ] "Future" ] keep mailbox>> spawn-linked-to drop ] keep ; inline diff --git a/basis/concurrency/locks/locks-tests.factor b/basis/concurrency/locks/locks-tests.factor index 67f9bbb15a..8f82aa88ba 100644 --- a/basis/concurrency/locks/locks-tests.factor +++ b/basis/concurrency/locks/locks-tests.factor @@ -3,7 +3,7 @@ USING: tools.test concurrency.locks concurrency.count-downs concurrency.messaging concurrency.mailboxes locals kernel threads sequences calendar accessors ; -:: lock-test-0 ( -- ) +:: lock-test-0 ( -- v ) [let | v [ V{ } clone ] c [ 2 ] | @@ -27,7 +27,7 @@ threads sequences calendar accessors ; v ] ; -:: lock-test-1 ( -- ) +:: lock-test-1 ( -- v ) [let | v [ V{ } clone ] l [ ] c [ 2 ] | @@ -79,7 +79,7 @@ threads sequences calendar accessors ; [ ] [ dup [ [ ] with-read-lock ] with-write-lock ] unit-test -:: rw-lock-test-1 ( -- ) +:: rw-lock-test-1 ( -- v ) [let | l [ ] c [ 1 ] c' [ 1 ] @@ -100,7 +100,7 @@ threads sequences calendar accessors ; c await l [ 4 v push - 1000 sleep + 1 seconds sleep 5 v push ] with-write-lock c'' count-down @@ -129,7 +129,7 @@ threads sequences calendar accessors ; [ V{ 1 2 3 4 5 6 } ] [ rw-lock-test-1 ] unit-test -:: rw-lock-test-2 ( -- ) +:: rw-lock-test-2 ( -- v ) [let | l [ ] c [ 1 ] c' [ 2 ] @@ -139,7 +139,7 @@ threads sequences calendar accessors ; l [ 1 v push c count-down - 1000 sleep + 1 seconds sleep 2 v push ] with-write-lock c' count-down @@ -160,7 +160,7 @@ threads sequences calendar accessors ; [ V{ 1 2 3 } ] [ rw-lock-test-2 ] unit-test ! Test lock timeouts -:: lock-timeout-test ( -- ) +:: lock-timeout-test ( -- v ) [let | l [ ] | [ l [ 1 seconds sleep ] with-lock @@ -177,19 +177,6 @@ threads sequences calendar accessors ; thread>> name>> "Lock timeout-er" = ] must-fail-with -:: read/write-test ( -- ) - [let | l [ ] | - [ - l [ 1 seconds sleep ] with-lock - ] "Lock holder" spawn drop - - [ - l 1/10 seconds [ ] with-lock-timeout - ] "Lock timeout-er" spawn-linked drop - - receive - ] ; - [ dup [ 1 seconds [ ] with-write-lock-timeout diff --git a/basis/concurrency/locks/locks.factor b/basis/concurrency/locks/locks.factor index 8c1392dbfb..0094f3323d 100644 --- a/basis/concurrency/locks/locks.factor +++ b/basis/concurrency/locks/locks.factor @@ -1,7 +1,8 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: deques dlists kernel threads continuations math -concurrency.conditions combinators.short-circuit accessors ; +concurrency.conditions combinators.short-circuit accessors +locals ; IN: concurrency.locks ! Simple critical sections @@ -17,16 +18,16 @@ TUPLE: lock threads owner reentrant? ; : acquire-lock ( lock timeout -- ) over owner>> - [ 2dup >r threads>> r> "lock" wait ] when drop + [ 2dup [ threads>> ] dip "lock" wait ] when drop self >>owner drop ; : release-lock ( lock -- ) f >>owner threads>> notify-1 ; -: do-lock ( lock timeout quot acquire release -- ) - >r >r pick rot r> call ! use up timeout acquire - swap r> curry [ ] cleanup ; inline +:: do-lock ( lock timeout quot acquire release -- ) + lock timeout acquire call + quot lock release curry [ ] cleanup ; inline : (with-lock) ( lock timeout quot -- ) [ acquire-lock ] [ release-lock ] do-lock ; inline @@ -60,7 +61,7 @@ TUPLE: rw-lock readers writers reader# writer ; : acquire-read-lock ( lock timeout -- ) over writer>> - [ 2dup >r readers>> r> "read lock" wait ] when drop + [ 2dup [ readers>> ] dip "read lock" wait ] when drop add-reader ; : notify-writer ( lock -- ) @@ -75,7 +76,7 @@ TUPLE: rw-lock readers writers reader# writer ; : acquire-write-lock ( lock timeout -- ) over writer>> pick reader#>> 0 > or - [ 2dup >r writers>> r> "write lock" wait ] when drop + [ 2dup [ writers>> ] dip "write lock" wait ] when drop self >>writer drop ; : release-write-lock ( lock -- ) diff --git a/basis/concurrency/mailboxes/mailboxes.factor b/basis/concurrency/mailboxes/mailboxes.factor index 39b21e0943..63707041a2 100644 --- a/basis/concurrency/mailboxes/mailboxes.factor +++ b/basis/concurrency/mailboxes/mailboxes.factor @@ -4,7 +4,7 @@ IN: concurrency.mailboxes USING: dlists deques threads sequences continuations destructors namespaces math quotations words kernel arrays assocs init system concurrency.conditions accessors -debugger debugger.threads locals ; +debugger debugger.threads locals fry ; TUPLE: mailbox threads data disposed ; @@ -21,7 +21,7 @@ M: mailbox dispose* threads>> notify-all ; [ threads>> notify-all ] bi yield ; : wait-for-mailbox ( mailbox timeout -- ) - >r threads>> r> "mailbox" wait ; + [ threads>> ] dip "mailbox" wait ; :: block-unless-pred ( mailbox timeout pred: ( message -- ? ) -- ) mailbox check-disposed @@ -57,11 +57,11 @@ M: mailbox dispose* threads>> notify-all ; f mailbox-get-all-timeout ; : while-mailbox-empty ( mailbox quot -- ) - [ [ mailbox-empty? ] curry ] dip [ ] while ; inline + [ '[ _ mailbox-empty? ] ] dip [ ] while ; inline : mailbox-get-timeout? ( mailbox timeout pred -- obj ) [ block-unless-pred ] - [ nip >r data>> r> delete-node-if ] + [ [ drop data>> ] dip delete-node-if ] 3bi ; inline : mailbox-get? ( mailbox pred -- obj ) @@ -90,7 +90,7 @@ M: linked-thread error-in-thread [ ] [ supervisor>> ] bi mailbox-put ; : ( quot name mailbox -- thread' ) - >r linked-thread new-thread r> >>supervisor ; + [ linked-thread new-thread ] dip >>supervisor ; : spawn-linked-to ( quot name mailbox -- thread ) [ (spawn) ] keep ; diff --git a/basis/concurrency/messaging/messaging-docs.factor b/basis/concurrency/messaging/messaging-docs.factor index 6c9e530d9b..3bd2d330c3 100644 --- a/basis/concurrency/messaging/messaging-docs.factor +++ b/basis/concurrency/messaging/messaging-docs.factor @@ -8,20 +8,20 @@ HELP: send { $values { "message" object } { "thread" thread } } -{ $description "Send the message to the thread by placing it in the threades mailbox. This is an asynchronous operation and will return immediately. The receving thread will act on the message the next time it retrieves that item from its mailbox (usually using the " { $link receive } " word. The message can be any Factor object. For destinations that are instances of remote-thread the message must be a serializable Factor type." } +{ $description "Send the message to the thread by placing it in the threads mailbox. This is an asynchronous operation and will return immediately. The receving thread will act on the message the next time it retrieves that item from its mailbox (usually using the " { $link receive } " word. The message can be any Factor object. For destinations that are instances of remote-thread the message must be a serializable Factor type." } { $see-also receive receive-if } ; HELP: receive { $values { "message" object } } -{ $description "Return a message from the current threades mailbox. If the box is empty, suspend the thread until another thread places an item in the mailbox (usually via the " { $link send } " word." } +{ $description "Return a message from the current threads mailbox. If the box is empty, suspend the thread until another thread places an item in the mailbox (usually via the " { $link send } " word." } { $see-also send receive-if } ; HELP: receive-if { $values { "pred" "a predicate with stack effect " { $snippet "( obj -- ? )" } } { "message" object } } -{ $description "Return the first message from the current threades mailbox that satisfies the predicate. To satisfy the predicate, " { $snippet "pred" } " is called with the item on the stack and the predicate should leave a boolean indicating whether it was satisfied or not. If nothing in the mailbox satisfies the predicate then the thread will block until something does." } +{ $description "Return the first message from the current threads mailbox that satisfies the predicate. To satisfy the predicate, " { $snippet "pred" } " is called with the item on the stack and the predicate should leave a boolean indicating whether it was satisfied or not. If nothing in the mailbox satisfies the predicate then the thread will block until something does." } { $see-also send receive } ; HELP: spawn-linked @@ -29,7 +29,7 @@ HELP: spawn-linked { "name" string } { "thread" thread } } -{ $description "Start a thread which runs the given quotation. If that quotation throws an error which is not caught then the error will get propagated to the thread that spawned it. This can be used to set up 'supervisor' threades that restart child threades that crash due to uncaught errors.\n" } +{ $description "Start a thread which runs the given quotation. If that quotation throws an error which is not caught then the error will get propagated to the thread that spawned it. This can be used to set up 'supervisor' threads that restart child threads that crash due to uncaught errors.\n" } { $see-also spawn } ; ARTICLE: { "concurrency" "messaging" } "Sending and receiving messages" @@ -55,7 +55,7 @@ ARTICLE: { "concurrency" "synchronous-sends" } "Synchronous sends" { $example "USING: concurrency.messaging kernel threads ;" ": pong-server ( -- )" - " receive >r \"pong\" r> reply-synchronous ;" + " receive [ \"pong\" ] dip reply-synchronous ;" "[ pong-server t ] \"pong-server\" spawn-server" "\"ping\" swap send-synchronous ." "\"pong\"" @@ -64,7 +64,7 @@ ARTICLE: { "concurrency" "synchronous-sends" } "Synchronous sends" ARTICLE: { "concurrency" "exceptions" } "Linked exceptions" "A thread can handle exceptions using the standard Factor exception handling mechanism. If an exception is uncaught the thread will terminate. For example:" { $code "[ 1 0 / \"This will not print\" print ] \"division-by-zero\" spawn" } -"Processes can be linked so that a parent thread can receive the exception that caused the child thread to terminate. In this way 'supervisor' threades can be created that are notified when child threades terminate and possibly restart them." +"Processes can be linked so that a parent thread can receive the exception that caused the child thread to terminate. In this way 'supervisor' threads can be created that are notified when child threads terminate and possibly restart them." { $subsection spawn-linked } "This will create a unidirectional link, such that if an uncaught exception causes the child to terminate, the parent thread can catch it:" { $code "[" @@ -74,11 +74,11 @@ ARTICLE: { "concurrency" "exceptions" } "Linked exceptions" "Exceptions are only raised in the parent when the parent does a " { $link receive } " or " { $link receive-if } ". This is because the exception is sent from the child to the parent as a message." ; ARTICLE: "concurrency.messaging" "Message-passing concurrency" -"The " { $vocab-link "concurrency.messaging" } " vocabulary is based upon the style of concurrency used in systems like Erlang and Termite. It is built on top of the standard Factor lightweight thread system." +"The " { $vocab-link "concurrency.messaging" } " vocabulary is based upon the style of concurrency used in systems like Erlang and Termite. It is built on top of " { $link "threads" } "." $nl -"A concurrency oriented program is one in which multiple threades run simultaneously in a single Factor image or across multiple running Factor instances. The threades can communicate with each other by asynchronous message sends." +"A concurrency-oriented program is one in which multiple threads run simultaneously in a single Factor image or across multiple running Factor instances. The threads can communicate with each other by asynchronous message sends." $nl -"Although threades can share data via Factor's mutable data structures it is not recommended to mix shared state with message passing as it can lead to confusing code." +"Although threads can share data via Factor's mutable data structures it is not recommended to mix shared state with message passing as it can lead to confusing code." { $subsection { "concurrency" "messaging" } } { $subsection { "concurrency" "synchronous-sends" } } { $subsection { "concurrency" "exceptions" } } ; diff --git a/basis/concurrency/messaging/messaging.factor b/basis/concurrency/messaging/messaging.factor index 9aeb24ed72..7a00f62e9e 100644 --- a/basis/concurrency/messaging/messaging.factor +++ b/basis/concurrency/messaging/messaging.factor @@ -1,10 +1,7 @@ ! Copyright (C) 2005, 2008 Chris Double, Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -! -! Concurrency library for Factor, based on Erlang/Termite style -! concurrency. USING: kernel threads concurrency.mailboxes continuations -namespaces assocs accessors summary ; +namespaces assocs accessors summary fry ; IN: concurrency.messaging GENERIC: send ( message thread -- ) @@ -32,7 +29,7 @@ M: thread send ( message thread -- ) my-mailbox -rot mailbox-get-timeout? ?linked ; inline : rethrow-linked ( error process supervisor -- ) - >r r> send ; + [ ] dip send ; : spawn-linked ( quot name -- thread ) my-mailbox spawn-linked-to ; @@ -48,9 +45,7 @@ TUPLE: reply data tag ; tag>> \ reply boa ; : synchronous-reply? ( response synchronous -- ? ) - over reply? - [ >r tag>> r> tag>> = ] - [ 2drop f ] if ; + over reply? [ [ tag>> ] bi@ = ] [ 2drop f ] if ; ERROR: cannot-send-synchronous-to-self message thread ; @@ -61,8 +56,8 @@ M: cannot-send-synchronous-to-self summary dup self eq? [ cannot-send-synchronous-to-self ] [ - >r dup r> send - [ synchronous-reply? ] curry receive-if + [ dup ] dip send + '[ _ synchronous-reply? ] receive-if data>> ] if ; diff --git a/basis/concurrency/promises/promises-docs.factor b/basis/concurrency/promises/promises-docs.factor index be7a8cf65b..8e160842a9 100644 --- a/basis/concurrency/promises/promises-docs.factor +++ b/basis/concurrency/promises/promises-docs.factor @@ -13,7 +13,7 @@ HELP: promise-fulfilled? HELP: ?promise-timeout { $values { "promise" promise } { "timeout" { $maybe duration } } { "result" object } } -{ $description "Waits for another thread to fulfill a promise, returning immediately if the promise has already been fulfilled. A timeout of " { $link f } " indicates that the thread may block indefinitely, otherwise it will wait up to " { $snippet "timeout" } " milliseconds." } +{ $description "Waits for another thread to fulfill a promise, returning immediately if the promise has already been fulfilled. A timeout of " { $link f } " indicates that the thread may block indefinitely, otherwise it will wait up to the " { $snippet "timeout" } " before throwing an error." } { $errors "Throws an error if the timeout expires before the promise has been fulfilled." } ; HELP: ?promise diff --git a/basis/concurrency/promises/promises.factor b/basis/concurrency/promises/promises.factor index 382697e04f..2ff338c4e3 100644 --- a/basis/concurrency/promises/promises.factor +++ b/basis/concurrency/promises/promises.factor @@ -20,7 +20,7 @@ ERROR: promise-already-fulfilled promise ; ] if ; : ?promise-timeout ( promise timeout -- result ) - >r mailbox>> r> block-if-empty mailbox-peek ; + [ mailbox>> ] dip block-if-empty mailbox-peek ; : ?promise ( promise -- result ) f ?promise-timeout ; diff --git a/basis/concurrency/semaphores/semaphores.factor b/basis/concurrency/semaphores/semaphores.factor index 1b55c7afa5..59518f4c8d 100644 --- a/basis/concurrency/semaphores/semaphores.factor +++ b/basis/concurrency/semaphores/semaphores.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: dlists kernel threads math concurrency.conditions -continuations accessors summary ; +continuations accessors summary locals fry ; IN: concurrency.semaphores TUPLE: semaphore count threads ; @@ -30,9 +30,9 @@ M: negative-count-semaphore summary [ 1+ ] change-count threads>> notify-1 ; -: with-semaphore-timeout ( semaphore timeout quot -- ) - pick rot acquire-timeout swap - [ release ] curry [ ] cleanup ; inline +:: with-semaphore-timeout ( semaphore timeout quot -- ) + semaphore timeout acquire-timeout + quot [ semaphore release ] [ ] cleanup ; inline : with-semaphore ( semaphore quot -- ) - over acquire swap [ release ] curry [ ] cleanup ; inline + swap dup acquire '[ _ release ] [ ] cleanup ; inline diff --git a/basis/core-foundation/arrays/arrays-docs.factor b/basis/core-foundation/arrays/arrays-docs.factor new file mode 100644 index 0000000000..36d14a8660 --- /dev/null +++ b/basis/core-foundation/arrays/arrays-docs.factor @@ -0,0 +1,11 @@ +USING: help.syntax help.markup arrays alien ; +IN: core-foundation.arrays + +HELP: CF>array +{ $values { "alien" "a " { $snippet "CFArray" } } { "array" "an array of " { $link alien } " instances" } } +{ $description "Creates a Factor array from a Core Foundation array." } ; + +HELP: +{ $values { "seq" "a sequence of " { $link alien } " instances" } { "alien" "a " { $snippet "CFArray" } } } +{ $description "Creates a Core Foundation array from a Factor array." } ; + diff --git a/basis/core-foundation/arrays/arrays.factor b/basis/core-foundation/arrays/arrays.factor new file mode 100644 index 0000000000..3708059f2b --- /dev/null +++ b/basis/core-foundation/arrays/arrays.factor @@ -0,0 +1,22 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.syntax kernel sequences ; +IN: core-foundation.arrays + +TYPEDEF: void* CFArrayRef + +FUNCTION: CFArrayRef CFArrayCreateMutable ( CFAllocatorRef allocator, CFIndex capacity, void* callbacks ) ; + +FUNCTION: void* CFArrayGetValueAtIndex ( CFArrayRef array, CFIndex idx ) ; + +FUNCTION: void CFArraySetValueAtIndex ( CFArrayRef array, CFIndex index, void* value ) ; + +FUNCTION: CFIndex CFArrayGetCount ( CFArrayRef array ) ; + +: CF>array ( alien -- array ) + dup CFArrayGetCount [ CFArrayGetValueAtIndex ] with map ; + +: ( seq -- alien ) + [ f swap length f CFArrayCreateMutable ] keep + [ length ] keep + [ [ dupd ] dip CFArraySetValueAtIndex ] 2each ; diff --git a/basis/core-foundation/arrays/tags.txt b/basis/core-foundation/arrays/tags.txt new file mode 100644 index 0000000000..2320bdd648 --- /dev/null +++ b/basis/core-foundation/arrays/tags.txt @@ -0,0 +1,2 @@ +unportable +bindings diff --git a/basis/core-foundation/bundles/bundles-docs.factor b/basis/core-foundation/bundles/bundles-docs.factor new file mode 100644 index 0000000000..baa1b4d5df --- /dev/null +++ b/basis/core-foundation/bundles/bundles-docs.factor @@ -0,0 +1,11 @@ +USING: help.syntax help.markup ; +IN: core-foundation.bundles + +HELP: +{ $values { "string" "a pathname string" } { "bundle" "a " { $snippet "CFBundle" } } } +{ $description "Creates a new " { $snippet "CFBundle" } "." } ; + +HELP: load-framework +{ $values { "name" "a pathname string" } } +{ $description "Loads a Core Foundation framework." } ; + diff --git a/basis/core-foundation/bundles/bundles.factor b/basis/core-foundation/bundles/bundles.factor new file mode 100644 index 0000000000..790f1766c3 --- /dev/null +++ b/basis/core-foundation/bundles/bundles.factor @@ -0,0 +1,23 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.syntax kernel sequences core-foundation +core-foundation.urls ; +IN: core-foundation.bundles + +TYPEDEF: void* CFBundleRef + +FUNCTION: CFBundleRef CFBundleCreate ( CFAllocatorRef allocator, CFURLRef bundleURL ) ; + +FUNCTION: Boolean CFBundleLoadExecutable ( CFBundleRef bundle ) ; + +: ( string -- bundle ) + t [ + f swap CFBundleCreate + ] keep CFRelease ; + +: load-framework ( name -- ) + dup [ + CFBundleLoadExecutable drop + ] [ + "Cannot load bundle named " prepend throw + ] ?if ; diff --git a/basis/core-foundation/bundles/tags.txt b/basis/core-foundation/bundles/tags.txt new file mode 100644 index 0000000000..2320bdd648 --- /dev/null +++ b/basis/core-foundation/bundles/tags.txt @@ -0,0 +1,2 @@ +unportable +bindings diff --git a/basis/core-foundation/core-foundation-docs.factor b/basis/core-foundation/core-foundation-docs.factor index d577c523cf..c1783cb92b 100644 --- a/basis/core-foundation/core-foundation-docs.factor +++ b/basis/core-foundation/core-foundation-docs.factor @@ -1,42 +1,6 @@ USING: alien strings arrays help.markup help.syntax destructors ; IN: core-foundation -HELP: CF>array -{ $values { "alien" "a " { $snippet "CFArray" } } { "array" "an array of " { $link alien } " instances" } } -{ $description "Creates a Factor array from a Core Foundation array." } ; - -HELP: -{ $values { "seq" "a sequence of " { $link alien } " instances" } { "alien" "a " { $snippet "CFArray" } } } -{ $description "Creates a Core Foundation array from a Factor array." } ; - -HELP: -{ $values { "string" string } { "alien" "a " { $snippet "CFString" } } } -{ $description "Creates a Core Foundation string from a Factor string." } ; - -HELP: CF>string -{ $values { "alien" "a " { $snippet "CFString" } } { "string" string } } -{ $description "Creates a Factor string from a Core Foundation string." } ; - -HELP: CF>string-array -{ $values { "alien" "a " { $snippet "CFArray" } " of " { $snippet "CFString" } " instances" } { "seq" string } } -{ $description "Creates an array of Factor strings from a " { $snippet "CFArray" } " of " { $snippet "CFString" } "s." } ; - -HELP: -{ $values { "string" "a pathname string" } { "dir?" "a boolean indicating if the pathname is a directory" } { "url" "a " { $snippet "CFURL" } } } -{ $description "Creates a new " { $snippet "CFURL" } " pointing to the given local pathname." } ; - -HELP: -{ $values { "string" "a URL string" } { "url" "a " { $snippet "CFURL" } } } -{ $description "Creates a new " { $snippet "CFURL" } "." } ; - -HELP: -{ $values { "string" "a pathname string" } { "bundle" "a " { $snippet "CFBundle" } } } -{ $description "Creates a new " { $snippet "CFBundle" } "." } ; - -HELP: load-framework -{ $values { "name" "a pathname string" } } -{ $description "Loads a Core Foundation framework." } ; - HELP: &CFRelease { $values { "alien" "Pointer to a Core Foundation object" } } { $description "Marks the given Core Foundation object for unconditional release via " { $link CFRelease } " at the end of the enclosing " { $link with-destructors } " scope." } ; @@ -46,24 +10,3 @@ HELP: |CFRelease { $description "Marks the given Core Foundation object for release via " { $link CFRelease } " in the event of an error at the end of the enclosing " { $link with-destructors } " scope." } ; { CFRelease |CFRelease &CFRelease } related-words - -ARTICLE: "core-foundation" "Core foundation utilities" -"The " { $vocab-link "core-foundation" } " vocabulary defines bindings for some frequently-used Core Foundation functions. It also provides some utility words." -$nl -"Strings:" -{ $subsection } -{ $subsection CF>string } -"Arrays:" -{ $subsection } -{ $subsection CF>array } -{ $subsection CF>string-array } -"URLs:" -{ $subsection } -{ $subsection } -"Frameworks:" -{ $subsection load-framework } -"Memory management:" -{ $subsection &CFRelease } -{ $subsection |CFRelease } ; - -ABOUT: "core-foundation" diff --git a/basis/core-foundation/core-foundation.factor b/basis/core-foundation/core-foundation.factor index 00bf73e9dd..0f64c0666f 100644 --- a/basis/core-foundation/core-foundation.factor +++ b/basis/core-foundation/core-foundation.factor @@ -1,148 +1,32 @@ ! Copyright (C) 2006, 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. -USING: alien alien.c-types alien.strings alien.syntax kernel -math sequences io.encodings.utf16 destructors accessors combinators ; +USING: alien.syntax destructors accessors kernel ; IN: core-foundation -TYPEDEF: void* CFAllocatorRef -TYPEDEF: void* CFArrayRef -TYPEDEF: void* CFDataRef -TYPEDEF: void* CFDictionaryRef -TYPEDEF: void* CFMutableDictionaryRef -TYPEDEF: void* CFNumberRef -TYPEDEF: void* CFBundleRef -TYPEDEF: void* CFSetRef -TYPEDEF: void* CFStringRef -TYPEDEF: void* CFURLRef -TYPEDEF: void* CFUUIDRef TYPEDEF: void* CFTypeRef + +TYPEDEF: void* CFAllocatorRef +: kCFAllocatorDefault f ; inline + TYPEDEF: bool Boolean TYPEDEF: long CFIndex TYPEDEF: int SInt32 TYPEDEF: uint UInt32 TYPEDEF: ulong CFTypeID +TYPEDEF: UInt32 CFOptionFlags TYPEDEF: double CFTimeInterval TYPEDEF: double CFAbsoluteTime -TYPEDEF: int CFNumberType -: kCFNumberSInt8Type 1 ; inline -: kCFNumberSInt16Type 2 ; inline -: kCFNumberSInt32Type 3 ; inline -: kCFNumberSInt64Type 4 ; inline -: kCFNumberFloat32Type 5 ; inline -: kCFNumberFloat64Type 6 ; inline -: kCFNumberCharType 7 ; inline -: kCFNumberShortType 8 ; inline -: kCFNumberIntType 9 ; inline -: kCFNumberLongType 10 ; inline -: kCFNumberLongLongType 11 ; inline -: kCFNumberFloatType 12 ; inline -: kCFNumberDoubleType 13 ; inline -: kCFNumberCFIndexType 14 ; inline -: kCFNumberNSIntegerType 15 ; inline -: kCFNumberCGFloatType 16 ; inline -: kCFNumberMaxType 16 ; inline - -TYPEDEF: int CFPropertyListMutabilityOptions -: kCFPropertyListImmutable 0 ; inline -: kCFPropertyListMutableContainers 1 ; inline -: kCFPropertyListMutableContainersAndLeaves 2 ; inline - -FUNCTION: CFArrayRef CFArrayCreateMutable ( CFAllocatorRef allocator, CFIndex capacity, void* callbacks ) ; - -FUNCTION: void* CFArrayGetValueAtIndex ( CFArrayRef array, CFIndex idx ) ; - -FUNCTION: void CFArraySetValueAtIndex ( CFArrayRef array, CFIndex index, void* value ) ; - -FUNCTION: CFIndex CFArrayGetCount ( CFArrayRef array ) ; - -: kCFURLPOSIXPathStyle 0 ; inline -: kCFAllocatorDefault f ; inline - -FUNCTION: CFURLRef CFURLCreateWithFileSystemPath ( CFAllocatorRef allocator, CFStringRef filePath, int pathStyle, Boolean isDirectory ) ; - -FUNCTION: CFURLRef CFURLCreateWithString ( CFAllocatorRef allocator, CFStringRef string, CFURLRef base ) ; - -FUNCTION: CFURLRef CFURLCopyFileSystemPath ( CFURLRef url, int pathStyle ) ; - -FUNCTION: CFStringRef CFStringCreateWithCharacters ( CFAllocatorRef allocator, wchar_t* cStr, CFIndex numChars ) ; - -FUNCTION: CFIndex CFStringGetLength ( CFStringRef theString ) ; - -FUNCTION: void CFStringGetCharacters ( void* theString, CFIndex start, CFIndex length, void* buffer ) ; - -FUNCTION: CFNumberRef CFNumberCreate ( CFAllocatorRef allocator, CFNumberType theType, void* valuePtr ) ; - -FUNCTION: CFDataRef CFDataCreate ( CFAllocatorRef allocator, uchar* bytes, CFIndex length ) ; - -FUNCTION: CFBundleRef CFBundleCreate ( CFAllocatorRef allocator, CFURLRef bundleURL ) ; - -FUNCTION: Boolean CFBundleLoadExecutable ( CFBundleRef bundle ) ; - FUNCTION: CFTypeRef CFRetain ( CFTypeRef cf ) ; + FUNCTION: void CFRelease ( CFTypeRef cf ) ; -FUNCTION: CFTypeID CFGetTypeID ( CFTypeRef cf ) ; - -: CF>array ( alien -- array ) - dup CFArrayGetCount [ CFArrayGetValueAtIndex ] with map ; - -: ( seq -- alien ) - [ f swap length f CFArrayCreateMutable ] keep - [ length ] keep - [ >r dupd r> CFArraySetValueAtIndex ] 2each ; - -: ( string -- alien ) - f swap dup length CFStringCreateWithCharacters ; - -: CF>string ( alien -- string ) - dup CFStringGetLength 1+ "ushort" [ - >r 0 over CFStringGetLength r> CFStringGetCharacters - ] keep utf16n alien>string ; - -: CF>string-array ( alien -- seq ) - CF>array [ CF>string ] map ; - -: ( seq -- alien ) - [ ] map dup swap [ CFRelease ] each ; - -: ( string dir? -- url ) - >r f over kCFURLPOSIXPathStyle - r> CFURLCreateWithFileSystemPath swap CFRelease ; - -: ( string -- url ) - - [ f swap f CFURLCreateWithString ] keep - CFRelease ; - -: ( string -- bundle ) - t [ - f swap CFBundleCreate - ] keep CFRelease ; - -GENERIC: ( number -- alien ) -M: integer - [ f kCFNumberLongLongType ] dip CFNumberCreate ; -M: float - [ f kCFNumberDoubleType ] dip CFNumberCreate ; -M: t - drop f kCFNumberIntType 1 CFNumberCreate ; -M: f - drop f kCFNumberIntType 0 CFNumberCreate ; - -: ( byte-array -- alien ) - [ f ] dip dup length CFDataCreate ; - -: load-framework ( name -- ) - dup [ - CFBundleLoadExecutable drop - ] [ - "Cannot load bundle named " prepend throw - ] ?if ; - TUPLE: CFRelease-destructor alien disposed ; + M: CFRelease-destructor dispose* alien>> CFRelease ; + : &CFRelease ( alien -- alien ) dup f CFRelease-destructor boa &dispose drop ; inline + : |CFRelease ( alien -- alien ) dup f CFRelease-destructor boa |dispose drop ; inline diff --git a/basis/core-foundation/data/data.factor b/basis/core-foundation/data/data.factor new file mode 100644 index 0000000000..043fb905ad --- /dev/null +++ b/basis/core-foundation/data/data.factor @@ -0,0 +1,58 @@ +! Copyright (C) 2008 Joe Groff. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.syntax alien.c-types sequences kernel math ; +IN: core-foundation.data + +TYPEDEF: void* CFDataRef +TYPEDEF: void* CFDictionaryRef +TYPEDEF: void* CFMutableDictionaryRef +TYPEDEF: void* CFNumberRef +TYPEDEF: void* CFSetRef +TYPEDEF: void* CFUUIDRef + +TYPEDEF: int CFNumberType +: kCFNumberSInt8Type 1 ; inline +: kCFNumberSInt16Type 2 ; inline +: kCFNumberSInt32Type 3 ; inline +: kCFNumberSInt64Type 4 ; inline +: kCFNumberFloat32Type 5 ; inline +: kCFNumberFloat64Type 6 ; inline +: kCFNumberCharType 7 ; inline +: kCFNumberShortType 8 ; inline +: kCFNumberIntType 9 ; inline +: kCFNumberLongType 10 ; inline +: kCFNumberLongLongType 11 ; inline +: kCFNumberFloatType 12 ; inline +: kCFNumberDoubleType 13 ; inline +: kCFNumberCFIndexType 14 ; inline +: kCFNumberNSIntegerType 15 ; inline +: kCFNumberCGFloatType 16 ; inline +: kCFNumberMaxType 16 ; inline + +TYPEDEF: int CFPropertyListMutabilityOptions +: kCFPropertyListImmutable 0 ; inline +: kCFPropertyListMutableContainers 1 ; inline +: kCFPropertyListMutableContainersAndLeaves 2 ; inline + +FUNCTION: CFNumberRef CFNumberCreate ( CFAllocatorRef allocator, CFNumberType theType, void* valuePtr ) ; + +FUNCTION: CFDataRef CFDataCreate ( CFAllocatorRef allocator, uchar* bytes, CFIndex length ) ; + +FUNCTION: CFTypeID CFGetTypeID ( CFTypeRef cf ) ; + +GENERIC: ( number -- alien ) + +M: integer + [ f kCFNumberLongLongType ] dip CFNumberCreate ; + +M: float + [ f kCFNumberDoubleType ] dip CFNumberCreate ; + +M: t + drop f kCFNumberIntType 1 CFNumberCreate ; + +M: f + drop f kCFNumberIntType 0 CFNumberCreate ; + +: ( byte-array -- alien ) + [ f ] dip dup length CFDataCreate ; diff --git a/basis/core-foundation/data/tags.txt b/basis/core-foundation/data/tags.txt new file mode 100644 index 0000000000..2320bdd648 --- /dev/null +++ b/basis/core-foundation/data/tags.txt @@ -0,0 +1,2 @@ +unportable +bindings diff --git a/basis/core-foundation/file-descriptors/file-descriptors.factor b/basis/core-foundation/file-descriptors/file-descriptors.factor new file mode 100644 index 0000000000..29c4219678 --- /dev/null +++ b/basis/core-foundation/file-descriptors/file-descriptors.factor @@ -0,0 +1,32 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.syntax kernel math.bitwise core-foundation ; +IN: core-foundation.file-descriptors + +TYPEDEF: void* CFFileDescriptorRef +TYPEDEF: int CFFileDescriptorNativeDescriptor +TYPEDEF: void* CFFileDescriptorCallBack + +FUNCTION: CFFileDescriptorRef CFFileDescriptorCreate ( + CFAllocatorRef allocator, + CFFileDescriptorNativeDescriptor fd, + Boolean closeOnInvalidate, + CFFileDescriptorCallBack callout, + CFFileDescriptorContext* context +) ; + +: kCFFileDescriptorReadCallBack 1 ; inline +: kCFFileDescriptorWriteCallBack 2 ; inline + +FUNCTION: void CFFileDescriptorEnableCallBacks ( + CFFileDescriptorRef f, + CFOptionFlags callBackTypes +) ; + +: enable-all-callbacks ( fd -- ) + { kCFFileDescriptorReadCallBack kCFFileDescriptorWriteCallBack } flags + CFFileDescriptorEnableCallBacks ; + +: ( fd callback -- handle ) + [ f swap ] [ t swap ] bi* f CFFileDescriptorCreate + [ "CFFileDescriptorCreate failed" throw ] unless* ; diff --git a/basis/core-foundation/file-descriptors/tags.txt b/basis/core-foundation/file-descriptors/tags.txt new file mode 100644 index 0000000000..2320bdd648 --- /dev/null +++ b/basis/core-foundation/file-descriptors/tags.txt @@ -0,0 +1,2 @@ +unportable +bindings diff --git a/basis/core-foundation/fsevents/fsevents.factor b/basis/core-foundation/fsevents/fsevents.factor index 6bec4b23c0..7ed040b455 100644 --- a/basis/core-foundation/fsevents/fsevents.factor +++ b/basis/core-foundation/fsevents/fsevents.factor @@ -2,9 +2,10 @@ ! See http://factorcode.org/license.txt for BSD license. USING: alien alien.c-types alien.strings alien.syntax kernel math sequences namespaces make assocs init accessors -continuations combinators core-foundation -core-foundation.run-loop core-foundation.run-loop.thread -io.encodings.utf8 destructors ; +continuations combinators io.encodings.utf8 destructors locals +arrays specialized-arrays.direct.alien +specialized-arrays.direct.int specialized-arrays.direct.longlong +core-foundation core-foundation.run-loop core-foundation.strings ; IN: core-foundation.fsevents : kFSEventStreamCreateFlagUseCFTypes 2 ; inline @@ -105,19 +106,18 @@ FUNCTION: CFStringRef FSEventStreamCopyDescription ( FSEventStreamRef streamRef "FSEventStreamContext" [ set-FSEventStreamContext-info ] keep ; -: ( callback info paths latency flags -- event-stream ) - >r >r >r >r >r +:: ( callback info paths latency flags -- event-stream ) f ! allocator - r> ! callback - r> make-FSEventStreamContext - r> ! paths + callback + info make-FSEventStreamContext + paths FSEventStreamEventIdSinceNow ! sinceWhen - r> ! latency - r> ! flags + latency + flags FSEventStreamCreate ; : kCFRunLoopCommonModes ( -- string ) - "kCFRunLoopCommonModes" f dlsym *void* ; + &: kCFRunLoopCommonModes *void* ; : schedule-event-stream ( event-stream -- ) CFRunLoopGetMain @@ -161,13 +161,12 @@ SYMBOL: event-stream-callbacks : remove-event-source-callback ( id -- ) event-stream-callbacks get delete-at ; -: >event-triple ( n eventPaths eventFlags eventIds -- triple ) - [ - >r >r >r dup dup - r> void*-nth utf8 alien>string , - r> int-nth , - r> longlong-nth , - ] { } make ; +:: (master-event-source-callback) ( eventStream info numEvents eventPaths eventFlags eventIds -- ) + eventPaths numEvents [ utf8 alien>string ] { } map-as + eventFlags numEvents + eventIds numEvents + 3array flip + info event-stream-callbacks get at [ drop ] or call ; : master-event-source-callback ( -- alien ) "void" @@ -179,19 +178,15 @@ SYMBOL: event-stream-callbacks "FSEventStreamEventFlags*" "FSEventStreamEventId*" } - "cdecl" [ - [ >event-triple ] 3curry map - swap event-stream-callbacks get at - dup [ call drop ] [ 3drop ] if - ] alien-callback ; + "cdecl" [ (master-event-source-callback) ] alien-callback ; TUPLE: event-stream info handle disposed ; : ( quot paths latency flags -- event-stream ) - >r >r >r - add-event-source-callback dup - >r master-event-source-callback r> - r> r> r> + [ + add-event-source-callback dup + [ master-event-source-callback ] dip + ] 3dip dup enable-event-stream f event-stream boa ; diff --git a/basis/core-foundation/run-loop/run-loop.factor b/basis/core-foundation/run-loop/run-loop.factor index e30cc2eb60..475991a246 100644 --- a/basis/core-foundation/run-loop/run-loop.factor +++ b/basis/core-foundation/run-loop/run-loop.factor @@ -1,7 +1,8 @@ ! Copyright (C) 2008 Slava Pestov ! See http://factorcode.org/license.txt for BSD license. -USING: alien.syntax kernel threads init namespaces alien -core-foundation ; +USING: alien alien.syntax kernel namespaces core-foundation +core-foundation.strings core-foundation.file-descriptors +core-foundation.timers ; IN: core-foundation.run-loop : kCFRunLoopRunFinished 1 ; inline @@ -10,6 +11,7 @@ IN: core-foundation.run-loop : kCFRunLoopRunHandledSource 4 ; inline TYPEDEF: void* CFRunLoopRef +TYPEDEF: void* CFRunLoopSourceRef FUNCTION: CFRunLoopRef CFRunLoopGetMain ( ) ; FUNCTION: CFRunLoopRef CFRunLoopGetCurrent ( ) ; @@ -20,6 +22,36 @@ FUNCTION: SInt32 CFRunLoopRunInMode ( Boolean returnAfterSourceHandled ) ; +FUNCTION: CFRunLoopSourceRef CFFileDescriptorCreateRunLoopSource ( + CFAllocatorRef allocator, + CFFileDescriptorRef f, + CFIndex order +) ; + +FUNCTION: void CFRunLoopAddSource ( + CFRunLoopRef rl, + CFRunLoopSourceRef source, + CFStringRef mode +) ; + +FUNCTION: void CFRunLoopRemoveSource ( + CFRunLoopRef rl, + CFRunLoopSourceRef source, + CFStringRef mode +) ; + +FUNCTION: void CFRunLoopAddTimer ( + CFRunLoopRef rl, + CFRunLoopTimerRef timer, + CFStringRef mode +) ; + +FUNCTION: void CFRunLoopRemoveTimer ( + CFRunLoopRef rl, + CFRunLoopTimerRef timer, + CFStringRef mode +) ; + : CFRunLoopDefaultMode ( -- alien ) #! Ugly, but we don't have static NSStrings \ CFRunLoopDefaultMode get-global dup expired? [ @@ -27,11 +59,3 @@ FUNCTION: SInt32 CFRunLoopRunInMode ( "kCFRunLoopDefaultMode" dup \ CFRunLoopDefaultMode set-global ] when ; - -: run-loop-thread ( -- ) - CFRunLoopDefaultMode 0 f CFRunLoopRunInMode - kCFRunLoopRunHandledSource = [ 1000 sleep ] unless - run-loop-thread ; - -: start-run-loop-thread ( -- ) - [ run-loop-thread t ] "CFRunLoop dispatcher" spawn-server drop ; diff --git a/basis/core-foundation/run-loop/thread/summary.txt b/basis/core-foundation/run-loop/thread/summary.txt deleted file mode 100644 index e5818b3d78..0000000000 --- a/basis/core-foundation/run-loop/thread/summary.txt +++ /dev/null @@ -1 +0,0 @@ -Vocabulary with init hook for running CoreFoundation event loop diff --git a/basis/core-foundation/run-loop/thread/thread.factor b/basis/core-foundation/run-loop/thread/thread.factor deleted file mode 100644 index 326226ec0e..0000000000 --- a/basis/core-foundation/run-loop/thread/thread.factor +++ /dev/null @@ -1,8 +0,0 @@ -! Copyright (C) 2008 Slava Pestov -! See http://factorcode.org/license.txt for BSD license. -USING: init core-foundation.run-loop ; -IN: core-foundation.run-loop.thread - -! Load this vocabulary if you need a run loop running. - -[ start-run-loop-thread ] "core-foundation.run-loop.thread" add-init-hook diff --git a/basis/core-foundation/strings/strings-docs.factor b/basis/core-foundation/strings/strings-docs.factor new file mode 100644 index 0000000000..4c12fb5d52 --- /dev/null +++ b/basis/core-foundation/strings/strings-docs.factor @@ -0,0 +1,14 @@ +USING: help.syntax help.markup strings ; +IN: core-foundation.strings + +HELP: +{ $values { "string" string } { "alien" "a " { $snippet "CFString" } } } +{ $description "Creates a Core Foundation string from a Factor string." } ; + +HELP: CF>string +{ $values { "alien" "a " { $snippet "CFString" } } { "string" string } } +{ $description "Creates a Factor string from a Core Foundation string." } ; + +HELP: CF>string-array +{ $values { "alien" "a " { $snippet "CFArray" } " of " { $snippet "CFString" } " instances" } { "seq" string } } +{ $description "Creates an array of Factor strings from a " { $snippet "CFArray" } " of " { $snippet "CFString" } "s." } ; diff --git a/basis/core-foundation/strings/strings-tests.factor b/basis/core-foundation/strings/strings-tests.factor new file mode 100644 index 0000000000..39d5ee6ac0 --- /dev/null +++ b/basis/core-foundation/strings/strings-tests.factor @@ -0,0 +1,9 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: core-foundation.strings core-foundation tools.test kernel ; +IN: core-foundation + +[ ] [ "Hello" CFRelease ] unit-test +[ "Hello" ] [ "Hello" [ CF>string ] [ CFRelease ] bi ] unit-test +[ "Hello\u003456" ] [ "Hello\u003456" [ CF>string ] [ CFRelease ] bi ] unit-test +[ "Hello\u013456" ] [ "Hello\u013456" [ CF>string ] [ CFRelease ] bi ] unit-test diff --git a/basis/core-foundation/strings/strings.factor b/basis/core-foundation/strings/strings.factor new file mode 100644 index 0000000000..2e6180c897 --- /dev/null +++ b/basis/core-foundation/strings/strings.factor @@ -0,0 +1,66 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.syntax alien.strings kernel sequences byte-arrays +io.encodings.utf8 math core-foundation core-foundation.arrays ; +IN: core-foundation.strings + +TYPEDEF: void* CFStringRef + +TYPEDEF: int CFStringEncoding +: kCFStringEncodingMacRoman HEX: 0 ; +: kCFStringEncodingWindowsLatin1 HEX: 0500 ; +: kCFStringEncodingISOLatin1 HEX: 0201 ; +: kCFStringEncodingNextStepLatin HEX: 0B01 ; +: kCFStringEncodingASCII HEX: 0600 ; +: kCFStringEncodingUnicode HEX: 0100 ; +: kCFStringEncodingUTF8 HEX: 08000100 ; +: kCFStringEncodingNonLossyASCII HEX: 0BFF ; +: kCFStringEncodingUTF16 HEX: 0100 ; +: kCFStringEncodingUTF16BE HEX: 10000100 ; +: kCFStringEncodingUTF16LE HEX: 14000100 ; +: kCFStringEncodingUTF32 HEX: 0c000100 ; +: kCFStringEncodingUTF32BE HEX: 18000100 ; +: kCFStringEncodingUTF32LE HEX: 1c000100 ; + +FUNCTION: CFStringRef CFStringCreateWithBytes ( + CFAllocatorRef alloc, + UInt8* bytes, + CFIndex numBytes, + CFStringEncoding encoding, + Boolean isExternalRepresentation +) ; + +FUNCTION: CFIndex CFStringGetLength ( CFStringRef theString ) ; + +FUNCTION: void CFStringGetCharacters ( void* theString, CFIndex start, CFIndex length, void* buffer ) ; + +FUNCTION: Boolean CFStringGetCString ( + CFStringRef theString, + char* buffer, + CFIndex bufferSize, + CFStringEncoding encoding +) ; + +FUNCTION: CFStringRef CFStringCreateWithCString ( + CFAllocatorRef alloc, + char* cStr, + CFStringEncoding encoding +) ; + +: ( string -- alien ) + f swap utf8 string>alien kCFStringEncodingUTF8 CFStringCreateWithCString + [ "CFStringCreateWithCString failed" throw ] unless* ; + +: CF>string ( alien -- string ) + dup CFStringGetLength 4 * 1 + [ + dup length + kCFStringEncodingUTF8 + CFStringGetCString + [ "CFStringGetCString failed" throw ] unless + ] keep utf8 alien>string ; + +: CF>string-array ( alien -- seq ) + CF>array [ CF>string ] map ; + +: ( seq -- alien ) + [ ] map [ ] [ [ CFRelease ] each ] bi ; diff --git a/basis/core-foundation/strings/tags.txt b/basis/core-foundation/strings/tags.txt new file mode 100644 index 0000000000..2320bdd648 --- /dev/null +++ b/basis/core-foundation/strings/tags.txt @@ -0,0 +1,2 @@ +unportable +bindings diff --git a/basis/core-foundation/timers/tags.txt b/basis/core-foundation/timers/tags.txt new file mode 100644 index 0000000000..2320bdd648 --- /dev/null +++ b/basis/core-foundation/timers/tags.txt @@ -0,0 +1,2 @@ +unportable +bindings diff --git a/basis/core-foundation/timers/timers.factor b/basis/core-foundation/timers/timers.factor new file mode 100644 index 0000000000..049e80b20f --- /dev/null +++ b/basis/core-foundation/timers/timers.factor @@ -0,0 +1,30 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.syntax system math kernel core-foundation ; +IN: core-foundation.timers + +TYPEDEF: void* CFRunLoopTimerRef +TYPEDEF: void* CFRunLoopTimerCallBack +TYPEDEF: void* CFRunLoopTimerContext + +FUNCTION: CFRunLoopTimerRef CFRunLoopTimerCreate ( + CFAllocatorRef allocator, + CFAbsoluteTime fireDate, + CFTimeInterval interval, + CFOptionFlags flags, + CFIndex order, + CFRunLoopTimerCallBack callout, + CFRunLoopTimerContext* context +) ; + +: ( callback -- timer ) + [ f millis 1000 /f 60 0 0 ] dip f CFRunLoopTimerCreate ; + +FUNCTION: void CFRunLoopTimerInvalidate ( + CFRunLoopTimerRef timer +) ; + +FUNCTION: void CFRunLoopTimerSetNextFireDate ( + CFRunLoopTimerRef timer, + CFAbsoluteTime fireDate +) ; diff --git a/basis/core-foundation/urls/tags.txt b/basis/core-foundation/urls/tags.txt new file mode 100644 index 0000000000..2320bdd648 --- /dev/null +++ b/basis/core-foundation/urls/tags.txt @@ -0,0 +1,2 @@ +unportable +bindings diff --git a/basis/core-foundation/urls/urls-docs.factor b/basis/core-foundation/urls/urls-docs.factor new file mode 100644 index 0000000000..d017e70fa6 --- /dev/null +++ b/basis/core-foundation/urls/urls-docs.factor @@ -0,0 +1,10 @@ +USING: help.syntax help.markup ; +IN: core-foundation.urls + +HELP: +{ $values { "string" "a pathname string" } { "dir?" "a boolean indicating if the pathname is a directory" } { "url" "a " { $snippet "CFURL" } } } +{ $description "Creates a new " { $snippet "CFURL" } " pointing to the given local pathname." } ; + +HELP: +{ $values { "string" "a URL string" } { "url" "a " { $snippet "CFURL" } } } +{ $description "Creates a new " { $snippet "CFURL" } "." } ; diff --git a/basis/core-foundation/urls/urls.factor b/basis/core-foundation/urls/urls.factor new file mode 100644 index 0000000000..9f9d3a67cb --- /dev/null +++ b/basis/core-foundation/urls/urls.factor @@ -0,0 +1,24 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: alien.syntax kernel core-foundation.strings +core-foundation ; +IN: core-foundation.urls + +: kCFURLPOSIXPathStyle 0 ; inline + +TYPEDEF: void* CFURLRef + +FUNCTION: CFURLRef CFURLCreateWithFileSystemPath ( CFAllocatorRef allocator, CFStringRef filePath, int pathStyle, Boolean isDirectory ) ; + +FUNCTION: CFURLRef CFURLCreateWithString ( CFAllocatorRef allocator, CFStringRef string, CFURLRef base ) ; + +FUNCTION: CFURLRef CFURLCopyFileSystemPath ( CFURLRef url, int pathStyle ) ; + +: ( string dir? -- url ) + [ f over kCFURLPOSIXPathStyle ] dip + CFURLCreateWithFileSystemPath swap CFRelease ; + +: ( string -- url ) + + [ f swap f CFURLCreateWithString ] keep + CFRelease ; diff --git a/basis/cpu/architecture/architecture.factor b/basis/cpu/architecture/architecture.factor index 96dd577c10..c609b9e98d 100644 --- a/basis/cpu/architecture/architecture.factor +++ b/basis/cpu/architecture/architecture.factor @@ -59,6 +59,7 @@ HOOK: %set-slot cpu ( src obj slot tag temp -- ) HOOK: %set-slot-imm cpu ( src obj slot tag -- ) HOOK: %string-nth cpu ( dst obj index temp -- ) +HOOK: %set-string-nth-fast cpu ( ch obj index temp -- ) HOOK: %add cpu ( dst src1 src2 -- ) HOOK: %add-imm cpu ( dst src1 src2 -- ) @@ -76,6 +77,14 @@ HOOK: %shl-imm cpu ( dst src1 src2 -- ) HOOK: %shr-imm cpu ( dst src1 src2 -- ) HOOK: %sar-imm cpu ( dst src1 src2 -- ) HOOK: %not cpu ( dst src -- ) +HOOK: %log2 cpu ( dst src -- ) + +HOOK: %fixnum-add cpu ( src1 src2 -- ) +HOOK: %fixnum-add-tail cpu ( src1 src2 -- ) +HOOK: %fixnum-sub cpu ( src1 src2 -- ) +HOOK: %fixnum-sub-tail cpu ( src1 src2 -- ) +HOOK: %fixnum-mul cpu ( src1 src2 temp1 temp2 -- ) +HOOK: %fixnum-mul-tail cpu ( src1 src2 temp1 temp2 -- ) HOOK: %integer>bignum cpu ( dst src temp -- ) HOOK: %bignum>integer cpu ( dst src temp -- ) @@ -112,6 +121,8 @@ HOOK: %set-alien-cell cpu ( ptr value -- ) HOOK: %set-alien-float cpu ( ptr value -- ) HOOK: %set-alien-double cpu ( ptr value -- ) +HOOK: %alien-global cpu ( dst symbol library -- ) + HOOK: %allot cpu ( dst size class temp -- ) HOOK: %write-barrier cpu ( src card# table -- ) HOOK: %gc cpu ( -- ) @@ -119,9 +130,9 @@ HOOK: %gc cpu ( -- ) HOOK: %prologue cpu ( n -- ) HOOK: %epilogue cpu ( n -- ) -HOOK: %compare cpu ( dst cc src1 src2 -- ) -HOOK: %compare-imm cpu ( dst cc src1 src2 -- ) -HOOK: %compare-float cpu ( dst cc src1 src2 -- ) +HOOK: %compare cpu ( dst temp cc src1 src2 -- ) +HOOK: %compare-imm cpu ( dst temp cc src1 src2 -- ) +HOOK: %compare-float cpu ( dst temp cc src1 src2 -- ) HOOK: %compare-branch cpu ( label cc src1 src2 -- ) HOOK: %compare-imm-branch cpu ( label cc src1 src2 -- ) @@ -141,10 +152,10 @@ HOOK: %loop-entry cpu ( -- ) HOOK: small-enough? cpu ( n -- ? ) ! Is this structure small enough to be returned in registers? -HOOK: struct-small-enough? cpu ( heap-size -- ? ) +HOOK: struct-small-enough? cpu ( c-type -- ? ) -! Do we pass value structs by value or hidden reference? -HOOK: value-structs? cpu ( -- ? ) +! Do we pass this struct by value or hidden reference? +HOOK: value-struct? cpu ( c-type -- ? ) ! If t, all parameters are shadowed by dummy stack parameters HOOK: dummy-stack-params? cpu ( -- ? ) @@ -207,14 +218,3 @@ M: object %callback-return drop %return ; M: stack-params param-reg drop ; M: stack-params param-regs drop f ; - -: if-small-struct ( n size true false -- ? ) - [ 2dup [ not ] [ struct-small-enough? ] bi* and ] 2dip - [ '[ nip @ ] ] dip if ; - inline - -: %unbox-struct ( n c-type -- ) - [ %unbox-small-struct ] [ %unbox-large-struct ] if-small-struct ; - -: %box-struct ( n c-type -- ) - [ %box-small-struct ] [ %box-large-struct ] if-small-struct ; diff --git a/basis/cpu/ppc/bootstrap.factor b/basis/cpu/ppc/bootstrap.factor index aee0f3f4f3..445c7082bc 100644 --- a/basis/cpu/ppc/bootstrap.factor +++ b/basis/cpu/ppc/bootstrap.factor @@ -24,7 +24,6 @@ big-endian on [ 0 6 LOAD32 - 6 dup 0 LWZ 11 6 profile-count-offset LWZ 11 11 1 tag-fixnum ADDI 11 6 profile-count-offset STW @@ -32,7 +31,7 @@ big-endian on 11 11 compiled-header-size ADDI 11 MTCTR BCTR -] rc-absolute-ppc-2/2 rt-literal 1 jit-profiling jit-define +] rc-absolute-ppc-2/2 rt-immediate 1 jit-profiling jit-define [ 0 6 LOAD32 @@ -44,12 +43,6 @@ big-endian on 0 1 lr-save stack-frame + STW ] rc-absolute-ppc-2/2 rt-label 1 jit-prolog jit-define -[ - 0 6 LOAD32 - 6 dup 0 LWZ - 6 ds-reg 4 STWU -] rc-absolute-ppc-2/2 rt-literal 1 jit-push-literal jit-define - [ 0 6 LOAD32 6 ds-reg 4 STWU @@ -71,7 +64,19 @@ big-endian on [ 0 B ] rc-relative-ppc-3 rt-xt 0 jit-word-jump jit-define -: jit-call-quot ( -- ) +[ + 3 ds-reg 0 LWZ + ds-reg dup 4 SUBI + 0 3 \ f tag-number CMPI + 2 BEQ + 0 B +] rc-relative-ppc-3 rt-xt 4 jit-if-1 jit-define + +[ + 0 B +] rc-relative-ppc-3 rt-xt 0 jit-if-2 jit-define + +: jit-jump-quot ( -- ) 4 3 quot-xt-offset LWZ 4 MTCTR BCTR ; @@ -79,24 +84,76 @@ big-endian on [ 0 3 LOAD32 6 ds-reg 0 LWZ - 0 6 \ f tag-number CMPI - 2 BNE - 3 3 4 ADDI - 3 3 0 LWZ - ds-reg dup 4 SUBI - jit-call-quot -] rc-absolute-ppc-2/2 rt-literal 1 jit-if-jump jit-define - -[ - 0 3 LOAD32 - 3 3 0 LWZ - 6 ds-reg 0 LWZ 6 6 1 SRAWI 3 3 6 ADD 3 3 array-start-offset LWZ ds-reg dup 4 SUBI - jit-call-quot -] rc-absolute-ppc-2/2 rt-literal 1 jit-dispatch jit-define + jit-jump-quot +] rc-absolute-ppc-2/2 rt-immediate 1 jit-dispatch jit-define + +: jit->r ( -- ) + 4 ds-reg 0 LWZ + ds-reg dup 4 SUBI + 4 rs-reg 4 STWU ; + +: jit-2>r ( -- ) + 4 ds-reg 0 LWZ + 5 ds-reg -4 LWZ + ds-reg dup 8 SUBI + rs-reg dup 8 ADDI + 4 rs-reg 0 STW + 5 rs-reg -4 STW ; + +: jit-3>r ( -- ) + 4 ds-reg 0 LWZ + 5 ds-reg -4 LWZ + 6 ds-reg -8 LWZ + ds-reg dup 12 SUBI + rs-reg dup 12 ADDI + 4 rs-reg 0 STW + 5 rs-reg -4 STW + 6 rs-reg -8 STW ; + +: jit-r> ( -- ) + 4 rs-reg 0 LWZ + rs-reg dup 4 SUBI + 4 ds-reg 4 STWU ; + +: jit-2r> ( -- ) + 4 rs-reg 0 LWZ + 5 rs-reg -4 LWZ + rs-reg dup 8 SUBI + ds-reg dup 8 ADDI + 4 ds-reg 0 STW + 5 ds-reg -4 STW ; + +: jit-3r> ( -- ) + 4 rs-reg 0 LWZ + 5 rs-reg -4 LWZ + 6 rs-reg -8 LWZ + rs-reg dup 12 SUBI + ds-reg dup 12 ADDI + 4 ds-reg 0 STW + 5 ds-reg -4 STW + 6 ds-reg -8 STW ; + +[ + jit->r + 0 BL + jit-r> +] rc-relative-ppc-3 rt-xt 3 jit-dip jit-define + +[ + jit-2>r + 0 BL + jit-2r> +] rc-relative-ppc-3 rt-xt 6 jit-2dip jit-define + +[ + jit-3>r + 0 BL + jit-3r> +] rc-relative-ppc-3 rt-xt 8 jit-3dip jit-define [ 0 1 lr-save stack-frame + LWZ @@ -112,7 +169,7 @@ big-endian on [ 3 ds-reg 0 LWZ ds-reg dup 4 SUBI - jit-call-quot + jit-jump-quot ] f f f \ (call) define-sub-primitive [ @@ -245,22 +302,13 @@ big-endian on 4 ds-reg 0 STW ] f f f \ -rot define-sub-primitive -[ - 3 ds-reg 0 LWZ - ds-reg dup 4 SUBI - 3 rs-reg 4 STWU -] f f f \ >r define-sub-primitive +[ jit->r ] f f f \ >r define-sub-primitive -[ - 3 rs-reg 0 LWZ - rs-reg dup 4 SUBI - 3 ds-reg 4 STWU -] f f f \ r> define-sub-primitive +[ jit-r> ] f f f \ r> define-sub-primitive ! Comparisons : jit-compare ( insn -- ) 0 3 LOAD32 - 3 3 0 LWZ 4 ds-reg 0 LWZ 5 ds-reg -4 LWZU 5 0 4 CMP @@ -269,7 +317,7 @@ big-endian on 3 ds-reg 0 STW ; : define-jit-compare ( insn word -- ) - [ [ jit-compare ] curry rc-absolute-ppc-2/2 rt-literal 1 ] dip + [ [ jit-compare ] curry rc-absolute-ppc-2/2 rt-immediate 1 ] dip define-sub-primitive ; \ BEQ \ eq? define-jit-compare @@ -279,6 +327,19 @@ big-endian on \ BLT \ fixnum< define-jit-compare ! Math +[ + 3 ds-reg 0 LWZ + ds-reg ds-reg 4 SUBI + 4 ds-reg 0 LWZ + 3 3 4 OR + 3 3 tag-mask get ANDI + \ f tag-number 4 LI + 0 3 0 CMPI + 2 BNE + 1 tag-fixnum 4 LI + 4 ds-reg 0 STW +] f f f \ both-fixnums? define-sub-primitive + : jit-math ( insn -- ) 3 ds-reg 0 LWZ 4 ds-reg -4 LWZU @@ -335,12 +396,30 @@ big-endian on 7 ds-reg 0 STW ] f f f \ fixnum-mod define-sub-primitive +[ + 3 ds-reg 0 LWZ + ds-reg ds-reg 4 SUBI + 4 ds-reg 0 LWZ + 5 4 3 DIVW + 5 5 tag-bits get SLWI + 5 ds-reg 0 STW +] f f f \ fixnum/i-fast define-sub-primitive + +[ + 3 ds-reg 0 LWZ + 4 ds-reg -4 LWZ + 5 4 3 DIVW + 6 5 3 MULLW + 7 6 4 SUBF + 5 5 tag-bits get SLWI + 5 ds-reg -4 STW + 7 ds-reg 0 STW +] f f f \ fixnum/mod-fast define-sub-primitive + [ 3 ds-reg 0 LWZ 3 3 1 SRAWI - 4 4 LI - 4 3 4 SUBF - rs-reg 3 4 LWZX + rs-reg 3 3 LWZX 3 ds-reg 0 STW ] f f f \ get-local define-sub-primitive diff --git a/basis/cpu/ppc/linux/linux.factor b/basis/cpu/ppc/linux/linux.factor index 090495aa11..5cfa1391c4 100644 --- a/basis/cpu/ppc/linux/linux.factor +++ b/basis/cpu/ppc/linux/linux.factor @@ -15,7 +15,7 @@ M: linux lr-save 1 cells ; M: float-regs param-regs drop { 1 2 3 4 5 6 7 8 } ; -M: ppc value-structs? f ; +M: ppc value-struct? drop f ; M: ppc dummy-stack-params? f ; diff --git a/basis/cpu/ppc/macosx/macosx.factor b/basis/cpu/ppc/macosx/macosx.factor index 877fb37d31..c742cf2ddc 100644 --- a/basis/cpu/ppc/macosx/macosx.factor +++ b/basis/cpu/ppc/macosx/macosx.factor @@ -16,7 +16,7 @@ M: macosx lr-save 2 cells ; M: float-regs param-regs drop { 1 2 3 4 5 6 7 8 9 10 11 12 13 } ; -M: ppc value-structs? t ; +M: ppc value-struct? drop t ; M: ppc dummy-stack-params? t ; diff --git a/basis/cpu/ppc/ppc.factor b/basis/cpu/ppc/ppc.factor index c656ae4d89..c555c4b809 100644 --- a/basis/cpu/ppc/ppc.factor +++ b/basis/cpu/ppc/ppc.factor @@ -34,10 +34,11 @@ M: ppc two-operand? f ; M: ppc %load-immediate ( reg n -- ) swap LOAD ; -M:: ppc %load-indirect ( reg obj -- ) - 0 reg LOAD32 - obj rc-absolute-ppc-2/2 rel-literal - reg reg 0 LWZ ; +M: ppc %load-indirect ( reg obj -- ) + [ 0 swap LOAD32 ] [ rc-absolute-ppc-2/2 rel-immediate ] bi* ; + +M: ppc %alien-global ( register symbol dll -- ) + [ 0 swap LOAD32 ] 2dip rc-absolute-ppc-2/2 rel-dlsym ; : ds-reg 29 ; inline : rs-reg 30 ; inline @@ -138,17 +139,21 @@ M:: ppc %string-nth ( dst src index temp -- ) "end" define-label temp src index ADD dst temp string-offset LBZ + 0 dst HEX: 80 CMPI + "end" get BLT temp src string-aux-offset LWZ - 0 temp \ f tag-number CMPI - "end" get BEQ temp temp index ADD temp temp index ADD temp temp byte-array-offset LHZ - temp temp 8 SLWI - dst dst temp OR + temp temp 7 SLWI + dst dst temp XOR "end" resolve-label ] with-scope ; +M:: ppc %set-string-nth-fast ( ch obj index temp -- ) + temp obj index ADD + ch temp string-offset STB ; + M: ppc %add ADD ; M: ppc %add-imm ADDI ; M: ppc %sub swap SUBF ; @@ -166,6 +171,91 @@ M: ppc %shr-imm swapd SRWI ; M: ppc %sar-imm SRAWI ; M: ppc %not NOT ; +: %alien-invoke-tail ( func dll -- ) + [ scratch-reg ] 2dip %alien-global scratch-reg MTCTR BCTR ; + +:: exchange-regs ( r1 r2 -- ) + scratch-reg r1 MR + r1 r2 MR + r2 scratch-reg MR ; + +: ?MR ( r1 r2 -- ) 2dup = [ 2drop ] [ MR ] if ; + +:: move>args ( src1 src2 -- ) + { + { [ src1 4 = ] [ 3 src2 ?MR 3 4 exchange-regs ] } + { [ src1 3 = ] [ 4 src2 ?MR ] } + { [ src2 3 = ] [ 4 src1 ?MR 3 4 exchange-regs ] } + { [ src2 4 = ] [ 3 src1 ?MR ] } + [ 3 src1 MR 4 src2 MR ] + } cond ; + +: clear-xer ( -- ) + 0 0 LI + 0 MTXER ; inline + +:: overflow-template ( src1 src2 insn func -- ) + "no-overflow" define-label + clear-xer + scratch-reg src2 src1 insn call + scratch-reg ds-reg 0 STW + "no-overflow" get BNO + src1 src2 move>args + %prepare-alien-invoke + func f %alien-invoke + "no-overflow" resolve-label ; inline + +:: overflow-template-tail ( src1 src2 insn func -- ) + "overflow" define-label + clear-xer + scratch-reg src2 src1 insn call + "overflow" get BO + scratch-reg ds-reg 0 STW + BLR + "overflow" resolve-label + src1 src2 move>args + %prepare-alien-invoke + func f %alien-invoke-tail ; inline + +M: ppc %fixnum-add ( src1 src2 -- ) + [ ADDO. ] "overflow_fixnum_add" overflow-template ; + +M: ppc %fixnum-add-tail ( src1 src2 -- ) + [ ADDO. ] "overflow_fixnum_add" overflow-template-tail ; + +M: ppc %fixnum-sub ( src1 src2 -- ) + [ SUBFO. ] "overflow_fixnum_subtract" overflow-template ; + +M: ppc %fixnum-sub-tail ( src1 src2 -- ) + [ SUBFO. ] "overflow_fixnum_subtract" overflow-template-tail ; + +M:: ppc %fixnum-mul ( src1 src2 temp1 temp2 -- ) + "no-overflow" define-label + clear-xer + temp1 src1 tag-bits get SRAWI + temp2 temp1 src2 MULLWO. + temp2 ds-reg 0 STW + "no-overflow" get BNO + src2 src2 tag-bits get SRAWI + temp1 src2 move>args + %prepare-alien-invoke + "overflow_fixnum_multiply" f %alien-invoke + "no-overflow" resolve-label ; + +M:: ppc %fixnum-mul-tail ( src1 src2 temp1 temp2 -- ) + "overflow" define-label + clear-xer + temp1 src1 tag-bits get SRAWI + temp2 temp1 src2 MULLWO. + "overflow" get BO + temp2 ds-reg 0 STW + BLR + "overflow" resolve-label + src2 src2 tag-bits get SRAWI + temp1 src2 move>args + %prepare-alien-invoke + "overflow_fixnum_multiply" f %alien-invoke-tail ; + : bignum@ ( n -- offset ) cells bignum tag-number - ; inline M:: ppc %integer>bignum ( dst src temp -- ) @@ -320,11 +410,8 @@ M: ppc %set-alien-cell swap 0 STW ; M: ppc %set-alien-float swap 0 STFS ; M: ppc %set-alien-double swap 0 STFD ; -: %load-dlsym ( symbol dll register -- ) - 0 swap LOAD32 rc-absolute-ppc-2/2 rel-dlsym ; - : load-zone-ptr ( reg -- ) - [ "nursery" f ] dip %load-dlsym ; + "nursery" f %alien-global ; : load-allot-ptr ( nursery-ptr allot-ptr -- ) [ drop load-zone-ptr ] [ swap 4 LWZ ] 2bi ; @@ -346,14 +433,11 @@ M:: ppc %allot ( dst size class nursery-ptr -- ) dst class store-header dst class store-tagged ; -: %alien-global ( dst name -- ) - [ f rot %load-dlsym ] [ drop dup 0 LWZ ] 2bi ; - : load-cards-offset ( dst -- ) - "cards_offset" %alien-global ; + [ "cards_offset" f %alien-global ] [ dup 0 LWZ ] bi ; : load-decks-offset ( dst -- ) - "decks_offset" %alien-global ; + [ "decks_offset" f %alien-global ] [ dup 0 LWZ ] bi ; M:: ppc %write-barrier ( src card# table -- ) card-mark scratch-reg LI @@ -398,14 +482,14 @@ M: ppc %epilogue ( n -- ) 1 1 rot ADDI 0 MTLR ; -:: (%boolean) ( dst word -- ) +:: (%boolean) ( dst temp word -- ) "end" define-label dst \ f tag-number %load-immediate "end" get word execute dst \ t %load-indirect "end" get resolve-label ; inline -: %boolean ( dst cc -- ) +: %boolean ( dst temp cc -- ) negate-cc { { cc< [ \ BLT (%boolean) ] } { cc<= [ \ BLE (%boolean) ] } @@ -540,14 +624,14 @@ M: ppc %prepare-alien-invoke #! Save Factor stack pointers in case the C code calls a #! callback which does a GC, which must reliably trace #! all roots. - "stack_chain" f 11 %load-dlsym - 11 11 0 LWZ - 1 11 0 STW - ds-reg 11 8 STW - rs-reg 11 12 STW ; + scratch-reg "stack_chain" f %alien-global + scratch-reg scratch-reg 0 LWZ + 1 scratch-reg 0 STW + ds-reg scratch-reg 8 STW + rs-reg scratch-reg 12 STW ; M: ppc %alien-invoke ( symbol dll -- ) - 11 %load-dlsym 11 MTLR BLRL ; + [ 11 ] 2dip %alien-global 11 MTLR BLRL ; M: ppc %alien-callback ( quot -- ) 3 swap %load-indirect "c_to_factor" f %alien-invoke ; diff --git a/basis/cpu/x86/32/32.factor b/basis/cpu/x86/32/32.factor old mode 100644 new mode 100755 index f892271fd5..5e06e72118 --- a/basis/cpu/x86/32/32.factor +++ b/basis/cpu/x86/32/32.factor @@ -23,8 +23,8 @@ M: x86.32 machine-registers M: x86.32 ds-reg ESI ; M: x86.32 rs-reg EDI ; M: x86.32 stack-reg ESP ; -M: x86.32 temp-reg-1 EAX ; -M: x86.32 temp-reg-2 ECX ; +M: x86.32 temp-reg-1 ECX ; +M: x86.32 temp-reg-2 EDX ; M:: x86.32 %dispatch ( src temp offset -- ) ! Load jump table base. @@ -38,12 +38,16 @@ M:: x86.32 %dispatch ( src temp offset -- ) [ align-code ] bi ; +! Registers for fastcall +M: x86.32 param-reg-1 EAX ; +M: x86.32 param-reg-2 EDX ; + M: x86.32 reserved-area-size 0 ; -M: x86.32 %alien-global 0 [] MOV rc-absolute-cell rel-dlsym ; - M: x86.32 %alien-invoke (CALL) rel-dlsym ; +M: x86.32 %alien-invoke-tail (JMP) rel-dlsym ; + M: x86.32 struct-small-enough? ( size -- ? ) heap-size { 1 2 4 8 } member? os { linux netbsd solaris } member? not and ; @@ -88,8 +92,6 @@ M: float-regs store-return-reg [ [ align-sub ] [ call ] bi* ] [ [ align-add ] [ drop ] bi* ] 2bi ; inline -M: x86.32 rel-literal-x86 rc-absolute-cell rel-literal ; - M: x86.32 %prologue ( n -- ) dup PUSH 0 PUSH rc-absolute-cell rel-this @@ -303,7 +305,7 @@ FUNCTION: bool check_sse2 ( ) ; : sse2? ( -- ? ) check_sse2 ; -"-no-sse2" cli-args member? [ +"-no-sse2" (command-line) member? [ [ optimized-recompile-hook ] recompile-hook [ { check_sse2 } compile ] with-variable diff --git a/basis/cpu/x86/32/bootstrap.factor b/basis/cpu/x86/32/bootstrap.factor index ba963ab477..f29dec128c 100644 --- a/basis/cpu/x86/32/bootstrap.factor +++ b/basis/cpu/x86/32/bootstrap.factor @@ -10,18 +10,20 @@ IN: bootstrap.x86 : shift-arg ( -- reg ) ECX ; : div-arg ( -- reg ) EAX ; : mod-arg ( -- reg ) EDX ; -: arg0 ( -- reg ) EAX ; -: arg1 ( -- reg ) EDX ; -: temp-reg ( -- reg ) EBX ; +: arg ( -- reg ) EAX ; +: temp0 ( -- reg ) EAX ; +: temp1 ( -- reg ) EDX ; +: temp2 ( -- reg ) ECX ; +: temp3 ( -- reg ) EBX ; : stack-reg ( -- reg ) ESP ; : ds-reg ( -- reg ) ESI ; : rs-reg ( -- reg ) EDI ; -: fixnum>slot@ ( -- ) arg0 1 SAR ; +: fixnum>slot@ ( -- ) temp0 1 SAR ; : rex-length ( -- n ) 0 ; [ - arg0 0 [] MOV ! load stack_chain - arg0 [] stack-reg MOV ! save stack pointer + temp0 0 [] MOV ! load stack_chain + temp0 [] stack-reg MOV ! save stack pointer ] rc-absolute-cell rt-stack-chain 2 jit-save-stack jit-define [ diff --git a/basis/cpu/x86/64/64.factor b/basis/cpu/x86/64/64.factor index 75c808b50a..2077f51e0a 100644 --- a/basis/cpu/x86/64/64.factor +++ b/basis/cpu/x86/64/64.factor @@ -21,8 +21,6 @@ M: x86.64 machine-registers M: x86.64 ds-reg R14 ; M: x86.64 rs-reg R15 ; M: x86.64 stack-reg RSP ; -M: x86.64 temp-reg-1 RAX ; -M: x86.64 temp-reg-2 RCX ; M:: x86.64 %dispatch ( src temp offset -- ) ! Load jump table base. @@ -37,15 +35,13 @@ M:: x86.64 %dispatch ( src temp offset -- ) [ align-code ] bi ; -: param-reg-1 int-regs param-regs first ; inline -: param-reg-2 int-regs param-regs second ; inline +M: x86.64 param-reg-1 int-regs param-regs first ; +M: x86.64 param-reg-2 int-regs param-regs second ; : param-reg-3 int-regs param-regs third ; inline M: int-regs return-reg drop RAX ; M: float-regs return-reg drop XMM0 ; -M: x86.64 rel-literal-x86 rc-relative rel-literal ; - M: x86.64 %prologue ( n -- ) temp-reg-1 0 MOV rc-absolute-cell rel-this dup PUSH @@ -162,14 +158,16 @@ M: x86.64 %prepare-box-struct ( -- ) M: x86.64 %prepare-var-args RAX RAX XOR ; -M: x86.64 %alien-global - [ 0 MOV rc-absolute-cell rel-dlsym ] [ dup [] MOV ] bi ; - M: x86.64 %alien-invoke R11 0 MOV rc-absolute-cell rel-dlsym R11 CALL ; +M: x86.64 %alien-invoke-tail + R11 0 MOV + rc-absolute-cell rel-dlsym + R11 JMP ; + M: x86.64 %prepare-alien-indirect ( -- ) "unbox_alien" f %alien-invoke RBP RAX MOV ; diff --git a/basis/cpu/x86/64/bootstrap.factor b/basis/cpu/x86/64/bootstrap.factor index 83a72d6dd3..efa3de3065 100644 --- a/basis/cpu/x86/64/bootstrap.factor +++ b/basis/cpu/x86/64/bootstrap.factor @@ -9,7 +9,10 @@ IN: bootstrap.x86 : shift-arg ( -- reg ) RCX ; : div-arg ( -- reg ) RAX ; : mod-arg ( -- reg ) RDX ; -: temp-reg ( -- reg ) RBX ; +: temp0 ( -- reg ) RDI ; +: temp1 ( -- reg ) RSI ; +: temp2 ( -- reg ) RDX ; +: temp3 ( -- reg ) RBX ; : stack-reg ( -- reg ) RSP ; : ds-reg ( -- reg ) R14 ; : rs-reg ( -- reg ) R15 ; @@ -17,14 +20,14 @@ IN: bootstrap.x86 : rex-length ( -- n ) 1 ; [ - arg0 0 MOV ! load stack_chain - arg0 arg0 [] MOV - arg0 [] stack-reg MOV ! save stack pointer + temp0 0 MOV ! load stack_chain + temp0 temp0 [] MOV + temp0 [] stack-reg MOV ! save stack pointer ] rc-absolute-cell rt-stack-chain 1 rex-length + jit-save-stack jit-define [ - arg1 0 MOV ! load XT - arg1 JMP ! go + temp1 0 MOV ! load XT + temp1 JMP ! go ] rc-absolute-cell rt-primitive 1 rex-length + jit-primitive jit-define << "resource:basis/cpu/x86/bootstrap.factor" parse-file parsed >> diff --git a/basis/cpu/x86/64/unix/bootstrap.factor b/basis/cpu/x86/64/unix/bootstrap.factor index 29d48bd794..20a953b6d5 100644 --- a/basis/cpu/x86/64/unix/bootstrap.factor +++ b/basis/cpu/x86/64/unix/bootstrap.factor @@ -5,8 +5,7 @@ cpu.x86.assembler layouts vocabs parser ; IN: bootstrap.x86 : stack-frame-size ( -- n ) 4 bootstrap-cells ; -: arg0 ( -- reg ) RDI ; -: arg1 ( -- reg ) RSI ; +: arg ( -- reg ) RDI ; << "resource:basis/cpu/x86/64/bootstrap.factor" parse-file parsed >> call diff --git a/basis/cpu/x86/64/unix/unix.factor b/basis/cpu/x86/64/unix/unix.factor index ddb412873a..f5fb5b9640 100644 --- a/basis/cpu/x86/64/unix/unix.factor +++ b/basis/cpu/x86/64/unix/unix.factor @@ -52,3 +52,7 @@ M: x86.64 dummy-stack-params? f ; M: x86.64 dummy-int-params? f ; M: x86.64 dummy-fp-params? f ; + +M: x86.64 temp-reg-1 R8 ; + +M: x86.64 temp-reg-2 R9 ; diff --git a/basis/cpu/x86/64/winnt/bootstrap.factor b/basis/cpu/x86/64/winnt/bootstrap.factor index a62b946e83..3accca400f 100644 --- a/basis/cpu/x86/64/winnt/bootstrap.factor +++ b/basis/cpu/x86/64/winnt/bootstrap.factor @@ -5,8 +5,7 @@ cpu.x86.assembler layouts vocabs parser ; IN: bootstrap.x86 : stack-frame-size ( -- n ) 8 bootstrap-cells ; -: arg0 ( -- reg ) RCX ; -: arg1 ( -- reg ) RDX ; +: arg ( -- reg ) RCX ; << "resource:basis/cpu/x86/64/bootstrap.factor" parse-file parsed >> call diff --git a/basis/cpu/x86/64/winnt/winnt.factor b/basis/cpu/x86/64/winnt/winnt.factor index 0124c40877..4c6af6c1e7 100644 --- a/basis/cpu/x86/64/winnt/winnt.factor +++ b/basis/cpu/x86/64/winnt/winnt.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel layouts system math alien.c-types +USING: kernel layouts system math alien.c-types sequences compiler.cfg.registers cpu.architecture cpu.x86.assembler cpu.x86 ; IN: cpu.x86.64.winnt @@ -10,8 +10,9 @@ M: float-regs param-regs drop { XMM0 XMM1 XMM2 XMM3 } ; M: x86.64 reserved-area-size 4 cells ; -M: x86.64 struct-small-enough? ( size -- ? ) - heap-size cell <= ; +M: x86.64 struct-small-enough? heap-size { 1 2 4 8 } member? ; + +M: x86.64 value-struct? heap-size { 1 2 4 8 } member? ; M: x86.64 dummy-stack-params? f ; @@ -19,8 +20,13 @@ M: x86.64 dummy-int-params? t ; M: x86.64 dummy-fp-params? t ; +M: x86.64 temp-reg-1 RAX ; + +M: x86.64 temp-reg-2 RCX ; + << "longlong" "ptrdiff_t" typedef -"int" "long" typedef -"uint" "ulong" typedef +"longlong" "intptr_t" typedef +"int" c-type "long" define-primitive-type +"uint" c-type "ulong" define-primitive-type >> diff --git a/basis/cpu/x86/assembler/assembler.factor b/basis/cpu/x86/assembler/assembler.factor index 5c6fff2348..3a98d47416 100644 --- a/basis/cpu/x86/assembler/assembler.factor +++ b/basis/cpu/x86/assembler/assembler.factor @@ -130,7 +130,7 @@ M: register modifier drop BIN: 11 ; GENERIC# n, 1 ( value n -- ) M: integer n, >le % ; -M: byte n, >r value>> r> n, ; +M: byte n, [ value>> ] dip n, ; : 1, ( n -- ) 1 n, ; inline : 4, ( n -- ) 4 n, ; inline : 2, ( n -- ) 2 n, ; inline @@ -209,7 +209,7 @@ M: object operand-64? drop f ; : short-operand ( reg rex.w n -- ) #! Some instructions encode their single operand as part of #! the opcode. - >r dupd prefix-1 reg-code r> + , ; + [ dupd prefix-1 reg-code ] dip + , ; : opcode, ( opcode -- ) dup array? [ % ] [ , ] if ; @@ -224,7 +224,7 @@ M: object operand-64? drop f ; : 1-operand ( op reg,rex.w,opcode -- ) #! The 'reg' is not really a register, but a value for the #! 'reg' field of the mod-r/m byte. - first3 >r >r over r> prefix-1 r> opcode, swap addressing ; + first3 [ [ over ] dip prefix-1 ] dip opcode, swap addressing ; : immediate-operand-size-bit ( imm dst reg,rex.w,opcode -- imm dst reg,rex.w,opcode ) pick integer? [ first3 BIN: 1 opcode-or 3array ] when ; @@ -250,7 +250,7 @@ M: object operand-64? drop f ; ] if ; : (2-operand) ( dst src op -- ) - >r 2dup t rex-prefix r> opcode, + [ 2dup t rex-prefix ] dip opcode, reg-code swap addressing ; : direction-bit ( dst src op -- dst' src' op' ) @@ -271,11 +271,11 @@ M: object operand-64? drop f ; PRIVATE> : [] ( reg/displacement -- indirect ) - dup integer? [ >r f f f r> ] [ f f f ] if ; + dup integer? [ [ f f f ] dip ] [ f f f ] if ; : [+] ( reg displacement -- indirect ) dup integer? - [ dup zero? [ drop f ] when >r f f r> ] + [ dup zero? [ drop f ] when [ f f ] dip ] [ f f ] if ; @@ -300,7 +300,7 @@ PREDICATE: callable < word register? not ; GENERIC: MOV ( dst src -- ) M: immediate MOV swap (MOV-I) ; -M: callable MOV 0 rot (MOV-I) rc-absolute-cell rel-word ; +M: callable MOV [ 0 ] 2dip (MOV-I) rc-absolute-cell rel-word ; M: operand MOV HEX: 88 2-operand ; : LEA ( dst src -- ) swap HEX: 8d 2-operand ; @@ -308,18 +308,21 @@ M: operand MOV HEX: 88 2-operand ; ! Control flow GENERIC: JMP ( op -- ) : (JMP) ( -- rel-class ) HEX: e9 , 0 4, rc-relative ; +M: f JMP (JMP) 2drop ; M: callable JMP (JMP) rel-word ; M: label JMP (JMP) label-fixup ; M: operand JMP { BIN: 100 t HEX: ff } 1-operand ; GENERIC: CALL ( op -- ) : (CALL) ( -- rel-class ) HEX: e8 , 0 4, rc-relative ; +M: f CALL (CALL) 2drop ; M: callable CALL (CALL) rel-word ; M: label CALL (CALL) label-fixup ; M: operand CALL { BIN: 010 t HEX: ff } 1-operand ; GENERIC# JUMPcc 1 ( addr opcode -- ) : (JUMPcc) ( n -- rel-class ) extended-opcode, 0 4, rc-relative ; +M: f JUMPcc nip (JUMPcc) drop ; M: callable JUMPcc (JUMPcc) rel-word ; M: label JUMPcc (JUMPcc) label-fixup ; @@ -343,7 +346,7 @@ M: label JUMPcc (JUMPcc) label-fixup ; : LEAVE ( -- ) HEX: c9 , ; : RET ( n -- ) - dup zero? [ drop HEX: c3 , ] [ HEX: C2 , 2, ] if ; + dup zero? [ drop HEX: c3 , ] [ HEX: c2 , 2, ] if ; ! Arithmetic @@ -381,6 +384,8 @@ M: operand CMP OCT: 070 2-operand ; : XCHG ( dst src -- ) OCT: 207 2-operand ; +: BSR ( dst src -- ) swap { HEX: 0f HEX: bd } (2-operand) ; + : NOT ( dst -- ) { BIN: 010 t HEX: f7 } 1-operand ; : NEG ( dst -- ) { BIN: 011 t HEX: f7 } 1-operand ; : MUL ( dst -- ) { BIN: 100 t HEX: f7 } 1-operand ; diff --git a/basis/cpu/x86/assembler/syntax/syntax.factor b/basis/cpu/x86/assembler/syntax/syntax.factor index d267baaf4f..6ddec4af07 100644 --- a/basis/cpu/x86/assembler/syntax/syntax.factor +++ b/basis/cpu/x86/assembler/syntax/syntax.factor @@ -4,8 +4,8 @@ USING: kernel words sequences lexer parser fry ; IN: cpu.x86.assembler.syntax : define-register ( name num size -- ) - >r >r "cpu.x86.assembler" create dup define-symbol r> r> - >r dupd "register" set-word-prop r> + [ "cpu.x86.assembler" create dup define-symbol ] 2dip + [ dupd "register" set-word-prop ] dip "register-size" set-word-prop ; : define-registers ( names size -- ) diff --git a/basis/cpu/x86/bootstrap.factor b/basis/cpu/x86/bootstrap.factor index 1ee74a434b..42fcfaa6a2 100644 --- a/basis/cpu/x86/bootstrap.factor +++ b/basis/cpu/x86/bootstrap.factor @@ -12,69 +12,147 @@ big-endian off [ ! Load word - temp-reg 0 MOV - temp-reg dup [] MOV + temp0 0 MOV ! Bump profiling counter - temp-reg profile-count-offset [+] 1 tag-fixnum ADD + temp0 profile-count-offset [+] 1 tag-fixnum ADD ! Load word->code - temp-reg temp-reg word-code-offset [+] MOV + temp0 temp0 word-code-offset [+] MOV ! Compute word XT - temp-reg compiled-header-size ADD + temp0 compiled-header-size ADD ! Jump to XT - temp-reg JMP -] rc-absolute-cell rt-literal 1 rex-length + jit-profiling jit-define + temp0 JMP +] rc-absolute-cell rt-immediate 1 rex-length + jit-profiling jit-define [ - temp-reg 0 MOV ! load XT - stack-frame-size PUSH ! save stack frame size - temp-reg PUSH ! push XT - stack-reg stack-frame-size 3 bootstrap-cells - SUB ! alignment + ! load XT + temp0 0 MOV + ! save stack frame size + stack-frame-size PUSH + ! push XT + temp0 PUSH + ! alignment + stack-reg stack-frame-size 3 bootstrap-cells - SUB ] rc-absolute-cell rt-label 1 rex-length + jit-prolog jit-define [ - arg0 0 MOV ! load literal - arg0 dup [] MOV - ds-reg bootstrap-cell ADD ! increment datastack pointer - ds-reg [] arg0 MOV ! store literal on datastack -] rc-absolute-cell rt-literal 1 rex-length + jit-push-literal jit-define - -[ - arg0 0 MOV ! load literal - ds-reg bootstrap-cell ADD ! increment datastack pointer - ds-reg [] arg0 MOV ! store literal on datastack + ! load literal + temp0 0 MOV + ! increment datastack pointer + ds-reg bootstrap-cell ADD + ! store literal on datastack + ds-reg [] temp0 MOV ] rc-absolute-cell rt-immediate 1 rex-length + jit-push-immediate jit-define [ - (JMP) drop + f JMP ] rc-relative rt-xt 1 jit-word-jump jit-define [ - (CALL) drop + f CALL ] rc-relative rt-xt 1 jit-word-call jit-define [ - arg1 0 MOV ! load addr of true quotation - arg0 ds-reg [] MOV ! load boolean - ds-reg bootstrap-cell SUB ! pop boolean - arg0 \ f tag-number CMP ! compare it with f - arg0 arg1 [] CMOVNE ! load true branch if not equal - arg0 arg1 bootstrap-cell [+] CMOVE ! load false branch if equal - arg0 quot-xt-offset [+] JMP ! jump to quotation-xt -] rc-absolute-cell rt-literal 1 rex-length + jit-if-jump jit-define + ! load boolean + temp0 ds-reg [] MOV + ! pop boolean + ds-reg bootstrap-cell SUB + ! compare boolean with f + temp0 \ f tag-number CMP + ! jump to true branch if not equal + f JNE +] rc-relative rt-xt 10 rex-length 3 * + jit-if-1 jit-define [ - arg1 0 MOV ! load dispatch table - arg1 dup [] MOV - arg0 ds-reg [] MOV ! load index - fixnum>slot@ ! turn it into an array offset - ds-reg bootstrap-cell SUB ! pop index - arg0 arg1 ADD ! compute quotation location - arg0 arg0 array-start-offset [+] MOV ! load quotation - arg0 quot-xt-offset [+] JMP ! execute branch -] rc-absolute-cell rt-literal 1 rex-length + jit-dispatch jit-define + ! jump to false branch if equal + f JMP +] rc-relative rt-xt 1 jit-if-2 jit-define [ - stack-reg stack-frame-size bootstrap-cell - ADD ! unwind stack frame + ! load dispatch table + temp1 0 MOV + ! load index + temp0 ds-reg [] MOV + ! turn it into an array offset + fixnum>slot@ + ! pop index + ds-reg bootstrap-cell SUB + ! compute quotation location + temp0 temp1 ADD + ! load quotation + temp0 temp0 array-start-offset [+] MOV + ! execute branch + temp0 quot-xt-offset [+] JMP +] rc-absolute-cell rt-immediate 1 rex-length + jit-dispatch jit-define + +: jit->r ( -- ) + rs-reg bootstrap-cell ADD + temp0 ds-reg [] MOV + ds-reg bootstrap-cell SUB + rs-reg [] temp0 MOV ; + +: jit-2>r ( -- ) + rs-reg 2 bootstrap-cells ADD + temp0 ds-reg [] MOV + temp1 ds-reg -1 bootstrap-cells [+] MOV + ds-reg 2 bootstrap-cells SUB + rs-reg [] temp0 MOV + rs-reg -1 bootstrap-cells [+] temp1 MOV ; + +: jit-3>r ( -- ) + rs-reg 3 bootstrap-cells ADD + temp0 ds-reg [] MOV + temp1 ds-reg -1 bootstrap-cells [+] MOV + temp2 ds-reg -2 bootstrap-cells [+] MOV + ds-reg 3 bootstrap-cells SUB + rs-reg [] temp0 MOV + rs-reg -1 bootstrap-cells [+] temp1 MOV + rs-reg -2 bootstrap-cells [+] temp2 MOV ; + +: jit-r> ( -- ) + ds-reg bootstrap-cell ADD + temp0 rs-reg [] MOV + rs-reg bootstrap-cell SUB + ds-reg [] temp0 MOV ; + +: jit-2r> ( -- ) + ds-reg 2 bootstrap-cells ADD + temp0 rs-reg [] MOV + temp1 rs-reg -1 bootstrap-cells [+] MOV + rs-reg 2 bootstrap-cells SUB + ds-reg [] temp0 MOV + ds-reg -1 bootstrap-cells [+] temp1 MOV ; + +: jit-3r> ( -- ) + ds-reg 3 bootstrap-cells ADD + temp0 rs-reg [] MOV + temp1 rs-reg -1 bootstrap-cells [+] MOV + temp2 rs-reg -2 bootstrap-cells [+] MOV + rs-reg 3 bootstrap-cells SUB + ds-reg [] temp0 MOV + ds-reg -1 bootstrap-cells [+] temp1 MOV + ds-reg -2 bootstrap-cells [+] temp2 MOV ; + +[ + jit->r + f CALL + jit-r> +] rc-relative rt-xt 11 rex-length 4 * + jit-dip jit-define + +[ + jit-2>r + f CALL + jit-2r> +] rc-relative rt-xt 17 rex-length 6 * + jit-2dip jit-define + +[ + jit-3>r + f CALL + jit-3r> +] rc-relative rt-xt 23 rex-length 8 * + jit-3dip jit-define + +[ + ! unwind stack frame + stack-reg stack-frame-size bootstrap-cell - ADD ] f f f jit-epilog jit-define [ 0 RET ] f f f jit-return jit-define @@ -83,34 +161,51 @@ big-endian off ! Quotations and words [ - arg0 ds-reg [] MOV ! load from stack - ds-reg bootstrap-cell SUB ! pop stack - arg0 quot-xt-offset [+] JMP ! call quotation + ! load from stack + arg ds-reg [] MOV + ! pop stack + ds-reg bootstrap-cell SUB + ! call quotation + arg quot-xt-offset [+] JMP ] f f f \ (call) define-sub-primitive [ - arg0 ds-reg [] MOV ! load from stack - ds-reg bootstrap-cell SUB ! pop stack - arg0 word-xt-offset [+] JMP ! execute word + ! load from stack + temp0 ds-reg [] MOV + ! pop stack + ds-reg bootstrap-cell SUB + ! execute word + temp0 word-xt-offset [+] JMP ] f f f \ (execute) define-sub-primitive ! Objects [ - arg1 ds-reg [] MOV ! load from stack - arg1 tag-mask get AND ! compute tag - arg1 tag-bits get SHL ! tag the tag - ds-reg [] arg1 MOV ! push to stack + ! load from stack + temp0 ds-reg [] MOV + ! compute tag + temp0 tag-mask get AND + ! tag the tag + temp0 tag-bits get SHL + ! push to stack + ds-reg [] temp0 MOV ] f f f \ tag define-sub-primitive [ - arg0 ds-reg [] MOV ! load slot number - ds-reg bootstrap-cell SUB ! adjust stack pointer - arg1 ds-reg [] MOV ! load object - fixnum>slot@ ! turn slot number into offset - arg1 tag-bits get SHR ! mask off tag - arg1 tag-bits get SHL - arg0 arg1 arg0 [+] MOV ! load slot value - ds-reg [] arg0 MOV ! push to stack + ! load slot number + temp0 ds-reg [] MOV + ! adjust stack pointer + ds-reg bootstrap-cell SUB + ! load object + temp1 ds-reg [] MOV + ! turn slot number into offset + fixnum>slot@ + ! mask off tag + temp1 tag-bits get SHR + temp1 tag-bits get SHL + ! load slot value + temp0 temp1 temp0 [+] MOV + ! push to stack + ds-reg [] temp0 MOV ] f f f \ slot define-sub-primitive ! Shufflers @@ -127,156 +222,159 @@ big-endian off ] f f f \ 3drop define-sub-primitive [ - arg0 ds-reg [] MOV + temp0 ds-reg [] MOV ds-reg bootstrap-cell ADD - ds-reg [] arg0 MOV + ds-reg [] temp0 MOV ] f f f \ dup define-sub-primitive [ - arg0 ds-reg [] MOV - arg1 ds-reg bootstrap-cell neg [+] MOV + temp0 ds-reg [] MOV + temp1 ds-reg bootstrap-cell neg [+] MOV ds-reg 2 bootstrap-cells ADD - ds-reg [] arg0 MOV - ds-reg bootstrap-cell neg [+] arg1 MOV + ds-reg [] temp0 MOV + ds-reg bootstrap-cell neg [+] temp1 MOV ] f f f \ 2dup define-sub-primitive [ - arg0 ds-reg [] MOV - arg1 ds-reg -1 bootstrap-cells [+] MOV - temp-reg ds-reg -2 bootstrap-cells [+] MOV + temp0 ds-reg [] MOV + temp1 ds-reg -1 bootstrap-cells [+] MOV + temp3 ds-reg -2 bootstrap-cells [+] MOV ds-reg 3 bootstrap-cells ADD - ds-reg [] arg0 MOV - ds-reg -1 bootstrap-cells [+] arg1 MOV - ds-reg -2 bootstrap-cells [+] temp-reg MOV + ds-reg [] temp0 MOV + ds-reg -1 bootstrap-cells [+] temp1 MOV + ds-reg -2 bootstrap-cells [+] temp3 MOV ] f f f \ 3dup define-sub-primitive [ - arg0 ds-reg [] MOV + temp0 ds-reg [] MOV ds-reg bootstrap-cell SUB - ds-reg [] arg0 MOV + ds-reg [] temp0 MOV ] f f f \ nip define-sub-primitive [ - arg0 ds-reg [] MOV + temp0 ds-reg [] MOV ds-reg 2 bootstrap-cells SUB - ds-reg [] arg0 MOV + ds-reg [] temp0 MOV ] f f f \ 2nip define-sub-primitive [ - arg0 ds-reg -1 bootstrap-cells [+] MOV + temp0 ds-reg -1 bootstrap-cells [+] MOV ds-reg bootstrap-cell ADD - ds-reg [] arg0 MOV + ds-reg [] temp0 MOV ] f f f \ over define-sub-primitive [ - arg0 ds-reg -2 bootstrap-cells [+] MOV + temp0 ds-reg -2 bootstrap-cells [+] MOV ds-reg bootstrap-cell ADD - ds-reg [] arg0 MOV + ds-reg [] temp0 MOV ] f f f \ pick define-sub-primitive [ - arg0 ds-reg [] MOV - arg1 ds-reg -1 bootstrap-cells [+] MOV - ds-reg [] arg1 MOV + temp0 ds-reg [] MOV + temp1 ds-reg -1 bootstrap-cells [+] MOV + ds-reg [] temp1 MOV ds-reg bootstrap-cell ADD - ds-reg [] arg0 MOV + ds-reg [] temp0 MOV ] f f f \ dupd define-sub-primitive [ - arg0 ds-reg [] MOV - arg1 ds-reg -1 bootstrap-cells [+] MOV + temp0 ds-reg [] MOV + temp1 ds-reg -1 bootstrap-cells [+] MOV ds-reg bootstrap-cell ADD - ds-reg [] arg0 MOV - ds-reg -1 bootstrap-cells [+] arg1 MOV - ds-reg -2 bootstrap-cells [+] arg0 MOV + ds-reg [] temp0 MOV + ds-reg -1 bootstrap-cells [+] temp1 MOV + ds-reg -2 bootstrap-cells [+] temp0 MOV ] f f f \ tuck define-sub-primitive [ - arg0 ds-reg [] MOV - arg1 ds-reg bootstrap-cell neg [+] MOV - ds-reg bootstrap-cell neg [+] arg0 MOV - ds-reg [] arg1 MOV + temp0 ds-reg [] MOV + temp1 ds-reg bootstrap-cell neg [+] MOV + ds-reg bootstrap-cell neg [+] temp0 MOV + ds-reg [] temp1 MOV ] f f f \ swap define-sub-primitive [ - arg0 ds-reg -1 bootstrap-cells [+] MOV - arg1 ds-reg -2 bootstrap-cells [+] MOV - ds-reg -2 bootstrap-cells [+] arg0 MOV - ds-reg -1 bootstrap-cells [+] arg1 MOV + temp0 ds-reg -1 bootstrap-cells [+] MOV + temp1 ds-reg -2 bootstrap-cells [+] MOV + ds-reg -2 bootstrap-cells [+] temp0 MOV + ds-reg -1 bootstrap-cells [+] temp1 MOV ] f f f \ swapd define-sub-primitive [ - arg0 ds-reg [] MOV - arg1 ds-reg -1 bootstrap-cells [+] MOV - temp-reg ds-reg -2 bootstrap-cells [+] MOV - ds-reg -2 bootstrap-cells [+] arg1 MOV - ds-reg -1 bootstrap-cells [+] arg0 MOV - ds-reg [] temp-reg MOV + temp0 ds-reg [] MOV + temp1 ds-reg -1 bootstrap-cells [+] MOV + temp3 ds-reg -2 bootstrap-cells [+] MOV + ds-reg -2 bootstrap-cells [+] temp1 MOV + ds-reg -1 bootstrap-cells [+] temp0 MOV + ds-reg [] temp3 MOV ] f f f \ rot define-sub-primitive [ - arg0 ds-reg [] MOV - arg1 ds-reg -1 bootstrap-cells [+] MOV - temp-reg ds-reg -2 bootstrap-cells [+] MOV - ds-reg -2 bootstrap-cells [+] arg0 MOV - ds-reg -1 bootstrap-cells [+] temp-reg MOV - ds-reg [] arg1 MOV + temp0 ds-reg [] MOV + temp1 ds-reg -1 bootstrap-cells [+] MOV + temp3 ds-reg -2 bootstrap-cells [+] MOV + ds-reg -2 bootstrap-cells [+] temp0 MOV + ds-reg -1 bootstrap-cells [+] temp3 MOV + ds-reg [] temp1 MOV ] f f f \ -rot define-sub-primitive -[ - rs-reg bootstrap-cell ADD - arg0 ds-reg [] MOV - ds-reg bootstrap-cell SUB - rs-reg [] arg0 MOV -] f f f \ >r define-sub-primitive +[ jit->r ] f f f \ >r define-sub-primitive -[ - ds-reg bootstrap-cell ADD - arg0 rs-reg [] MOV - rs-reg bootstrap-cell SUB - ds-reg [] arg0 MOV -] f f f \ r> define-sub-primitive +[ jit-r> ] f f f \ r> define-sub-primitive ! Comparisons : jit-compare ( insn -- ) - arg1 0 MOV ! load t - arg1 dup [] MOV - temp-reg \ f tag-number MOV ! load f - arg0 ds-reg [] MOV ! load first value - ds-reg bootstrap-cell SUB ! adjust stack pointer - ds-reg [] arg0 CMP ! compare with second value - [ arg1 temp-reg ] dip execute ! move t if true - ds-reg [] arg1 MOV ! store - ; + ! load t + temp3 0 MOV + ! load f + temp1 \ f tag-number MOV + ! load first value + temp0 ds-reg [] MOV + ! adjust stack pointer + ds-reg bootstrap-cell SUB + ! compare with second value + ds-reg [] temp0 CMP + ! move t if true + [ temp1 temp3 ] dip execute + ! store + ds-reg [] temp1 MOV ; : define-jit-compare ( insn word -- ) - [ [ jit-compare ] curry rc-absolute-cell rt-literal 1 rex-length + ] dip + [ [ jit-compare ] curry rc-absolute-cell rt-immediate 1 rex-length + ] dip define-sub-primitive ; -\ CMOVNE \ eq? define-jit-compare -\ CMOVL \ fixnum>= define-jit-compare -\ CMOVG \ fixnum<= define-jit-compare -\ CMOVLE \ fixnum> define-jit-compare -\ CMOVGE \ fixnum< define-jit-compare +\ CMOVE \ eq? define-jit-compare +\ CMOVGE \ fixnum>= define-jit-compare +\ CMOVLE \ fixnum<= define-jit-compare +\ CMOVG \ fixnum> define-jit-compare +\ CMOVL \ fixnum< define-jit-compare ! Math : jit-math ( insn -- ) - arg0 ds-reg [] MOV ! load second input - ds-reg bootstrap-cell SUB ! pop stack - [ ds-reg [] arg0 ] dip execute ! compute result - ; + ! load second input + temp0 ds-reg [] MOV + ! pop stack + ds-reg bootstrap-cell SUB + ! compute result + [ ds-reg [] temp0 ] dip execute ; [ \ ADD jit-math ] f f f \ fixnum+fast define-sub-primitive [ \ SUB jit-math ] f f f \ fixnum-fast define-sub-primitive [ - arg0 ds-reg [] MOV ! load second input - ds-reg bootstrap-cell SUB ! pop stack - arg1 ds-reg [] MOV ! load first input - arg0 tag-bits get SAR ! untag second input - arg0 arg1 IMUL2 ! multiply - ds-reg [] arg1 MOV ! push result + ! load second input + temp0 ds-reg [] MOV + ! pop stack + ds-reg bootstrap-cell SUB + ! load first input + temp1 ds-reg [] MOV + ! untag second input + temp0 tag-bits get SAR + ! multiply + temp0 temp1 IMUL2 + ! push result + ds-reg [] temp1 MOV ] f f f \ fixnum*fast define-sub-primitive [ \ AND jit-math ] f f f \ fixnum-bitand define-sub-primitive @@ -286,49 +384,106 @@ big-endian off [ \ XOR jit-math ] f f f \ fixnum-bitxor define-sub-primitive [ - ds-reg [] NOT ! complement - ds-reg [] tag-mask get XOR ! clear tag bits + ! complement + ds-reg [] NOT + ! clear tag bits + ds-reg [] tag-mask get XOR ] f f f \ fixnum-bitnot define-sub-primitive [ - shift-arg ds-reg [] MOV ! load shift count - shift-arg tag-bits get SAR ! untag shift count - ds-reg bootstrap-cell SUB ! adjust stack pointer - temp-reg ds-reg [] MOV ! load value - arg1 temp-reg MOV ! make a copy - arg1 CL SHL ! compute positive shift value in arg1 - shift-arg NEG ! compute negative shift value in arg0 - temp-reg CL SAR - temp-reg tag-mask get bitnot AND - shift-arg 0 CMP ! if shift count was negative, move arg0 to arg1 - arg1 temp-reg CMOVGE - ds-reg [] arg1 MOV ! push to stack + ! load shift count + shift-arg ds-reg [] MOV + ! untag shift count + shift-arg tag-bits get SAR + ! adjust stack pointer + ds-reg bootstrap-cell SUB + ! load value + temp3 ds-reg [] MOV + ! make a copy + temp1 temp3 MOV + ! compute positive shift value in temp1 + temp1 CL SHL + shift-arg NEG + ! compute negative shift value in temp3 + temp3 CL SAR + temp3 tag-mask get bitnot AND + shift-arg 0 CMP + ! if shift count was negative, move temp0 to temp1 + temp1 temp3 CMOVGE + ! push to stack + ds-reg [] temp1 MOV ] f f f \ fixnum-shift-fast define-sub-primitive +: jit-fixnum-/mod ( -- ) + ! load second parameter + temp3 ds-reg [] MOV + ! load first parameter + div-arg ds-reg bootstrap-cell neg [+] MOV + ! make a copy + mod-arg div-arg MOV + ! sign-extend + mod-arg bootstrap-cell-bits 1- SAR + ! divide + temp3 IDIV ; + [ - temp-reg ds-reg [] MOV ! load second parameter - ds-reg bootstrap-cell SUB ! adjust stack pointer - div-arg ds-reg [] MOV ! load first parameter - mod-arg div-arg MOV ! make a copy - mod-arg bootstrap-cell-bits 1- SAR ! sign-extend - temp-reg IDIV ! divide - ds-reg [] mod-arg MOV ! push to stack + jit-fixnum-/mod + ! adjust stack pointer + ds-reg bootstrap-cell SUB + ! push to stack + ds-reg [] mod-arg MOV ] f f f \ fixnum-mod define-sub-primitive [ - arg0 ds-reg [] MOV ! load local number - fixnum>slot@ ! turn local number into offset - arg1 bootstrap-cell MOV ! load base - arg1 arg0 SUB ! turn it into a stack offset - arg0 rs-reg arg1 [+] MOV ! load local value - ds-reg [] arg0 MOV ! push to stack + jit-fixnum-/mod + ! adjust stack pointer + ds-reg bootstrap-cell SUB + ! tag it + div-arg tag-bits get SHL + ! push to stack + ds-reg [] div-arg MOV +] f f f \ fixnum/i-fast define-sub-primitive + +[ + jit-fixnum-/mod + ! tag it + div-arg tag-bits get SHL + ! push to stack + ds-reg [] mod-arg MOV + ds-reg bootstrap-cell neg [+] div-arg MOV +] f f f \ fixnum/mod-fast define-sub-primitive + +[ + temp0 ds-reg [] MOV + ds-reg bootstrap-cell SUB + temp0 ds-reg [] OR + temp0 tag-mask get AND + temp0 \ f tag-number MOV + temp1 1 tag-fixnum MOV + temp0 temp1 CMOVE + ds-reg [] temp0 MOV +] f f f \ both-fixnums? define-sub-primitive + +[ + ! load local number + temp0 ds-reg [] MOV + ! turn local number into offset + fixnum>slot@ + ! load local value + temp0 rs-reg temp0 [+] MOV + ! push to stack + ds-reg [] temp0 MOV ] f f f \ get-local define-sub-primitive [ - arg0 ds-reg [] MOV ! load local count - ds-reg bootstrap-cell SUB ! adjust stack pointer - fixnum>slot@ ! turn local number into offset - rs-reg arg0 SUB ! decrement retain stack pointer + ! load local count + temp0 ds-reg [] MOV + ! adjust stack pointer + ds-reg bootstrap-cell SUB + ! turn local number into offset + fixnum>slot@ + ! decrement retain stack pointer + rs-reg temp0 SUB ] f f f \ drop-locals define-sub-primitive [ "bootstrap.x86" forget-vocab ] with-compilation-unit diff --git a/basis/cpu/x86/x86.factor b/basis/cpu/x86/x86.factor index dfe3d3e55e..44300a75f9 100644 --- a/basis/cpu/x86/x86.factor +++ b/basis/cpu/x86/x86.factor @@ -5,20 +5,23 @@ cpu.x86.assembler cpu.x86.assembler.private cpu.architecture kernel kernel.private math memory namespaces make sequences words system layouts combinators math.order fry locals compiler.constants compiler.cfg.registers -compiler.cfg.instructions compiler.codegen -compiler.codegen.fixup ; +compiler.cfg.instructions compiler.cfg.intrinsics +compiler.codegen compiler.codegen.fixup ; IN: cpu.x86 +<< enable-fixnum-log2 >> + M: x86 two-operand? t ; HOOK: temp-reg-1 cpu ( -- reg ) HOOK: temp-reg-2 cpu ( -- reg ) +HOOK: param-reg-1 cpu ( -- reg ) +HOOK: param-reg-2 cpu ( -- reg ) + M: x86 %load-immediate MOV ; -HOOK: rel-literal-x86 cpu ( literal -- ) - -M: x86 %load-indirect swap 0 [] MOV rel-literal-x86 ; +M: x86 %load-indirect swap 0 MOV rc-absolute-cell rel-immediate ; HOOK: ds-reg cpu ( -- reg ) HOOK: rs-reg cpu ( -- reg ) @@ -91,6 +94,88 @@ M: x86 %shl-imm nip SHL ; M: x86 %shr-imm nip SHR ; M: x86 %sar-imm nip SAR ; M: x86 %not drop NOT ; +M: x86 %log2 BSR ; + +: ?MOV ( dst src -- ) + 2dup = [ 2drop ] [ MOV ] if ; inline + +:: move>args ( src1 src2 -- ) + { + { [ src1 param-reg-2 = ] [ param-reg-1 src2 ?MOV param-reg-1 param-reg-2 XCHG ] } + { [ src1 param-reg-1 = ] [ param-reg-2 src2 ?MOV ] } + { [ src2 param-reg-1 = ] [ param-reg-2 src1 ?MOV param-reg-1 param-reg-2 XCHG ] } + { [ src2 param-reg-2 = ] [ param-reg-1 src1 ?MOV ] } + [ + param-reg-1 src1 MOV + param-reg-2 src2 MOV + ] + } cond ; + +HOOK: %alien-invoke-tail cpu ( func dll -- ) + +:: overflow-template ( src1 src2 insn inverse func -- ) +