Merge branch 'master' of git://factorcode.org/git/factor
commit
4dd6992c7e
basis
alien
compiler
cfg
linear-scan
allocation
assignment
optimizer
renaming
stack-analysis
value-numbering
tree
modular-arithmetic
propagation
farkup
io/launcher
struct-arrays
struct-vectors
urls/encoding
core
alien
hashtables
extra
bson
reader
writer
contributors
html/elements
mongodb
benchmark
connection
tuple/collection
misc/fuel
|
@ -2,7 +2,7 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors arrays combinators fry generalizations
|
USING: accessors arrays combinators fry generalizations
|
||||||
io.encodings.ascii io.files io.files.temp io.launcher kernel
|
io.encodings.ascii io.files io.files.temp io.launcher kernel
|
||||||
locals sequences system ;
|
locals make sequences system vocabs.parser words ;
|
||||||
IN: alien.inline.compiler
|
IN: alien.inline.compiler
|
||||||
|
|
||||||
SYMBOL: C
|
SYMBOL: C
|
||||||
|
@ -15,37 +15,59 @@ SYMBOL: C++
|
||||||
{ [ dup windows? ] [ drop ".dll" ] }
|
{ [ dup windows? ] [ drop ".dll" ] }
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
|
: library-path ( str -- str' )
|
||||||
|
'[
|
||||||
|
"lib-" % current-vocab name>> %
|
||||||
|
"-" % _ % library-suffix %
|
||||||
|
] "" make temp-file ;
|
||||||
|
|
||||||
: src-suffix ( lang -- str )
|
: src-suffix ( lang -- str )
|
||||||
{
|
{
|
||||||
{ C [ ".c" ] }
|
{ C [ ".c" ] }
|
||||||
{ C++ [ ".cpp" ] }
|
{ C++ [ ".cpp" ] }
|
||||||
} case ;
|
} case ;
|
||||||
|
|
||||||
: compiler ( lang -- str )
|
HOOK: compiler os ( lang -- str )
|
||||||
|
|
||||||
|
M: word compiler ( lang -- str )
|
||||||
{
|
{
|
||||||
{ C [ "gcc" ] }
|
{ C [ "gcc" ] }
|
||||||
{ C++ [ "g++" ] }
|
{ C++ [ "g++" ] }
|
||||||
} case ;
|
} case ;
|
||||||
|
|
||||||
|
M: openbsd compiler ( lang -- str )
|
||||||
|
{
|
||||||
|
{ C [ "gcc" ] }
|
||||||
|
{ C++ [ "eg++" ] }
|
||||||
|
} case ;
|
||||||
|
|
||||||
|
HOOK: compiler-descr os ( lang -- descr )
|
||||||
|
|
||||||
|
M: word compiler-descr compiler 1array ;
|
||||||
|
M: macosx compiler-descr
|
||||||
|
call-next-method cpu x86.64?
|
||||||
|
[ { "-arch" "x86_64" } append ] when ;
|
||||||
|
|
||||||
|
HOOK: link-descr os ( -- descr )
|
||||||
|
|
||||||
|
M: word link-descr { "-shared" "-o" } ;
|
||||||
|
M: macosx link-descr
|
||||||
|
{ "-g" "-prebind" "-dynamiclib" "-o" }
|
||||||
|
cpu x86.64? [ { "-arch" "x86_64" } prepend ] when ;
|
||||||
|
|
||||||
: link-command ( in out lang -- descr )
|
: link-command ( in out lang -- descr )
|
||||||
compiler os {
|
compiler-descr link-descr append prepend prepend ;
|
||||||
{ [ dup linux? ]
|
|
||||||
[ drop { "-shared" "-o" } ] }
|
|
||||||
{ [ dup macosx? ]
|
|
||||||
[ drop { "-g" "-prebind" "-dynamiclib" "-o" } ] }
|
|
||||||
[ name>> "unimplemented for: " prepend throw ]
|
|
||||||
} cond swap prefix prepend prepend ;
|
|
||||||
|
|
||||||
:: compile-to-object ( lang contents name -- )
|
:: compile-to-object ( lang contents name -- )
|
||||||
name ".o" append temp-file
|
name ".o" append temp-file
|
||||||
contents name lang src-suffix append temp-file
|
contents name lang src-suffix append temp-file
|
||||||
[ ascii set-file-contents ] keep 2array
|
[ ascii set-file-contents ] keep 2array
|
||||||
{ "-fPIC" "-c" "-o" } lang compiler prefix prepend
|
lang compiler-descr { "-fPIC" "-c" "-o" } append prepend
|
||||||
try-process ;
|
try-process ;
|
||||||
|
|
||||||
:: link-object ( lang args name -- )
|
:: link-object ( lang args name -- )
|
||||||
args name [ "lib" prepend library-suffix append ]
|
args name [ library-path ]
|
||||||
[ ".o" append ] bi [ temp-file ] bi@ 2array
|
[ ".o" append temp-file ] bi 2array
|
||||||
lang link-command try-process ;
|
lang link-command try-process ;
|
||||||
|
|
||||||
:: compile-to-library ( lang args contents name -- )
|
:: compile-to-library ( lang args contents name -- )
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
! Copyright (C) 2009 Jeremy Hughes.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: alien.inline alien.inline.private io.directories io.files
|
||||||
|
kernel namespaces tools.test alien.c-types alien.structs ;
|
||||||
|
IN: alien.inline.tests
|
||||||
|
|
||||||
|
DELETE-C-LIBRARY: test
|
||||||
|
C-LIBRARY: test
|
||||||
|
|
||||||
|
C-FUNCTION: const-int add ( int a, int b )
|
||||||
|
return a + b;
|
||||||
|
;
|
||||||
|
|
||||||
|
C-TYPEDEF: double bigfloat
|
||||||
|
|
||||||
|
C-FUNCTION: bigfloat smaller ( bigfloat a )
|
||||||
|
return a / 10;
|
||||||
|
;
|
||||||
|
|
||||||
|
C-STRUCTURE: rectangle
|
||||||
|
{ "int" "width" }
|
||||||
|
{ "int" "height" } ;
|
||||||
|
|
||||||
|
C-FUNCTION: int area ( rectangle c )
|
||||||
|
return c.width * c.height;
|
||||||
|
;
|
||||||
|
|
||||||
|
;C-LIBRARY
|
||||||
|
|
||||||
|
{ 2 1 } [ add ] must-infer-as
|
||||||
|
[ 5 ] [ 2 3 add ] unit-test
|
||||||
|
|
||||||
|
[ t ] [ "double" "bigfloat" [ resolve-typedef ] bi@ = ] unit-test
|
||||||
|
{ 1 1 } [ smaller ] must-infer-as
|
||||||
|
[ 1.0 ] [ 10 smaller ] unit-test
|
||||||
|
|
||||||
|
[ t ] [ "rectangle" resolve-typedef struct-type? ] unit-test
|
||||||
|
{ 1 1 } [ area ] must-infer-as
|
||||||
|
[ 20 ] [
|
||||||
|
"rectangle" <c-object>
|
||||||
|
4 over set-rectangle-width
|
||||||
|
5 over set-rectangle-height
|
||||||
|
area
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
|
||||||
|
DELETE-C-LIBRARY: cpplib
|
||||||
|
C-LIBRARY: cpplib
|
||||||
|
|
||||||
|
COMPILE-AS-C++
|
||||||
|
|
||||||
|
C-INCLUDE: <string>
|
||||||
|
|
||||||
|
C-FUNCTION: const-char* hello ( )
|
||||||
|
std::string s("hello world");
|
||||||
|
return s.c_str();
|
||||||
|
;
|
||||||
|
|
||||||
|
;C-LIBRARY
|
||||||
|
|
||||||
|
{ 0 1 } [ hello ] must-infer-as
|
||||||
|
[ "hello world" ] [ hello ] unit-test
|
||||||
|
|
||||||
|
|
||||||
|
DELETE-C-LIBRARY: compile-error
|
||||||
|
C-LIBRARY: compile-error
|
||||||
|
|
||||||
|
C-FUNCTION: char* breakme ( )
|
||||||
|
return not a string;
|
||||||
|
;
|
||||||
|
|
||||||
|
<< [ compile-c-library ] must-fail >>
|
|
@ -2,10 +2,11 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors alien.inline.compiler alien.inline.types
|
USING: accessors alien.inline.compiler alien.inline.types
|
||||||
alien.libraries alien.parser arrays assocs effects fry
|
alien.libraries alien.parser arrays assocs effects fry
|
||||||
generalizations grouping io.files io.files.info io.files.temp
|
generalizations grouping io.directories io.files
|
||||||
kernel lexer math math.order math.ranges multiline namespaces
|
io.files.info io.files.temp kernel lexer math math.order
|
||||||
sequences splitting strings system vocabs.loader
|
math.ranges multiline namespaces sequences source-files
|
||||||
vocabs.parser words ;
|
splitting strings system vocabs.loader vocabs.parser words
|
||||||
|
alien.c-types alien.structs make parser ;
|
||||||
IN: alien.inline
|
IN: alien.inline
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
@ -41,15 +42,12 @@ SYMBOL: c-strings
|
||||||
: append-function-body ( prototype-str -- str )
|
: append-function-body ( prototype-str -- str )
|
||||||
" {\n" append parse-here append "\n}\n" append ;
|
" {\n" append parse-here append "\n}\n" append ;
|
||||||
|
|
||||||
|
|
||||||
: library-path ( -- str )
|
|
||||||
"lib" c-library get library-suffix
|
|
||||||
3array concat temp-file ;
|
|
||||||
|
|
||||||
: compile-library? ( -- ? )
|
: compile-library? ( -- ? )
|
||||||
library-path dup exists? [
|
c-library get library-path dup exists? [
|
||||||
current-vocab vocab-source-path
|
file get [
|
||||||
[ file-info modified>> ] bi@ <=> +lt+ =
|
path>>
|
||||||
|
[ file-info modified>> ] bi@ <=> +lt+ =
|
||||||
|
] [ drop t ] if*
|
||||||
] [ drop t ] if ;
|
] [ drop t ] if ;
|
||||||
|
|
||||||
: compile-library ( -- )
|
: compile-library ( -- )
|
||||||
|
@ -66,7 +64,7 @@ PRIVATE>
|
||||||
|
|
||||||
: compile-c-library ( -- )
|
: compile-c-library ( -- )
|
||||||
compile-library? [ compile-library ] when
|
compile-library? [ compile-library ] when
|
||||||
c-library get library-path "cdecl" add-library ;
|
c-library get dup library-path "cdecl" add-library ;
|
||||||
|
|
||||||
: define-c-function ( function types effect -- )
|
: define-c-function ( function types effect -- )
|
||||||
[ factor-function define-declared ] 3keep prototype-string
|
[ factor-function define-declared ] 3keep prototype-string
|
||||||
|
@ -89,6 +87,25 @@ PRIVATE>
|
||||||
: define-c-include ( str -- )
|
: define-c-include ( str -- )
|
||||||
"#include " prepend c-strings get push ;
|
"#include " prepend c-strings get push ;
|
||||||
|
|
||||||
|
: define-c-typedef ( old new -- )
|
||||||
|
[ typedef ] [
|
||||||
|
[ swap "typedef " % % " " % % ";" % ]
|
||||||
|
"" make c-strings get push
|
||||||
|
] 2bi ;
|
||||||
|
|
||||||
|
: define-c-struct ( name vocab fields -- )
|
||||||
|
[ define-struct ] [
|
||||||
|
nip over
|
||||||
|
[
|
||||||
|
"typedef struct " % "_" % % " {\n" %
|
||||||
|
[ first2 swap % " " % % ";\n" % ] each
|
||||||
|
"} " % % ";\n" %
|
||||||
|
] "" make c-strings get push
|
||||||
|
] 3bi ;
|
||||||
|
|
||||||
|
: delete-inline-library ( str -- )
|
||||||
|
library-path dup exists? [ delete-file ] [ drop ] if ;
|
||||||
|
|
||||||
SYNTAX: C-LIBRARY: scan define-c-library ;
|
SYNTAX: C-LIBRARY: scan define-c-library ;
|
||||||
|
|
||||||
SYNTAX: COMPILE-AS-C++ t library-is-c++ set ;
|
SYNTAX: COMPILE-AS-C++ t library-is-c++ set ;
|
||||||
|
@ -104,4 +121,14 @@ SYNTAX: C-INCLUDE: scan define-c-include ;
|
||||||
SYNTAX: C-FUNCTION:
|
SYNTAX: C-FUNCTION:
|
||||||
function-types-effect define-c-function ;
|
function-types-effect define-c-function ;
|
||||||
|
|
||||||
|
SYNTAX: C-TYPEDEF: scan scan define-c-typedef ;
|
||||||
|
|
||||||
|
SYNTAX: C-STRUCTURE:
|
||||||
|
scan current-vocab parse-definition define-c-struct ;
|
||||||
|
|
||||||
SYNTAX: ;C-LIBRARY compile-c-library ;
|
SYNTAX: ;C-LIBRARY compile-c-library ;
|
||||||
|
|
||||||
|
SYNTAX: DELETE-C-LIBRARY: scan delete-inline-library ;
|
||||||
|
|
||||||
|
SYNTAX: RAW-C:
|
||||||
|
[ "\n" % parse-here % "\n" % c-strings get push ] "" make ;
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
! Copyright (C) 2009 Jeremy Hughes.
|
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
|
||||||
USING: tools.test alien.inline alien.inline.private io.files
|
|
||||||
io.directories kernel ;
|
|
||||||
IN: alien.inline.tests
|
|
||||||
|
|
||||||
C-LIBRARY: const
|
|
||||||
|
|
||||||
C-FUNCTION: const-int add ( int a, int b )
|
|
||||||
return a + b;
|
|
||||||
;
|
|
||||||
|
|
||||||
;C-LIBRARY
|
|
||||||
|
|
||||||
{ 2 1 } [ add ] must-infer-as
|
|
||||||
[ 5 ] [ 2 3 add ] unit-test
|
|
||||||
|
|
||||||
<< library-path dup exists? [ delete-file ] [ drop ] if >>
|
|
||||||
|
|
||||||
|
|
||||||
C-LIBRARY: cpplib
|
|
||||||
|
|
||||||
COMPILE-AS-C++
|
|
||||||
|
|
||||||
C-INCLUDE: <string>
|
|
||||||
|
|
||||||
C-FUNCTION: const-char* hello ( )
|
|
||||||
std::string s("hello world");
|
|
||||||
return s.c_str();
|
|
||||||
;
|
|
||||||
|
|
||||||
;C-LIBRARY
|
|
||||||
|
|
||||||
{ 0 1 } [ hello ] must-infer-as
|
|
||||||
[ "hello world" ] [ hello ] unit-test
|
|
||||||
|
|
||||||
<< library-path dup exists? [ delete-file ] [ drop ] if >>
|
|
||||||
|
|
||||||
|
|
||||||
C-LIBRARY: compile-error
|
|
||||||
|
|
||||||
C-FUNCTION: char* breakme ( )
|
|
||||||
return not a string;
|
|
||||||
;
|
|
||||||
|
|
||||||
<< [ compile-c-library ] must-fail >>
|
|
||||||
|
|
||||||
<< library-path dup exists? [ delete-file ] [ drop ] if >>
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2009 Slava Pestov.
|
! Copyright (C) 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors alien alien.syntax assocs help.markup
|
USING: accessors alien alien.syntax assocs help.markup
|
||||||
help.syntax io.backend kernel namespaces ;
|
help.syntax io.backend kernel namespaces strings ;
|
||||||
IN: alien.libraries
|
IN: alien.libraries
|
||||||
|
|
||||||
HELP: <library>
|
HELP: <library>
|
||||||
|
@ -15,7 +15,7 @@ HELP: libraries
|
||||||
{ $description "A global hashtable that keeps a list of open libraries. Use the " { $link add-library } " word to construct a library and add it with a single call." } ;
|
{ $description "A global hashtable that keeps a list of open libraries. Use the " { $link add-library } " word to construct a library and add it with a single call." } ;
|
||||||
|
|
||||||
HELP: library
|
HELP: library
|
||||||
{ $values { "name" "a string" } { "library" assoc } }
|
{ $values { "name" string } { "library" assoc } }
|
||||||
{ $description "Looks up a library by its logical name. The library object is a hashtable with the following keys:"
|
{ $description "Looks up a library by its logical name. The library object is a hashtable with the following keys:"
|
||||||
{ $list
|
{ $list
|
||||||
{ { $snippet "name" } " - the full path of the C library binary" }
|
{ { $snippet "name" } " - the full path of the C library binary" }
|
||||||
|
@ -40,11 +40,11 @@ HELP: dlclose ( dll -- )
|
||||||
{ $description "Closes a DLL handle created by " { $link dlopen } ". This word might not be implemented on all platforms." } ;
|
{ $description "Closes a DLL handle created by " { $link dlopen } ". This word might not be implemented on all platforms." } ;
|
||||||
|
|
||||||
HELP: load-library
|
HELP: load-library
|
||||||
{ $values { "name" "a string" } { "dll" "a DLL handle" } }
|
{ $values { "name" string } { "dll" "a DLL handle" } }
|
||||||
{ $description "Loads a library by logical name and outputs a handle which may be passed to " { $link dlsym } " or " { $link dlclose } ". If the library is already loaded, returns the existing handle." } ;
|
{ $description "Loads a library by logical name and outputs a handle which may be passed to " { $link dlsym } " or " { $link dlclose } ". If the library is already loaded, returns the existing handle." } ;
|
||||||
|
|
||||||
HELP: add-library
|
HELP: add-library
|
||||||
{ $values { "name" "a string" } { "path" "a string" } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } }
|
{ $values { "name" string } { "path" string } { "abi" "one of " { $snippet "\"cdecl\"" } " or " { $snippet "\"stdcall\"" } } }
|
||||||
{ $description "Defines a new logical library named " { $snippet "name" } " located in the file system at " { $snippet "path" } "and the specified ABI." }
|
{ $description "Defines a new logical library named " { $snippet "name" } " located in the file system at " { $snippet "path" } "and the specified ABI." }
|
||||||
{ $notes "Because the entire source file is parsed before top-level forms are executed, " { $link add-library } " cannot be used in the same file as " { $link POSTPONE: FUNCTION: } " definitions from that library. The " { $link add-library } " call will happen too late, after compilation, and the alien calls will not work."
|
{ $notes "Because the entire source file is parsed before top-level forms are executed, " { $link add-library } " cannot be used in the same file as " { $link POSTPONE: FUNCTION: } " definitions from that library. The " { $link add-library } " call will happen too late, after compilation, and the alien calls will not work."
|
||||||
$nl
|
$nl
|
||||||
|
@ -59,9 +59,14 @@ $nl
|
||||||
}
|
}
|
||||||
"Note the parse time evaluation with " { $link POSTPONE: << } "." } ;
|
"Note the parse time evaluation with " { $link POSTPONE: << } "." } ;
|
||||||
|
|
||||||
|
HELP: remove-library
|
||||||
|
{ $values { "name" string } }
|
||||||
|
{ $description "Unloads a library and removes it from the internal list of libraries. The " { $snippet "name" } " parameter should be a name that was previously passed to " { $link add-library } ". If no library with that name exists, this word does nothing." } ;
|
||||||
|
|
||||||
ARTICLE: "loading-libs" "Loading native libraries"
|
ARTICLE: "loading-libs" "Loading native libraries"
|
||||||
"Before calling a C library, you must associate its path name on disk with a logical name which Factor uses to identify the library:"
|
"Before calling a C library, you must associate its path name on disk with a logical name which Factor uses to identify the library:"
|
||||||
{ $subsection add-library }
|
{ $subsection add-library }
|
||||||
|
{ $subsection remove-library }
|
||||||
"Once a library has been defined, you can try loading it to see if the path name is correct:"
|
"Once a library has been defined, you can try loading it to see if the path name is correct:"
|
||||||
{ $subsection load-library }
|
{ $subsection load-library }
|
||||||
"If the compiler cannot load a library, or cannot resolve a symbol in a library, a linkage error is reported using the compiler error mechanism (see " { $link "compiler-errors" } "). Once you install the right library, reload the source file containing the " { $link add-library } " form to force the compiler to try loading the library again." ;
|
"If the compiler cannot load a library, or cannot resolve a symbol in a library, a linkage error is reported using the compiler error mechanism (see " { $link "compiler-errors" } "). Once you install the right library, reload the source file containing the " { $link add-library } " form to force the compiler to try loading the library again." ;
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
IN: alien.libraries.tests
|
||||||
|
USING: alien.libraries alien.syntax tools.test kernel ;
|
||||||
|
|
||||||
|
[ f ] [ DLL" fadfasdfsada" dll-valid? ] unit-test
|
||||||
|
|
||||||
|
[ f ] [ "does not exist" DLL" fadsfasfdsaf" dlsym ] unit-test
|
||||||
|
|
||||||
|
[ ] [ "doesnotexist" dlopen dlclose ] unit-test
|
||||||
|
|
||||||
|
[ "fdasfsf" dll-valid? drop ] must-fail
|
|
@ -1,6 +1,7 @@
|
||||||
! Copyright (C) 2009 Slava Pestov.
|
! Copyright (C) 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors alien alien.strings assocs io.backend kernel namespaces ;
|
USING: accessors alien alien.strings assocs io.backend
|
||||||
|
kernel namespaces destructors ;
|
||||||
IN: alien.libraries
|
IN: alien.libraries
|
||||||
|
|
||||||
: dlopen ( path -- dll ) native-string>alien (dlopen) ;
|
: dlopen ( path -- dll ) native-string>alien (dlopen) ;
|
||||||
|
@ -21,5 +22,12 @@ TUPLE: library path abi dll ;
|
||||||
: load-library ( name -- dll )
|
: load-library ( name -- dll )
|
||||||
library dup [ dll>> ] when ;
|
library dup [ dll>> ] when ;
|
||||||
|
|
||||||
: add-library ( name path abi -- )
|
M: dll dispose dlclose ;
|
||||||
<library> swap libraries get set-at ;
|
|
||||||
|
M: library dispose dll>> [ dispose ] when* ;
|
||||||
|
|
||||||
|
: remove-library ( name -- )
|
||||||
|
libraries get delete-at* [ dispose ] [ drop ] if ;
|
||||||
|
|
||||||
|
: add-library ( name path abi -- )
|
||||||
|
<library> swap libraries get [ delete-at ] [ set-at ] 2bi ;
|
|
@ -48,6 +48,9 @@ SYMBOL: visited
|
||||||
building get push
|
building get push
|
||||||
] with-variable ; inline
|
] with-variable ; inline
|
||||||
|
|
||||||
|
: back-edge? ( from to -- ? )
|
||||||
|
[ number>> ] bi@ > ;
|
||||||
|
|
||||||
TUPLE: cfg { entry basic-block } word label spill-counts post-order ;
|
TUPLE: cfg { entry basic-block } word label spill-counts post-order ;
|
||||||
|
|
||||||
: <cfg> ( entry word label -- cfg ) f f cfg boa ;
|
: <cfg> ( entry word label -- cfg ) f f cfg boa ;
|
||||||
|
|
|
@ -28,16 +28,30 @@ IN: compiler.cfg.linear-scan.allocation
|
||||||
: no-free-registers? ( result -- ? )
|
: no-free-registers? ( result -- ? )
|
||||||
second 0 = ; inline
|
second 0 = ; inline
|
||||||
|
|
||||||
|
: split-to-fit ( new n -- before after )
|
||||||
|
split-interval
|
||||||
|
[ [ compute-start/end ] bi@ ]
|
||||||
|
[ >>split-next drop ]
|
||||||
|
[ ]
|
||||||
|
2tri ;
|
||||||
|
|
||||||
: register-partially-available ( new result -- )
|
: register-partially-available ( new result -- )
|
||||||
[ second split-before-use ] keep
|
{
|
||||||
'[ _ register-available ] [ add-unhandled ] bi* ;
|
{ [ 2dup second 1 - spill-live-out? ] [ drop spill-live-out ] }
|
||||||
|
{ [ 2dup second 1 - spill-live-in? ] [ drop spill-live-in ] }
|
||||||
|
[
|
||||||
|
[ second 1 - split-to-fit ] keep
|
||||||
|
'[ _ register-available ] [ add-unhandled ] bi*
|
||||||
|
]
|
||||||
|
} cond ;
|
||||||
|
|
||||||
: assign-register ( new -- )
|
: assign-register ( new -- )
|
||||||
dup coalesce? [ coalesce ] [
|
dup coalesce? [ coalesce ] [
|
||||||
dup register-status {
|
dup register-status {
|
||||||
{ [ dup no-free-registers? ] [ drop assign-blocked-register ] }
|
{ [ dup no-free-registers? ] [ drop assign-blocked-register ] }
|
||||||
{ [ 2dup register-available? ] [ register-available ] }
|
{ [ 2dup register-available? ] [ register-available ] }
|
||||||
[ register-partially-available ]
|
! [ register-partially-available ]
|
||||||
|
[ drop assign-blocked-register ]
|
||||||
} cond
|
} cond
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
|
|
|
@ -38,10 +38,10 @@ ERROR: bad-live-ranges interval ;
|
||||||
} 2cleave ;
|
} 2cleave ;
|
||||||
|
|
||||||
: assign-spill ( live-interval -- )
|
: assign-spill ( live-interval -- )
|
||||||
dup vreg>> assign-spill-slot >>spill-to drop ;
|
dup assign-spill-slot >>spill-to f >>split-next drop ;
|
||||||
|
|
||||||
: assign-reload ( live-interval -- )
|
: assign-reload ( live-interval -- )
|
||||||
dup vreg>> assign-spill-slot >>reload-from drop ;
|
dup assign-spill-slot >>reload-from drop ;
|
||||||
|
|
||||||
: split-and-spill ( live-interval n -- before after )
|
: split-and-spill ( live-interval n -- before after )
|
||||||
split-for-spill 2dup [ assign-spill ] [ assign-reload ] bi* ;
|
split-for-spill 2dup [ assign-spill ] [ assign-reload ] bi* ;
|
||||||
|
@ -80,10 +80,12 @@ ERROR: bad-live-ranges interval ;
|
||||||
[ add-unhandled ]
|
[ add-unhandled ]
|
||||||
} cleave ;
|
} cleave ;
|
||||||
|
|
||||||
: split-intersecting? ( live-interval new reg -- ? )
|
: spill-live-out? ( live-interval n -- ? ) [ uses>> last ] dip < ;
|
||||||
{ [ [ drop reg>> ] dip = ] [ drop intervals-intersect? ] } 3&& ;
|
|
||||||
|
|
||||||
: split-live-out ( live-interval -- )
|
: spill-live-out ( live-interval -- )
|
||||||
|
! The interval has no more usages after the spill location. This
|
||||||
|
! means it is the first child of an interval that was split. We
|
||||||
|
! spill the value and let the resolve pass insert a reload later.
|
||||||
{
|
{
|
||||||
[ trim-before-ranges ]
|
[ trim-before-ranges ]
|
||||||
[ compute-start/end ]
|
[ compute-start/end ]
|
||||||
|
@ -91,7 +93,13 @@ ERROR: bad-live-ranges interval ;
|
||||||
[ add-handled ]
|
[ add-handled ]
|
||||||
} cleave ;
|
} cleave ;
|
||||||
|
|
||||||
: split-live-in ( live-interval -- )
|
: spill-live-in? ( live-interval n -- ? ) [ uses>> first ] dip > ;
|
||||||
|
|
||||||
|
: spill-live-in ( live-interval -- )
|
||||||
|
! The interval does not have any usages before the spill location.
|
||||||
|
! This means it is the second child of an interval that was
|
||||||
|
! split. We reload the value and let the resolve pass insert a
|
||||||
|
! split later.
|
||||||
{
|
{
|
||||||
[ trim-after-ranges ]
|
[ trim-after-ranges ]
|
||||||
[ compute-start/end ]
|
[ compute-start/end ]
|
||||||
|
@ -99,40 +107,48 @@ ERROR: bad-live-ranges interval ;
|
||||||
[ add-unhandled ]
|
[ add-unhandled ]
|
||||||
} cleave ;
|
} cleave ;
|
||||||
|
|
||||||
: (split-intersecting) ( live-interval new -- )
|
: spill ( live-interval n -- )
|
||||||
start>> {
|
{
|
||||||
{ [ 2dup [ uses>> last ] dip < ] [ drop split-live-out ] }
|
{ [ 2dup spill-live-out? ] [ drop spill-live-out ] }
|
||||||
{ [ 2dup [ uses>> first ] dip > ] [ drop split-live-in ] }
|
{ [ 2dup spill-live-in? ] [ drop spill-live-in ] }
|
||||||
[ split-and-spill [ add-handled ] [ add-unhandled ] bi* ]
|
[ split-and-spill [ add-handled ] [ add-unhandled ] bi* ]
|
||||||
} cond ;
|
} cond ;
|
||||||
|
|
||||||
: (split-intersecting-active) ( active new -- )
|
:: spill-intersecting-active ( new reg -- )
|
||||||
[ drop delete-active ]
|
! If there is an active interval using 'reg' (there should be at
|
||||||
[ (split-intersecting) ] 2bi ;
|
! most one) are split and spilled and removed from the inactive
|
||||||
|
! set.
|
||||||
|
new vreg>> active-intervals-for [ [ reg>> reg = ] find swap dup ] keep
|
||||||
|
'[ _ delete-nth new start>> spill ] [ 2drop ] if ;
|
||||||
|
|
||||||
: split-intersecting-active ( new reg -- )
|
:: spill-intersecting-inactive ( new reg -- )
|
||||||
[ [ vreg>> active-intervals-for ] keep ] dip
|
! Any inactive intervals using 'reg' are split and spilled
|
||||||
[ '[ _ _ split-intersecting? ] filter ] 2keep drop
|
! and removed from the inactive set.
|
||||||
'[ _ (split-intersecting-active) ] each ;
|
new vreg>> inactive-intervals-for [
|
||||||
|
dup reg>> reg = [
|
||||||
|
dup new intervals-intersect? [
|
||||||
|
new start>> spill f
|
||||||
|
] [ drop t ] if
|
||||||
|
] [ drop t ] if
|
||||||
|
] filter-here ;
|
||||||
|
|
||||||
: (split-intersecting-inactive) ( inactive new -- )
|
: spill-intersecting ( new reg -- )
|
||||||
[ drop delete-inactive ]
|
! Split and spill all active and inactive intervals
|
||||||
[ (split-intersecting) ] 2bi ;
|
! which intersect 'new' and use 'reg'.
|
||||||
|
[ spill-intersecting-active ]
|
||||||
: split-intersecting-inactive ( new reg -- )
|
[ spill-intersecting-inactive ]
|
||||||
[ [ vreg>> inactive-intervals-for ] keep ] dip
|
|
||||||
[ '[ _ _ split-intersecting? ] filter ] 2keep drop
|
|
||||||
'[ _ (split-intersecting-inactive) ] each ;
|
|
||||||
|
|
||||||
: split-intersecting ( new reg -- )
|
|
||||||
[ split-intersecting-active ]
|
|
||||||
[ split-intersecting-inactive ]
|
|
||||||
2bi ;
|
2bi ;
|
||||||
|
|
||||||
: spill-available ( new pair -- )
|
: spill-available ( new pair -- )
|
||||||
[ first split-intersecting ] [ register-available ] 2bi ;
|
! A register would become fully available if all
|
||||||
|
! active and inactive intervals using it were split
|
||||||
|
! and spilled.
|
||||||
|
[ first spill-intersecting ] [ register-available ] 2bi ;
|
||||||
|
|
||||||
: spill-partially-available ( new pair -- )
|
: spill-partially-available ( new pair -- )
|
||||||
|
! A register would be available for part of the new
|
||||||
|
! interval's lifetime if all active and inactive intervals
|
||||||
|
! using that register were split and spilled.
|
||||||
[ second 1 - split-and-spill add-unhandled ] keep
|
[ second 1 - split-and-spill add-unhandled ] keep
|
||||||
spill-available ;
|
spill-available ;
|
||||||
|
|
||||||
|
|
|
@ -61,23 +61,3 @@ ERROR: splitting-atomic-interval ;
|
||||||
after split-after ;
|
after split-after ;
|
||||||
|
|
||||||
HINTS: split-interval live-interval object ;
|
HINTS: split-interval live-interval object ;
|
||||||
|
|
||||||
: split-between-blocks ( new n -- before after )
|
|
||||||
split-interval
|
|
||||||
2dup [ compute-start/end ] bi@ ;
|
|
||||||
|
|
||||||
: insert-use-for-copy ( seq n -- seq' )
|
|
||||||
[ '[ _ < ] filter ]
|
|
||||||
[ nip dup 1 + 2array ]
|
|
||||||
[ 1 + '[ _ > ] filter ]
|
|
||||||
2tri 3append ;
|
|
||||||
|
|
||||||
: split-before-use ( new n -- before after )
|
|
||||||
1 -
|
|
||||||
2dup swap covers? [
|
|
||||||
[ '[ _ insert-use-for-copy ] change-uses ] keep
|
|
||||||
split-between-blocks
|
|
||||||
2dup >>split-next drop
|
|
||||||
] [
|
|
||||||
split-between-blocks
|
|
||||||
] if ;
|
|
|
@ -126,8 +126,18 @@ SYMBOL: spill-counts
|
||||||
! Mapping from vregs to spill slots
|
! Mapping from vregs to spill slots
|
||||||
SYMBOL: spill-slots
|
SYMBOL: spill-slots
|
||||||
|
|
||||||
: assign-spill-slot ( vreg -- n )
|
DEFER: assign-spill-slot
|
||||||
spill-slots get [ reg-class>> next-spill-slot ] cache ;
|
|
||||||
|
: compute-spill-slot ( live-interval -- n )
|
||||||
|
dup copy-from>>
|
||||||
|
[ assign-spill-slot ]
|
||||||
|
[ vreg>> reg-class>> next-spill-slot ] ?if ;
|
||||||
|
|
||||||
|
: assign-spill-slot ( live-interval -- n )
|
||||||
|
dup vreg>> spill-slots get at [ ] [
|
||||||
|
[ compute-spill-slot dup ] keep
|
||||||
|
vreg>> spill-slots get set-at
|
||||||
|
] ?if ;
|
||||||
|
|
||||||
: init-allocator ( registers -- )
|
: init-allocator ( registers -- )
|
||||||
registers set
|
registers set
|
||||||
|
|
|
@ -8,6 +8,7 @@ compiler.cfg.def-use
|
||||||
compiler.cfg.liveness
|
compiler.cfg.liveness
|
||||||
compiler.cfg.registers
|
compiler.cfg.registers
|
||||||
compiler.cfg.instructions
|
compiler.cfg.instructions
|
||||||
|
compiler.cfg.linear-scan.mapping
|
||||||
compiler.cfg.linear-scan.allocation
|
compiler.cfg.linear-scan.allocation
|
||||||
compiler.cfg.linear-scan.allocation.state
|
compiler.cfg.linear-scan.allocation.state
|
||||||
compiler.cfg.linear-scan.live-intervals ;
|
compiler.cfg.linear-scan.live-intervals ;
|
||||||
|
@ -42,16 +43,11 @@ SYMBOL: register-live-outs
|
||||||
H{ } clone register-live-outs set
|
H{ } clone register-live-outs set
|
||||||
init-unhandled ;
|
init-unhandled ;
|
||||||
|
|
||||||
: insert-spill ( live-interval -- )
|
|
||||||
{
|
|
||||||
[ reg>> ]
|
|
||||||
[ vreg>> reg-class>> ]
|
|
||||||
[ spill-to>> ]
|
|
||||||
[ end>> ]
|
|
||||||
} cleave f swap \ _spill boa , ;
|
|
||||||
|
|
||||||
: handle-spill ( live-interval -- )
|
: handle-spill ( live-interval -- )
|
||||||
dup spill-to>> [ insert-spill ] [ drop ] if ;
|
dup spill-to>> [
|
||||||
|
[ reg>> ] [ spill-to>> <spill-slot> ] [ vreg>> reg-class>> ] tri
|
||||||
|
register->memory
|
||||||
|
] [ drop ] if ;
|
||||||
|
|
||||||
: first-split ( live-interval -- live-interval' )
|
: first-split ( live-interval -- live-interval' )
|
||||||
dup split-before>> [ first-split ] [ ] ?if ;
|
dup split-before>> [ first-split ] [ ] ?if ;
|
||||||
|
@ -59,22 +55,19 @@ SYMBOL: register-live-outs
|
||||||
: next-interval ( live-interval -- live-interval' )
|
: next-interval ( live-interval -- live-interval' )
|
||||||
split-next>> first-split ;
|
split-next>> first-split ;
|
||||||
|
|
||||||
: insert-copy ( live-interval -- )
|
|
||||||
{
|
|
||||||
[ next-interval reg>> ]
|
|
||||||
[ reg>> ]
|
|
||||||
[ vreg>> reg-class>> ]
|
|
||||||
[ end>> ]
|
|
||||||
} cleave f swap \ _copy boa , ;
|
|
||||||
|
|
||||||
: handle-copy ( live-interval -- )
|
: handle-copy ( live-interval -- )
|
||||||
dup split-next>> [ insert-copy ] [ drop ] if ;
|
dup split-next>> [
|
||||||
|
[ reg>> ] [ next-interval reg>> ] [ vreg>> reg-class>> ] tri
|
||||||
|
register->register
|
||||||
|
] [ drop ] if ;
|
||||||
|
|
||||||
: expire-old-intervals ( n -- )
|
: expire-old-intervals ( n -- )
|
||||||
[ pending-intervals get ] dip '[
|
[
|
||||||
dup end>> _ <
|
[ pending-intervals get ] dip '[
|
||||||
[ [ handle-spill ] [ handle-copy ] bi f ] [ drop t ] if
|
dup end>> _ <
|
||||||
] filter-here ;
|
[ [ handle-spill ] [ handle-copy ] bi f ] [ drop t ] if
|
||||||
|
] filter-here
|
||||||
|
] { } make mapping-instructions % ;
|
||||||
|
|
||||||
: insert-reload ( live-interval -- )
|
: insert-reload ( live-interval -- )
|
||||||
{
|
{
|
||||||
|
@ -114,7 +107,7 @@ SYMBOL: check-assignment?
|
||||||
ERROR: overlapping-registers intervals ;
|
ERROR: overlapping-registers intervals ;
|
||||||
|
|
||||||
: check-assignment ( intervals -- )
|
: check-assignment ( intervals -- )
|
||||||
dup [ copy-from>> ] map sift '[ vreg>> _ member? not ] filter
|
dup [ copy-from>> ] map sift [ vreg>> ] map '[ vreg>> _ member? not ] filter
|
||||||
dup [ reg>> ] map all-unique? [ drop ] [ overlapping-registers ] if ;
|
dup [ reg>> ] map all-unique? [ drop ] [ overlapping-registers ] if ;
|
||||||
|
|
||||||
: active-intervals ( n -- intervals )
|
: active-intervals ( n -- intervals )
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
IN: compiler.cfg.linear-scan.tests
|
IN: compiler.cfg.linear-scan.tests
|
||||||
USING: tools.test random sorting sequences sets hashtables assocs
|
USING: tools.test random sorting sequences sets hashtables assocs
|
||||||
kernel fry arrays splitting namespaces math accessors vectors locals
|
kernel fry arrays splitting namespaces math accessors vectors locals
|
||||||
math.order grouping strings strings.private
|
math.order grouping strings strings.private classes
|
||||||
cpu.architecture
|
cpu.architecture
|
||||||
compiler.cfg
|
compiler.cfg
|
||||||
compiler.cfg.optimizer
|
compiler.cfg.optimizer
|
||||||
|
@ -153,56 +153,6 @@ check-numbering? on
|
||||||
} 10 split-for-spill [ f >>split-next ] bi@
|
} 10 split-for-spill [ f >>split-next ] bi@
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[
|
|
||||||
T{ live-interval
|
|
||||||
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
|
||||||
{ start 0 }
|
|
||||||
{ end 4 }
|
|
||||||
{ uses V{ 0 1 4 } }
|
|
||||||
{ ranges V{ T{ live-range f 0 4 } } }
|
|
||||||
}
|
|
||||||
T{ live-interval
|
|
||||||
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
|
||||||
{ start 5 }
|
|
||||||
{ end 5 }
|
|
||||||
{ uses V{ 5 } }
|
|
||||||
{ ranges V{ T{ live-range f 5 5 } } }
|
|
||||||
}
|
|
||||||
] [
|
|
||||||
T{ live-interval
|
|
||||||
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
|
||||||
{ start 0 }
|
|
||||||
{ end 5 }
|
|
||||||
{ uses V{ 0 1 5 } }
|
|
||||||
{ ranges V{ T{ live-range f 0 5 } } }
|
|
||||||
} 5 split-before-use [ f >>split-next ] bi@
|
|
||||||
] unit-test
|
|
||||||
|
|
||||||
[
|
|
||||||
T{ live-interval
|
|
||||||
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
|
||||||
{ start 0 }
|
|
||||||
{ end 4 }
|
|
||||||
{ uses V{ 0 1 4 } }
|
|
||||||
{ ranges V{ T{ live-range f 0 4 } } }
|
|
||||||
}
|
|
||||||
T{ live-interval
|
|
||||||
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
|
||||||
{ start 5 }
|
|
||||||
{ end 10 }
|
|
||||||
{ uses V{ 5 10 } }
|
|
||||||
{ ranges V{ T{ live-range f 5 10 } } }
|
|
||||||
}
|
|
||||||
] [
|
|
||||||
T{ live-interval
|
|
||||||
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
|
||||||
{ start 0 }
|
|
||||||
{ end 10 }
|
|
||||||
{ uses V{ 0 1 10 } }
|
|
||||||
{ ranges V{ T{ live-range f 0 10 } } }
|
|
||||||
} 5 split-before-use [ f >>split-next ] bi@
|
|
||||||
] unit-test
|
|
||||||
|
|
||||||
[
|
[
|
||||||
T{ live-interval
|
T{ live-interval
|
||||||
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
{ vreg T{ vreg { reg-class int-regs } { n 1 } } }
|
||||||
|
@ -225,7 +175,7 @@ check-numbering? on
|
||||||
{ end 10 }
|
{ end 10 }
|
||||||
{ uses V{ 0 1 4 5 10 } }
|
{ uses V{ 0 1 4 5 10 } }
|
||||||
{ ranges V{ T{ live-range f 0 10 } } }
|
{ ranges V{ T{ live-range f 0 10 } } }
|
||||||
} 5 split-before-use [ f >>split-next ] bi@
|
} 4 split-to-fit [ f >>split-next ] bi@
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[
|
[
|
||||||
|
@ -1847,8 +1797,6 @@ test-diamond
|
||||||
|
|
||||||
[ ] [ { 1 2 } test-linear-scan-on-cfg ] unit-test
|
[ ] [ { 1 2 } test-linear-scan-on-cfg ] unit-test
|
||||||
|
|
||||||
USING: classes ;
|
|
||||||
|
|
||||||
[ ] [
|
[ ] [
|
||||||
1 get instructions>> first regs>> V int-regs 0 swap at
|
1 get instructions>> first regs>> V int-regs 0 swap at
|
||||||
2 get instructions>> first regs>> V int-regs 1 swap at assert=
|
2 get instructions>> first regs>> V int-regs 1 swap at assert=
|
||||||
|
|
|
@ -10,7 +10,8 @@ compiler.cfg.linear-scan.live-intervals
|
||||||
compiler.cfg.linear-scan.allocation
|
compiler.cfg.linear-scan.allocation
|
||||||
compiler.cfg.linear-scan.allocation.state
|
compiler.cfg.linear-scan.allocation.state
|
||||||
compiler.cfg.linear-scan.assignment
|
compiler.cfg.linear-scan.assignment
|
||||||
compiler.cfg.linear-scan.resolve ;
|
compiler.cfg.linear-scan.resolve
|
||||||
|
compiler.cfg.linear-scan.mapping ;
|
||||||
IN: compiler.cfg.linear-scan
|
IN: compiler.cfg.linear-scan
|
||||||
|
|
||||||
! References:
|
! References:
|
||||||
|
@ -36,6 +37,7 @@ IN: compiler.cfg.linear-scan
|
||||||
|
|
||||||
: linear-scan ( cfg -- cfg' )
|
: linear-scan ( cfg -- cfg' )
|
||||||
[
|
[
|
||||||
|
init-mapping
|
||||||
dup reverse-post-order machine-registers (linear-scan)
|
dup reverse-post-order machine-registers (linear-scan)
|
||||||
spill-counts get >>spill-counts
|
spill-counts get >>spill-counts
|
||||||
] with-scope ;
|
] with-scope ;
|
||||||
|
|
|
@ -0,0 +1,145 @@
|
||||||
|
USING: compiler.cfg.instructions
|
||||||
|
compiler.cfg.linear-scan.allocation.state
|
||||||
|
compiler.cfg.linear-scan.mapping cpu.architecture kernel
|
||||||
|
namespaces tools.test ;
|
||||||
|
IN: compiler.cfg.linear-scan.mapping.tests
|
||||||
|
|
||||||
|
H{ { int-regs 10 } { float-regs 20 } } clone spill-counts set
|
||||||
|
init-mapping
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ _copy { dst 5 } { src 4 } { class int-regs } }
|
||||||
|
T{ _spill { src 1 } { class int-regs } { n 10 } }
|
||||||
|
T{ _copy { dst 1 } { src 0 } { class int-regs } }
|
||||||
|
T{ _reload { dst 0 } { class int-regs } { n 10 } }
|
||||||
|
T{ _spill { src 1 } { class float-regs } { n 20 } }
|
||||||
|
T{ _copy { dst 1 } { src 0 } { class float-regs } }
|
||||||
|
T{ _reload { dst 0 } { class float-regs } { n 20 } }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ register->register { from 0 } { to 1 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 1 } { to 0 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 0 } { to 1 } { reg-class float-regs } }
|
||||||
|
T{ register->register { from 1 } { to 0 } { reg-class float-regs } }
|
||||||
|
T{ register->register { from 4 } { to 5 } { reg-class int-regs } }
|
||||||
|
} mapping-instructions
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ _spill { src 2 } { class int-regs } { n 10 } }
|
||||||
|
T{ _copy { dst 2 } { src 1 } { class int-regs } }
|
||||||
|
T{ _copy { dst 1 } { src 0 } { class int-regs } }
|
||||||
|
T{ _reload { dst 0 } { class int-regs } { n 10 } }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ register->register { from 0 } { to 1 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 1 } { to 2 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 2 } { to 0 } { reg-class int-regs } }
|
||||||
|
} mapping-instructions
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ _spill { src 0 } { class int-regs } { n 10 } }
|
||||||
|
T{ _copy { dst 0 } { src 2 } { class int-regs } }
|
||||||
|
T{ _copy { dst 2 } { src 1 } { class int-regs } }
|
||||||
|
T{ _reload { dst 1 } { class int-regs } { n 10 } }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ register->register { from 1 } { to 2 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 2 } { to 0 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 0 } { to 1 } { reg-class int-regs } }
|
||||||
|
} mapping-instructions
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ _copy { dst 1 } { src 0 } { class int-regs } }
|
||||||
|
T{ _copy { dst 2 } { src 0 } { class int-regs } }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ register->register { from 0 } { to 1 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 0 } { to 2 } { reg-class int-regs } }
|
||||||
|
} mapping-instructions
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{ }
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ register->register { from 4 } { to 4 } { reg-class int-regs } }
|
||||||
|
} mapping-instructions
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ _spill { src 3 } { class int-regs } { n 4 } }
|
||||||
|
T{ _reload { dst 2 } { class int-regs } { n 1 } }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ register->memory { from 3 } { to T{ spill-slot f 4 } } { reg-class int-regs } }
|
||||||
|
T{ memory->register { from T{ spill-slot f 1 } } { to 2 } { reg-class int-regs } }
|
||||||
|
} mapping-instructions
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ _copy { dst 1 } { src 0 } { class int-regs } }
|
||||||
|
T{ _copy { dst 2 } { src 0 } { class int-regs } }
|
||||||
|
T{ _copy { dst 0 } { src 3 } { class int-regs } }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ register->register { from 0 } { to 1 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 3 } { to 0 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 0 } { to 2 } { reg-class int-regs } }
|
||||||
|
} mapping-instructions
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ _copy { dst 1 } { src 0 } { class int-regs } }
|
||||||
|
T{ _copy { dst 2 } { src 0 } { class int-regs } }
|
||||||
|
T{ _spill { src 4 } { class int-regs } { n 10 } }
|
||||||
|
T{ _copy { dst 4 } { src 0 } { class int-regs } }
|
||||||
|
T{ _copy { dst 0 } { src 3 } { class int-regs } }
|
||||||
|
T{ _reload { dst 3 } { class int-regs } { n 10 } }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ register->register { from 0 } { to 1 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 0 } { to 2 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 3 } { to 0 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 4 } { to 3 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 0 } { to 4 } { reg-class int-regs } }
|
||||||
|
} mapping-instructions
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[
|
||||||
|
{
|
||||||
|
T{ _copy { dst 2 } { src 0 } { class int-regs } }
|
||||||
|
T{ _copy { dst 9 } { src 1 } { class int-regs } }
|
||||||
|
T{ _copy { dst 1 } { src 0 } { class int-regs } }
|
||||||
|
T{ _spill { src 4 } { class int-regs } { n 10 } }
|
||||||
|
T{ _copy { dst 4 } { src 0 } { class int-regs } }
|
||||||
|
T{ _copy { dst 0 } { src 3 } { class int-regs } }
|
||||||
|
T{ _reload { dst 3 } { class int-regs } { n 10 } }
|
||||||
|
}
|
||||||
|
] [
|
||||||
|
{
|
||||||
|
T{ register->register { from 0 } { to 1 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 0 } { to 2 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 1 } { to 9 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 3 } { to 0 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 4 } { to 3 } { reg-class int-regs } }
|
||||||
|
T{ register->register { from 0 } { to 4 } { reg-class int-regs } }
|
||||||
|
} mapping-instructions
|
||||||
|
] unit-test
|
|
@ -0,0 +1,148 @@
|
||||||
|
! Copyright (C) 2009 Doug Coleman.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: accessors arrays assocs classes.parser classes.tuple
|
||||||
|
combinators compiler.cfg.instructions
|
||||||
|
compiler.cfg.linear-scan.allocation.state fry hashtables kernel
|
||||||
|
locals make namespaces parser sequences sets words ;
|
||||||
|
IN: compiler.cfg.linear-scan.mapping
|
||||||
|
|
||||||
|
SYMBOL: spill-temps
|
||||||
|
|
||||||
|
: spill-temp ( reg-class -- n )
|
||||||
|
spill-temps get [ next-spill-slot ] cache ;
|
||||||
|
|
||||||
|
<<
|
||||||
|
|
||||||
|
TUPLE: operation from to reg-class ;
|
||||||
|
|
||||||
|
SYNTAX: OPERATION:
|
||||||
|
CREATE-CLASS dup save-location
|
||||||
|
[ operation { } define-tuple-class ]
|
||||||
|
[ dup '[ _ boa , ] (( from to reg-class -- )) define-declared ] bi ;
|
||||||
|
|
||||||
|
>>
|
||||||
|
|
||||||
|
OPERATION: register->memory
|
||||||
|
OPERATION: memory->register
|
||||||
|
OPERATION: register->register
|
||||||
|
|
||||||
|
! This should never come up because of how spill slots are assigned,
|
||||||
|
! so make it an error.
|
||||||
|
: memory->memory ( from to reg-class -- ) drop [ n>> ] bi@ assert= ;
|
||||||
|
|
||||||
|
GENERIC: >insn ( operation -- )
|
||||||
|
|
||||||
|
M: register->memory >insn
|
||||||
|
[ from>> ] [ reg-class>> ] [ to>> n>> ] tri _spill ;
|
||||||
|
|
||||||
|
M: memory->register >insn
|
||||||
|
[ to>> ] [ reg-class>> ] [ from>> n>> ] tri _reload ;
|
||||||
|
|
||||||
|
M: register->register >insn
|
||||||
|
[ to>> ] [ from>> ] [ reg-class>> ] tri _copy ;
|
||||||
|
|
||||||
|
SYMBOL: froms
|
||||||
|
SYMBOL: tos
|
||||||
|
|
||||||
|
SINGLETONS: memory register ;
|
||||||
|
|
||||||
|
: from-loc ( operation -- obj ) from>> spill-slot? memory register ? ;
|
||||||
|
|
||||||
|
: to-loc ( operation -- obj ) to>> spill-slot? memory register ? ;
|
||||||
|
|
||||||
|
: from-reg ( operation -- seq )
|
||||||
|
[ from-loc ] [ from>> ] [ reg-class>> ] tri 3array ;
|
||||||
|
|
||||||
|
: to-reg ( operation -- seq )
|
||||||
|
[ to-loc ] [ to>> ] [ reg-class>> ] tri 3array ;
|
||||||
|
|
||||||
|
: start? ( operations -- pair )
|
||||||
|
from-reg tos get key? not ;
|
||||||
|
|
||||||
|
: independent-assignment? ( operations -- pair )
|
||||||
|
to-reg froms get key? not ;
|
||||||
|
|
||||||
|
: set-tos/froms ( operations -- )
|
||||||
|
[ [ [ from-reg ] keep ] H{ } map>assoc froms set ]
|
||||||
|
[ [ [ to-reg ] keep ] H{ } map>assoc tos set ]
|
||||||
|
bi ;
|
||||||
|
|
||||||
|
:: (trace-chain) ( obj hashtable -- )
|
||||||
|
obj to-reg froms get at* [
|
||||||
|
dup ,
|
||||||
|
obj over hashtable clone [ maybe-set-at ] keep swap
|
||||||
|
[ (trace-chain) ] [ 2drop ] if
|
||||||
|
] [
|
||||||
|
drop
|
||||||
|
] if ;
|
||||||
|
|
||||||
|
: trace-chain ( obj -- seq )
|
||||||
|
[
|
||||||
|
dup ,
|
||||||
|
dup dup associate (trace-chain)
|
||||||
|
] { } make prune reverse ;
|
||||||
|
|
||||||
|
: trace-chains ( seq -- seq' )
|
||||||
|
[ trace-chain ] map concat ;
|
||||||
|
|
||||||
|
ERROR: resolve-error ;
|
||||||
|
|
||||||
|
: split-cycle ( operations -- chain spilled-operation )
|
||||||
|
unclip [
|
||||||
|
[ set-tos/froms ]
|
||||||
|
[
|
||||||
|
[ start? ] find nip
|
||||||
|
[ resolve-error ] unless* trace-chain
|
||||||
|
] bi
|
||||||
|
] dip ;
|
||||||
|
|
||||||
|
: break-cycle-n ( operations -- operations' )
|
||||||
|
split-cycle [
|
||||||
|
[ from>> ]
|
||||||
|
[ reg-class>> spill-temp <spill-slot> ]
|
||||||
|
[ reg-class>> ]
|
||||||
|
tri \ register->memory boa
|
||||||
|
] [
|
||||||
|
[ reg-class>> spill-temp <spill-slot> ]
|
||||||
|
[ to>> ]
|
||||||
|
[ reg-class>> ]
|
||||||
|
tri \ memory->register boa
|
||||||
|
] bi [ 1array ] bi@ surround ;
|
||||||
|
|
||||||
|
: break-cycle ( operations -- operations' )
|
||||||
|
dup length {
|
||||||
|
{ 1 [ ] }
|
||||||
|
[ drop break-cycle-n ]
|
||||||
|
} case ;
|
||||||
|
|
||||||
|
: (group-cycles) ( seq -- )
|
||||||
|
[
|
||||||
|
dup set-tos/froms
|
||||||
|
unclip trace-chain
|
||||||
|
[ diff ] keep , (group-cycles)
|
||||||
|
] unless-empty ;
|
||||||
|
|
||||||
|
: group-cycles ( seq -- seqs )
|
||||||
|
[ (group-cycles) ] { } make ;
|
||||||
|
|
||||||
|
: remove-dead-mappings ( seq -- seq' )
|
||||||
|
prune [ [ from-reg ] [ to-reg ] bi = not ] filter ;
|
||||||
|
|
||||||
|
: parallel-mappings ( operations -- seq )
|
||||||
|
[
|
||||||
|
[ independent-assignment? not ] partition %
|
||||||
|
[ start? not ] partition
|
||||||
|
[ trace-chain ] map concat dup %
|
||||||
|
diff group-cycles [ break-cycle ] map concat %
|
||||||
|
] { } make remove-dead-mappings ;
|
||||||
|
|
||||||
|
: mapping-instructions ( mappings -- insns )
|
||||||
|
[ { } ] [
|
||||||
|
[
|
||||||
|
[ set-tos/froms ] [ parallel-mappings ] bi
|
||||||
|
[ [ >insn ] each ] { } make
|
||||||
|
] with-scope
|
||||||
|
] if-empty ;
|
||||||
|
|
||||||
|
: init-mapping ( -- )
|
||||||
|
H{ } clone spill-temps set ;
|
|
@ -1,154 +1,7 @@
|
||||||
USING: accessors arrays classes compiler.cfg
|
USING: arrays compiler.cfg.linear-scan.resolve kernel
|
||||||
compiler.cfg.debugger compiler.cfg.instructions
|
tools.test ;
|
||||||
compiler.cfg.linear-scan.debugger
|
|
||||||
compiler.cfg.linear-scan.live-intervals
|
|
||||||
compiler.cfg.linear-scan.numbering
|
|
||||||
compiler.cfg.linear-scan.allocation.state
|
|
||||||
compiler.cfg.linear-scan.resolve compiler.cfg.predecessors
|
|
||||||
compiler.cfg.registers compiler.cfg.rpo cpu.architecture kernel
|
|
||||||
namespaces tools.test vectors ;
|
|
||||||
IN: compiler.cfg.linear-scan.resolve.tests
|
IN: compiler.cfg.linear-scan.resolve.tests
|
||||||
|
|
||||||
[ { 1 2 3 4 5 6 } ] [
|
[ { 1 2 3 4 5 6 } ] [
|
||||||
{ 3 4 } V{ 1 2 } clone [ { 5 6 } 3append-here ] keep >array
|
{ 3 4 } V{ 1 2 } clone [ { 5 6 } 3append-here ] keep >array
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
H{ { int-regs 10 } { float-regs 20 } } clone spill-counts set
|
|
||||||
H{ } clone spill-temps set
|
|
||||||
|
|
||||||
[
|
|
||||||
{
|
|
||||||
T{ _copy { dst 5 } { src 4 } { class int-regs } }
|
|
||||||
T{ _spill { src 1 } { class int-regs } { n 10 } }
|
|
||||||
T{ _copy { dst 1 } { src 0 } { class int-regs } }
|
|
||||||
T{ _reload { dst 0 } { class int-regs } { n 10 } }
|
|
||||||
T{ _spill { src 1 } { class float-regs } { n 20 } }
|
|
||||||
T{ _copy { dst 1 } { src 0 } { class float-regs } }
|
|
||||||
T{ _reload { dst 0 } { class float-regs } { n 20 } }
|
|
||||||
}
|
|
||||||
] [
|
|
||||||
{
|
|
||||||
T{ register->register { from 0 } { to 1 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 1 } { to 0 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 0 } { to 1 } { reg-class float-regs } }
|
|
||||||
T{ register->register { from 1 } { to 0 } { reg-class float-regs } }
|
|
||||||
T{ register->register { from 4 } { to 5 } { reg-class int-regs } }
|
|
||||||
} mapping-instructions
|
|
||||||
] unit-test
|
|
||||||
|
|
||||||
[
|
|
||||||
{
|
|
||||||
T{ _spill { src 2 } { class int-regs } { n 10 } }
|
|
||||||
T{ _copy { dst 2 } { src 1 } { class int-regs } }
|
|
||||||
T{ _copy { dst 1 } { src 0 } { class int-regs } }
|
|
||||||
T{ _reload { dst 0 } { class int-regs } { n 10 } }
|
|
||||||
}
|
|
||||||
] [
|
|
||||||
{
|
|
||||||
T{ register->register { from 0 } { to 1 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 1 } { to 2 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 2 } { to 0 } { reg-class int-regs } }
|
|
||||||
} mapping-instructions
|
|
||||||
] unit-test
|
|
||||||
|
|
||||||
[
|
|
||||||
{
|
|
||||||
T{ _spill { src 0 } { class int-regs } { n 10 } }
|
|
||||||
T{ _copy { dst 0 } { src 2 } { class int-regs } }
|
|
||||||
T{ _copy { dst 2 } { src 1 } { class int-regs } }
|
|
||||||
T{ _reload { dst 1 } { class int-regs } { n 10 } }
|
|
||||||
}
|
|
||||||
] [
|
|
||||||
{
|
|
||||||
T{ register->register { from 1 } { to 2 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 2 } { to 0 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 0 } { to 1 } { reg-class int-regs } }
|
|
||||||
} mapping-instructions
|
|
||||||
] unit-test
|
|
||||||
|
|
||||||
[
|
|
||||||
{
|
|
||||||
T{ _copy { dst 1 } { src 0 } { class int-regs } }
|
|
||||||
T{ _copy { dst 2 } { src 0 } { class int-regs } }
|
|
||||||
}
|
|
||||||
] [
|
|
||||||
{
|
|
||||||
T{ register->register { from 0 } { to 1 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 0 } { to 2 } { reg-class int-regs } }
|
|
||||||
} mapping-instructions
|
|
||||||
] unit-test
|
|
||||||
|
|
||||||
[
|
|
||||||
{ }
|
|
||||||
] [
|
|
||||||
{
|
|
||||||
T{ register->register { from 4 } { to 4 } { reg-class int-regs } }
|
|
||||||
} mapping-instructions
|
|
||||||
] unit-test
|
|
||||||
|
|
||||||
[
|
|
||||||
{
|
|
||||||
T{ _spill { src 3 } { class int-regs } { n 4 } }
|
|
||||||
T{ _reload { dst 2 } { class int-regs } { n 1 } }
|
|
||||||
}
|
|
||||||
] [
|
|
||||||
{
|
|
||||||
T{ register->memory { from 3 } { to T{ spill-slot f 4 } } { reg-class int-regs } }
|
|
||||||
T{ memory->register { from T{ spill-slot f 1 } } { to 2 } { reg-class int-regs } }
|
|
||||||
} mapping-instructions
|
|
||||||
] unit-test
|
|
||||||
|
|
||||||
|
|
||||||
[
|
|
||||||
{
|
|
||||||
T{ _copy { dst 1 } { src 0 } { class int-regs } }
|
|
||||||
T{ _copy { dst 2 } { src 0 } { class int-regs } }
|
|
||||||
T{ _copy { dst 0 } { src 3 } { class int-regs } }
|
|
||||||
}
|
|
||||||
] [
|
|
||||||
{
|
|
||||||
T{ register->register { from 0 } { to 1 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 3 } { to 0 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 0 } { to 2 } { reg-class int-regs } }
|
|
||||||
} mapping-instructions
|
|
||||||
] unit-test
|
|
||||||
|
|
||||||
[
|
|
||||||
{
|
|
||||||
T{ _copy { dst 1 } { src 0 } { class int-regs } }
|
|
||||||
T{ _copy { dst 2 } { src 0 } { class int-regs } }
|
|
||||||
T{ _spill { src 4 } { class int-regs } { n 10 } }
|
|
||||||
T{ _copy { dst 4 } { src 0 } { class int-regs } }
|
|
||||||
T{ _copy { dst 0 } { src 3 } { class int-regs } }
|
|
||||||
T{ _reload { dst 3 } { class int-regs } { n 10 } }
|
|
||||||
}
|
|
||||||
] [
|
|
||||||
{
|
|
||||||
T{ register->register { from 0 } { to 1 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 0 } { to 2 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 3 } { to 0 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 4 } { to 3 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 0 } { to 4 } { reg-class int-regs } }
|
|
||||||
} mapping-instructions
|
|
||||||
] unit-test
|
|
||||||
|
|
||||||
[
|
|
||||||
{
|
|
||||||
T{ _copy { dst 2 } { src 0 } { class int-regs } }
|
|
||||||
T{ _copy { dst 9 } { src 1 } { class int-regs } }
|
|
||||||
T{ _copy { dst 1 } { src 0 } { class int-regs } }
|
|
||||||
T{ _spill { src 4 } { class int-regs } { n 10 } }
|
|
||||||
T{ _copy { dst 4 } { src 0 } { class int-regs } }
|
|
||||||
T{ _copy { dst 0 } { src 3 } { class int-regs } }
|
|
||||||
T{ _reload { dst 3 } { class int-regs } { n 10 } }
|
|
||||||
}
|
|
||||||
] [
|
|
||||||
{
|
|
||||||
T{ register->register { from 0 } { to 1 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 0 } { to 2 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 1 } { to 9 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 3 } { to 0 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 4 } { to 3 } { reg-class int-regs } }
|
|
||||||
T{ register->register { from 0 } { to 4 } { reg-class int-regs } }
|
|
||||||
} mapping-instructions
|
|
||||||
] unit-test
|
|
||||||
|
|
|
@ -1,36 +1,13 @@
|
||||||
! Copyright (C) 2009 Slava Pestov, Doug Coleman.
|
! Copyright (C) 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors arrays assocs classes.parser classes.tuple
|
USING: accessors arrays assocs combinators
|
||||||
combinators combinators.short-circuit fry hashtables kernel locals
|
combinators.short-circuit fry kernel locals
|
||||||
make math math.order namespaces sequences sets words parser
|
make math sequences
|
||||||
compiler.cfg.instructions compiler.cfg.linear-scan.allocation.state
|
compiler.cfg.instructions
|
||||||
compiler.cfg.linear-scan.assignment compiler.cfg.liveness ;
|
compiler.cfg.linear-scan.assignment
|
||||||
|
compiler.cfg.linear-scan.mapping compiler.cfg.liveness ;
|
||||||
IN: compiler.cfg.linear-scan.resolve
|
IN: compiler.cfg.linear-scan.resolve
|
||||||
|
|
||||||
SYMBOL: spill-temps
|
|
||||||
|
|
||||||
: spill-temp ( reg-class -- n )
|
|
||||||
spill-temps get [ next-spill-slot ] cache ;
|
|
||||||
|
|
||||||
<<
|
|
||||||
|
|
||||||
TUPLE: operation from to reg-class ;
|
|
||||||
|
|
||||||
SYNTAX: OPERATION:
|
|
||||||
CREATE-CLASS dup save-location
|
|
||||||
[ operation { } define-tuple-class ]
|
|
||||||
[ dup '[ _ boa , ] (( from to reg-class -- )) define-declared ] bi ;
|
|
||||||
|
|
||||||
>>
|
|
||||||
|
|
||||||
OPERATION: register->memory
|
|
||||||
OPERATION: memory->register
|
|
||||||
OPERATION: register->register
|
|
||||||
|
|
||||||
! This should never come up because of how spill slots are assigned,
|
|
||||||
! so make it an error.
|
|
||||||
: memory->memory ( from to reg-class -- ) drop [ n>> ] bi@ assert= ;
|
|
||||||
|
|
||||||
: add-mapping ( from to reg-class -- )
|
: add-mapping ( from to reg-class -- )
|
||||||
over spill-slot? [
|
over spill-slot? [
|
||||||
pick spill-slot?
|
pick spill-slot?
|
||||||
|
@ -53,118 +30,6 @@ OPERATION: register->register
|
||||||
[ resolve-value-data-flow ] with with each
|
[ resolve-value-data-flow ] with with each
|
||||||
] { } make ;
|
] { } make ;
|
||||||
|
|
||||||
GENERIC: >insn ( operation -- )
|
|
||||||
|
|
||||||
M: register->memory >insn
|
|
||||||
[ from>> ] [ reg-class>> ] [ to>> n>> ] tri _spill ;
|
|
||||||
|
|
||||||
M: memory->register >insn
|
|
||||||
[ to>> ] [ reg-class>> ] [ from>> n>> ] tri _reload ;
|
|
||||||
|
|
||||||
M: register->register >insn
|
|
||||||
[ to>> ] [ from>> ] [ reg-class>> ] tri _copy ;
|
|
||||||
|
|
||||||
SYMBOL: froms
|
|
||||||
SYMBOL: tos
|
|
||||||
|
|
||||||
SINGLETONS: memory register ;
|
|
||||||
|
|
||||||
: from-loc ( operation -- obj ) from>> spill-slot? memory register ? ;
|
|
||||||
|
|
||||||
: to-loc ( operation -- obj ) to>> spill-slot? memory register ? ;
|
|
||||||
|
|
||||||
: from-reg ( operation -- seq )
|
|
||||||
[ from-loc ] [ from>> ] [ reg-class>> ] tri 3array ;
|
|
||||||
|
|
||||||
: to-reg ( operation -- seq )
|
|
||||||
[ to-loc ] [ to>> ] [ reg-class>> ] tri 3array ;
|
|
||||||
|
|
||||||
: start? ( operations -- pair )
|
|
||||||
from-reg tos get key? not ;
|
|
||||||
|
|
||||||
: independent-assignment? ( operations -- pair )
|
|
||||||
to-reg froms get key? not ;
|
|
||||||
|
|
||||||
: set-tos/froms ( operations -- )
|
|
||||||
[ [ [ from-reg ] keep ] H{ } map>assoc froms set ]
|
|
||||||
[ [ [ to-reg ] keep ] H{ } map>assoc tos set ]
|
|
||||||
bi ;
|
|
||||||
|
|
||||||
:: (trace-chain) ( obj hashtable -- )
|
|
||||||
obj to-reg froms get at* [
|
|
||||||
dup ,
|
|
||||||
obj over hashtable clone [ maybe-set-at ] keep swap
|
|
||||||
[ (trace-chain) ] [ 2drop ] if
|
|
||||||
] [
|
|
||||||
drop
|
|
||||||
] if ;
|
|
||||||
|
|
||||||
: trace-chain ( obj -- seq )
|
|
||||||
[
|
|
||||||
dup ,
|
|
||||||
dup dup associate (trace-chain)
|
|
||||||
] { } make prune reverse ;
|
|
||||||
|
|
||||||
: trace-chains ( seq -- seq' )
|
|
||||||
[ trace-chain ] map concat ;
|
|
||||||
|
|
||||||
ERROR: resolve-error ;
|
|
||||||
|
|
||||||
: split-cycle ( operations -- chain spilled-operation )
|
|
||||||
unclip [
|
|
||||||
[ set-tos/froms ]
|
|
||||||
[
|
|
||||||
[ start? ] find nip
|
|
||||||
[ resolve-error ] unless* trace-chain
|
|
||||||
] bi
|
|
||||||
] dip ;
|
|
||||||
|
|
||||||
: break-cycle-n ( operations -- operations' )
|
|
||||||
split-cycle [
|
|
||||||
[ from>> ]
|
|
||||||
[ reg-class>> spill-temp <spill-slot> ]
|
|
||||||
[ reg-class>> ]
|
|
||||||
tri \ register->memory boa
|
|
||||||
] [
|
|
||||||
[ reg-class>> spill-temp <spill-slot> ]
|
|
||||||
[ to>> ]
|
|
||||||
[ reg-class>> ]
|
|
||||||
tri \ memory->register boa
|
|
||||||
] bi [ 1array ] bi@ surround ;
|
|
||||||
|
|
||||||
: break-cycle ( operations -- operations' )
|
|
||||||
dup length {
|
|
||||||
{ 1 [ ] }
|
|
||||||
[ drop break-cycle-n ]
|
|
||||||
} case ;
|
|
||||||
|
|
||||||
: (group-cycles) ( seq -- )
|
|
||||||
[
|
|
||||||
dup set-tos/froms
|
|
||||||
unclip trace-chain
|
|
||||||
[ diff ] keep , (group-cycles)
|
|
||||||
] unless-empty ;
|
|
||||||
|
|
||||||
: group-cycles ( seq -- seqs )
|
|
||||||
[ (group-cycles) ] { } make ;
|
|
||||||
|
|
||||||
: remove-dead-mappings ( seq -- seq' )
|
|
||||||
prune [ [ from-reg ] [ to-reg ] bi = not ] filter ;
|
|
||||||
|
|
||||||
: parallel-mappings ( operations -- seq )
|
|
||||||
[
|
|
||||||
[ independent-assignment? not ] partition %
|
|
||||||
[ start? not ] partition
|
|
||||||
[ trace-chain ] map concat dup %
|
|
||||||
diff group-cycles [ break-cycle ] map concat %
|
|
||||||
] { } make remove-dead-mappings ;
|
|
||||||
|
|
||||||
: mapping-instructions ( mappings -- insns )
|
|
||||||
[
|
|
||||||
[ set-tos/froms ] [ parallel-mappings ] bi
|
|
||||||
[ [ >insn ] each ] { } make
|
|
||||||
] with-scope ;
|
|
||||||
|
|
||||||
: fork? ( from to -- ? )
|
: fork? ( from to -- ? )
|
||||||
{
|
{
|
||||||
[ drop successors>> length 1 >= ]
|
[ drop successors>> length 1 >= ]
|
||||||
|
@ -206,5 +71,4 @@ ERROR: resolve-error ;
|
||||||
dup successors>> [ resolve-edge-data-flow ] with each ;
|
dup successors>> [ resolve-edge-data-flow ] with each ;
|
||||||
|
|
||||||
: resolve-data-flow ( rpo -- )
|
: resolve-data-flow ( rpo -- )
|
||||||
H{ } clone spill-temps set
|
|
||||||
[ resolve-block-data-flow ] each ;
|
[ resolve-block-data-flow ] each ;
|
||||||
|
|
|
@ -2,7 +2,7 @@ USING: accessors arrays compiler.cfg.checker
|
||||||
compiler.cfg.debugger compiler.cfg.def-use
|
compiler.cfg.debugger compiler.cfg.def-use
|
||||||
compiler.cfg.instructions fry kernel kernel.private math
|
compiler.cfg.instructions fry kernel kernel.private math
|
||||||
math.private sbufs sequences sequences.private sets
|
math.private sbufs sequences sequences.private sets
|
||||||
slots.private strings tools.test vectors ;
|
slots.private strings tools.test vectors layouts ;
|
||||||
IN: compiler.cfg.optimizer.tests
|
IN: compiler.cfg.optimizer.tests
|
||||||
|
|
||||||
! Miscellaneous tests
|
! Miscellaneous tests
|
||||||
|
@ -35,10 +35,11 @@ IN: compiler.cfg.optimizer.tests
|
||||||
[ [ ] ] dip '[ _ test-mr first check-mr ] unit-test
|
[ [ ] ] dip '[ _ test-mr first check-mr ] unit-test
|
||||||
] each
|
] each
|
||||||
|
|
||||||
[ t ]
|
cell 8 = [
|
||||||
[
|
[ t ]
|
||||||
[
|
[
|
||||||
HEX: 7fff fixnum-bitand 13 fixnum-shift-fast
|
[
|
||||||
112 23 fixnum-shift-fast fixnum+fast
|
1 50 fixnum-shift-fast fixnum+fast
|
||||||
] test-mr first instructions>> [ ##add? ] any?
|
] test-mr first instructions>> [ ##add? ] any?
|
||||||
] unit-test
|
] unit-test
|
||||||
|
] when
|
||||||
|
|
|
@ -0,0 +1,151 @@
|
||||||
|
! Copyright (C) 2009 Slava Pestov.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: accessors assocs kernel namespaces sequences
|
||||||
|
compiler.cfg.instructions compiler.cfg.registers ;
|
||||||
|
IN: compiler.cfg.renaming
|
||||||
|
|
||||||
|
SYMBOL: renamings
|
||||||
|
|
||||||
|
: rename-value ( vreg -- vreg' ) renamings get at ;
|
||||||
|
|
||||||
|
GENERIC: rename-insn-defs ( insn -- )
|
||||||
|
|
||||||
|
M: ##flushable rename-insn-defs
|
||||||
|
[ rename-value ] change-dst
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: insn rename-insn-defs drop ;
|
||||||
|
|
||||||
|
GENERIC: rename-insn-uses ( insn -- )
|
||||||
|
|
||||||
|
M: ##effect rename-insn-uses
|
||||||
|
[ rename-value ] change-src
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##unary rename-insn-uses
|
||||||
|
[ rename-value ] change-src
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##binary rename-insn-uses
|
||||||
|
[ rename-value ] change-src1
|
||||||
|
[ rename-value ] change-src2
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##binary-imm rename-insn-uses
|
||||||
|
[ rename-value ] change-src1
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##slot rename-insn-uses
|
||||||
|
[ rename-value ] change-obj
|
||||||
|
[ rename-value ] change-slot
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##slot-imm rename-insn-uses
|
||||||
|
[ rename-value ] change-obj
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##set-slot rename-insn-uses
|
||||||
|
dup call-next-method
|
||||||
|
[ rename-value ] change-obj
|
||||||
|
[ rename-value ] change-slot
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##string-nth rename-insn-uses
|
||||||
|
[ rename-value ] change-obj
|
||||||
|
[ rename-value ] change-index
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##set-slot-imm rename-insn-uses
|
||||||
|
dup call-next-method
|
||||||
|
[ rename-value ] change-obj
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##alien-getter rename-insn-uses
|
||||||
|
dup call-next-method
|
||||||
|
[ rename-value ] change-src
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##alien-setter rename-insn-uses
|
||||||
|
dup call-next-method
|
||||||
|
[ rename-value ] change-value
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##conditional-branch rename-insn-uses
|
||||||
|
[ rename-value ] change-src1
|
||||||
|
[ rename-value ] change-src2
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##compare-imm-branch rename-insn-uses
|
||||||
|
[ rename-value ] change-src1
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##dispatch rename-insn-uses
|
||||||
|
[ rename-value ] change-src
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##fixnum-overflow rename-insn-uses
|
||||||
|
[ rename-value ] change-src1
|
||||||
|
[ rename-value ] change-src2
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: insn rename-insn-uses drop ;
|
||||||
|
|
||||||
|
: fresh-vreg ( vreg -- vreg' )
|
||||||
|
reg-class>> next-vreg ;
|
||||||
|
|
||||||
|
GENERIC: fresh-insn-temps ( insn -- )
|
||||||
|
|
||||||
|
M: ##write-barrier fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-card#
|
||||||
|
[ fresh-vreg ] change-table
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##unary/temp fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-temp drop ;
|
||||||
|
|
||||||
|
M: ##allot fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-temp drop ;
|
||||||
|
|
||||||
|
M: ##dispatch fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-temp drop ;
|
||||||
|
|
||||||
|
M: ##slot fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-temp drop ;
|
||||||
|
|
||||||
|
M: ##set-slot fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-temp drop ;
|
||||||
|
|
||||||
|
M: ##string-nth fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-temp drop ;
|
||||||
|
|
||||||
|
M: ##set-string-nth-fast fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-temp drop ;
|
||||||
|
|
||||||
|
M: ##compare fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-temp drop ;
|
||||||
|
|
||||||
|
M: ##compare-imm fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-temp drop ;
|
||||||
|
|
||||||
|
M: ##compare-float fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-temp drop ;
|
||||||
|
|
||||||
|
M: ##fixnum-mul fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-temp1
|
||||||
|
[ fresh-vreg ] change-temp2
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##fixnum-mul-tail fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-temp1
|
||||||
|
[ fresh-vreg ] change-temp2
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: ##gc fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-temp1
|
||||||
|
[ fresh-vreg ] change-temp2
|
||||||
|
drop ;
|
||||||
|
|
||||||
|
M: _dispatch fresh-insn-temps
|
||||||
|
[ fresh-vreg ] change-temp drop ;
|
||||||
|
|
||||||
|
M: insn fresh-insn-temps drop ;
|
|
@ -60,9 +60,6 @@ UNION: sync-if-back-edge
|
||||||
##dispatch
|
##dispatch
|
||||||
##loop-entry ;
|
##loop-entry ;
|
||||||
|
|
||||||
: back-edge? ( from to -- ? )
|
|
||||||
[ number>> ] bi@ > ;
|
|
||||||
|
|
||||||
: sync-state? ( -- ? )
|
: sync-state? ( -- ? )
|
||||||
basic-block get successors>>
|
basic-block get successors>>
|
||||||
[ [ predecessors>> ] keep '[ _ back-edge? ] any? ] any? ;
|
[ [ predecessors>> ] keep '[ _ back-edge? ] any? ] any? ;
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
|
||||||
USING: namespaces assocs sequences kernel accessors
|
|
||||||
compiler.cfg.instructions compiler.cfg.value-numbering.graph ;
|
|
||||||
IN: compiler.cfg.value-numbering.propagate
|
|
||||||
|
|
||||||
! If two vregs compute the same value, replace references to
|
|
||||||
! the latter with the former.
|
|
||||||
|
|
||||||
: resolve ( vreg -- vreg' ) vreg>vn vn>vreg ; inline
|
|
||||||
|
|
||||||
GENERIC: propagate ( insn -- insn )
|
|
||||||
|
|
||||||
M: ##effect propagate
|
|
||||||
[ resolve ] change-src ;
|
|
||||||
|
|
||||||
M: ##unary propagate
|
|
||||||
[ resolve ] change-src ;
|
|
||||||
|
|
||||||
M: ##binary propagate
|
|
||||||
[ resolve ] change-src1
|
|
||||||
[ resolve ] change-src2 ;
|
|
||||||
|
|
||||||
M: ##binary-imm propagate
|
|
||||||
[ resolve ] change-src1 ;
|
|
||||||
|
|
||||||
M: ##slot propagate
|
|
||||||
[ resolve ] change-obj
|
|
||||||
[ resolve ] change-slot ;
|
|
||||||
|
|
||||||
M: ##slot-imm propagate
|
|
||||||
[ resolve ] change-obj ;
|
|
||||||
|
|
||||||
M: ##set-slot propagate
|
|
||||||
call-next-method
|
|
||||||
[ resolve ] change-obj
|
|
||||||
[ resolve ] change-slot ;
|
|
||||||
|
|
||||||
M: ##string-nth propagate
|
|
||||||
[ resolve ] change-obj
|
|
||||||
[ resolve ] change-index ;
|
|
||||||
|
|
||||||
M: ##set-slot-imm propagate
|
|
||||||
call-next-method
|
|
||||||
[ resolve ] change-obj ;
|
|
||||||
|
|
||||||
M: ##alien-getter propagate
|
|
||||||
call-next-method
|
|
||||||
[ resolve ] change-src ;
|
|
||||||
|
|
||||||
M: ##alien-setter propagate
|
|
||||||
call-next-method
|
|
||||||
[ resolve ] change-value ;
|
|
||||||
|
|
||||||
M: ##conditional-branch propagate
|
|
||||||
[ resolve ] change-src1
|
|
||||||
[ resolve ] change-src2 ;
|
|
||||||
|
|
||||||
M: ##compare-imm-branch propagate
|
|
||||||
[ resolve ] change-src1 ;
|
|
||||||
|
|
||||||
M: ##dispatch propagate
|
|
||||||
[ resolve ] change-src ;
|
|
||||||
|
|
||||||
M: ##fixnum-overflow propagate
|
|
||||||
[ resolve ] change-src1
|
|
||||||
[ resolve ] change-src2 ;
|
|
||||||
|
|
||||||
M: insn propagate ;
|
|
|
@ -1 +0,0 @@
|
||||||
Propagation pass to update code after value numbering
|
|
|
@ -1,12 +1,12 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: namespaces assocs biassocs classes kernel math accessors
|
USING: namespaces assocs biassocs classes kernel math accessors
|
||||||
sorting sets sequences
|
sorting sets sequences fry
|
||||||
compiler.cfg.local
|
compiler.cfg.local
|
||||||
compiler.cfg.liveness
|
compiler.cfg.liveness
|
||||||
|
compiler.cfg.renaming
|
||||||
compiler.cfg.value-numbering.graph
|
compiler.cfg.value-numbering.graph
|
||||||
compiler.cfg.value-numbering.expressions
|
compiler.cfg.value-numbering.expressions
|
||||||
compiler.cfg.value-numbering.propagate
|
|
||||||
compiler.cfg.value-numbering.simplify
|
compiler.cfg.value-numbering.simplify
|
||||||
compiler.cfg.value-numbering.rewrite ;
|
compiler.cfg.value-numbering.rewrite ;
|
||||||
IN: compiler.cfg.value-numbering
|
IN: compiler.cfg.value-numbering
|
||||||
|
@ -19,8 +19,18 @@ IN: compiler.cfg.value-numbering
|
||||||
init-expressions
|
init-expressions
|
||||||
number-input-values ;
|
number-input-values ;
|
||||||
|
|
||||||
|
: vreg>vreg-mapping ( -- assoc )
|
||||||
|
vregs>vns get [ keys ] keep
|
||||||
|
'[ dup _ [ at ] [ value-at ] bi ] H{ } map>assoc ;
|
||||||
|
|
||||||
|
: rename-uses ( insns -- )
|
||||||
|
vreg>vreg-mapping renamings [
|
||||||
|
[ rename-insn-uses ] each
|
||||||
|
] with-variable ;
|
||||||
|
|
||||||
: value-numbering-step ( insns -- insns' )
|
: value-numbering-step ( insns -- insns' )
|
||||||
[ [ number-values ] [ rewrite propagate ] bi ] map ;
|
[ [ number-values ] [ rewrite ] bi ] map
|
||||||
|
dup rename-uses ;
|
||||||
|
|
||||||
: value-numbering ( cfg -- cfg' )
|
: value-numbering ( cfg -- cfg' )
|
||||||
[ init-value-numbering ] [ value-numbering-step ] local-optimization ;
|
[ init-value-numbering ] [ value-numbering-step ] local-optimization ;
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Slava Pestov
|
||||||
|
Daniel Ehrenberg
|
|
@ -1,9 +1,12 @@
|
||||||
|
! Copyright (C) 2008, 2009 Slava Pestov, Daniel Ehrenberg.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
IN: compiler.tree.modular-arithmetic.tests
|
IN: compiler.tree.modular-arithmetic.tests
|
||||||
USING: kernel kernel.private tools.test math math.partial-dispatch
|
USING: kernel kernel.private tools.test math math.partial-dispatch
|
||||||
math.private accessors slots.private sequences strings sbufs
|
math.private accessors slots.private sequences strings sbufs
|
||||||
compiler.tree.builder
|
compiler.tree.builder
|
||||||
compiler.tree.optimizer
|
compiler.tree.optimizer
|
||||||
compiler.tree.debugger ;
|
compiler.tree.debugger
|
||||||
|
alien.accessors layouts combinators byte-arrays ;
|
||||||
|
|
||||||
: test-modular-arithmetic ( quot -- quot' )
|
: test-modular-arithmetic ( quot -- quot' )
|
||||||
build-tree optimize-tree nodes>quot ;
|
build-tree optimize-tree nodes>quot ;
|
||||||
|
@ -135,4 +138,36 @@ TUPLE: declared-fixnum { x fixnum } ;
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ [ >fixnum 255 fixnum-bitand ] ]
|
[ [ >fixnum 255 fixnum-bitand ] ]
|
||||||
[ [ >integer 256 rem ] test-modular-arithmetic ] unit-test
|
[ [ >integer 256 rem ] test-modular-arithmetic ] unit-test
|
||||||
|
|
||||||
|
[ [ "COMPLEX SHUFFLE" fixnum+fast "COMPLEX SHUFFLE" set-alien-unsigned-1 ] ]
|
||||||
|
[ [ [ { fixnum fixnum } declare + ] 2dip set-alien-unsigned-1 ] test-modular-arithmetic ] unit-test
|
||||||
|
|
||||||
|
[ [ "COMPLEX SHUFFLE" fixnum+fast "COMPLEX SHUFFLE" set-alien-unsigned-2 ] ]
|
||||||
|
[ [ [ { fixnum fixnum } declare + ] 2dip set-alien-unsigned-2 ] test-modular-arithmetic ] unit-test
|
||||||
|
|
||||||
|
cell {
|
||||||
|
{ 4 [ [ [ "COMPLEX SHUFFLE" fixnum+ "COMPLEX SHUFFLE" set-alien-unsigned-4 ] ] ] }
|
||||||
|
{ 8 [ [ [ "COMPLEX SHUFFLE" fixnum+fast "COMPLEX SHUFFLE" set-alien-unsigned-4 ] ] ] }
|
||||||
|
} case
|
||||||
|
[ [ [ { fixnum fixnum } declare + ] 2dip set-alien-unsigned-4 ] test-modular-arithmetic ] unit-test
|
||||||
|
|
||||||
|
[ [ "COMPLEX SHUFFLE" fixnum+ "COMPLEX SHUFFLE" set-alien-unsigned-8 ] ]
|
||||||
|
[ [ [ { fixnum fixnum } declare + ] 2dip set-alien-unsigned-8 ] test-modular-arithmetic ] unit-test
|
||||||
|
|
||||||
|
[ [ "COMPLEX SHUFFLE" fixnum+fast "COMPLEX SHUFFLE" set-alien-signed-1 ] ]
|
||||||
|
[ [ [ { fixnum fixnum } declare + ] 2dip set-alien-signed-1 ] test-modular-arithmetic ] unit-test
|
||||||
|
|
||||||
|
[ [ "COMPLEX SHUFFLE" fixnum+fast "COMPLEX SHUFFLE" set-alien-signed-2 ] ]
|
||||||
|
[ [ [ { fixnum fixnum } declare + ] 2dip set-alien-signed-2 ] test-modular-arithmetic ] unit-test
|
||||||
|
|
||||||
|
cell {
|
||||||
|
{ 4 [ [ [ "COMPLEX SHUFFLE" fixnum+ "COMPLEX SHUFFLE" set-alien-signed-4 ] ] ] }
|
||||||
|
{ 8 [ [ [ "COMPLEX SHUFFLE" fixnum+fast "COMPLEX SHUFFLE" set-alien-signed-4 ] ] ] }
|
||||||
|
} case
|
||||||
|
[ [ [ { fixnum fixnum } declare + ] 2dip set-alien-signed-4 ] test-modular-arithmetic ] unit-test
|
||||||
|
|
||||||
|
[ [ "COMPLEX SHUFFLE" fixnum+ "COMPLEX SHUFFLE" set-alien-signed-8 ] ]
|
||||||
|
[ [ [ { fixnum fixnum } declare + ] 2dip set-alien-signed-8 ] test-modular-arithmetic ] unit-test
|
||||||
|
|
||||||
|
[ t ] [ [ { fixnum byte-array } declare [ + ] with map ] { + fixnum+ >fixnum } inlined? ] unit-test
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
! Copyright (C) 2008, 2009 Slava Pestov, Daniel Ehrenberg.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: math math.partial-dispatch namespaces sequences sets
|
USING: math math.partial-dispatch namespaces sequences sets
|
||||||
accessors assocs words kernel memoize fry combinators
|
accessors assocs words kernel memoize fry combinators
|
||||||
combinators.short-circuit
|
combinators.short-circuit layouts alien.accessors
|
||||||
compiler.tree
|
compiler.tree
|
||||||
compiler.tree.combinators
|
compiler.tree.combinators
|
||||||
compiler.tree.def-use
|
compiler.tree.def-use
|
||||||
|
@ -28,6 +28,16 @@ IN: compiler.tree.modular-arithmetic
|
||||||
{ bitand bitor bitxor bitnot }
|
{ bitand bitor bitxor bitnot }
|
||||||
[ t "modular-arithmetic" set-word-prop ] each
|
[ t "modular-arithmetic" set-word-prop ] each
|
||||||
|
|
||||||
|
{
|
||||||
|
>fixnum
|
||||||
|
set-alien-unsigned-1 set-alien-signed-1
|
||||||
|
set-alien-unsigned-2 set-alien-signed-2
|
||||||
|
}
|
||||||
|
cell 8 = [
|
||||||
|
{ set-alien-unsigned-4 set-alien-signed-4 } append
|
||||||
|
] when
|
||||||
|
[ t "low-order" set-word-prop ] each
|
||||||
|
|
||||||
SYMBOL: modularize-values
|
SYMBOL: modularize-values
|
||||||
|
|
||||||
: modular-value? ( value -- ? )
|
: modular-value? ( value -- ? )
|
||||||
|
@ -54,7 +64,7 @@ M: node maybe-modularize* 2drop ;
|
||||||
GENERIC: compute-modularized-values* ( node -- )
|
GENERIC: compute-modularized-values* ( node -- )
|
||||||
|
|
||||||
M: #call compute-modularized-values*
|
M: #call compute-modularized-values*
|
||||||
dup word>> \ >fixnum eq?
|
dup word>> "low-order" word-prop
|
||||||
[ in-d>> first maybe-modularize ] [ drop ] if ;
|
[ in-d>> first maybe-modularize ] [ drop ] if ;
|
||||||
|
|
||||||
M: node compute-modularized-values* drop ;
|
M: node compute-modularized-values* drop ;
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
! Copyright (C) 2008, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: assocs classes classes.algebra classes.tuple
|
USING: assocs classes classes.algebra classes.tuple
|
||||||
classes.tuple.private kernel accessors math math.intervals
|
classes.tuple.private kernel accessors math math.intervals
|
||||||
namespaces sequences words combinators
|
namespaces sequences words combinators byte-arrays strings
|
||||||
arrays compiler.tree.propagation.copy ;
|
arrays compiler.tree.propagation.copy ;
|
||||||
IN: compiler.tree.propagation.info
|
IN: compiler.tree.propagation.info
|
||||||
|
|
||||||
|
@ -66,12 +66,17 @@ DEFER: <literal-info>
|
||||||
[ read-only>> [ <literal-info> ] [ drop f ] if ] 2map
|
[ read-only>> [ <literal-info> ] [ drop f ] if ] 2map
|
||||||
f prefix ;
|
f prefix ;
|
||||||
|
|
||||||
|
UNION: fixed-length array byte-array string ;
|
||||||
|
|
||||||
: init-literal-info ( info -- info )
|
: init-literal-info ( info -- info )
|
||||||
|
[-inf,inf] >>interval
|
||||||
dup literal>> class >>class
|
dup literal>> class >>class
|
||||||
dup literal>> dup real? [ [a,a] >>interval ] [
|
dup literal>> {
|
||||||
[ [-inf,inf] >>interval ] dip
|
{ [ dup real? ] [ [a,a] >>interval ] }
|
||||||
dup tuple? [ tuple-slot-infos >>slots ] [ drop ] if
|
{ [ dup tuple? ] [ tuple-slot-infos >>slots ] }
|
||||||
] if ; inline
|
{ [ dup fixed-length? ] [ length <literal-info> >>length ] }
|
||||||
|
[ drop ]
|
||||||
|
} cond ; inline
|
||||||
|
|
||||||
: init-value-info ( info -- info )
|
: init-value-info ( info -- info )
|
||||||
dup literal?>> [
|
dup literal?>> [
|
||||||
|
|
|
@ -331,6 +331,16 @@ cell-bits 32 = [
|
||||||
[ { fixnum } declare dup 10 eq? [ "A" throw ] unless ] final-literals
|
[ { fixnum } declare dup 10 eq? [ "A" throw ] unless ] final-literals
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
[ V{ 3 } ] [ [ [ { 1 2 3 } ] [ { 4 5 6 } ] if length ] final-literals ] unit-test
|
||||||
|
|
||||||
|
[ V{ 3 } ] [ [ [ B{ 1 2 3 } ] [ B{ 4 5 6 } ] if length ] final-literals ] unit-test
|
||||||
|
|
||||||
|
[ V{ 3 } ] [ [ [ "yay" ] [ "hah" ] if length ] final-literals ] unit-test
|
||||||
|
|
||||||
|
[ V{ 3 } ] [ [ 3 <byte-array> length ] final-literals ] unit-test
|
||||||
|
|
||||||
|
[ V{ 3 } ] [ [ 3 f <string> length ] final-literals ] unit-test
|
||||||
|
|
||||||
! Slot propagation
|
! Slot propagation
|
||||||
TUPLE: prop-test-tuple { x integer } ;
|
TUPLE: prop-test-tuple { x integer } ;
|
||||||
|
|
||||||
|
|
|
@ -128,7 +128,7 @@ link-no-follow? off
|
||||||
|
|
||||||
[ "<p><a href=\"a\">a</a> <a href=\"b\">c</a></p>" ] [ "[[a]] [[b|c]]" convert-farkup ] unit-test
|
[ "<p><a href=\"a\">a</a> <a href=\"b\">c</a></p>" ] [ "[[a]] [[b|c]]" convert-farkup ] unit-test
|
||||||
|
|
||||||
[ "<p><a href=\"C%2b%2b\">C++</a></p>" ] [ "[[C++]]" convert-farkup ] unit-test
|
[ "<p><a href=\"C%2B%2B\">C++</a></p>" ] [ "[[C++]]" convert-farkup ] unit-test
|
||||||
|
|
||||||
[ "<p><foo></p>" ] [ "<foo>" convert-farkup ] unit-test
|
[ "<p><foo></p>" ] [ "<foo>" convert-farkup ] unit-test
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespaces urls ;
|
||||||
{ version "1.1" }
|
{ version "1.1" }
|
||||||
{ cookies V{ } }
|
{ cookies V{ } }
|
||||||
{ header H{ { "connection" "close" } { "user-agent" "Factor http.client" } } }
|
{ header H{ { "connection" "close" } { "user-agent" "Factor http.client" } } }
|
||||||
|
{ redirects 10 }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
"http://www.apple.com/index.html"
|
"http://www.apple.com/index.html"
|
||||||
|
@ -29,6 +30,7 @@ namespaces urls ;
|
||||||
{ version "1.1" }
|
{ version "1.1" }
|
||||||
{ cookies V{ } }
|
{ cookies V{ } }
|
||||||
{ header H{ { "connection" "close" } { "user-agent" "Factor http.client" } } }
|
{ header H{ { "connection" "close" } { "user-agent" "Factor http.client" } } }
|
||||||
|
{ redirects 10 }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
"https://www.amazon.com/index.html"
|
"https://www.amazon.com/index.html"
|
||||||
|
|
|
@ -12,8 +12,6 @@ IN: http.client
|
||||||
|
|
||||||
ERROR: too-many-redirects ;
|
ERROR: too-many-redirects ;
|
||||||
|
|
||||||
CONSTANT: max-redirects 10
|
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
: write-request-line ( request -- request )
|
: write-request-line ( request -- request )
|
||||||
|
@ -79,7 +77,7 @@ SYMBOL: redirects
|
||||||
|
|
||||||
:: do-redirect ( quot: ( chunk -- ) response -- response )
|
:: do-redirect ( quot: ( chunk -- ) response -- response )
|
||||||
redirects inc
|
redirects inc
|
||||||
redirects get max-redirects < [
|
redirects get request get redirects>> < [
|
||||||
request get clone
|
request get clone
|
||||||
response "location" header redirect-url
|
response "location" header redirect-url
|
||||||
response code>> 307 = [ "GET" >>method ] unless
|
response code>> 307 = [ "GET" >>method ] unless
|
||||||
|
@ -116,7 +114,8 @@ SYMBOL: redirects
|
||||||
with-output-stream*
|
with-output-stream*
|
||||||
] [
|
] [
|
||||||
in>> [
|
in>> [
|
||||||
read-response dup redirect? [ t ] [
|
read-response dup redirect?
|
||||||
|
request get redirects>> 0 > and [ t ] [
|
||||||
[ nip response set ]
|
[ nip response set ]
|
||||||
[ read-response-body ]
|
[ read-response-body ]
|
||||||
[ ]
|
[ ]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
! Copyright (C) 2008 Slava Pestov.
|
! Copyright (C) 2008 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel summary debugger io make math.parser
|
USING: kernel summary debugger io make math.parser
|
||||||
prettyprint http.client accessors ;
|
prettyprint http http.client accessors ;
|
||||||
IN: http.client.debugger
|
IN: http.client.debugger
|
||||||
|
|
||||||
M: too-many-redirects summary
|
M: too-many-redirects summary
|
||||||
|
|
|
@ -17,6 +17,7 @@ $nl
|
||||||
{ { $slot "header" } { "An assoc of HTTP header values. See " { $link "http.headers" } } }
|
{ { $slot "header" } { "An assoc of HTTP header values. See " { $link "http.headers" } } }
|
||||||
{ { $slot "post-data" } { "See " { $link "http.post-data" } } }
|
{ { $slot "post-data" } { "See " { $link "http.post-data" } } }
|
||||||
{ { $slot "cookies" } { "A sequence of HTTP cookies. See " { $link "http.cookies" } } }
|
{ { $slot "cookies" } { "A sequence of HTTP cookies. See " { $link "http.cookies" } } }
|
||||||
|
{ { $slot "redirects" } { "Number of redirects to attempt before throwing an error. Default is " { $snippet "max-redirects" } " ." } }
|
||||||
} } ;
|
} } ;
|
||||||
|
|
||||||
HELP: <response>
|
HELP: <response>
|
||||||
|
|
|
@ -33,6 +33,7 @@ blah
|
||||||
{ header H{ { "some-header" "1; 2" } { "content-length" "4" } { "content-type" "application/octet-stream" } } }
|
{ header H{ { "some-header" "1; 2" } { "content-length" "4" } { "content-type" "application/octet-stream" } } }
|
||||||
{ post-data T{ post-data { data "blah" } { content-type "application/octet-stream" } } }
|
{ post-data T{ post-data { data "blah" } { content-type "application/octet-stream" } } }
|
||||||
{ cookies V{ } }
|
{ cookies V{ } }
|
||||||
|
{ redirects 10 }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
read-request-test-1 lf>crlf [
|
read-request-test-1 lf>crlf [
|
||||||
|
@ -70,6 +71,7 @@ Host: www.sex.com
|
||||||
{ version "1.1" }
|
{ version "1.1" }
|
||||||
{ header H{ { "host" "www.sex.com" } } }
|
{ header H{ { "host" "www.sex.com" } } }
|
||||||
{ cookies V{ } }
|
{ cookies V{ } }
|
||||||
|
{ redirects 10 }
|
||||||
}
|
}
|
||||||
] [
|
] [
|
||||||
read-request-test-2 lf>crlf [
|
read-request-test-2 lf>crlf [
|
||||||
|
|
|
@ -10,6 +10,8 @@ http.parsers
|
||||||
base64 ;
|
base64 ;
|
||||||
IN: http
|
IN: http
|
||||||
|
|
||||||
|
CONSTANT: max-redirects 10
|
||||||
|
|
||||||
: (read-header) ( -- alist )
|
: (read-header) ( -- alist )
|
||||||
[ read-crlf dup f like ] [ parse-header-line ] produce nip ;
|
[ read-crlf dup f like ] [ parse-header-line ] produce nip ;
|
||||||
|
|
||||||
|
@ -137,7 +139,8 @@ url
|
||||||
version
|
version
|
||||||
header
|
header
|
||||||
post-data
|
post-data
|
||||||
cookies ;
|
cookies
|
||||||
|
redirects ;
|
||||||
|
|
||||||
: set-header ( request/response value key -- request/response )
|
: set-header ( request/response value key -- request/response )
|
||||||
pick header>> set-at ;
|
pick header>> set-at ;
|
||||||
|
@ -154,7 +157,8 @@ cookies ;
|
||||||
H{ } clone >>header
|
H{ } clone >>header
|
||||||
V{ } clone >>cookies
|
V{ } clone >>cookies
|
||||||
"close" "connection" set-header
|
"close" "connection" set-header
|
||||||
"Factor http.client" "user-agent" set-header ;
|
"Factor http.client" "user-agent" set-header
|
||||||
|
max-redirects >>redirects ;
|
||||||
|
|
||||||
: header ( request/response key -- value )
|
: header ( request/response key -- value )
|
||||||
swap header>> at ;
|
swap header>> at ;
|
||||||
|
|
|
@ -280,5 +280,3 @@ M: output-process-error error.
|
||||||
{ [ os winnt? ] [ "io.launcher.windows.nt" require ] }
|
{ [ os winnt? ] [ "io.launcher.windows.nt" require ] }
|
||||||
[ ]
|
[ ]
|
||||||
} cond
|
} cond
|
||||||
|
|
||||||
: run-desc ( desc -- result ) ascii <process-reader> f swap stream-read-until drop ;
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
IN: struct-arrays.tests
|
IN: struct-arrays.tests
|
||||||
USING: struct-arrays tools.test kernel math sequences
|
USING: struct-arrays tools.test kernel math sequences
|
||||||
alien.syntax alien.c-types destructors libc accessors ;
|
alien.syntax alien.c-types destructors libc accessors sequences.private ;
|
||||||
|
|
||||||
C-STRUCT: test-struct
|
C-STRUCT: test-struct
|
||||||
{ "int" "x" }
|
{ "int" "x" }
|
||||||
|
@ -37,4 +37,4 @@ C-STRUCT: test-struct
|
||||||
] with-destructors
|
] with-destructors
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
[ 15 ] [ 15 10 "point" <struct-array> resize length ] unit-test
|
[ 15 ] [ 15 10 "test-struct" <struct-array> resize length ] unit-test
|
|
@ -1,5 +1,6 @@
|
||||||
IN: struct-vectors.tests
|
IN: struct-vectors.tests
|
||||||
USING: struct-vectors tools.test alien.c-types kernel sequences ;
|
USING: struct-vectors tools.test alien.c-types alien.syntax
|
||||||
|
namespaces kernel sequences ;
|
||||||
|
|
||||||
C-STRUCT: point
|
C-STRUCT: point
|
||||||
{ "float" "x" }
|
{ "float" "x" }
|
||||||
|
|
|
@ -37,7 +37,7 @@ IN: urls.encoding
|
||||||
|
|
||||||
: push-utf8 ( ch -- )
|
: push-utf8 ( ch -- )
|
||||||
1string utf8 encode
|
1string utf8 encode
|
||||||
[ CHAR: % , >hex 2 CHAR: 0 pad-head % ] each ;
|
[ CHAR: % , >hex >upper 2 CHAR: 0 pad-head % ] each ;
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
|
|
|
@ -71,10 +71,6 @@ cell 8 = [
|
||||||
|
|
||||||
[ "( displaced alien )" ] [ 0 B{ 1 2 3 } <displaced-alien> unparse ] unit-test
|
[ "( displaced alien )" ] [ 0 B{ 1 2 3 } <displaced-alien> unparse ] unit-test
|
||||||
|
|
||||||
[ f ] [ DLL" fadfasdfsada" dll-valid? ] unit-test
|
|
||||||
|
|
||||||
[ f ] [ "does not exist" DLL" fadsfasfdsaf" dlsym ] unit-test
|
|
||||||
|
|
||||||
SYMBOL: initialize-test
|
SYMBOL: initialize-test
|
||||||
|
|
||||||
f initialize-test set-global
|
f initialize-test set-global
|
||||||
|
|
|
@ -176,3 +176,6 @@ H{ } "x" set
|
||||||
[ 1 ] [ "h" get assoc-size ] unit-test
|
[ 1 ] [ "h" get assoc-size ] unit-test
|
||||||
|
|
||||||
[ 1 ] [ 2 "h" get at ] unit-test
|
[ 1 ] [ 2 "h" get at ] unit-test
|
||||||
|
|
||||||
|
! Random test case
|
||||||
|
[ "A" ] [ 100 [ dup ] H{ } map>assoc 32 over delete-at "A" 32 pick set-at 32 swap at ] unit-test
|
|
@ -1,6 +1,6 @@
|
||||||
USING: accessors assocs bson.constants byte-arrays byte-vectors fry io
|
USING: accessors assocs bson.constants calendar fry io io.binary
|
||||||
io.binary io.encodings.string io.encodings.utf8 kernel math namespaces
|
io.encodings io.encodings.utf8 kernel math math.bitwise namespaces
|
||||||
sequences serialize arrays calendar io.encodings ;
|
sequences serialize ;
|
||||||
|
|
||||||
FROM: kernel.private => declare ;
|
FROM: kernel.private => declare ;
|
||||||
FROM: io.encodings.private => (read-until) ;
|
FROM: io.encodings.private => (read-until) ;
|
||||||
|
@ -44,20 +44,17 @@ GENERIC: element-read ( type -- cont? )
|
||||||
GENERIC: element-data-read ( type -- object )
|
GENERIC: element-data-read ( type -- object )
|
||||||
GENERIC: element-binary-read ( length type -- object )
|
GENERIC: element-binary-read ( length type -- object )
|
||||||
|
|
||||||
: byte-array>number ( seq -- number )
|
|
||||||
byte-array>bignum >integer ; inline
|
|
||||||
|
|
||||||
: get-state ( -- state )
|
: get-state ( -- state )
|
||||||
state get ; inline
|
state get ; inline
|
||||||
|
|
||||||
: read-int32 ( -- int32 )
|
: read-int32 ( -- int32 )
|
||||||
4 read byte-array>number ; inline
|
4 read signed-le> ; inline
|
||||||
|
|
||||||
: read-longlong ( -- longlong )
|
: read-longlong ( -- longlong )
|
||||||
8 read byte-array>number ; inline
|
8 read signed-le> ; inline
|
||||||
|
|
||||||
: read-double ( -- double )
|
: read-double ( -- double )
|
||||||
8 read byte-array>number bits>double ; inline
|
8 read le> bits>double ; inline
|
||||||
|
|
||||||
: read-byte-raw ( -- byte-raw )
|
: read-byte-raw ( -- byte-raw )
|
||||||
1 read ; inline
|
1 read ; inline
|
||||||
|
|
|
@ -75,24 +75,23 @@ M: byte-array bson-type? ( byte-array -- type ) drop T_Binary ;
|
||||||
|
|
||||||
: write-utf8-string ( string -- ) output-stream get '[ _ swap char>utf8 ] each ; inline
|
: write-utf8-string ( string -- ) output-stream get '[ _ swap char>utf8 ] each ; inline
|
||||||
|
|
||||||
: write-byte ( byte -- ) CHAR-SIZE >le write ; inline
|
|
||||||
: write-int32 ( int -- ) INT32-SIZE >le write ; inline
|
: write-int32 ( int -- ) INT32-SIZE >le write ; inline
|
||||||
: write-double ( real -- ) double>bits INT64-SIZE >le write ; inline
|
: write-double ( real -- ) double>bits INT64-SIZE >le write ; inline
|
||||||
: write-cstring ( string -- ) write-utf8-string 0 write-byte ; inline
|
: write-cstring ( string -- ) write-utf8-string 0 write1 ; inline
|
||||||
: write-longlong ( object -- ) INT64-SIZE >le write ; inline
|
: write-longlong ( object -- ) INT64-SIZE >le write ; inline
|
||||||
|
|
||||||
: write-eoo ( -- ) T_EOO write-byte ; inline
|
: write-eoo ( -- ) T_EOO write1 ; inline
|
||||||
: write-type ( obj -- obj ) [ bson-type? write-byte ] keep ; inline
|
: write-type ( obj -- obj ) [ bson-type? write1 ] keep ; inline
|
||||||
: write-pair ( name object -- ) write-type [ write-cstring ] dip bson-write ; inline
|
: write-pair ( name object -- ) write-type [ write-cstring ] dip bson-write ; inline
|
||||||
|
|
||||||
M: string bson-write ( obj -- )
|
M: string bson-write ( obj -- )
|
||||||
'[ _ write-cstring ] with-length-prefix-excl ;
|
'[ _ write-cstring ] with-length-prefix-excl ;
|
||||||
|
|
||||||
M: f bson-write ( f -- )
|
M: f bson-write ( f -- )
|
||||||
drop 0 write-byte ;
|
drop 0 write1 ;
|
||||||
|
|
||||||
M: t bson-write ( t -- )
|
M: t bson-write ( t -- )
|
||||||
drop 1 write-byte ;
|
drop 1 write1 ;
|
||||||
|
|
||||||
M: integer bson-write ( num -- )
|
M: integer bson-write ( num -- )
|
||||||
write-int32 ;
|
write-int32 ;
|
||||||
|
@ -105,7 +104,7 @@ M: timestamp bson-write ( timestamp -- )
|
||||||
|
|
||||||
M: byte-array bson-write ( binary -- )
|
M: byte-array bson-write ( binary -- )
|
||||||
[ length write-int32 ] keep
|
[ length write-int32 ] keep
|
||||||
T_Binary_Bytes write-byte
|
T_Binary_Bytes write1
|
||||||
write ;
|
write ;
|
||||||
|
|
||||||
M: oid bson-write ( oid -- )
|
M: oid bson-write ( oid -- )
|
||||||
|
@ -134,7 +133,7 @@ M: assoc bson-write ( assoc -- )
|
||||||
|
|
||||||
: (serialize-code) ( code -- )
|
: (serialize-code) ( code -- )
|
||||||
object>bytes [ length write-int32 ] keep
|
object>bytes [ length write-int32 ] keep
|
||||||
T_Binary_Custom write-byte
|
T_Binary_Custom write1
|
||||||
write ;
|
write ;
|
||||||
|
|
||||||
M: quotation bson-write ( quotation -- )
|
M: quotation bson-write ( quotation -- )
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Matthew Willis
|
|
@ -0,0 +1,16 @@
|
||||||
|
USING: central destructors help.markup help.syntax ;
|
||||||
|
|
||||||
|
HELP: CENTRAL:
|
||||||
|
{ $description
|
||||||
|
"This parsing word defines a pair of words useful for "
|
||||||
|
"implementing the \"central\" pattern: " { $snippet "symbol" } " and "
|
||||||
|
{ $snippet "with-symbol" } ". This is a middle ground between excessive "
|
||||||
|
"stack manipulation and full-out locals, meant to solve the case where "
|
||||||
|
"one object is operated on by several related words."
|
||||||
|
} ;
|
||||||
|
|
||||||
|
HELP: DISPOSABLE-CENTRAL:
|
||||||
|
{ $description
|
||||||
|
"Like " { $link POSTPONE: CENTRAL: } ", but generates " { $snippet "with-" }
|
||||||
|
" words that are wrapped in a " { $link with-disposal } "."
|
||||||
|
} ;
|
|
@ -0,0 +1,19 @@
|
||||||
|
USING: accessors central destructors kernel math tools.test ;
|
||||||
|
|
||||||
|
IN: scratchpad
|
||||||
|
|
||||||
|
CENTRAL: test-central
|
||||||
|
|
||||||
|
[ 3 ] [ 3 [ test-central ] with-test-central ] unit-test
|
||||||
|
|
||||||
|
TUPLE: test-disp-cent value disposed ;
|
||||||
|
|
||||||
|
! A phony destructor that adds 1 to the value so we can make sure it got called.
|
||||||
|
M: test-disp-cent dispose* dup value>> 1+ >>value drop ;
|
||||||
|
|
||||||
|
DISPOSABLE-CENTRAL: t-d-c
|
||||||
|
|
||||||
|
: test-t-d-c ( -- n )
|
||||||
|
test-disp-cent new 3 >>value [ t-d-c ] with-t-d-c value>> ;
|
||||||
|
|
||||||
|
[ 4 ] [ test-t-d-c ] unit-test
|
|
@ -0,0 +1,28 @@
|
||||||
|
USING: destructors kernel lexer namespaces parser sequences words ;
|
||||||
|
|
||||||
|
IN: central
|
||||||
|
|
||||||
|
: define-central-getter ( word -- )
|
||||||
|
dup [ get ] curry (( -- obj )) define-declared ;
|
||||||
|
|
||||||
|
: define-centrals ( str -- getter setter )
|
||||||
|
[ create-in dup define-central-getter ]
|
||||||
|
[ "with-" prepend create-in dup make-inline ] bi ;
|
||||||
|
|
||||||
|
: central-setter-def ( word with-word -- with-word quot )
|
||||||
|
[ with-variable ] with ;
|
||||||
|
|
||||||
|
: disposable-setter-def ( word with-word -- with-word quot )
|
||||||
|
[ pick [ drop with-variable ] with-disposal ] with ;
|
||||||
|
|
||||||
|
: declare-central ( with-word quot -- ) (( object quot -- )) define-declared ;
|
||||||
|
|
||||||
|
: define-central ( word-name -- )
|
||||||
|
define-centrals central-setter-def declare-central ;
|
||||||
|
|
||||||
|
: define-disposable-central ( word-name -- )
|
||||||
|
define-centrals disposable-setter-def declare-central ;
|
||||||
|
|
||||||
|
SYNTAX: CENTRAL: ( -- ) scan define-central ;
|
||||||
|
|
||||||
|
SYNTAX: DISPOSABLE-CENTRAL: ( -- ) scan define-disposable-central ;
|
|
@ -0,0 +1 @@
|
||||||
|
extensions
|
|
@ -7,7 +7,7 @@ IN: contributors
|
||||||
|
|
||||||
: changelog ( -- authors )
|
: changelog ( -- authors )
|
||||||
image parent-directory [
|
image parent-directory [
|
||||||
"git log --pretty=format:%an" ascii <process-reader> stream-lines
|
"git log --no-merges --pretty=format:%an" ascii <process-reader> stream-lines
|
||||||
] with-directory ;
|
] with-directory ;
|
||||||
|
|
||||||
: patch-counts ( authors -- assoc )
|
: patch-counts ( authors -- assoc )
|
||||||
|
|
|
@ -98,7 +98,7 @@ SYMBOL: html
|
||||||
[
|
[
|
||||||
"h1" "h2" "h3" "h4" "h5" "h6" "h7" "h8" "h9"
|
"h1" "h2" "h3" "h4" "h5" "h6" "h7" "h8" "h9"
|
||||||
"ol" "li" "form" "a" "p" "html" "head" "body" "title"
|
"ol" "li" "form" "a" "p" "html" "head" "body" "title"
|
||||||
"b" "i" "ul" "table" "tbody" "tr" "td" "th" "pre" "textarea"
|
"b" "i" "ul" "table" "thead" "tfoot" "tbody" "tr" "td" "th" "pre" "textarea"
|
||||||
"script" "div" "span" "select" "option" "style" "input"
|
"script" "div" "span" "select" "option" "style" "input"
|
||||||
"strong"
|
"strong"
|
||||||
] [ define-closed-html-word ] each
|
] [ define-closed-html-word ] each
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Matthew Willis
|
|
@ -0,0 +1,418 @@
|
||||||
|
! Copyright (C) 2009 Matthew Willis.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: alien.libraries alien.syntax ;
|
||||||
|
|
||||||
|
IN: llvm.core
|
||||||
|
|
||||||
|
<<
|
||||||
|
|
||||||
|
"LLVMSystem" "/usr/local/lib/libLLVMSystem.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
"LLVMSupport" "/usr/local/lib/libLLVMSupport.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
"LLVMCore" "/usr/local/lib/libLLVMCore.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
"LLVMBitReader" "/usr/local/lib/libLLVMBitReader.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
>>
|
||||||
|
|
||||||
|
! llvm-c/Core.h
|
||||||
|
|
||||||
|
LIBRARY: LLVMCore
|
||||||
|
|
||||||
|
TYPEDEF: uint unsigned
|
||||||
|
TYPEDEF: unsigned enum
|
||||||
|
|
||||||
|
CONSTANT: LLVMZExtAttribute BIN: 1
|
||||||
|
CONSTANT: LLVMSExtAttribute BIN: 10
|
||||||
|
CONSTANT: LLVMNoReturnAttribute BIN: 100
|
||||||
|
CONSTANT: LLVMInRegAttribute BIN: 1000
|
||||||
|
CONSTANT: LLVMStructRetAttribute BIN: 10000
|
||||||
|
CONSTANT: LLVMNoUnwindAttribute BIN: 100000
|
||||||
|
CONSTANT: LLVMNoAliasAttribute BIN: 1000000
|
||||||
|
CONSTANT: LLVMByValAttribute BIN: 10000000
|
||||||
|
CONSTANT: LLVMNestAttribute BIN: 100000000
|
||||||
|
CONSTANT: LLVMReadNoneAttribute BIN: 1000000000
|
||||||
|
CONSTANT: LLVMReadOnlyAttribute BIN: 10000000000
|
||||||
|
TYPEDEF: enum LLVMAttribute;
|
||||||
|
|
||||||
|
C-ENUM:
|
||||||
|
LLVMVoidTypeKind
|
||||||
|
LLVMFloatTypeKind
|
||||||
|
LLVMDoubleTypeKind
|
||||||
|
LLVMX86_FP80TypeKind
|
||||||
|
LLVMFP128TypeKind
|
||||||
|
LLVMPPC_FP128TypeKind
|
||||||
|
LLVMLabelTypeKind
|
||||||
|
LLVMMetadataTypeKind
|
||||||
|
LLVMIntegerTypeKind
|
||||||
|
LLVMFunctionTypeKind
|
||||||
|
LLVMStructTypeKind
|
||||||
|
LLVMArrayTypeKind
|
||||||
|
LLVMPointerTypeKind
|
||||||
|
LLVMOpaqueTypeKind
|
||||||
|
LLVMVectorTypeKind ;
|
||||||
|
TYPEDEF: enum LLVMTypeKind
|
||||||
|
|
||||||
|
C-ENUM:
|
||||||
|
LLVMExternalLinkage
|
||||||
|
LLVMLinkOnceLinkage
|
||||||
|
LLVMWeakLinkage
|
||||||
|
LLVMAppendingLinkage
|
||||||
|
LLVMInternalLinkage
|
||||||
|
LLVMDLLImportLinkage
|
||||||
|
LLVMDLLExportLinkage
|
||||||
|
LLVMExternalWeakLinkage
|
||||||
|
LLVMGhostLinkage ;
|
||||||
|
TYPEDEF: enum LLVMLinkage
|
||||||
|
|
||||||
|
C-ENUM:
|
||||||
|
LLVMDefaultVisibility
|
||||||
|
LLVMHiddenVisibility
|
||||||
|
LLVMProtectedVisibility ;
|
||||||
|
TYPEDEF: enum LLVMVisibility
|
||||||
|
|
||||||
|
CONSTANT: LLVMCCallConv 0
|
||||||
|
CONSTANT: LLVMFastCallConv 8
|
||||||
|
CONSTANT: LLVMColdCallConv 9
|
||||||
|
CONSTANT: LLVMX86StdcallCallConv 64
|
||||||
|
CONSTANT: LLVMX86FastcallCallConv 65
|
||||||
|
TYPEDEF: enum LLVMCallConv
|
||||||
|
|
||||||
|
CONSTANT: LLVMIntEQ 32
|
||||||
|
CONSTANT: LLVMIntNE 33
|
||||||
|
CONSTANT: LLVMIntUGT 34
|
||||||
|
CONSTANT: LLVMIntUGE 35
|
||||||
|
CONSTANT: LLVMIntULT 36
|
||||||
|
CONSTANT: LLVMIntULE 37
|
||||||
|
CONSTANT: LLVMIntSGT 38
|
||||||
|
CONSTANT: LLVMIntSGE 39
|
||||||
|
CONSTANT: LLVMIntSLT 40
|
||||||
|
CONSTANT: LLVMIntSLE 41
|
||||||
|
TYPEDEF: enum LLVMIntPredicate
|
||||||
|
|
||||||
|
C-ENUM:
|
||||||
|
LLVMRealPredicateFalse
|
||||||
|
LLVMRealOEQ
|
||||||
|
LLVMRealOGT
|
||||||
|
LLVMRealOGE
|
||||||
|
LLVMRealOLT
|
||||||
|
LLVMRealOLE
|
||||||
|
LLVMRealONE
|
||||||
|
LLVMRealORD
|
||||||
|
LLVMRealUNO
|
||||||
|
LLVMRealUEQ
|
||||||
|
LLVMRealUGT
|
||||||
|
LLVMRealUGE
|
||||||
|
LLVMRealULT
|
||||||
|
LLVMRealULE
|
||||||
|
LLVMRealUNE
|
||||||
|
LLVMRealPredicateTrue ;
|
||||||
|
TYPEDEF: enum LLVMRealPredicate
|
||||||
|
|
||||||
|
! Opaque Types
|
||||||
|
|
||||||
|
TYPEDEF: void* LLVMModuleRef
|
||||||
|
|
||||||
|
TYPEDEF: void* LLVMPassManagerRef
|
||||||
|
|
||||||
|
TYPEDEF: void* LLVMModuleProviderRef
|
||||||
|
|
||||||
|
TYPEDEF: void* LLVMTypeRef
|
||||||
|
|
||||||
|
TYPEDEF: void* LLVMTypeHandleRef
|
||||||
|
|
||||||
|
TYPEDEF: void* LLVMValueRef
|
||||||
|
|
||||||
|
TYPEDEF: void* LLVMBasicBlockRef
|
||||||
|
|
||||||
|
TYPEDEF: void* LLVMBuilderRef
|
||||||
|
|
||||||
|
TYPEDEF: void* LLVMMemoryBufferRef
|
||||||
|
|
||||||
|
! Functions
|
||||||
|
|
||||||
|
FUNCTION: void LLVMDisposeMessage ( char* Message ) ;
|
||||||
|
|
||||||
|
FUNCTION: LLVMModuleRef LLVMModuleCreateWithName ( char* ModuleID ) ;
|
||||||
|
|
||||||
|
FUNCTION: int LLVMAddTypeName ( LLVMModuleRef M, char* Name, LLVMTypeRef Ty ) ;
|
||||||
|
|
||||||
|
FUNCTION: void LLVMDisposeModule ( LLVMModuleRef M ) ;
|
||||||
|
|
||||||
|
FUNCTION: void LLVMDumpModule ( LLVMModuleRef M ) ;
|
||||||
|
|
||||||
|
FUNCTION: LLVMModuleProviderRef
|
||||||
|
LLVMCreateModuleProviderForExistingModule ( LLVMModuleRef M ) ;
|
||||||
|
|
||||||
|
FUNCTION: void LLVMDisposeModuleProvider ( LLVMModuleProviderRef MP ) ;
|
||||||
|
|
||||||
|
! Types
|
||||||
|
|
||||||
|
! LLVM types conform to the following hierarchy:
|
||||||
|
!
|
||||||
|
! types:
|
||||||
|
! integer type
|
||||||
|
! real type
|
||||||
|
! function type
|
||||||
|
! sequence types:
|
||||||
|
! array type
|
||||||
|
! pointer type
|
||||||
|
! vector type
|
||||||
|
! void type
|
||||||
|
! label type
|
||||||
|
! opaque type
|
||||||
|
|
||||||
|
! See llvm::LLVMTypeKind::getTypeID.
|
||||||
|
FUNCTION: LLVMTypeKind LLVMGetTypeKind ( LLVMTypeRef Ty ) ;
|
||||||
|
|
||||||
|
! Operations on integer types
|
||||||
|
FUNCTION: LLVMTypeRef LLVMInt1Type ( ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMInt8Type ( ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMInt16Type ( ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMInt32Type ( ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMInt64Type ( ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMIntType ( unsigned NumBits ) ;
|
||||||
|
FUNCTION: unsigned LLVMGetIntTypeWidth ( LLVMTypeRef IntegerTy ) ;
|
||||||
|
|
||||||
|
! Operations on real types
|
||||||
|
FUNCTION: LLVMTypeRef LLVMFloatType ( ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMDoubleType ( ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMX86FP80Type ( ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMFP128Type ( ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMPPCFP128Type ( ) ;
|
||||||
|
|
||||||
|
! Operations on function types
|
||||||
|
FUNCTION: LLVMTypeRef
|
||||||
|
LLVMFunctionType ( LLVMTypeRef ReturnType, LLVMTypeRef* ParamTypes, unsigned ParamCount, int IsVarArg ) ;
|
||||||
|
FUNCTION: int LLVMIsFunctionVarArg ( LLVMTypeRef FunctionTy ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMGetReturnType ( LLVMTypeRef FunctionTy ) ;
|
||||||
|
FUNCTION: unsigned LLVMCountParamTypes ( LLVMTypeRef FunctionTy ) ;
|
||||||
|
FUNCTION: void LLVMGetParamTypes ( LLVMTypeRef FunctionTy, LLVMTypeRef* Dest ) ;
|
||||||
|
|
||||||
|
! Operations on struct types
|
||||||
|
FUNCTION: LLVMTypeRef
|
||||||
|
LLVMStructType ( LLVMTypeRef* ElementTypes, unsigned ElementCount, int Packed ) ;
|
||||||
|
FUNCTION: unsigned LLVMCountStructElementTypes ( LLVMTypeRef StructTy ) ;
|
||||||
|
FUNCTION: void LLVMGetStructElementTypes ( LLVMTypeRef StructTy, LLVMTypeRef* Dest ) ;
|
||||||
|
FUNCTION: int LLVMIsPackedStruct ( LLVMTypeRef StructTy ) ;
|
||||||
|
|
||||||
|
! Operations on array, pointer, and vector types (sequence types)
|
||||||
|
FUNCTION: LLVMTypeRef LLVMArrayType ( LLVMTypeRef ElementType, unsigned ElementCount ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMPointerType ( LLVMTypeRef ElementType, unsigned AddressSpace ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMVectorType ( LLVMTypeRef ElementType, unsigned ElementCount ) ;
|
||||||
|
|
||||||
|
FUNCTION: LLVMTypeRef LLVMGetElementType ( LLVMTypeRef Ty ) ;
|
||||||
|
FUNCTION: unsigned LLVMGetArrayLength ( LLVMTypeRef ArrayTy ) ;
|
||||||
|
FUNCTION: unsigned LLVMGetPointerAddressSpace ( LLVMTypeRef PointerTy ) ;
|
||||||
|
FUNCTION: unsigned LLVMGetVectorSize ( LLVMTypeRef VectorTy ) ;
|
||||||
|
|
||||||
|
! Operations on other types
|
||||||
|
FUNCTION: LLVMTypeRef LLVMVoidType ( ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMLabelType ( ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMOpaqueType ( ) ;
|
||||||
|
|
||||||
|
! Operations on type handles
|
||||||
|
FUNCTION: LLVMTypeHandleRef LLVMCreateTypeHandle ( LLVMTypeRef PotentiallyAbstractTy ) ;
|
||||||
|
FUNCTION: void LLVMRefineType ( LLVMTypeRef AbstractTy, LLVMTypeRef ConcreteTy ) ;
|
||||||
|
FUNCTION: LLVMTypeRef LLVMResolveTypeHandle ( LLVMTypeHandleRef TypeHandle ) ;
|
||||||
|
FUNCTION: void LLVMDisposeTypeHandle ( LLVMTypeHandleRef TypeHandle ) ;
|
||||||
|
|
||||||
|
! Types end
|
||||||
|
|
||||||
|
FUNCTION: unsigned LLVMCountParams ( LLVMValueRef Fn ) ;
|
||||||
|
|
||||||
|
FUNCTION: void LLVMGetParams ( LLVMValueRef Fn, LLVMValueRef* Params ) ;
|
||||||
|
|
||||||
|
FUNCTION: LLVMValueRef
|
||||||
|
LLVMAddFunction ( LLVMModuleRef M, char* Name, LLVMTypeRef FunctionTy ) ;
|
||||||
|
|
||||||
|
FUNCTION: LLVMValueRef LLVMGetFirstFunction ( LLVMModuleRef M ) ;
|
||||||
|
|
||||||
|
FUNCTION: LLVMValueRef LLVMGetNextFunction ( LLVMValueRef Fn ) ;
|
||||||
|
|
||||||
|
FUNCTION: unsigned LLVMGetFunctionCallConv ( LLVMValueRef Fn ) ;
|
||||||
|
|
||||||
|
FUNCTION: void LLVMSetFunctionCallConv ( LLVMValueRef Fn, unsigned CC ) ;
|
||||||
|
|
||||||
|
FUNCTION: LLVMBasicBlockRef
|
||||||
|
LLVMAppendBasicBlock ( LLVMValueRef Fn, char* Name ) ;
|
||||||
|
|
||||||
|
FUNCTION: LLVMValueRef LLVMGetBasicBlockParent ( LLVMBasicBlockRef BB ) ;
|
||||||
|
|
||||||
|
! Values
|
||||||
|
|
||||||
|
FUNCTION: LLVMTypeRef LLVMTypeOf ( LLVMValueRef Val ) ;
|
||||||
|
FUNCTION: char* LLVMGetValueName ( LLVMValueRef Val ) ;
|
||||||
|
FUNCTION: void LLVMSetValueName ( LLVMValueRef Val, char* Name ) ;
|
||||||
|
FUNCTION: void LLVMDumpValue ( LLVMValueRef Val ) ;
|
||||||
|
|
||||||
|
! Instruction Builders
|
||||||
|
|
||||||
|
FUNCTION: LLVMBuilderRef LLVMCreateBuilder ( ) ;
|
||||||
|
FUNCTION: void LLVMPositionBuilder
|
||||||
|
( LLVMBuilderRef Builder, LLVMBasicBlockRef Block, LLVMValueRef Instr ) ;
|
||||||
|
FUNCTION: void LLVMPositionBuilderBefore
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Instr ) ;
|
||||||
|
FUNCTION: void LLVMPositionBuilderAtEnd
|
||||||
|
( LLVMBuilderRef Builder, LLVMBasicBlockRef Block ) ;
|
||||||
|
FUNCTION: LLVMBasicBlockRef LLVMGetInsertBlock
|
||||||
|
( LLVMBuilderRef Builder ) ;
|
||||||
|
FUNCTION: void LLVMClearInsertionPosition
|
||||||
|
( LLVMBuilderRef Builder ) ;
|
||||||
|
FUNCTION: void LLVMInsertIntoBuilder
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Instr ) ;
|
||||||
|
FUNCTION: void LLVMDisposeBuilder
|
||||||
|
( LLVMBuilderRef Builder ) ;
|
||||||
|
|
||||||
|
! IB Terminators
|
||||||
|
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildRetVoid
|
||||||
|
( LLVMBuilderRef Builder ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildRet
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef V ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildBr
|
||||||
|
( LLVMBuilderRef Builder, LLVMBasicBlockRef Dest ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildCondBr
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef If, LLVMBasicBlockRef Then, LLVMBasicBlockRef Else ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildSwitch
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef V, LLVMBasicBlockRef Else, unsigned NumCases ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildInvoke
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Fn, LLVMValueRef* Args, unsigned NumArgs,
|
||||||
|
LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildUnwind
|
||||||
|
( LLVMBuilderRef Builder ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildUnreachable
|
||||||
|
( LLVMBuilderRef Builder ) ;
|
||||||
|
|
||||||
|
! IB Add Case to Switch
|
||||||
|
|
||||||
|
FUNCTION: void LLVMAddCase
|
||||||
|
( LLVMValueRef Switch, LLVMValueRef OnVal, LLVMBasicBlockRef Dest ) ;
|
||||||
|
|
||||||
|
! IB Arithmetic
|
||||||
|
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildAdd
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildSub
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildMul
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildUDiv
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildSDiv
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildFDiv
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildURem
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildSRem
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildFRem
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildShl
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildLShr
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildAShr
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildAnd
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildOr
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildXor
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildNeg
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef V, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildNot
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef V, char* Name ) ;
|
||||||
|
|
||||||
|
! IB Memory
|
||||||
|
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildMalloc
|
||||||
|
( LLVMBuilderRef Builder, LLVMTypeRef Ty, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildArrayMalloc
|
||||||
|
( LLVMBuilderRef Builder, LLVMTypeRef Ty, LLVMValueRef Val, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildAlloca
|
||||||
|
( LLVMBuilderRef Builder, LLVMTypeRef Ty, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildArrayAlloca
|
||||||
|
( LLVMBuilderRef Builder, LLVMTypeRef Ty, LLVMValueRef Val, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildFree
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef PointerVal ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildLoad
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef PointerVal, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildStore
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMValueRef Ptr ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildGEP
|
||||||
|
( LLVMBuilderRef B, LLVMValueRef Pointer, LLVMValueRef* Indices,
|
||||||
|
unsigned NumIndices, char* Name ) ;
|
||||||
|
|
||||||
|
! IB Casts
|
||||||
|
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildTrunc
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildZExt
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildSExt
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildFPToUI
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildFPToSI
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildUIToFP
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildSIToFP
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildFPTrunc
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildFPExt
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildPtrToInt
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildIntToPtr
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildBitCast
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Val, LLVMTypeRef DestTy, char* Name ) ;
|
||||||
|
|
||||||
|
! IB Comparisons
|
||||||
|
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildICmp
|
||||||
|
( LLVMBuilderRef Builder, LLVMIntPredicate Op, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildFCmp
|
||||||
|
( LLVMBuilderRef Builder, LLVMRealPredicate Op, LLVMValueRef LHS, LLVMValueRef RHS, char* Name ) ;
|
||||||
|
|
||||||
|
! IB Misc Instructions
|
||||||
|
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildPhi
|
||||||
|
( LLVMBuilderRef Builder, LLVMTypeRef Ty, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildCall
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef Fn, LLVMValueRef* Args, unsigned NumArgs, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildSelect
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef If, LLVMValueRef Then, LLVMValueRef Else, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildVAArg
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef List, LLVMTypeRef Ty, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildExtractElement
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef VecVal, LLVMValueRef Index, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildInsertElement
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef VecVal, LLVMValueRef EltVal, LLVMValueRef Index, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildShuffleVector
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef V1, LLVMValueRef V2, LLVMValueRef Mask, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildExtractValue
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef AggVal, unsigned Index, char* Name ) ;
|
||||||
|
FUNCTION: LLVMValueRef LLVMBuildInsertValue
|
||||||
|
( LLVMBuilderRef Builder, LLVMValueRef AggVal, LLVMValueRef EltVal, unsigned Index, char* Name ) ;
|
||||||
|
|
||||||
|
! Memory Buffers/Bit Reader
|
||||||
|
|
||||||
|
FUNCTION: int LLVMCreateMemoryBufferWithContentsOfFile
|
||||||
|
( char* Path, LLVMMemoryBufferRef* OutMemBuf, char** OutMessage ) ;
|
||||||
|
|
||||||
|
FUNCTION: void LLVMDisposeMemoryBuffer ( LLVMMemoryBufferRef MemBuf ) ;
|
||||||
|
|
||||||
|
LIBRARY: LLVMBitReader
|
||||||
|
|
||||||
|
FUNCTION: int LLVMParseBitcode
|
||||||
|
( LLVMMemoryBufferRef MemBuf, LLVMModuleRef* OutModule, char** OutMessage ) ;
|
||||||
|
|
||||||
|
FUNCTION: int LLVMGetBitcodeModuleProvider
|
||||||
|
( LLVMMemoryBufferRef MemBuf, LLVMModuleProviderRef* OutMP, char** OutMessage ) ;
|
|
@ -0,0 +1,68 @@
|
||||||
|
! Copyright (C) 2009 Matthew Willis.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: alien.libraries alien.syntax llvm.core ;
|
||||||
|
IN: llvm.engine
|
||||||
|
|
||||||
|
<<
|
||||||
|
|
||||||
|
"LLVMExecutionEngine" "/usr/local/lib/libLLVMExecutionEngine.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
"LLVMTarget" "/usr/local/lib/libLLVMTarget.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
"LLVMAnalysis" "/usr/local/lib/libLLVMAnalysis.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
"LLVMipa" "/usr/local/lib/libLLVMipa.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
"LLVMTransformUtils" "/usr/local/lib/libLLVMTransformUtils.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
"LLVMScalarOpts" "/usr/local/lib/libLLVMScalarOpts.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
"LLVMCodeGen" "/usr/local/lib/libLLVMCodeGen.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
"LLVMAsmPrinter" "/usr/local/lib/libLLVMAsmPrinter.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
"LLVMSelectionDAG" "/usr/local/lib/libLLVMSelectionDAG.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
"LLVMX86CodeGen" "/usr/local/lib/libLLVMX86CodeGen.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
"LLVMJIT" "/usr/local/lib/libLLVMJIT.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
"LLVMInterpreter.dylib" "/usr/local/lib/libLLVMInterpreter.dylib" "cdecl" add-library
|
||||||
|
|
||||||
|
>>
|
||||||
|
|
||||||
|
! llvm-c/ExecutionEngine.h
|
||||||
|
|
||||||
|
LIBRARY: LLVMExecutionEngine
|
||||||
|
|
||||||
|
TYPEDEF: void* LLVMGenericValueRef
|
||||||
|
TYPEDEF: void* LLVMExecutionEngineRef
|
||||||
|
|
||||||
|
FUNCTION: LLVMGenericValueRef LLVMCreateGenericValueOfInt
|
||||||
|
( LLVMTypeRef Ty, ulonglong N, int IsSigned ) ;
|
||||||
|
|
||||||
|
FUNCTION: ulonglong LLVMGenericValueToInt
|
||||||
|
( LLVMGenericValueRef GenVal, int IsSigned ) ;
|
||||||
|
|
||||||
|
FUNCTION: int LLVMCreateExecutionEngine
|
||||||
|
( LLVMExecutionEngineRef *OutEE, LLVMModuleProviderRef MP, char** OutError ) ;
|
||||||
|
|
||||||
|
FUNCTION: int LLVMCreateJITCompiler
|
||||||
|
( LLVMExecutionEngineRef* OutJIT, LLVMModuleProviderRef MP, unsigned OptLevel, char** OutError ) ;
|
||||||
|
|
||||||
|
FUNCTION: void LLVMDisposeExecutionEngine ( LLVMExecutionEngineRef EE ) ;
|
||||||
|
|
||||||
|
FUNCTION: void LLVMFreeMachineCodeForFunction ( LLVMExecutionEngineRef EE, LLVMValueRef F ) ;
|
||||||
|
|
||||||
|
FUNCTION: void LLVMAddModuleProvider ( LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP ) ;
|
||||||
|
|
||||||
|
FUNCTION: int LLVMRemoveModuleProvider
|
||||||
|
( LLVMExecutionEngineRef EE, LLVMModuleProviderRef MP, LLVMModuleRef* OutMod, char** OutError ) ;
|
||||||
|
|
||||||
|
FUNCTION: int LLVMFindFunction
|
||||||
|
( LLVMExecutionEngineRef EE, char* Name, LLVMValueRef* OutFn ) ;
|
||||||
|
|
||||||
|
FUNCTION: void* LLVMGetPointerToGlobal ( LLVMExecutionEngineRef EE, LLVMValueRef Global ) ;
|
||||||
|
|
||||||
|
FUNCTION: LLVMGenericValueRef LLVMRunFunction
|
||||||
|
( LLVMExecutionEngineRef EE, LLVMValueRef F, unsigned NumArgs, LLVMGenericValueRef* Args ) ;
|
|
@ -0,0 +1,7 @@
|
||||||
|
! Copyright (C) 2009 Matthew Willis.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: alien.llvm io.pathnames llvm.invoker llvm.reader tools.test ;
|
||||||
|
|
||||||
|
[ 3 ] [
|
||||||
|
<< "resource:extra/llvm/reader/add.bc" install-bc >> 1 2 add
|
||||||
|
] unit-test
|
|
@ -0,0 +1,56 @@
|
||||||
|
! Copyright (C) 2009 Matthew Willis.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: accessors alien arrays assocs compiler.units effects
|
||||||
|
io.backend io.pathnames kernel llvm.core llvm.jit llvm.reader
|
||||||
|
llvm.types make namespaces sequences specialized-arrays.alien
|
||||||
|
vocabs words ;
|
||||||
|
|
||||||
|
IN: llvm.invoker
|
||||||
|
|
||||||
|
! get function name, ret type, param types and names
|
||||||
|
|
||||||
|
! load module
|
||||||
|
! iterate through functions in a module
|
||||||
|
|
||||||
|
TUPLE: function name alien return params ;
|
||||||
|
|
||||||
|
: params ( llvm-function -- param-list )
|
||||||
|
dup LLVMCountParams <void*-array>
|
||||||
|
[ LLVMGetParams ] keep >array
|
||||||
|
[ [ LLVMGetValueName ] [ LLVMTypeOf tref> ] bi 2array ] map ;
|
||||||
|
|
||||||
|
: <function> ( LLVMValueRef -- function )
|
||||||
|
function new
|
||||||
|
over LLVMGetValueName >>name
|
||||||
|
over LLVMTypeOf tref> type>> return>> >>return
|
||||||
|
swap params >>params ;
|
||||||
|
|
||||||
|
: (functions) ( llvm-function -- )
|
||||||
|
[ dup , LLVMGetNextFunction (functions) ] when* ;
|
||||||
|
|
||||||
|
: functions ( llvm-module -- functions )
|
||||||
|
LLVMGetFirstFunction [ (functions) ] { } make [ <function> ] map ;
|
||||||
|
|
||||||
|
: function-effect ( function -- effect )
|
||||||
|
[ params>> [ first ] map ] [ return>> void? 0 1 ? ] bi <effect> ;
|
||||||
|
|
||||||
|
: install-function ( function -- )
|
||||||
|
dup name>> "alien.llvm" create-vocab drop
|
||||||
|
"alien.llvm" create swap
|
||||||
|
[
|
||||||
|
dup name>> function-pointer ,
|
||||||
|
dup return>> c-type ,
|
||||||
|
dup params>> [ second c-type ] map ,
|
||||||
|
"cdecl" , \ alien-indirect ,
|
||||||
|
] [ ] make swap function-effect [ define-declared ] with-compilation-unit ;
|
||||||
|
|
||||||
|
: install-module ( name -- )
|
||||||
|
thejit get mps>> at [
|
||||||
|
module>> functions [ install-function ] each
|
||||||
|
] [ "no such module" throw ] if* ;
|
||||||
|
|
||||||
|
: install-bc ( path -- )
|
||||||
|
[ normalize-path ] [ file-name ] bi
|
||||||
|
[ load-into-jit ] keep install-module ;
|
||||||
|
|
||||||
|
<< "alien.llvm" create-vocab drop >>
|
|
@ -0,0 +1,5 @@
|
||||||
|
! Copyright (C) 2009 Matthew Willis.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: destructors llvm.jit llvm.wrappers tools.test ;
|
||||||
|
|
||||||
|
[ ] [ "test" <module> "test" add-module "test" remove-module ] unit-test
|
|
@ -0,0 +1,49 @@
|
||||||
|
! Copyright (C) 2009 Matthew Willis.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: accessors alien.c-types alien.syntax assocs destructors
|
||||||
|
kernel llvm.core llvm.engine llvm.wrappers namespaces ;
|
||||||
|
|
||||||
|
IN: llvm.jit
|
||||||
|
|
||||||
|
SYMBOL: thejit
|
||||||
|
|
||||||
|
TUPLE: jit ee mps ;
|
||||||
|
|
||||||
|
: empty-engine ( -- engine )
|
||||||
|
"initial-module" <module> <provider> <engine> ;
|
||||||
|
|
||||||
|
: <jit> ( -- jit )
|
||||||
|
jit new empty-engine >>ee H{ } clone >>mps ;
|
||||||
|
|
||||||
|
: (remove-functions) ( function -- )
|
||||||
|
thejit get ee>> value>> over LLVMFreeMachineCodeForFunction
|
||||||
|
LLVMGetNextFunction dup ALIEN: 0 = [ drop ] [ (remove-functions) ] if ;
|
||||||
|
|
||||||
|
: remove-functions ( module -- )
|
||||||
|
! free machine code for each function in module
|
||||||
|
LLVMGetFirstFunction dup ALIEN: 0 = [ drop ] [ (remove-functions) ] if ;
|
||||||
|
|
||||||
|
: remove-provider ( provider -- )
|
||||||
|
thejit get ee>> value>> swap value>> f <void*> f <void*>
|
||||||
|
[ LLVMRemoveModuleProvider drop ] 2keep *void* [ llvm-throw ] when*
|
||||||
|
*void* module new swap >>value
|
||||||
|
[ value>> remove-functions ] with-disposal ;
|
||||||
|
|
||||||
|
: remove-module ( name -- )
|
||||||
|
dup thejit get mps>> at [
|
||||||
|
remove-provider
|
||||||
|
thejit get mps>> delete-at
|
||||||
|
] [ drop ] if* ;
|
||||||
|
|
||||||
|
: add-module ( module name -- )
|
||||||
|
[ <provider> ] dip [ remove-module ] keep
|
||||||
|
thejit get ee>> value>> pick
|
||||||
|
[ [ value>> LLVMAddModuleProvider ] [ t >>disposed drop ] bi ] with-disposal
|
||||||
|
thejit get mps>> set-at ;
|
||||||
|
|
||||||
|
: function-pointer ( name -- alien )
|
||||||
|
thejit get ee>> value>> dup
|
||||||
|
rot f <void*> [ LLVMFindFunction drop ] keep
|
||||||
|
*void* LLVMGetPointerToGlobal ;
|
||||||
|
|
||||||
|
thejit [ <jit> ] initialize
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
||||||
|
define i32 @add(i32 %x, i32 %y) {
|
||||||
|
entry:
|
||||||
|
%sum = add i32 %x, %y
|
||||||
|
ret i32 %sum
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
! Copyright (C) 2009 Matthew Willis.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: accessors alien.c-types alien.syntax destructors kernel
|
||||||
|
llvm.core llvm.engine llvm.jit llvm.wrappers ;
|
||||||
|
|
||||||
|
IN: llvm.reader
|
||||||
|
|
||||||
|
: buffer>module ( buffer -- module )
|
||||||
|
[
|
||||||
|
value>> f <void*> f <void*>
|
||||||
|
[ LLVMParseBitcode drop ] 2keep
|
||||||
|
*void* [ llvm-throw ] when* *void*
|
||||||
|
module new swap >>value
|
||||||
|
] with-disposal ;
|
||||||
|
|
||||||
|
: load-module ( path -- module )
|
||||||
|
<buffer> buffer>module ;
|
||||||
|
|
||||||
|
: load-into-jit ( path name -- )
|
||||||
|
[ load-module ] dip add-module ;
|
|
@ -0,0 +1 @@
|
||||||
|
bindings
|
|
@ -0,0 +1,40 @@
|
||||||
|
! Copyright (C) 2009 Matthew Willis.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: kernel llvm.types sequences tools.test ;
|
||||||
|
|
||||||
|
[ T{ integer f 32 } ] [ " i32 " parse-type ] unit-test
|
||||||
|
[ float ] [ " float " parse-type ] unit-test
|
||||||
|
[ T{ pointer f f x86_fp80 } ] [ " x86_fp80 * " parse-type ] unit-test
|
||||||
|
[ T{ vector f f 4 T{ integer f 32 } } ] [ " < 4 x i32 > " parse-type ] unit-test
|
||||||
|
[ T{ struct f f { float double } f } ] [ TYPE: { float , double } ; ] unit-test
|
||||||
|
[ T{ array f f 0 float } ] [ TYPE: [ 0 x float ] ; ] unit-test
|
||||||
|
|
||||||
|
[ label void metadata ]
|
||||||
|
[ [ " label " " void " " metadata " ] [ parse-type ] each ] unit-test
|
||||||
|
|
||||||
|
[ T{ function f f float { float float } t } ]
|
||||||
|
[ TYPE: float ( float , float , ... ) ; ] unit-test
|
||||||
|
|
||||||
|
[ T{ struct f f { float TYPE: i32 (i32)* ; } t } ]
|
||||||
|
[ TYPE: < { float, i32 (i32)* } > ; ] unit-test
|
||||||
|
|
||||||
|
[ t ] [ TYPE: i32 ; TYPE: i32 ; [ >tref ] bi@ = ] unit-test
|
||||||
|
[ t ] [ TYPE: i32 * ; TYPE: i32 * ; [ >tref ] bi@ = ] unit-test
|
||||||
|
|
||||||
|
[ TYPE: i32 ; ] [ TYPE: i32 ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: float ; ] [ TYPE: float ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: double ; ] [ TYPE: double ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: x86_fp80 ; ] [ TYPE: x86_fp80 ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: fp128 ; ] [ TYPE: fp128 ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: ppc_fp128 ; ] [ TYPE: ppc_fp128 ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: opaque ; ] [ TYPE: opaque ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: label ; ] [ TYPE: label ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: void ; ] [ TYPE: void ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: i32* ; ] [ TYPE: i32* ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: < 2 x i32 > ; ] [ TYPE: < 2 x i32 > ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: [ 0 x i32 ] ; ] [ TYPE: [ 0 x i32 ] ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: { i32, i32 } ; ] [ TYPE: { i32, i32 } ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: < { i32, i32 } > ; ] [ TYPE: < { i32, i32 } > ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: i32 ( i32 ) ; ] [ TYPE: i32 ( i32 ) ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: \1* ; ] [ TYPE: \1* ; >tref tref> ] unit-test
|
||||||
|
[ TYPE: { i32, \2* } ; ] [ TYPE: { i32, \2* } ; >tref tref> ] unit-test
|
|
@ -0,0 +1,246 @@
|
||||||
|
! Copyright (C) 2009 Matthew Willis.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: accessors arrays combinators kernel llvm.core
|
||||||
|
locals math.parser math multiline
|
||||||
|
namespaces parser peg.ebnf sequences
|
||||||
|
sequences.deep specialized-arrays.alien strings vocabs words ;
|
||||||
|
|
||||||
|
IN: llvm.types
|
||||||
|
|
||||||
|
! Type resolution strategy:
|
||||||
|
! pass 1:
|
||||||
|
! create the type with uprefs mapped to opaque types
|
||||||
|
! cache typerefs in enclosing types for pass 2
|
||||||
|
! if our type is concrete, then we are done
|
||||||
|
!
|
||||||
|
! pass 2:
|
||||||
|
! wrap our abstract type in a type handle
|
||||||
|
! create a second type, using the cached enclosing type info
|
||||||
|
! resolve the first type to the second
|
||||||
|
!
|
||||||
|
GENERIC: (>tref) ( type -- LLVMTypeRef )
|
||||||
|
GENERIC: ((tref>)) ( LLVMTypeRef type -- type )
|
||||||
|
GENERIC: c-type ( type -- str )
|
||||||
|
|
||||||
|
! default implementation for simple types
|
||||||
|
M: object ((tref>)) nip ;
|
||||||
|
: unsupported-type ( -- )
|
||||||
|
"cannot generate c-type: unsupported llvm type" throw ;
|
||||||
|
M: object c-type unsupported-type ;
|
||||||
|
|
||||||
|
TUPLE: integer size ;
|
||||||
|
C: <integer> integer
|
||||||
|
|
||||||
|
M: integer (>tref) size>> LLVMIntType ;
|
||||||
|
M: integer ((tref>)) swap LLVMGetIntTypeWidth >>size ;
|
||||||
|
M: integer c-type size>> {
|
||||||
|
{ 64 [ "longlong" ] }
|
||||||
|
{ 32 [ "int" ] }
|
||||||
|
{ 16 [ "short" ] }
|
||||||
|
{ 8 [ "char" ] }
|
||||||
|
[ unsupported-type ]
|
||||||
|
} case ;
|
||||||
|
|
||||||
|
SINGLETONS: float double x86_fp80 fp128 ppc_fp128 ;
|
||||||
|
|
||||||
|
M: float (>tref) drop LLVMFloatType ;
|
||||||
|
M: double (>tref) drop LLVMDoubleType ;
|
||||||
|
M: double c-type drop "double" ;
|
||||||
|
M: x86_fp80 (>tref) drop LLVMX86FP80Type ;
|
||||||
|
M: fp128 (>tref) drop LLVMFP128Type ;
|
||||||
|
M: ppc_fp128 (>tref) drop LLVMPPCFP128Type ;
|
||||||
|
|
||||||
|
SINGLETONS: opaque label void metadata ;
|
||||||
|
|
||||||
|
M: opaque (>tref) drop LLVMOpaqueType ;
|
||||||
|
M: label (>tref) drop LLVMLabelType ;
|
||||||
|
M: void (>tref) drop LLVMVoidType ;
|
||||||
|
M: void c-type drop "void" ;
|
||||||
|
M: metadata (>tref) drop
|
||||||
|
"metadata types unsupported by llvm c bindings" throw ;
|
||||||
|
|
||||||
|
! enclosing types cache their llvm refs during
|
||||||
|
! the first pass, used in the second pass to
|
||||||
|
! resolve uprefs
|
||||||
|
TUPLE: enclosing cached ;
|
||||||
|
|
||||||
|
GENERIC: clean ( type -- )
|
||||||
|
GENERIC: clean* ( type -- )
|
||||||
|
M: object clean drop ;
|
||||||
|
M: enclosing clean f >>cached clean* ;
|
||||||
|
|
||||||
|
! builds the stack of types that uprefs need to refer to
|
||||||
|
SYMBOL: types
|
||||||
|
:: push-type ( type quot: ( type -- LLVMTypeRef ) -- LLVMTypeRef )
|
||||||
|
type types get push
|
||||||
|
type quot call( type -- LLVMTypeRef )
|
||||||
|
types get pop over >>cached drop ;
|
||||||
|
|
||||||
|
DEFER: <up-ref>
|
||||||
|
:: push-ref ( ref quot: ( LLVMTypeRef -- type ) -- type )
|
||||||
|
ref types get index
|
||||||
|
[ types get length swap - <up-ref> ] [
|
||||||
|
ref types get push
|
||||||
|
ref quot call( LLVMTypeRef -- type )
|
||||||
|
types get pop drop
|
||||||
|
] if* ;
|
||||||
|
|
||||||
|
GENERIC: (>tref)* ( type -- LLVMTypeRef )
|
||||||
|
M: enclosing (>tref) [ (>tref)* ] push-type ;
|
||||||
|
|
||||||
|
DEFER: type-kind
|
||||||
|
GENERIC: (tref>)* ( LLVMTypeRef type -- type )
|
||||||
|
M: enclosing ((tref>)) [ (tref>)* ] curry push-ref ;
|
||||||
|
|
||||||
|
: (tref>) ( LLVMTypeRef -- type ) dup type-kind ((tref>)) ;
|
||||||
|
|
||||||
|
TUPLE: pointer < enclosing type ;
|
||||||
|
: <pointer> ( t -- o ) pointer new swap >>type ;
|
||||||
|
|
||||||
|
M: pointer (>tref)* type>> (>tref) 0 LLVMPointerType ;
|
||||||
|
M: pointer clean* type>> clean ;
|
||||||
|
M: pointer (tref>)* swap LLVMGetElementType (tref>) >>type ;
|
||||||
|
M: pointer c-type type>> 8 <integer> = "char*" "void*" ? ;
|
||||||
|
|
||||||
|
TUPLE: vector < enclosing size type ;
|
||||||
|
: <vector> ( s t -- o )
|
||||||
|
vector new
|
||||||
|
swap >>type swap >>size ;
|
||||||
|
|
||||||
|
M: vector (>tref)* [ type>> (>tref) ] [ size>> ] bi LLVMVectorType ;
|
||||||
|
M: vector clean* type>> clean ;
|
||||||
|
M: vector (tref>)*
|
||||||
|
over LLVMGetElementType (tref>) >>type
|
||||||
|
swap LLVMGetVectorSize >>size ;
|
||||||
|
|
||||||
|
TUPLE: struct < enclosing types packed? ;
|
||||||
|
: <struct> ( ts p? -- o )
|
||||||
|
struct new
|
||||||
|
swap >>packed? swap >>types ;
|
||||||
|
|
||||||
|
M: struct (>tref)*
|
||||||
|
[ types>> [ (>tref) ] map >void*-array ]
|
||||||
|
[ types>> length ]
|
||||||
|
[ packed?>> 1 0 ? ] tri LLVMStructType ;
|
||||||
|
M: struct clean* types>> [ clean ] each ;
|
||||||
|
M: struct (tref>)*
|
||||||
|
over LLVMIsPackedStruct 0 = not >>packed?
|
||||||
|
swap dup LLVMCountStructElementTypes <void*-array>
|
||||||
|
[ LLVMGetStructElementTypes ] keep >array
|
||||||
|
[ (tref>) ] map >>types ;
|
||||||
|
|
||||||
|
TUPLE: array < enclosing size type ;
|
||||||
|
: <array> ( s t -- o )
|
||||||
|
array new
|
||||||
|
swap >>type swap >>size ;
|
||||||
|
|
||||||
|
M: array (>tref)* [ type>> (>tref) ] [ size>> ] bi LLVMArrayType ;
|
||||||
|
M: array clean* type>> clean ;
|
||||||
|
M: array (tref>)*
|
||||||
|
over LLVMGetElementType (tref>) >>type
|
||||||
|
swap LLVMGetArrayLength >>size ;
|
||||||
|
|
||||||
|
SYMBOL: ...
|
||||||
|
TUPLE: function < enclosing return params vararg? ;
|
||||||
|
: <function> ( ret params var? -- o )
|
||||||
|
function new
|
||||||
|
swap >>vararg? swap >>params swap >>return ;
|
||||||
|
|
||||||
|
M: function (>tref)* {
|
||||||
|
[ return>> (>tref) ]
|
||||||
|
[ params>> [ (>tref) ] map >void*-array ]
|
||||||
|
[ params>> length ]
|
||||||
|
[ vararg?>> 1 0 ? ]
|
||||||
|
} cleave LLVMFunctionType ;
|
||||||
|
M: function clean* [ return>> clean ] [ params>> [ clean ] each ] bi ;
|
||||||
|
M: function (tref>)*
|
||||||
|
over LLVMIsFunctionVarArg 0 = not >>vararg?
|
||||||
|
over LLVMGetReturnType (tref>) >>return
|
||||||
|
swap dup LLVMCountParamTypes <void*-array>
|
||||||
|
[ LLVMGetParamTypes ] keep >array
|
||||||
|
[ (tref>) ] map >>params ;
|
||||||
|
|
||||||
|
: type-kind ( LLVMTypeRef -- class )
|
||||||
|
LLVMGetTypeKind {
|
||||||
|
{ LLVMVoidTypeKind [ void ] }
|
||||||
|
{ LLVMFloatTypeKind [ float ] }
|
||||||
|
{ LLVMDoubleTypeKind [ double ] }
|
||||||
|
{ LLVMX86_FP80TypeKind [ x86_fp80 ] }
|
||||||
|
{ LLVMFP128TypeKind [ fp128 ] }
|
||||||
|
{ LLVMPPC_FP128TypeKind [ ppc_fp128 ] }
|
||||||
|
{ LLVMLabelTypeKind [ label ] }
|
||||||
|
{ LLVMIntegerTypeKind [ integer new ] }
|
||||||
|
{ LLVMFunctionTypeKind [ function new ] }
|
||||||
|
{ LLVMStructTypeKind [ struct new ] }
|
||||||
|
{ LLVMArrayTypeKind [ array new ] }
|
||||||
|
{ LLVMPointerTypeKind [ pointer new ] }
|
||||||
|
{ LLVMOpaqueTypeKind [ opaque ] }
|
||||||
|
{ LLVMVectorTypeKind [ vector new ] }
|
||||||
|
} case ;
|
||||||
|
|
||||||
|
TUPLE: up-ref height ;
|
||||||
|
C: <up-ref> up-ref
|
||||||
|
|
||||||
|
M: up-ref (>tref)
|
||||||
|
types get length swap height>> - types get nth
|
||||||
|
cached>> [ LLVMOpaqueType ] unless* ;
|
||||||
|
|
||||||
|
: resolve-types ( typeref typeref -- typeref )
|
||||||
|
over LLVMCreateTypeHandle [ LLVMRefineType ] dip
|
||||||
|
[ LLVMResolveTypeHandle ] keep LLVMDisposeTypeHandle ;
|
||||||
|
|
||||||
|
: >tref-caching ( type -- LLVMTypeRef )
|
||||||
|
V{ } clone types [ (>tref) ] with-variable ;
|
||||||
|
|
||||||
|
: >tref ( type -- LLVMTypeRef )
|
||||||
|
[ >tref-caching ] [ >tref-caching ] [ clean ] tri
|
||||||
|
2dup = [ drop ] [ resolve-types ] if ;
|
||||||
|
|
||||||
|
: tref> ( LLVMTypeRef -- type )
|
||||||
|
V{ } clone types [ (tref>) ] with-variable ;
|
||||||
|
|
||||||
|
: t. ( type -- )
|
||||||
|
>tref
|
||||||
|
"type-info" LLVMModuleCreateWithName
|
||||||
|
[ "t" rot LLVMAddTypeName drop ]
|
||||||
|
[ LLVMDumpModule ]
|
||||||
|
[ LLVMDisposeModule ] tri ;
|
||||||
|
|
||||||
|
EBNF: parse-type
|
||||||
|
|
||||||
|
WhiteSpace = " "*
|
||||||
|
|
||||||
|
Zero = "0" => [[ drop 0 ]]
|
||||||
|
LeadingDigit = [1-9]
|
||||||
|
DecimalDigit = [0-9]
|
||||||
|
Number = LeadingDigit:d (DecimalDigit)*:ds => [[ ds d prefix string>number ]]
|
||||||
|
WhiteNumberSpace = WhiteSpace Number:n WhiteSpace => [[ n ]]
|
||||||
|
WhiteZeroSpace = WhiteSpace (Zero | Number):n WhiteSpace => [[ n ]]
|
||||||
|
|
||||||
|
Integer = "i" Number:n => [[ n <integer> ]]
|
||||||
|
FloatingPoint = ( "float" | "double" | "x86_fp80" | "fp128" | "ppc_fp128" ) => [[ "llvm.types" vocab lookup ]]
|
||||||
|
LabelVoidMetadata = ( "label" | "void" | "metadata" | "opaque" ) => [[ "llvm.types" vocab lookup ]]
|
||||||
|
Primitive = LabelVoidMetadata | FloatingPoint
|
||||||
|
Pointer = T:t WhiteSpace "*" => [[ t <pointer> ]]
|
||||||
|
Vector = "<" WhiteNumberSpace:n "x" Type:t ">" => [[ n t <vector> ]]
|
||||||
|
StructureTypesList = "," Type:t => [[ t ]]
|
||||||
|
Structure = "{" Type:t (StructureTypesList)*:ts "}" => [[ ts t prefix >array f <struct> ]]
|
||||||
|
Array = "[" WhiteZeroSpace:n "x" Type:t "]" => [[ n t <array> ]]
|
||||||
|
NoFunctionParams = "(" WhiteSpace ")" => [[ drop { } ]]
|
||||||
|
VarArgs = WhiteSpace "..." WhiteSpace => [[ drop ... ]]
|
||||||
|
ParamListContinued = "," (Type | VarArgs):t => [[ t ]]
|
||||||
|
ParamList = "(" Type:t (ParamListContinued*):ts ")" => [[ ts t prefix ]]
|
||||||
|
Function = T:t WhiteSpace ( ParamList | NoFunctionParams ):ts => [[ ... ts member? dup [ ... ts delete ] when t ts >array rot <function> ]]
|
||||||
|
PackedStructure = "<" WhiteSpace "{" Type:ty (StructureTypesList)*:ts "}" WhiteSpace ">" => [[ ts ty prefix >array t <struct> ]]
|
||||||
|
UpReference = "\\" Number:n => [[ n <up-ref> ]]
|
||||||
|
Name = '%' ([a-zA-Z][a-zA-Z0-9]*):id => [[ id flatten >string ]]
|
||||||
|
|
||||||
|
T = Pointer | Function | Primitive | Integer | Vector | Structure | PackedStructure | Array | UpReference | Name
|
||||||
|
|
||||||
|
Type = WhiteSpace T:t WhiteSpace => [[ t ]]
|
||||||
|
|
||||||
|
Program = Type
|
||||||
|
|
||||||
|
;EBNF
|
||||||
|
|
||||||
|
SYNTAX: TYPE: ";" parse-multiline-string parse-type parsed ;
|
|
@ -0,0 +1,7 @@
|
||||||
|
! Copyright (C) 2009 Matthew Willis.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: destructors kernel llvm.wrappers sequences tools.test vocabs ;
|
||||||
|
|
||||||
|
[ ] [ "test" <module> dispose ] unit-test
|
||||||
|
[ ] [ "test" <module> <provider> dispose ] unit-test
|
||||||
|
[ ] [ "llvm.jit" vocabs member? [ "test" <module> <provider> <engine> dispose ] unless ] unit-test
|
|
@ -0,0 +1,62 @@
|
||||||
|
! Copyright (C) 2009 Matthew Willis.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: accessors alien.c-types alien.strings
|
||||||
|
io.encodings.utf8 destructors kernel
|
||||||
|
llvm.core llvm.engine ;
|
||||||
|
|
||||||
|
IN: llvm.wrappers
|
||||||
|
|
||||||
|
: llvm-throw ( char* -- )
|
||||||
|
[ utf8 alien>string ] [ LLVMDisposeMessage ] bi throw ;
|
||||||
|
|
||||||
|
: <dispose> ( alien class -- disposable ) new swap >>value ;
|
||||||
|
|
||||||
|
TUPLE: module value disposed ;
|
||||||
|
M: module dispose* value>> LLVMDisposeModule ;
|
||||||
|
|
||||||
|
: <module> ( name -- module )
|
||||||
|
LLVMModuleCreateWithName module <dispose> ;
|
||||||
|
|
||||||
|
TUPLE: provider value module disposed ;
|
||||||
|
M: provider dispose* value>> LLVMDisposeModuleProvider ;
|
||||||
|
|
||||||
|
: (provider) ( module -- provider )
|
||||||
|
[ value>> LLVMCreateModuleProviderForExistingModule provider <dispose> ]
|
||||||
|
[ t >>disposed value>> ] bi
|
||||||
|
>>module ;
|
||||||
|
|
||||||
|
: <provider> ( module -- provider )
|
||||||
|
[ (provider) ] with-disposal ;
|
||||||
|
|
||||||
|
TUPLE: engine value disposed ;
|
||||||
|
M: engine dispose* value>> LLVMDisposeExecutionEngine ;
|
||||||
|
|
||||||
|
: (engine) ( provider -- engine )
|
||||||
|
[
|
||||||
|
value>> f <void*> f <void*>
|
||||||
|
[ swapd 0 swap LLVMCreateJITCompiler drop ] 2keep
|
||||||
|
*void* [ llvm-throw ] when* *void*
|
||||||
|
]
|
||||||
|
[ t >>disposed drop ] bi
|
||||||
|
engine <dispose> ;
|
||||||
|
|
||||||
|
: <engine> ( provider -- engine )
|
||||||
|
[ (engine) ] with-disposal ;
|
||||||
|
|
||||||
|
: (add-block) ( name -- basic-block )
|
||||||
|
"function" swap LLVMAppendBasicBlock ;
|
||||||
|
|
||||||
|
TUPLE: builder value disposed ;
|
||||||
|
M: builder dispose* value>> LLVMDisposeBuilder ;
|
||||||
|
|
||||||
|
: <builder> ( name -- builder )
|
||||||
|
(add-block) LLVMCreateBuilder [ swap LLVMPositionBuilderAtEnd ] keep
|
||||||
|
builder <dispose> ;
|
||||||
|
|
||||||
|
TUPLE: buffer value disposed ;
|
||||||
|
M: buffer dispose* value>> LLVMDisposeMemoryBuffer ;
|
||||||
|
|
||||||
|
: <buffer> ( path -- module )
|
||||||
|
f <void*> f <void*>
|
||||||
|
[ LLVMCreateMemoryBufferWithContentsOfFile drop ] 2keep
|
||||||
|
*void* [ llvm-throw ] when* *void* buffer <dispose> ;
|
|
@ -163,7 +163,7 @@ CONSTANT: DOC-LARGE H{ { "base_url" "http://www.example.com/test-me" }
|
||||||
[ create-collection ] keep ;
|
[ create-collection ] keep ;
|
||||||
|
|
||||||
: prepare-index ( collection -- )
|
: prepare-index ( collection -- )
|
||||||
"_x_idx" [ "x" asc ] key-spec <index-spec> unique-index ensure-index ;
|
"_x_idx" [ "x" asc ] key-spec <index-spec> t >>unique? ensure-index ;
|
||||||
|
|
||||||
: insert ( doc-quot: ( i -- doc ) -- quot: ( -- ) )
|
: insert ( doc-quot: ( i -- doc ) -- quot: ( -- ) )
|
||||||
prepare-collection
|
prepare-collection
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: accessors assocs fry io.encodings.binary io.sockets kernel math
|
USING: accessors assocs fry io.encodings.binary io.sockets kernel math
|
||||||
math.parser mongodb.msg mongodb.operations namespaces destructors
|
math.parser mongodb.msg mongodb.operations namespaces destructors
|
||||||
constructors sequences splitting checksums checksums.md5 formatting
|
constructors sequences splitting checksums checksums.md5
|
||||||
io.streams.duplex io.encodings.utf8 io.encodings.string combinators.smart
|
io.streams.duplex io.encodings.utf8 io.encodings.string combinators.smart
|
||||||
arrays hashtables sequences.deep vectors locals ;
|
arrays hashtables sequences.deep vectors locals ;
|
||||||
|
|
||||||
|
@ -39,16 +39,16 @@ CONSTRUCTOR: mdb-connection ( instance -- mdb-connection ) ;
|
||||||
mdb-connection get instance>> ; inline
|
mdb-connection get instance>> ; inline
|
||||||
|
|
||||||
: index-collection ( -- ns )
|
: index-collection ( -- ns )
|
||||||
mdb-instance name>> "%s.system.indexes" sprintf ; inline
|
mdb-instance name>> "system.indexes" "." glue ; inline
|
||||||
|
|
||||||
: namespaces-collection ( -- ns )
|
: namespaces-collection ( -- ns )
|
||||||
mdb-instance name>> "%s.system.namespaces" sprintf ; inline
|
mdb-instance name>> "system.namespaces" "." glue ; inline
|
||||||
|
|
||||||
: cmd-collection ( -- ns )
|
: cmd-collection ( -- ns )
|
||||||
mdb-instance name>> "%s.$cmd" sprintf ; inline
|
mdb-instance name>> "$cmd" "." glue ; inline
|
||||||
|
|
||||||
: index-ns ( colname -- index-ns )
|
: index-ns ( colname -- index-ns )
|
||||||
[ mdb-instance name>> ] dip "%s.%s" sprintf ; inline
|
[ mdb-instance name>> ] dip "." glue ; inline
|
||||||
|
|
||||||
: send-message ( message -- )
|
: send-message ( message -- )
|
||||||
[ mdb-connection get handle>> ] dip '[ _ write-message ] with-stream* ;
|
[ mdb-connection get handle>> ] dip '[ _ write-message ] with-stream* ;
|
||||||
|
|
|
@ -131,7 +131,7 @@ HELP: ensure-index
|
||||||
"\"db\" \"127.0.0.1\" 27017 <mdb>"
|
"\"db\" \"127.0.0.1\" 27017 <mdb>"
|
||||||
"[ \"mycollection\" nameIdx [ \"name\" asc ] keyspec <index-spec> ensure-index ] with-db" "" }
|
"[ \"mycollection\" nameIdx [ \"name\" asc ] keyspec <index-spec> ensure-index ] with-db" "" }
|
||||||
{ $unchecked-example "USING: mongodb.driver ;"
|
{ $unchecked-example "USING: mongodb.driver ;"
|
||||||
"\"db\" \"127.0.0.1\" 27017 <mdb>" "[ \"mycollection\" nameIdx [ \"name\" asc ] keyspec <index-spec> unique-index ensure-index ] with-db" "" } } ;
|
"\"db\" \"127.0.0.1\" 27017 <mdb>" "[ \"mycollection\" nameIdx [ \"name\" asc ] keyspec <index-spec> t >>unique? ensure-index ] with-db" "" } } ;
|
||||||
|
|
||||||
HELP: explain.
|
HELP: explain.
|
||||||
{ $values
|
{ $values
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
USING: accessors assocs bson.constants bson.writer combinators combinators.smart
|
USING: accessors arrays assocs bson.constants combinators
|
||||||
constructors continuations destructors formatting fry io io.pools
|
combinators.smart constructors destructors formatting fry hashtables
|
||||||
io.encodings.binary io.sockets io.streams.duplex kernel linked-assocs hashtables
|
io io.pools io.sockets kernel linked-assocs math mongodb.connection
|
||||||
namespaces parser prettyprint sequences sets splitting strings uuid arrays
|
mongodb.msg parser prettyprint sequences sets splitting strings
|
||||||
math math.parser memoize mongodb.connection mongodb.msg mongodb.operations ;
|
tools.continuations uuid memoize locals ;
|
||||||
|
|
||||||
IN: mongodb.driver
|
IN: mongodb.driver
|
||||||
|
|
||||||
|
@ -23,9 +23,6 @@ TUPLE: index-spec
|
||||||
|
|
||||||
CONSTRUCTOR: index-spec ( ns name key -- index-spec ) ;
|
CONSTRUCTOR: index-spec ( ns name key -- index-spec ) ;
|
||||||
|
|
||||||
: unique-index ( index-spec -- index-spec )
|
|
||||||
t >>unique? ;
|
|
||||||
|
|
||||||
M: mdb-pool make-connection
|
M: mdb-pool make-connection
|
||||||
mdb>> mdb-open ;
|
mdb>> mdb-open ;
|
||||||
|
|
||||||
|
@ -83,6 +80,15 @@ M: mdb-getmore-msg verify-query-result
|
||||||
[ make-cursor ] 2tri
|
[ make-cursor ] 2tri
|
||||||
swap objects>> ;
|
swap objects>> ;
|
||||||
|
|
||||||
|
: make-collection-assoc ( collection assoc -- )
|
||||||
|
[ [ name>> "create" ] dip set-at ]
|
||||||
|
[ [ [ capped>> ] keep ] dip
|
||||||
|
'[ _ _
|
||||||
|
[ [ drop t "capped" ] dip set-at ]
|
||||||
|
[ [ size>> "size" ] dip set-at ]
|
||||||
|
[ [ max>> "max" ] dip set-at ] 2tri ] when
|
||||||
|
] 2bi ;
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
SYNTAX: r/ ( token -- mdbregexp )
|
SYNTAX: r/ ( token -- mdbregexp )
|
||||||
|
@ -100,23 +106,17 @@ SYNTAX: r/ ( token -- mdbregexp )
|
||||||
H{ } clone [ set-at ] keep <mdb-db>
|
H{ } clone [ set-at ] keep <mdb-db>
|
||||||
[ verify-nodes ] keep ;
|
[ verify-nodes ] keep ;
|
||||||
|
|
||||||
GENERIC: create-collection ( name -- )
|
GENERIC: create-collection ( name/collection -- )
|
||||||
|
|
||||||
M: string create-collection
|
M: string create-collection
|
||||||
<mdb-collection> create-collection ;
|
<mdb-collection> create-collection ;
|
||||||
|
|
||||||
M: mdb-collection create-collection
|
M: mdb-collection create-collection
|
||||||
[ cmd-collection ] dip
|
[ [ cmd-collection ] dip
|
||||||
<linked-hash> [
|
<linked-hash> [ make-collection-assoc ] keep
|
||||||
[ [ name>> "create" ] dip set-at ]
|
<mdb-query-msg> 1 >>return# send-query-plain drop ] keep
|
||||||
[ [ [ capped>> ] keep ] dip
|
[ ] [ name>> ] bi mdb-instance collections>> set-at ;
|
||||||
'[ _ _
|
|
||||||
[ [ drop t "capped" ] dip set-at ]
|
|
||||||
[ [ size>> "size" ] dip set-at ]
|
|
||||||
[ [ max>> "max" ] dip set-at ] 2tri ] when
|
|
||||||
] 2bi
|
|
||||||
] keep <mdb-query-msg> 1 >>return# send-query-plain drop ;
|
|
||||||
|
|
||||||
: load-collection-list ( -- collection-list )
|
: load-collection-list ( -- collection-list )
|
||||||
namespaces-collection
|
namespaces-collection
|
||||||
H{ } clone <mdb-query-msg> send-query-plain objects>> ;
|
H{ } clone <mdb-query-msg> send-query-plain objects>> ;
|
||||||
|
@ -125,27 +125,36 @@ M: mdb-collection create-collection
|
||||||
|
|
||||||
: ensure-valid-collection-name ( collection -- )
|
: ensure-valid-collection-name ( collection -- )
|
||||||
[ ";$." intersect length 0 > ] keep
|
[ ";$." intersect length 0 > ] keep
|
||||||
'[ _ "%s contains invalid characters ( . $ ; )" sprintf throw ] when ; inline
|
'[ _ "contains invalid characters ( . $ ; )" "." glue throw ] when ; inline
|
||||||
|
|
||||||
: (ensure-collection) ( collection -- )
|
: build-collection-map ( -- assoc )
|
||||||
mdb-instance collections>> dup keys length 0 =
|
H{ } clone load-collection-list
|
||||||
[ load-collection-list
|
[ [ "name" ] dip at "." split second <mdb-collection> ] map
|
||||||
[ [ "options" ] dip key? ] filter
|
over '[ [ ] [ name>> ] bi _ set-at ] each ;
|
||||||
[ [ "name" ] dip at "." split second <mdb-collection> ] map
|
|
||||||
over '[ [ ] [ name>> ] bi _ set-at ] each ] [ ] if
|
|
||||||
[ dup ] dip key? [ drop ]
|
|
||||||
[ [ ensure-valid-collection-name ] keep create-collection ] if ;
|
|
||||||
|
|
||||||
|
: ensure-collection-map ( mdb-instance -- assoc )
|
||||||
|
dup collections>> dup keys length 0 =
|
||||||
|
[ drop build-collection-map [ >>collections drop ] keep ]
|
||||||
|
[ nip ] if ;
|
||||||
|
|
||||||
|
: (ensure-collection) ( collection mdb-instance -- collection )
|
||||||
|
ensure-collection-map [ dup ] dip key?
|
||||||
|
[ ] [ [ ensure-valid-collection-name ]
|
||||||
|
[ create-collection ]
|
||||||
|
[ ] tri ] if ;
|
||||||
|
|
||||||
: reserved-namespace? ( name -- ? )
|
: reserved-namespace? ( name -- ? )
|
||||||
[ "$cmd" = ] [ "system" head? ] bi or ;
|
[ "$cmd" = ] [ "system" head? ] bi or ;
|
||||||
|
|
||||||
: check-collection ( collection -- fq-collection )
|
: check-collection ( collection -- fq-collection )
|
||||||
dup mdb-collection? [ name>> ] when
|
[let* | instance [ mdb-instance ]
|
||||||
"." split1 over mdb-instance name>> =
|
instance-name [ instance name>> ] |
|
||||||
[ nip ] [ drop ] if
|
dup mdb-collection? [ name>> ] when
|
||||||
[ ] [ reserved-namespace? ] bi
|
"." split1 over instance-name =
|
||||||
[ [ (ensure-collection) ] keep ] unless
|
[ nip ] [ drop ] if
|
||||||
[ mdb-instance name>> ] dip "%s.%s" sprintf ;
|
[ ] [ reserved-namespace? ] bi
|
||||||
|
[ instance (ensure-collection) ] unless
|
||||||
|
[ instance-name ] dip "." glue ] ;
|
||||||
|
|
||||||
: fix-query-collection ( mdb-query -- mdb-query )
|
: fix-query-collection ( mdb-query -- mdb-query )
|
||||||
[ check-collection ] change-collection ; inline
|
[ check-collection ] change-collection ; inline
|
||||||
|
|
|
@ -88,7 +88,7 @@ GENERIC: mdb-index-map ( tuple -- sequence )
|
||||||
: user-defined-key-index ( class -- assoc )
|
: user-defined-key-index ( class -- assoc )
|
||||||
mdb-slot-map user-defined-key
|
mdb-slot-map user-defined-key
|
||||||
[ drop [ "user-defined-key-index" 1 ] dip
|
[ drop [ "user-defined-key-index" 1 ] dip
|
||||||
H{ } clone [ set-at ] keep <tuple-index> unique-index
|
H{ } clone [ set-at ] keep <tuple-index> t >>unique?
|
||||||
[ ] [ name>> ] bi H{ } clone [ set-at ] keep
|
[ ] [ name>> ] bi H{ } clone [ set-at ] keep
|
||||||
] [ 2drop H{ } clone ] if ;
|
] [ 2drop H{ } clone ] if ;
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,8 @@
|
||||||
"HELP:" "HEX:" "HOOK:"
|
"HELP:" "HEX:" "HOOK:"
|
||||||
"IN:" "initial:" "INSTANCE:" "INTERSECTION:"
|
"IN:" "initial:" "INSTANCE:" "INTERSECTION:"
|
||||||
"LIBRARY:"
|
"LIBRARY:"
|
||||||
"M:" "MACRO:" "MACRO::" "MAIN:" "MATH:" "MEMO:" "MEMO:" "METHOD:" "MIXIN:"
|
"M:" "M::" "MACRO:" "MACRO::" "MAIN:" "MATH:"
|
||||||
|
"MEMO:" "MEMO:" "METHOD:" "MIXIN:"
|
||||||
"OCT:"
|
"OCT:"
|
||||||
"POSTPONE:" "PREDICATE:" "PRIMITIVE:" "PRIVATE>" "PROVIDE:"
|
"POSTPONE:" "PREDICATE:" "PRIMITIVE:" "PRIVATE>" "PROVIDE:"
|
||||||
"QUALIFIED-WITH:" "QUALIFIED:"
|
"QUALIFIED-WITH:" "QUALIFIED:"
|
||||||
|
@ -83,7 +84,7 @@
|
||||||
(format "%s +\\([^ \r\n]+\\)" (regexp-opt prefixes t)))
|
(format "%s +\\([^ \r\n]+\\)" (regexp-opt prefixes t)))
|
||||||
|
|
||||||
(defconst fuel-syntax--method-definition-regex
|
(defconst fuel-syntax--method-definition-regex
|
||||||
"^M: +\\([^ ]+\\) +\\([^ ]+\\)")
|
"^M::? +\\([^ ]+\\) +\\([^ ]+\\)")
|
||||||
|
|
||||||
(defconst fuel-syntax--integer-regex
|
(defconst fuel-syntax--integer-regex
|
||||||
"\\_<-?[0-9]+\\_>")
|
"\\_<-?[0-9]+\\_>")
|
||||||
|
@ -154,7 +155,7 @@
|
||||||
"C-ENUM" "C-STRUCT" "C-UNION"
|
"C-ENUM" "C-STRUCT" "C-UNION"
|
||||||
"FROM" "FUNCTION:"
|
"FROM" "FUNCTION:"
|
||||||
"INTERSECTION:"
|
"INTERSECTION:"
|
||||||
"M" "MACRO" "MACRO:"
|
"M" "M:" "MACRO" "MACRO:"
|
||||||
"MEMO" "MEMO:" "METHOD"
|
"MEMO" "MEMO:" "METHOD"
|
||||||
"SYNTAX"
|
"SYNTAX"
|
||||||
"PREDICATE" "PRIMITIVE"
|
"PREDICATE" "PRIMITIVE"
|
||||||
|
@ -215,7 +216,9 @@
|
||||||
(format ":[^ ]* \\([^ ]+\\)\\(%s\\)*" fuel-syntax--stack-effect-regex))
|
(format ":[^ ]* \\([^ ]+\\)\\(%s\\)*" fuel-syntax--stack-effect-regex))
|
||||||
|
|
||||||
(defconst fuel-syntax--defun-signature-regex
|
(defconst fuel-syntax--defun-signature-regex
|
||||||
(format "\\(%s\\|%s\\)" fuel-syntax--word-signature-regex "M[^:]*: [^ ]+ [^ ]+"))
|
(format "\\(%s\\|%s\\)"
|
||||||
|
fuel-syntax--word-signature-regex
|
||||||
|
"M[^:]*: [^ ]+ [^ ]+"))
|
||||||
|
|
||||||
(defconst fuel-syntax--constructor-decl-regex
|
(defconst fuel-syntax--constructor-decl-regex
|
||||||
"\\_<C: +\\(\\w+\\) +\\(\\w+\\)\\( .*\\)?$")
|
"\\_<C: +\\(\\w+\\) +\\(\\w+\\)\\( .*\\)?$")
|
||||||
|
|
11
vm/alien.cpp
11
vm/alien.cpp
|
@ -134,20 +134,21 @@ PRIMITIVE(dlsym)
|
||||||
box_alien(ffi_dlsym(NULL,sym));
|
box_alien(ffi_dlsym(NULL,sym));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tagged<dll> d = library.as<dll>();
|
dll *d = untag_check<dll>(library.value());
|
||||||
d.untag_check();
|
|
||||||
|
|
||||||
if(d->dll == NULL)
|
if(d->dll == NULL)
|
||||||
dpush(F);
|
dpush(F);
|
||||||
else
|
else
|
||||||
box_alien(ffi_dlsym(d.untagged(),sym));
|
box_alien(ffi_dlsym(d,sym));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* close a native library handle */
|
/* close a native library handle */
|
||||||
PRIMITIVE(dlclose)
|
PRIMITIVE(dlclose)
|
||||||
{
|
{
|
||||||
ffi_dlclose(untag_check<dll>(dpop()));
|
dll *d = untag_check<dll>(dpop());
|
||||||
|
if(d->dll != NULL)
|
||||||
|
ffi_dlclose(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIMITIVE(dll_validp)
|
PRIMITIVE(dll_validp)
|
||||||
|
@ -156,7 +157,7 @@ PRIMITIVE(dll_validp)
|
||||||
if(library == F)
|
if(library == F)
|
||||||
dpush(T);
|
dpush(T);
|
||||||
else
|
else
|
||||||
dpush(tagged<dll>(library)->dll == NULL ? F : T);
|
dpush(untag_check<dll>(library)->dll == NULL ? F : T);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* gets the address of an object representing a C pointer */
|
/* gets the address of an object representing a C pointer */
|
||||||
|
|
Loading…
Reference in New Issue