Merge branch 'master' of git://factorcode.org/git/factor
commit
1cce53a82a
|
@ -4,7 +4,7 @@ USING: functors destructors accessors kernel parser words
|
||||||
effects generalizations sequences ;
|
effects generalizations sequences ;
|
||||||
IN: alien.destructors
|
IN: alien.destructors
|
||||||
|
|
||||||
SLOT: alien
|
TUPLE: alien-destructor alien ;
|
||||||
|
|
||||||
FUNCTOR: define-destructor ( F -- )
|
FUNCTOR: define-destructor ( F -- )
|
||||||
|
|
||||||
|
@ -16,11 +16,12 @@ N [ F stack-effect out>> length ]
|
||||||
|
|
||||||
WHERE
|
WHERE
|
||||||
|
|
||||||
TUPLE: F-destructor alien disposed ;
|
TUPLE: F-destructor < alien-destructor ;
|
||||||
|
|
||||||
: <F-destructor> ( alien -- destructor ) f F-destructor boa ; inline
|
: <F-destructor> ( alien -- destructor )
|
||||||
|
F-destructor boa ; inline
|
||||||
|
|
||||||
M: F-destructor dispose* alien>> F N ndrop ;
|
M: F-destructor dispose alien>> F N ndrop ;
|
||||||
|
|
||||||
: &F ( alien -- alien ) dup <F-destructor> &dispose drop ; inline
|
: &F ( alien -- alien ) dup <F-destructor> &dispose drop ; inline
|
||||||
|
|
||||||
|
|
|
@ -38,11 +38,11 @@ IN: bootstrap.image
|
||||||
|
|
||||||
! Object cache; we only consider numbers equal if they have the
|
! Object cache; we only consider numbers equal if they have the
|
||||||
! same type
|
! same type
|
||||||
TUPLE: id obj ;
|
TUPLE: eql-wrapper obj ;
|
||||||
|
|
||||||
C: <id> id
|
C: <eql-wrapper> eql-wrapper
|
||||||
|
|
||||||
M: id hashcode* obj>> hashcode* ;
|
M: eql-wrapper hashcode* obj>> hashcode* ;
|
||||||
|
|
||||||
GENERIC: (eql?) ( obj1 obj2 -- ? )
|
GENERIC: (eql?) ( obj1 obj2 -- ? )
|
||||||
|
|
||||||
|
@ -62,19 +62,27 @@ M: sequence (eql?)
|
||||||
|
|
||||||
M: object (eql?) = ;
|
M: object (eql?) = ;
|
||||||
|
|
||||||
M: id equal?
|
M: eql-wrapper equal?
|
||||||
over id? [ [ obj>> ] bi@ eql? ] [ 2drop f ] if ;
|
over eql-wrapper? [ [ obj>> ] bi@ eql? ] [ 2drop f ] if ;
|
||||||
|
|
||||||
|
TUPLE: eq-wrapper obj ;
|
||||||
|
|
||||||
|
C: <eq-wrapper> eq-wrapper
|
||||||
|
|
||||||
|
M: eq-wrapper equal?
|
||||||
|
over eq-wrapper? [ [ obj>> ] bi@ eq? ] [ 2drop f ] if ;
|
||||||
|
|
||||||
SYMBOL: objects
|
SYMBOL: objects
|
||||||
|
|
||||||
: (objects) ( obj -- id assoc ) <id> objects get ; inline
|
: cache-eql-object ( obj quot -- value )
|
||||||
|
[ <eql-wrapper> objects get ] dip '[ obj>> @ ] cache ; inline
|
||||||
|
|
||||||
: lookup-object ( obj -- n/f ) (objects) at ;
|
: cache-eq-object ( obj quot -- value )
|
||||||
|
[ <eq-wrapper> objects get ] dip '[ obj>> @ ] cache ; inline
|
||||||
|
|
||||||
: put-object ( n obj -- ) (objects) set-at ;
|
: lookup-object ( obj -- n/f ) <eq-wrapper> objects get at ;
|
||||||
|
|
||||||
: cache-object ( obj quot -- value )
|
: put-object ( n obj -- ) <eq-wrapper> objects get set-at ;
|
||||||
[ (objects) ] dip '[ obj>> @ ] cache ; inline
|
|
||||||
|
|
||||||
! Constants
|
! Constants
|
||||||
|
|
||||||
|
@ -252,7 +260,7 @@ GENERIC: ' ( obj -- ptr )
|
||||||
M: bignum '
|
M: bignum '
|
||||||
[
|
[
|
||||||
bignum [ emit-bignum ] emit-object
|
bignum [ emit-bignum ] emit-object
|
||||||
] cache-object ;
|
] cache-eql-object ;
|
||||||
|
|
||||||
! Fixnums
|
! Fixnums
|
||||||
|
|
||||||
|
@ -277,7 +285,7 @@ M: float '
|
||||||
float [
|
float [
|
||||||
align-here double>bits emit-64
|
align-here double>bits emit-64
|
||||||
] emit-object
|
] emit-object
|
||||||
] cache-object ;
|
] cache-eql-object ;
|
||||||
|
|
||||||
! Special objects
|
! Special objects
|
||||||
|
|
||||||
|
@ -340,7 +348,7 @@ M: word ' ;
|
||||||
! Wrappers
|
! Wrappers
|
||||||
|
|
||||||
M: wrapper '
|
M: wrapper '
|
||||||
wrapped>> ' wrapper [ emit ] emit-object ;
|
[ wrapped>> ' wrapper [ emit ] emit-object ] cache-eql-object ;
|
||||||
|
|
||||||
! Strings
|
! Strings
|
||||||
: native> ( object -- object )
|
: native> ( object -- object )
|
||||||
|
@ -379,7 +387,7 @@ M: wrapper '
|
||||||
M: string '
|
M: string '
|
||||||
#! We pool strings so that each string is only written once
|
#! We pool strings so that each string is only written once
|
||||||
#! to the image
|
#! to the image
|
||||||
[ emit-string ] cache-object ;
|
[ emit-string ] cache-eql-object ;
|
||||||
|
|
||||||
: assert-empty ( seq -- )
|
: assert-empty ( seq -- )
|
||||||
length 0 assert= ;
|
length 0 assert= ;
|
||||||
|
@ -390,10 +398,12 @@ M: string '
|
||||||
] bi* ;
|
] bi* ;
|
||||||
|
|
||||||
M: byte-array '
|
M: byte-array '
|
||||||
|
[
|
||||||
byte-array [
|
byte-array [
|
||||||
dup length emit-fixnum
|
dup length emit-fixnum
|
||||||
pad-bytes emit-bytes
|
pad-bytes emit-bytes
|
||||||
] emit-object ;
|
] emit-object
|
||||||
|
] cache-eq-object ;
|
||||||
|
|
||||||
! Tuples
|
! Tuples
|
||||||
ERROR: tuple-removed class ;
|
ERROR: tuple-removed class ;
|
||||||
|
@ -408,20 +418,22 @@ ERROR: tuple-removed class ;
|
||||||
|
|
||||||
: emit-tuple ( tuple -- pointer )
|
: emit-tuple ( tuple -- pointer )
|
||||||
dup class name>> "tombstone" =
|
dup class name>> "tombstone" =
|
||||||
[ [ (emit-tuple) ] cache-object ] [ (emit-tuple) ] if ;
|
[ [ (emit-tuple) ] cache-eql-object ]
|
||||||
|
[ [ (emit-tuple) ] cache-eq-object ]
|
||||||
|
if ;
|
||||||
|
|
||||||
M: tuple ' emit-tuple ;
|
M: tuple ' emit-tuple ;
|
||||||
|
|
||||||
M: tombstone '
|
M: tombstone '
|
||||||
state>> "((tombstone))" "((empty))" ?
|
state>> "((tombstone))" "((empty))" ?
|
||||||
"hashtables.private" lookup def>> first
|
"hashtables.private" lookup def>> first
|
||||||
[ emit-tuple ] cache-object ;
|
[ emit-tuple ] cache-eql-object ;
|
||||||
|
|
||||||
! Arrays
|
! Arrays
|
||||||
: emit-array ( array -- offset )
|
: emit-array ( array -- offset )
|
||||||
[ ' ] map array [ [ length emit-fixnum ] [ emit-seq ] bi ] emit-object ;
|
[ ' ] map array [ [ length emit-fixnum ] [ emit-seq ] bi ] emit-object ;
|
||||||
|
|
||||||
M: array ' emit-array ;
|
M: array ' [ emit-array ] cache-eq-object ;
|
||||||
|
|
||||||
! This is a hack. We need to detect arrays which are tuple
|
! This is a hack. We need to detect arrays which are tuple
|
||||||
! layout arrays so that they can be internalized, but making
|
! layout arrays so that they can be internalized, but making
|
||||||
|
@ -438,7 +450,7 @@ M: tuple-layout-array '
|
||||||
[
|
[
|
||||||
[ dup integer? [ <fake-bignum> ] when ] map
|
[ dup integer? [ <fake-bignum> ] when ] map
|
||||||
emit-array
|
emit-array
|
||||||
] cache-object ;
|
] cache-eql-object ;
|
||||||
|
|
||||||
! Quotations
|
! Quotations
|
||||||
|
|
||||||
|
@ -452,7 +464,7 @@ M: quotation '
|
||||||
0 emit ! xt
|
0 emit ! xt
|
||||||
0 emit ! code
|
0 emit ! code
|
||||||
] emit-object
|
] emit-object
|
||||||
] cache-object ;
|
] cache-eql-object ;
|
||||||
|
|
||||||
! End of the image
|
! End of the image
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ IN: bootstrap.tools
|
||||||
"tools.crossref"
|
"tools.crossref"
|
||||||
"tools.errors"
|
"tools.errors"
|
||||||
"tools.deploy"
|
"tools.deploy"
|
||||||
|
"tools.destructors"
|
||||||
"tools.disassembler"
|
"tools.disassembler"
|
||||||
"tools.memory"
|
"tools.memory"
|
||||||
"tools.profiler"
|
"tools.profiler"
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
USING: kernel assocs math accessors destructors fry sequences ;
|
USING: kernel assocs math accessors destructors fry sequences ;
|
||||||
IN: cache
|
IN: cache
|
||||||
|
|
||||||
TUPLE: cache-assoc assoc max-age disposed ;
|
TUPLE: cache-assoc < disposable assoc max-age ;
|
||||||
|
|
||||||
: <cache-assoc> ( -- cache )
|
: <cache-assoc> ( -- cache )
|
||||||
H{ } clone 10 f cache-assoc boa ;
|
cache-assoc new-disposable H{ } clone >>assoc 10 >>max-age ;
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
|
|
|
@ -19,13 +19,13 @@ C: <openssl-checksum> openssl-checksum
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
TUPLE: evp-md-context handle ;
|
TUPLE: evp-md-context < disposable handle ;
|
||||||
|
|
||||||
: <evp-md-context> ( -- ctx )
|
: <evp-md-context> ( -- ctx )
|
||||||
"EVP_MD_CTX" <c-object>
|
evp-md-context new-disposable
|
||||||
dup EVP_MD_CTX_init evp-md-context boa ;
|
"EVP_MD_CTX" <c-object> dup EVP_MD_CTX_init >>handle ;
|
||||||
|
|
||||||
M: evp-md-context dispose
|
M: evp-md-context dispose*
|
||||||
handle>> EVP_MD_CTX_cleanup drop ;
|
handle>> EVP_MD_CTX_cleanup drop ;
|
||||||
|
|
||||||
: with-evp-md-context ( quot -- )
|
: with-evp-md-context ( quot -- )
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
! Copyright (C) 2006, 2009 Slava Pestov
|
! Copyright (C) 2006, 2009 Slava Pestov
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: specialized-arrays.int arrays kernel math namespaces make
|
USING: arrays kernel math namespaces make
|
||||||
cocoa cocoa.messages cocoa.classes core-graphics
|
cocoa cocoa.messages cocoa.classes core-graphics
|
||||||
core-graphics.types sequences continuations accessors ;
|
core-graphics.types sequences continuations accessors ;
|
||||||
IN: cocoa.views
|
IN: cocoa.views
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
! 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: kernel assocs math math.parser memoize
|
USING: kernel assocs math math.parser memoize io.encodings.utf8
|
||||||
io.encodings.ascii io.files lexer parser
|
io.files lexer parser colors sequences splitting
|
||||||
colors sequences splitting combinators.smart ascii ;
|
combinators.smart ascii ;
|
||||||
IN: colors.constants
|
IN: colors.constants
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
@ -19,7 +19,7 @@ IN: colors.constants
|
||||||
[ parse-color ] H{ } map>assoc ;
|
[ parse-color ] H{ } map>assoc ;
|
||||||
|
|
||||||
MEMO: rgb.txt ( -- assoc )
|
MEMO: rgb.txt ( -- assoc )
|
||||||
"resource:basis/colors/constants/rgb.txt" ascii file-lines parse-rgb.txt ;
|
"resource:basis/colors/constants/rgb.txt" utf8 file-lines parse-rgb.txt ;
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
|
|
|
@ -106,11 +106,21 @@ HELP: append-outputs-as
|
||||||
|
|
||||||
{ append-outputs append-outputs-as } related-words
|
{ append-outputs append-outputs-as } related-words
|
||||||
|
|
||||||
|
HELP: drop-outputs
|
||||||
|
{ $values { "quot" quotation } }
|
||||||
|
{ $description "Calls a quotation and drops any values it leaves on the stack." } ;
|
||||||
|
|
||||||
|
HELP: keep-inputs
|
||||||
|
{ $values { "quot" quotation } }
|
||||||
|
{ $description "Calls a quotation and preserves any values it takes off the stack." } ;
|
||||||
|
|
||||||
|
{ drop-outputs keep-inputs } related-words
|
||||||
|
|
||||||
ARTICLE: "combinators.smart" "Smart combinators"
|
ARTICLE: "combinators.smart" "Smart combinators"
|
||||||
"A " { $emphasis "smart combinator" } " is a macro which reflects on the stack effect of an input quotation. The " { $vocab-link "combinators.smart" } " vocabulary implements a few simple smart combinators which look at the static stack effects of input quotations and generate code which produces or consumes the relevant number of stack values." $nl
|
"A " { $emphasis "smart combinator" } " is a macro which reflects on the stack effect of an input quotation. The " { $vocab-link "combinators.smart" } " vocabulary implements a few simple smart combinators which look at the static stack effects of input quotations and generate code which produces or consumes the relevant number of stack values." $nl
|
||||||
"Call a quotation and discard all output values:"
|
"Call a quotation and discard all output values or preserve all input values:"
|
||||||
{ $subsection drop-outputs }
|
{ $subsection drop-outputs }
|
||||||
|
{ $subsection keep-inputs }
|
||||||
"Take all input values from a sequence:"
|
"Take all input values from a sequence:"
|
||||||
{ $subsection input<sequence }
|
{ $subsection input<sequence }
|
||||||
"Store all output values to a sequence:"
|
"Store all output values to a sequence:"
|
||||||
|
|
|
@ -7,6 +7,9 @@ IN: combinators.smart
|
||||||
MACRO: drop-outputs ( quot -- quot' )
|
MACRO: drop-outputs ( quot -- quot' )
|
||||||
dup infer out>> '[ @ _ ndrop ] ;
|
dup infer out>> '[ @ _ ndrop ] ;
|
||||||
|
|
||||||
|
MACRO: keep-inputs ( quot -- quot' )
|
||||||
|
dup infer in>> '[ _ _ nkeep ] ;
|
||||||
|
|
||||||
MACRO: output>sequence ( quot exemplar -- newquot )
|
MACRO: output>sequence ( quot exemplar -- newquot )
|
||||||
[ dup infer out>> ] dip
|
[ dup infer out>> ] dip
|
||||||
'[ @ _ _ nsequence ] ;
|
'[ @ _ _ nsequence ] ;
|
||||||
|
|
|
@ -180,3 +180,8 @@ IN: compiler.cfg.builder.tests
|
||||||
[ { byte-array fixnum } declare set-alien-unsigned-1 ]
|
[ { byte-array fixnum } declare set-alien-unsigned-1 ]
|
||||||
[ ##set-alien-integer-1? ] contains-insn?
|
[ ##set-alien-integer-1? ] contains-insn?
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
[ f ] [
|
||||||
|
[ 1000 [ ] times ]
|
||||||
|
[ [ ##peek? ] [ ##replace? ] bi or ] contains-insn?
|
||||||
|
] unit-test
|
|
@ -6,12 +6,12 @@ arrays assocs init system concurrency.conditions accessors
|
||||||
debugger debugger.threads locals fry ;
|
debugger debugger.threads locals fry ;
|
||||||
IN: concurrency.mailboxes
|
IN: concurrency.mailboxes
|
||||||
|
|
||||||
TUPLE: mailbox threads data disposed ;
|
TUPLE: mailbox < disposable threads data ;
|
||||||
|
|
||||||
M: mailbox dispose* threads>> notify-all ;
|
M: mailbox dispose* threads>> notify-all ;
|
||||||
|
|
||||||
: <mailbox> ( -- mailbox )
|
: <mailbox> ( -- mailbox )
|
||||||
<dlist> <dlist> f mailbox boa ;
|
mailbox new-disposable <dlist> >>threads <dlist> >>data ;
|
||||||
|
|
||||||
: mailbox-empty? ( mailbox -- bool )
|
: mailbox-empty? ( mailbox -- bool )
|
||||||
data>> deque-empty? ;
|
data>> deque-empty? ;
|
||||||
|
|
|
@ -181,15 +181,15 @@ SYMBOL: event-stream-callbacks
|
||||||
}
|
}
|
||||||
"cdecl" [ (master-event-source-callback) ] alien-callback ;
|
"cdecl" [ (master-event-source-callback) ] alien-callback ;
|
||||||
|
|
||||||
TUPLE: event-stream info handle disposed ;
|
TUPLE: event-stream < disposable info handle ;
|
||||||
|
|
||||||
: <event-stream> ( quot paths latency flags -- event-stream )
|
: <event-stream> ( quot paths latency flags -- event-stream )
|
||||||
[
|
[
|
||||||
add-event-source-callback dup
|
add-event-source-callback
|
||||||
[ master-event-source-callback ] dip
|
[ master-event-source-callback ] keep
|
||||||
] 3dip <FSEventStream>
|
] 3dip <FSEventStream>
|
||||||
dup enable-event-stream
|
dup enable-event-stream
|
||||||
f event-stream boa ;
|
event-stream new-disposable swap >>handle swap >>info ;
|
||||||
|
|
||||||
M: event-stream dispose*
|
M: event-stream dispose*
|
||||||
{
|
{
|
||||||
|
|
|
@ -46,7 +46,7 @@ ERROR: not-a-string object ;
|
||||||
CTLineCreateWithAttributedString
|
CTLineCreateWithAttributedString
|
||||||
] with-destructors ;
|
] with-destructors ;
|
||||||
|
|
||||||
TUPLE: line line metrics image loc dim disposed ;
|
TUPLE: line < disposable line metrics image loc dim ;
|
||||||
|
|
||||||
: typographic-bounds ( line -- width ascent descent leading )
|
: typographic-bounds ( line -- width ascent descent leading )
|
||||||
0 <CGFloat> 0 <CGFloat> 0 <CGFloat>
|
0 <CGFloat> 0 <CGFloat> 0 <CGFloat>
|
||||||
|
@ -109,6 +109,8 @@ TUPLE: line line metrics image loc dim disposed ;
|
||||||
|
|
||||||
:: <line> ( font string -- line )
|
:: <line> ( font string -- line )
|
||||||
[
|
[
|
||||||
|
line new-disposable
|
||||||
|
|
||||||
[let* | open-font [ font cache-font ]
|
[let* | open-font [ font cache-font ]
|
||||||
line [ string open-font font foreground>> <CTLine> |CFRelease ]
|
line [ string open-font font foreground>> <CTLine> |CFRelease ]
|
||||||
|
|
||||||
|
@ -120,7 +122,11 @@ TUPLE: line line metrics image loc dim disposed ;
|
||||||
ext [ (loc) (dim) [ + ceiling ] 2map ]
|
ext [ (loc) (dim) [ + ceiling ] 2map ]
|
||||||
dim [ ext loc [ - >integer ] 2map ]
|
dim [ ext loc [ - >integer ] 2map ]
|
||||||
metrics [ open-font line compute-line-metrics ] |
|
metrics [ open-font line compute-line-metrics ] |
|
||||||
line metrics
|
|
||||||
|
line >>line
|
||||||
|
|
||||||
|
metrics >>metrics
|
||||||
|
|
||||||
dim [
|
dim [
|
||||||
{
|
{
|
||||||
[ font dim fill-background ]
|
[ font dim fill-background ]
|
||||||
|
@ -128,11 +134,12 @@ TUPLE: line line metrics image loc dim disposed ;
|
||||||
[ loc set-text-position ]
|
[ loc set-text-position ]
|
||||||
[ [ line ] dip CTLineDraw ]
|
[ [ line ] dip CTLineDraw ]
|
||||||
} cleave
|
} cleave
|
||||||
] make-bitmap-image
|
] make-bitmap-image >>image
|
||||||
metrics loc dim line-loc
|
|
||||||
metrics metrics>dim
|
metrics loc dim line-loc >>loc
|
||||||
|
|
||||||
|
metrics metrics>dim >>dim
|
||||||
]
|
]
|
||||||
f line boa
|
|
||||||
] with-destructors ;
|
] with-destructors ;
|
||||||
|
|
||||||
M: line dispose* line>> CFRelease ;
|
M: line dispose* line>> CFRelease ;
|
||||||
|
|
|
@ -96,10 +96,7 @@ HOOK: reserved-area-size os ( -- n )
|
||||||
! frame, 8 bytes in size. This is in the param-save area so it
|
! frame, 8 bytes in size. This is in the param-save area so it
|
||||||
! does not overlap with spill slots.
|
! does not overlap with spill slots.
|
||||||
: scratch@ ( n -- offset )
|
: scratch@ ( n -- offset )
|
||||||
stack-frame get total-size>>
|
factor-area-size + ;
|
||||||
factor-area-size -
|
|
||||||
param-save-size -
|
|
||||||
+ ;
|
|
||||||
|
|
||||||
! GC root area
|
! GC root area
|
||||||
: gc-root@ ( n -- offset )
|
: gc-root@ ( n -- offset )
|
||||||
|
|
|
@ -287,9 +287,9 @@ ARTICLE: "handbook-tools-reference" "Developer tools"
|
||||||
{ $heading "Debugging" }
|
{ $heading "Debugging" }
|
||||||
{ $subsection "prettyprint" }
|
{ $subsection "prettyprint" }
|
||||||
{ $subsection "inspector" }
|
{ $subsection "inspector" }
|
||||||
|
{ $subsection "tools.inference" }
|
||||||
{ $subsection "tools.annotations" }
|
{ $subsection "tools.annotations" }
|
||||||
{ $subsection "tools.deprecation" }
|
{ $subsection "tools.deprecation" }
|
||||||
{ $subsection "tools.inference" }
|
|
||||||
{ $heading "Browsing" }
|
{ $heading "Browsing" }
|
||||||
{ $subsection "see" }
|
{ $subsection "see" }
|
||||||
{ $subsection "tools.crossref" }
|
{ $subsection "tools.crossref" }
|
||||||
|
@ -299,6 +299,7 @@ ARTICLE: "handbook-tools-reference" "Developer tools"
|
||||||
{ $subsection "profiling" }
|
{ $subsection "profiling" }
|
||||||
{ $subsection "tools.memory" }
|
{ $subsection "tools.memory" }
|
||||||
{ $subsection "tools.threads" }
|
{ $subsection "tools.threads" }
|
||||||
|
{ $subsection "tools.destructors" }
|
||||||
{ $subsection "tools.disassembler" }
|
{ $subsection "tools.disassembler" }
|
||||||
{ $heading "Deployment" }
|
{ $heading "Deployment" }
|
||||||
{ $subsection "tools.deploy" } ;
|
{ $subsection "tools.deploy" } ;
|
||||||
|
|
|
@ -137,6 +137,14 @@ ALIAS: $slot $snippet
|
||||||
] with-nesting
|
] with-nesting
|
||||||
] ($heading) ;
|
] ($heading) ;
|
||||||
|
|
||||||
|
: $deprecated ( element -- )
|
||||||
|
[
|
||||||
|
deprecated-style get [
|
||||||
|
last-element off
|
||||||
|
"This word is deprecated" $heading print-element
|
||||||
|
] with-nesting
|
||||||
|
] ($heading) ;
|
||||||
|
|
||||||
! Images
|
! Images
|
||||||
: $image ( element -- )
|
: $image ( element -- )
|
||||||
[ first write-image ] ($span) ;
|
[ first write-image ] ($span) ;
|
||||||
|
|
|
@ -85,6 +85,14 @@ H{
|
||||||
{ wrap-margin 500 }
|
{ wrap-margin 500 }
|
||||||
} warning-style set-global
|
} warning-style set-global
|
||||||
|
|
||||||
|
SYMBOL: deprecated-style
|
||||||
|
H{
|
||||||
|
{ page-color COLOR: gray90 }
|
||||||
|
{ border-color COLOR: red }
|
||||||
|
{ border-width 5 }
|
||||||
|
{ wrap-margin 500 }
|
||||||
|
} deprecated-style set-global
|
||||||
|
|
||||||
SYMBOL: table-content-style
|
SYMBOL: table-content-style
|
||||||
H{
|
H{
|
||||||
{ wrap-margin 350 }
|
{ wrap-margin 350 }
|
||||||
|
|
|
@ -249,7 +249,8 @@ C: <vocab-author> vocab-author
|
||||||
} cleave ;
|
} cleave ;
|
||||||
|
|
||||||
: keyed-vocabs ( str quot -- seq )
|
: keyed-vocabs ( str quot -- seq )
|
||||||
[ all-vocabs ] 2dip '[ [ _ swap @ member? ] filter ] assoc-map ; inline
|
[ all-vocabs-recursive ] 2dip
|
||||||
|
'[ [ _ swap @ member? ] filter no-prefixes ] assoc-map ; inline
|
||||||
|
|
||||||
: tagged ( tag -- assoc )
|
: tagged ( tag -- assoc )
|
||||||
[ vocab-tags ] keyed-vocabs ;
|
[ vocab-tags ] keyed-vocabs ;
|
||||||
|
|
|
@ -95,7 +95,11 @@ ERROR: unimplemented-color-type image ;
|
||||||
unimplemented-color-type ;
|
unimplemented-color-type ;
|
||||||
|
|
||||||
: decode-truecolor-alpha ( loading-png -- loading-png )
|
: decode-truecolor-alpha ( loading-png -- loading-png )
|
||||||
unimplemented-color-type ;
|
[ <image> ] dip {
|
||||||
|
[ png-image-bytes >>bitmap ]
|
||||||
|
[ [ width>> ] [ height>> ] bi 2array >>dim ]
|
||||||
|
[ drop RGBA >>component-order ubyte-components >>component-type ]
|
||||||
|
} cleave ;
|
||||||
|
|
||||||
: decode-png ( loading-png -- loading-png )
|
: decode-png ( loading-png -- loading-png )
|
||||||
dup color-type>> {
|
dup color-type>> {
|
||||||
|
|
|
@ -18,7 +18,7 @@ TUPLE: epoll-mx < mx events ;
|
||||||
max-events epoll_create dup io-error >>fd
|
max-events epoll_create dup io-error >>fd
|
||||||
max-events "epoll-event" <struct-array> >>events ;
|
max-events "epoll-event" <struct-array> >>events ;
|
||||||
|
|
||||||
M: epoll-mx dispose fd>> close-file ;
|
M: epoll-mx dispose* fd>> close-file ;
|
||||||
|
|
||||||
: make-event ( fd events -- event )
|
: make-event ( fd events -- event )
|
||||||
"epoll-event" <c-object>
|
"epoll-event" <c-object>
|
||||||
|
|
|
@ -17,7 +17,7 @@ TUPLE: kqueue-mx < mx events ;
|
||||||
kqueue dup io-error >>fd
|
kqueue dup io-error >>fd
|
||||||
max-events "kevent" <struct-array> >>events ;
|
max-events "kevent" <struct-array> >>events ;
|
||||||
|
|
||||||
M: kqueue-mx dispose fd>> close-file ;
|
M: kqueue-mx dispose* fd>> close-file ;
|
||||||
|
|
||||||
: make-kevent ( fd filter flags -- event )
|
: make-kevent ( fd filter flags -- event )
|
||||||
"kevent" <c-object>
|
"kevent" <c-object>
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
! 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 accessors assocs sequences threads ;
|
USING: kernel accessors assocs sequences threads destructors ;
|
||||||
IN: io.backend.unix.multiplexers
|
IN: io.backend.unix.multiplexers
|
||||||
|
|
||||||
TUPLE: mx fd reads writes ;
|
TUPLE: mx < disposable fd reads writes ;
|
||||||
|
|
||||||
: new-mx ( class -- obj )
|
: new-mx ( class -- obj )
|
||||||
new
|
new-disposable
|
||||||
H{ } clone >>reads
|
H{ } clone >>reads
|
||||||
H{ } clone >>writes ; inline
|
H{ } clone >>writes ; inline
|
||||||
|
|
||||||
|
|
|
@ -4,14 +4,15 @@ USING: alien alien.c-types alien.syntax generic assocs kernel
|
||||||
kernel.private math io.ports sequences strings sbufs threads
|
kernel.private math io.ports sequences strings sbufs threads
|
||||||
unix vectors io.buffers io.backend io.encodings math.parser
|
unix vectors io.buffers io.backend io.encodings math.parser
|
||||||
continuations system libc namespaces make io.timeouts
|
continuations system libc namespaces make io.timeouts
|
||||||
io.encodings.utf8 destructors accessors summary combinators
|
io.encodings.utf8 destructors destructors.private accessors
|
||||||
locals unix.time fry io.backend.unix.multiplexers ;
|
summary combinators locals unix.time fry
|
||||||
|
io.backend.unix.multiplexers ;
|
||||||
QUALIFIED: io
|
QUALIFIED: io
|
||||||
IN: io.backend.unix
|
IN: io.backend.unix
|
||||||
|
|
||||||
GENERIC: handle-fd ( handle -- fd )
|
GENERIC: handle-fd ( handle -- fd )
|
||||||
|
|
||||||
TUPLE: fd fd disposed ;
|
TUPLE: fd < disposable fd ;
|
||||||
|
|
||||||
: init-fd ( fd -- fd )
|
: init-fd ( fd -- fd )
|
||||||
[
|
[
|
||||||
|
@ -25,14 +26,16 @@ TUPLE: fd fd disposed ;
|
||||||
#! since on OS X 10.3, this operation fails from init-io
|
#! since on OS X 10.3, this operation fails from init-io
|
||||||
#! when running the Factor.app (presumably because fd 0 and
|
#! when running the Factor.app (presumably because fd 0 and
|
||||||
#! 1 are closed).
|
#! 1 are closed).
|
||||||
f fd boa ;
|
fd new-disposable swap >>fd ;
|
||||||
|
|
||||||
M: fd dispose
|
M: fd dispose
|
||||||
dup disposed>> [ drop ] [
|
dup disposed>> [ drop ] [
|
||||||
|
{
|
||||||
[ cancel-operation ]
|
[ cancel-operation ]
|
||||||
[ t >>disposed drop ]
|
[ t >>disposed drop ]
|
||||||
|
[ unregister-disposable ]
|
||||||
[ fd>> close-file ]
|
[ fd>> close-file ]
|
||||||
tri
|
} cleave
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
M: fd handle-fd dup check-disposed fd>> ;
|
M: fd handle-fd dup check-disposed fd>> ;
|
||||||
|
@ -133,7 +136,7 @@ M: unix io-multiplex ( ms/f -- )
|
||||||
! pipe to non-blocking, and read from it instead of the real
|
! pipe to non-blocking, and read from it instead of the real
|
||||||
! stdin. Very crufty, but it will suffice until we get native
|
! stdin. Very crufty, but it will suffice until we get native
|
||||||
! threading support at the language level.
|
! threading support at the language level.
|
||||||
TUPLE: stdin control size data disposed ;
|
TUPLE: stdin < disposable control size data ;
|
||||||
|
|
||||||
M: stdin dispose*
|
M: stdin dispose*
|
||||||
[
|
[
|
||||||
|
@ -168,7 +171,7 @@ M: stdin refill
|
||||||
: data-read-fd ( -- fd ) &: stdin_read *uint ;
|
: data-read-fd ( -- fd ) &: stdin_read *uint ;
|
||||||
|
|
||||||
: <stdin> ( -- stdin )
|
: <stdin> ( -- stdin )
|
||||||
stdin new
|
stdin new-disposable
|
||||||
control-write-fd <fd> <output-port> >>control
|
control-write-fd <fd> <output-port> >>control
|
||||||
size-read-fd <fd> init-fd <input-port> >>size
|
size-read-fd <fd> init-fd <input-port> >>size
|
||||||
data-read-fd <fd> >>data ;
|
data-read-fd <fd> >>data ;
|
||||||
|
|
|
@ -7,33 +7,21 @@ windows.kernel32 windows.shell32 windows.types windows.winsock
|
||||||
splitting continuations math.bitwise accessors init sets assocs ;
|
splitting continuations math.bitwise accessors init sets assocs ;
|
||||||
IN: io.backend.windows
|
IN: io.backend.windows
|
||||||
|
|
||||||
: win32-handles ( -- assoc )
|
TUPLE: win32-handle < disposable handle ;
|
||||||
\ win32-handles [ H{ } clone ] initialize-alien ;
|
|
||||||
|
|
||||||
TUPLE: win32-handle < identity-tuple handle disposed ;
|
|
||||||
|
|
||||||
M: win32-handle hashcode* handle>> hashcode* ;
|
|
||||||
|
|
||||||
: set-inherit ( handle ? -- )
|
: set-inherit ( handle ? -- )
|
||||||
[ handle>> HANDLE_FLAG_INHERIT ] dip
|
[ handle>> HANDLE_FLAG_INHERIT ] dip
|
||||||
>BOOLEAN SetHandleInformation win32-error=0/f ;
|
>BOOLEAN SetHandleInformation win32-error=0/f ;
|
||||||
|
|
||||||
: new-win32-handle ( handle class -- win32-handle )
|
: new-win32-handle ( handle class -- win32-handle )
|
||||||
new swap >>handle
|
new-disposable swap >>handle
|
||||||
dup f set-inherit
|
dup f set-inherit ;
|
||||||
dup win32-handles conjoin ;
|
|
||||||
|
|
||||||
: <win32-handle> ( handle -- win32-handle )
|
: <win32-handle> ( handle -- win32-handle )
|
||||||
win32-handle new-win32-handle ;
|
win32-handle new-win32-handle ;
|
||||||
|
|
||||||
ERROR: disposing-twice ;
|
|
||||||
|
|
||||||
: unregister-handle ( handle -- )
|
|
||||||
win32-handles delete-at*
|
|
||||||
[ t >>disposed drop ] [ disposing-twice ] if ;
|
|
||||||
|
|
||||||
M: win32-handle dispose* ( handle -- )
|
M: win32-handle dispose* ( handle -- )
|
||||||
[ unregister-handle ] [ handle>> CloseHandle win32-error=0/f ] bi ;
|
handle>> CloseHandle win32-error=0/f ;
|
||||||
|
|
||||||
TUPLE: win32-file < win32-handle ptr ;
|
TUPLE: win32-file < win32-handle ptr ;
|
||||||
|
|
||||||
|
@ -54,7 +42,7 @@ HOOK: add-completion io-backend ( port -- )
|
||||||
<win32-file> |dispose
|
<win32-file> |dispose
|
||||||
dup add-completion ;
|
dup add-completion ;
|
||||||
|
|
||||||
: share-mode ( -- fixnum )
|
: share-mode ( -- n )
|
||||||
{
|
{
|
||||||
FILE_SHARE_READ
|
FILE_SHARE_READ
|
||||||
FILE_SHARE_WRITE
|
FILE_SHARE_WRITE
|
||||||
|
|
|
@ -6,30 +6,29 @@ accessors vocabs.loader combinators alien.c-types
|
||||||
math ;
|
math ;
|
||||||
IN: io.mmap
|
IN: io.mmap
|
||||||
|
|
||||||
TUPLE: mapped-file address handle length disposed ;
|
TUPLE: mapped-file < disposable address handle length ;
|
||||||
|
|
||||||
HOOK: (mapped-file-reader) os ( path length -- address handle )
|
HOOK: (mapped-file-reader) os ( path length -- address handle )
|
||||||
HOOK: (mapped-file-r/w) os ( path length -- address handle )
|
HOOK: (mapped-file-r/w) os ( path length -- address handle )
|
||||||
|
|
||||||
ERROR: bad-mmap-size path size ;
|
ERROR: bad-mmap-size n ;
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
: prepare-mapped-file ( path -- path' n )
|
: prepare-mapped-file ( path quot -- mapped-file path' length )
|
||||||
|
[
|
||||||
[ normalize-path ] [ file-info size>> ] bi
|
[ normalize-path ] [ file-info size>> ] bi
|
||||||
dup 0 <= [ bad-mmap-size ] when ;
|
[ dup 0 <= [ bad-mmap-size ] [ 2drop ] if ]
|
||||||
|
[ nip mapped-file new-disposable swap >>length ]
|
||||||
|
] dip 2tri [ >>address ] [ >>handle ] bi* ; inline
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
: <mapped-file-reader> ( path -- mmap )
|
: <mapped-file-reader> ( path -- mmap )
|
||||||
prepare-mapped-file
|
[ (mapped-file-reader) ] prepare-mapped-file ;
|
||||||
[ (mapped-file-reader) ] keep
|
|
||||||
f mapped-file boa ;
|
|
||||||
|
|
||||||
: <mapped-file> ( path -- mmap )
|
: <mapped-file> ( path -- mmap )
|
||||||
prepare-mapped-file
|
[ (mapped-file-r/w) ] prepare-mapped-file ;
|
||||||
[ (mapped-file-r/w) ] keep
|
|
||||||
f mapped-file boa ;
|
|
||||||
|
|
||||||
HOOK: close-mapped-file io-backend ( mmap -- )
|
HOOK: close-mapped-file io-backend ( mmap -- )
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ SYMBOL: watches
|
||||||
|
|
||||||
SYMBOL: inotify
|
SYMBOL: inotify
|
||||||
|
|
||||||
TUPLE: linux-monitor < monitor wd inotify watches disposed ;
|
TUPLE: linux-monitor < monitor wd inotify watches ;
|
||||||
|
|
||||||
: <linux-monitor> ( wd path mailbox -- monitor )
|
: <linux-monitor> ( wd path mailbox -- monitor )
|
||||||
linux-monitor new-monitor
|
linux-monitor new-monitor
|
||||||
|
|
|
@ -17,7 +17,6 @@ M:: macosx (monitor) ( path recursive? mailbox -- monitor )
|
||||||
path 1array 0 0 <event-stream> >>handle
|
path 1array 0 0 <event-stream> >>handle
|
||||||
] ;
|
] ;
|
||||||
|
|
||||||
M: macosx-monitor dispose
|
M: macosx-monitor dispose* handle>> dispose ;
|
||||||
handle>> dispose ;
|
|
||||||
|
|
||||||
macosx set-io-backend
|
macosx set-io-backend
|
||||||
|
|
|
@ -20,16 +20,14 @@ M: object dispose-monitors ;
|
||||||
[ dispose-monitors ] [ ] cleanup
|
[ dispose-monitors ] [ ] cleanup
|
||||||
] with-scope ; inline
|
] with-scope ; inline
|
||||||
|
|
||||||
TUPLE: monitor < identity-tuple path queue timeout ;
|
TUPLE: monitor < disposable path queue timeout ;
|
||||||
|
|
||||||
M: monitor hashcode* path>> hashcode* ;
|
|
||||||
|
|
||||||
M: monitor timeout timeout>> ;
|
M: monitor timeout timeout>> ;
|
||||||
|
|
||||||
M: monitor set-timeout (>>timeout) ;
|
M: monitor set-timeout (>>timeout) ;
|
||||||
|
|
||||||
: new-monitor ( path mailbox class -- monitor )
|
: new-monitor ( path mailbox class -- monitor )
|
||||||
new
|
new-disposable
|
||||||
swap >>queue
|
swap >>queue
|
||||||
swap >>path ; inline
|
swap >>path ; inline
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ IN: io.monitors.recursive
|
||||||
|
|
||||||
! Simulate recursive monitors on platforms that don't have them
|
! Simulate recursive monitors on platforms that don't have them
|
||||||
|
|
||||||
TUPLE: recursive-monitor < monitor children thread ready disposed ;
|
TUPLE: recursive-monitor < monitor children thread ready ;
|
||||||
|
|
||||||
: notify? ( -- ? ) monitor tget ready>> promise-fulfilled? ;
|
: notify? ( -- ? ) monitor tget ready>> promise-fulfilled? ;
|
||||||
|
|
||||||
|
|
|
@ -10,14 +10,14 @@ IN: io.ports
|
||||||
SYMBOL: default-buffer-size
|
SYMBOL: default-buffer-size
|
||||||
64 1024 * default-buffer-size set-global
|
64 1024 * default-buffer-size set-global
|
||||||
|
|
||||||
TUPLE: port handle timeout disposed ;
|
TUPLE: port < disposable handle timeout ;
|
||||||
|
|
||||||
M: port timeout timeout>> ;
|
M: port timeout timeout>> ;
|
||||||
|
|
||||||
M: port set-timeout (>>timeout) ;
|
M: port set-timeout (>>timeout) ;
|
||||||
|
|
||||||
: <port> ( handle class -- port )
|
: <port> ( handle class -- port )
|
||||||
new swap >>handle ; inline
|
new-disposable swap >>handle ; inline
|
||||||
|
|
||||||
TUPLE: buffered-port < port { buffer buffer } ;
|
TUPLE: buffered-port < port { buffer buffer } ;
|
||||||
|
|
||||||
|
|
|
@ -78,9 +78,9 @@ TUPLE: openssl-context < secure-context aliens sessions ;
|
||||||
SSL_CTX_set_verify_depth
|
SSL_CTX_set_verify_depth
|
||||||
] [ drop ] if ;
|
] [ drop ] if ;
|
||||||
|
|
||||||
TUPLE: bio handle disposed ;
|
TUPLE: bio < disposable handle ;
|
||||||
|
|
||||||
: <bio> ( handle -- bio ) f bio boa ;
|
: <bio> ( handle -- bio ) bio new-disposable swap >>handle ;
|
||||||
|
|
||||||
M: bio dispose* handle>> BIO_free ssl-error ;
|
M: bio dispose* handle>> BIO_free ssl-error ;
|
||||||
|
|
||||||
|
@ -94,9 +94,9 @@ M: bio dispose* handle>> BIO_free ssl-error ;
|
||||||
SSL_CTX_set_tmp_dh ssl-error
|
SSL_CTX_set_tmp_dh ssl-error
|
||||||
] [ drop ] if ;
|
] [ drop ] if ;
|
||||||
|
|
||||||
TUPLE: rsa handle disposed ;
|
TUPLE: rsa < disposable handle ;
|
||||||
|
|
||||||
: <rsa> ( handle -- rsa ) f rsa boa ;
|
: <rsa> ( handle -- rsa ) rsa new-disposable swap >>handle ;
|
||||||
|
|
||||||
M: rsa dispose* handle>> RSA_free ;
|
M: rsa dispose* handle>> RSA_free ;
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ M: rsa dispose* handle>> RSA_free ;
|
||||||
SSL_CTX_set_tmp_rsa ssl-error ;
|
SSL_CTX_set_tmp_rsa ssl-error ;
|
||||||
|
|
||||||
: <openssl-context> ( config ctx -- context )
|
: <openssl-context> ( config ctx -- context )
|
||||||
openssl-context new
|
openssl-context new-disposable
|
||||||
swap >>handle
|
swap >>handle
|
||||||
swap >>config
|
swap >>config
|
||||||
V{ } clone >>aliens
|
V{ } clone >>aliens
|
||||||
|
@ -139,7 +139,7 @@ M: openssl-context dispose*
|
||||||
[ handle>> SSL_CTX_free ]
|
[ handle>> SSL_CTX_free ]
|
||||||
tri ;
|
tri ;
|
||||||
|
|
||||||
TUPLE: ssl-handle file handle connected disposed ;
|
TUPLE: ssl-handle < disposable file handle connected ;
|
||||||
|
|
||||||
SYMBOL: default-secure-context
|
SYMBOL: default-secure-context
|
||||||
|
|
||||||
|
@ -151,8 +151,10 @@ SYMBOL: default-secure-context
|
||||||
] unless* ;
|
] unless* ;
|
||||||
|
|
||||||
: <ssl-handle> ( fd -- ssl )
|
: <ssl-handle> ( fd -- ssl )
|
||||||
current-secure-context handle>> SSL_new dup ssl-error
|
ssl-handle new-disposable
|
||||||
f f ssl-handle boa ;
|
current-secure-context handle>> SSL_new
|
||||||
|
dup ssl-error >>handle
|
||||||
|
swap >>file ;
|
||||||
|
|
||||||
M: ssl-handle dispose*
|
M: ssl-handle dispose*
|
||||||
[ handle>> SSL_free ] [ file>> dispose ] bi ;
|
[ handle>> SSL_free ] [ file>> dispose ] bi ;
|
||||||
|
|
|
@ -29,7 +29,7 @@ ephemeral-key-bits ;
|
||||||
"vocab:openssl/cacert.pem" >>ca-file
|
"vocab:openssl/cacert.pem" >>ca-file
|
||||||
t >>verify ;
|
t >>verify ;
|
||||||
|
|
||||||
TUPLE: secure-context config handle disposed ;
|
TUPLE: secure-context < disposable config handle ;
|
||||||
|
|
||||||
HOOK: <secure-context> secure-socket-backend ( config -- context )
|
HOOK: <secure-context> secure-socket-backend ( config -- context )
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,8 @@ concurrency.promises threads io.streams.string ;
|
||||||
! See what happens if other end is closed
|
! See what happens if other end is closed
|
||||||
[ ] [ <promise> "port" set ] unit-test
|
[ ] [ <promise> "port" set ] unit-test
|
||||||
|
|
||||||
|
[ ] [ "datagram3" get dispose ] unit-test
|
||||||
|
|
||||||
[ ] [
|
[ ] [
|
||||||
[
|
[
|
||||||
"127.0.0.1" 0 <inet4> utf8 <server>
|
"127.0.0.1" 0 <inet4> utf8 <server>
|
||||||
|
@ -93,6 +95,8 @@ concurrency.promises threads io.streams.string ;
|
||||||
|
|
||||||
[ "hello" f ] [
|
[ "hello" f ] [
|
||||||
"port" get ?promise utf8 [
|
"port" get ?promise utf8 [
|
||||||
|
1 seconds input-stream get set-timeout
|
||||||
|
1 seconds output-stream get set-timeout
|
||||||
"hi\n" write flush readln readln
|
"hi\n" write flush readln readln
|
||||||
] with-client
|
] with-client
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
|
@ -5,7 +5,7 @@ IN: io.streams.duplex.tests
|
||||||
! Test duplex stream close behavior
|
! Test duplex stream close behavior
|
||||||
TUPLE: closing-stream < disposable ;
|
TUPLE: closing-stream < disposable ;
|
||||||
|
|
||||||
: <closing-stream> ( -- stream ) closing-stream new ;
|
: <closing-stream> ( -- stream ) closing-stream new-disposable ;
|
||||||
|
|
||||||
M: closing-stream dispose* drop ;
|
M: closing-stream dispose* drop ;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
USING: alien.syntax alien.c-types core-foundation
|
USING: alien.syntax alien.c-types core-foundation
|
||||||
core-foundation.bundles core-foundation.dictionaries system
|
core-foundation.bundles core-foundation.dictionaries system
|
||||||
combinators kernel sequences debugger io accessors ;
|
combinators kernel sequences io accessors ;
|
||||||
IN: iokit
|
IN: iokit
|
||||||
|
|
||||||
<<
|
<<
|
||||||
|
@ -136,11 +136,9 @@ FUNCTION: IOReturn IORegistryEntryCreateCFProperties ( io_registry_entry_t entry
|
||||||
|
|
||||||
FUNCTION: char* mach_error_string ( IOReturn error ) ;
|
FUNCTION: char* mach_error_string ( IOReturn error ) ;
|
||||||
|
|
||||||
TUPLE: mach-error error-code ;
|
TUPLE: mach-error error-code error-string ;
|
||||||
C: <mach-error> mach-error
|
: <mach-error> ( code -- error )
|
||||||
|
dup mach_error_string \ mach-error boa ;
|
||||||
M: mach-error error.
|
|
||||||
"IOKit call failed: " print error-code>> mach_error_string print ;
|
|
||||||
|
|
||||||
: mach-error ( return -- )
|
: mach-error ( return -- )
|
||||||
dup KERN_SUCCESS = [ drop ] [ <mach-error> throw ] if ;
|
dup KERN_SUCCESS = [ drop ] [ <mach-error> throw ] if ;
|
||||||
|
|
|
@ -4,8 +4,8 @@ destructors kernel ;
|
||||||
|
|
||||||
100 malloc "block" set
|
100 malloc "block" set
|
||||||
|
|
||||||
[ t ] [ "block" get mallocs key? ] unit-test
|
[ t ] [ "block" get malloc-exists? ] unit-test
|
||||||
|
|
||||||
[ ] [ [ "block" get &free drop ] with-destructors ] unit-test
|
[ ] [ [ "block" get &free drop ] with-destructors ] unit-test
|
||||||
|
|
||||||
[ f ] [ "block" get mallocs key? ] unit-test
|
[ f ] [ "block" get malloc-exists? ] unit-test
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
! Copyright (C) 2007, 2008 Doug Coleman
|
! Copyright (C) 2007, 2008 Doug Coleman
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: alien assocs continuations alien.destructors kernel
|
USING: alien assocs continuations alien.destructors kernel
|
||||||
namespaces accessors sets summary ;
|
namespaces accessors sets summary destructors destructors.private ;
|
||||||
IN: libc
|
IN: libc
|
||||||
|
|
||||||
: errno ( -- int )
|
: errno ( -- int )
|
||||||
|
@ -26,8 +26,16 @@ IN: libc
|
||||||
: (realloc) ( alien size -- newalien )
|
: (realloc) ( alien size -- newalien )
|
||||||
"void*" "libc" "realloc" { "void*" "ulong" } alien-invoke ;
|
"void*" "libc" "realloc" { "void*" "ulong" } alien-invoke ;
|
||||||
|
|
||||||
: mallocs ( -- assoc )
|
! We stick malloc-ptr instances in the global disposables set
|
||||||
\ mallocs [ H{ } clone ] initialize-alien ;
|
TUPLE: malloc-ptr value continuation ;
|
||||||
|
|
||||||
|
M: malloc-ptr hashcode* value>> hashcode* ;
|
||||||
|
|
||||||
|
M: malloc-ptr equal?
|
||||||
|
over malloc-ptr? [ [ value>> ] bi@ = ] [ 2drop f ] if ;
|
||||||
|
|
||||||
|
: <malloc-ptr> ( value -- malloc-ptr )
|
||||||
|
malloc-ptr new swap >>value ;
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
|
@ -39,11 +47,6 @@ M: bad-ptr summary
|
||||||
: check-ptr ( c-ptr -- c-ptr )
|
: check-ptr ( c-ptr -- c-ptr )
|
||||||
[ bad-ptr ] unless* ;
|
[ bad-ptr ] unless* ;
|
||||||
|
|
||||||
ERROR: double-free ;
|
|
||||||
|
|
||||||
M: double-free summary
|
|
||||||
drop "Free failed since memory is not allocated" ;
|
|
||||||
|
|
||||||
ERROR: realloc-error ptr size ;
|
ERROR: realloc-error ptr size ;
|
||||||
|
|
||||||
M: realloc-error summary
|
M: realloc-error summary
|
||||||
|
@ -52,16 +55,13 @@ M: realloc-error summary
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
: add-malloc ( alien -- alien )
|
: add-malloc ( alien -- alien )
|
||||||
dup mallocs conjoin ;
|
dup <malloc-ptr> register-disposable ;
|
||||||
|
|
||||||
: delete-malloc ( alien -- )
|
: delete-malloc ( alien -- )
|
||||||
[
|
[ <malloc-ptr> unregister-disposable ] when* ;
|
||||||
mallocs delete-at*
|
|
||||||
[ drop ] [ double-free ] if
|
|
||||||
] when* ;
|
|
||||||
|
|
||||||
: malloc-exists? ( alien -- ? )
|
: malloc-exists? ( alien -- ? )
|
||||||
mallocs key? ;
|
<malloc-ptr> disposables get key? ;
|
||||||
|
|
||||||
PRIVATE>
|
PRIVATE>
|
||||||
|
|
||||||
|
|
|
@ -163,6 +163,7 @@ SYMBOL: interactive-vocabs
|
||||||
"syntax"
|
"syntax"
|
||||||
"tools.annotations"
|
"tools.annotations"
|
||||||
"tools.crossref"
|
"tools.crossref"
|
||||||
|
"tools.destructors"
|
||||||
"tools.disassembler"
|
"tools.disassembler"
|
||||||
"tools.errors"
|
"tools.errors"
|
||||||
"tools.memory"
|
"tools.memory"
|
||||||
|
|
|
@ -23,6 +23,10 @@ IN: math.intervals.tests
|
||||||
|
|
||||||
[ T{ interval f { 1 t } { 1 t } } ] [ 1 [a,a] ] unit-test
|
[ T{ interval f { 1 t } { 1 t } } ] [ 1 [a,a] ] unit-test
|
||||||
|
|
||||||
|
! Not sure how to handle NaNs yet...
|
||||||
|
! [ 1 0/0. [a,b] ] must-fail
|
||||||
|
! [ 0/0. 1 [a,b] ] must-fail
|
||||||
|
|
||||||
[ t ] [ { 3 t } { 3 f } endpoint< ] unit-test
|
[ t ] [ { 3 t } { 3 f } endpoint< ] unit-test
|
||||||
[ t ] [ { 2 f } { 3 f } endpoint< ] unit-test
|
[ t ] [ { 2 f } { 3 f } endpoint< ] unit-test
|
||||||
[ f ] [ { 3 f } { 3 t } endpoint< ] unit-test
|
[ f ] [ { 3 f } { 3 t } endpoint< ] unit-test
|
||||||
|
@ -350,6 +354,10 @@ comparison-ops [
|
||||||
|
|
||||||
[ t ] [ full-interval interval-abs [0,inf] = ] unit-test
|
[ t ] [ full-interval interval-abs [0,inf] = ] unit-test
|
||||||
|
|
||||||
|
[ t ] [ [0,inf] interval-abs [0,inf] = ] unit-test
|
||||||
|
|
||||||
|
[ t ] [ empty-interval interval-abs empty-interval = ] unit-test
|
||||||
|
|
||||||
[ t ] [ [0,inf] interval-sq [0,inf] = ] unit-test
|
[ t ] [ [0,inf] interval-sq [0,inf] = ] unit-test
|
||||||
|
|
||||||
! Test that commutative interval ops really are
|
! Test that commutative interval ops really are
|
||||||
|
|
|
@ -268,7 +268,7 @@ DEFER: make-texture
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
TUPLE: single-texture image dim loc texture-coords texture display-list disposed ;
|
TUPLE: single-texture < disposable image dim loc texture-coords texture display-list ;
|
||||||
|
|
||||||
: adjust-texture-dim ( dim -- dim' )
|
: adjust-texture-dim ( dim -- dim' )
|
||||||
non-power-of-2-textures? get [
|
non-power-of-2-textures? get [
|
||||||
|
@ -331,7 +331,7 @@ TUPLE: single-texture image dim loc texture-coords texture display-list disposed
|
||||||
GL_COMPILE [ [ dim>> ] keep draw-textured-rect ] make-dlist ;
|
GL_COMPILE [ [ dim>> ] keep draw-textured-rect ] make-dlist ;
|
||||||
|
|
||||||
: <single-texture> ( image loc -- texture )
|
: <single-texture> ( image loc -- texture )
|
||||||
single-texture new swap >>loc swap [ >>image ] [ dim>> >>dim ] bi
|
single-texture new-disposable swap >>loc swap [ >>image ] [ dim>> >>dim ] bi
|
||||||
dup image>> dim>> product 0 = [
|
dup image>> dim>> product 0 = [
|
||||||
dup texture-coords >>texture-coords
|
dup texture-coords >>texture-coords
|
||||||
dup image>> make-texture >>texture
|
dup image>> make-texture >>texture
|
||||||
|
@ -347,7 +347,7 @@ M: single-texture draw-scaled-texture
|
||||||
dup texture>> [ draw-textured-rect ] [ 2drop ] if
|
dup texture>> [ draw-textured-rect ] [ 2drop ] if
|
||||||
] if ;
|
] if ;
|
||||||
|
|
||||||
TUPLE: multi-texture grid display-list loc disposed ;
|
TUPLE: multi-texture < disposable grid display-list loc ;
|
||||||
|
|
||||||
: image-locs ( image-grid -- loc-grid )
|
: image-locs ( image-grid -- loc-grid )
|
||||||
[ first [ dim>> first ] map ] [ [ first dim>> second ] map ] bi
|
[ first [ dim>> first ] map ] [ [ first dim>> second ] map ] bi
|
||||||
|
@ -373,11 +373,9 @@ TUPLE: multi-texture grid display-list loc disposed ;
|
||||||
|
|
||||||
: <multi-texture> ( image-grid loc -- multi-texture )
|
: <multi-texture> ( image-grid loc -- multi-texture )
|
||||||
[
|
[
|
||||||
[
|
[ multi-texture new-disposable ] 2dip
|
||||||
<texture-grid> dup
|
[ nip >>loc ] [ <texture-grid> >>grid ] 2bi
|
||||||
make-textured-grid-display-list
|
dup grid>> make-textured-grid-display-list >>display-list
|
||||||
] keep
|
|
||||||
f multi-texture boa
|
|
||||||
] with-destructors ;
|
] with-destructors ;
|
||||||
|
|
||||||
M: multi-texture draw-scaled-texture nip draw-texture ;
|
M: multi-texture draw-scaled-texture nip draw-texture ;
|
||||||
|
|
|
@ -60,7 +60,7 @@ pango_layout_iter_free ( PangoLayoutIter* iter ) ;
|
||||||
|
|
||||||
DESTRUCTOR: pango_layout_iter_free
|
DESTRUCTOR: pango_layout_iter_free
|
||||||
|
|
||||||
TUPLE: layout font string selection layout metrics ink-rect logical-rect image disposed ;
|
TUPLE: layout < disposable font string selection layout metrics ink-rect logical-rect image ;
|
||||||
|
|
||||||
SYMBOL: dpi
|
SYMBOL: dpi
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ MEMO: missing-font-metrics ( font -- metrics )
|
||||||
|
|
||||||
: <layout> ( font string -- line )
|
: <layout> ( font string -- line )
|
||||||
[
|
[
|
||||||
layout new
|
layout new-disposable
|
||||||
swap unpack-selection
|
swap unpack-selection
|
||||||
swap >>font
|
swap >>font
|
||||||
dup [ string>> ] [ font>> ] bi <PangoLayout> >>layout
|
dup [ string>> ] [ font>> ] bi <PangoLayout> >>layout
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
IN: tools.continuations
|
||||||
|
USING: help.markup help.syntax ;
|
||||||
|
|
||||||
|
HELP: break
|
||||||
|
{ $description "A breakpoint. When this word is executed, the walker tool opens with execution suspended at the breakpoint's location." }
|
||||||
|
{ $see-also "ui-walker" } ;
|
|
@ -1,4 +1,5 @@
|
||||||
USING: words ;
|
USING: kernel words ;
|
||||||
IN: generic
|
IN: generic
|
||||||
|
|
||||||
: next-method-quot ( method -- quot ) "next-method-quot" word-prop ;
|
: (call-next-method) ( method -- )
|
||||||
|
dup "next-method" word-prop execute ;
|
||||||
|
|
|
@ -6,7 +6,7 @@ vocabs sequences sequences.private words memory kernel.private
|
||||||
continuations io vocabs.loader system strings sets vectors quotations
|
continuations io vocabs.loader system strings sets vectors quotations
|
||||||
byte-arrays sorting compiler.units definitions generic
|
byte-arrays sorting compiler.units definitions generic
|
||||||
generic.standard generic.single tools.deploy.config combinators
|
generic.standard generic.single tools.deploy.config combinators
|
||||||
classes slots.private ;
|
classes classes.builtin slots.private grouping ;
|
||||||
QUALIFIED: bootstrap.stage2
|
QUALIFIED: bootstrap.stage2
|
||||||
QUALIFIED: command-line
|
QUALIFIED: command-line
|
||||||
QUALIFIED: compiler.errors
|
QUALIFIED: compiler.errors
|
||||||
|
@ -24,11 +24,12 @@ IN: tools.deploy.shaker
|
||||||
: strip-init-hooks ( -- )
|
: strip-init-hooks ( -- )
|
||||||
"Stripping startup hooks" show
|
"Stripping startup hooks" show
|
||||||
{
|
{
|
||||||
|
"alien.strings"
|
||||||
"command-line"
|
"command-line"
|
||||||
"cpu.x86"
|
"cpu.x86"
|
||||||
|
"destructors"
|
||||||
"environment"
|
"environment"
|
||||||
"libc"
|
"libc"
|
||||||
"alien.strings"
|
|
||||||
}
|
}
|
||||||
[ init-hooks get delete-at ] each
|
[ init-hooks get delete-at ] each
|
||||||
deploy-threads? get [
|
deploy-threads? get [
|
||||||
|
@ -65,6 +66,13 @@ IN: tools.deploy.shaker
|
||||||
run-file
|
run-file
|
||||||
] when ;
|
] when ;
|
||||||
|
|
||||||
|
: strip-destructors ( -- )
|
||||||
|
"libc" vocab [
|
||||||
|
"Stripping destructor debug code" show
|
||||||
|
"vocab:tools/deploy/shaker/strip-destructors.factor"
|
||||||
|
run-file
|
||||||
|
] when ;
|
||||||
|
|
||||||
: strip-call ( -- )
|
: strip-call ( -- )
|
||||||
"Stripping stack effect checking from call( and execute(" show
|
"Stripping stack effect checking from call( and execute(" show
|
||||||
"vocab:tools/deploy/shaker/strip-call.factor" run-file ;
|
"vocab:tools/deploy/shaker/strip-call.factor" run-file ;
|
||||||
|
@ -194,25 +202,64 @@ IN: tools.deploy.shaker
|
||||||
strip-word-names? [ dup strip-word-names ] when
|
strip-word-names? [ dup strip-word-names ] when
|
||||||
2drop ;
|
2drop ;
|
||||||
|
|
||||||
|
: compiler-classes ( -- seq )
|
||||||
|
{ "compiler" "stack-checker" }
|
||||||
|
[ child-vocabs [ words ] map concat [ class? ] filter ]
|
||||||
|
map concat unique ;
|
||||||
|
|
||||||
|
: prune-decision-tree ( tree classes -- )
|
||||||
|
[ tuple class>type ] 2dip '[
|
||||||
|
dup array? [
|
||||||
|
[
|
||||||
|
dup array? [
|
||||||
|
[
|
||||||
|
2 group
|
||||||
|
[ drop _ key? not ] assoc-filter
|
||||||
|
concat
|
||||||
|
] map
|
||||||
|
] when
|
||||||
|
] map
|
||||||
|
] when
|
||||||
|
] change-nth ;
|
||||||
|
|
||||||
: strip-compiler-classes ( -- )
|
: strip-compiler-classes ( -- )
|
||||||
strip-dictionary? [
|
strip-dictionary? [
|
||||||
"Stripping compiler classes" show
|
"Stripping compiler classes" show
|
||||||
{ "compiler" "stack-checker" }
|
[ single-generic? ] instances
|
||||||
[ child-vocabs [ words ] map concat [ class? ] filter ] map concat
|
compiler-classes '[ "decision-tree" word-prop _ prune-decision-tree ] each
|
||||||
[ dup implementors [ "methods" word-prop delete-at ] with each ] each
|
|
||||||
] when ;
|
] when ;
|
||||||
|
|
||||||
|
: recursive-subst ( seq old new -- )
|
||||||
|
'[
|
||||||
|
_ _
|
||||||
|
{
|
||||||
|
! old becomes new
|
||||||
|
{ [ 3dup drop eq? ] [ 2nip ] }
|
||||||
|
! recurse into arrays
|
||||||
|
{ [ pick array? ] [ [ dup ] 2dip recursive-subst ] }
|
||||||
|
! otherwise do nothing
|
||||||
|
[ 2drop ]
|
||||||
|
} cond
|
||||||
|
] change-each ;
|
||||||
|
|
||||||
|
: strip-default-method ( generic new-default -- )
|
||||||
|
[
|
||||||
|
[ "decision-tree" word-prop ]
|
||||||
|
[ "default-method" word-prop ] bi
|
||||||
|
] dip
|
||||||
|
recursive-subst ;
|
||||||
|
|
||||||
|
: new-default-method ( -- gensym )
|
||||||
|
[ [ "No method" throw ] (( -- * )) define-temp ] with-compilation-unit ;
|
||||||
|
|
||||||
: strip-default-methods ( -- )
|
: strip-default-methods ( -- )
|
||||||
|
! In a development image, each generic has its own default method.
|
||||||
|
! This gives better error messages for runtime type errors, but
|
||||||
|
! takes up space. For deployment we merge them all together.
|
||||||
strip-debugger? [
|
strip-debugger? [
|
||||||
"Stripping default methods" show
|
"Stripping default methods" show
|
||||||
[
|
[ single-generic? ] instances
|
||||||
[ generic? ] instances
|
new-default-method '[ _ strip-default-method ] each
|
||||||
[ "No method" throw ] (( -- * )) define-temp
|
|
||||||
dup t "default" set-word-prop
|
|
||||||
'[
|
|
||||||
[ _ "default-method" set-word-prop ] [ make-generic ] bi
|
|
||||||
] each
|
|
||||||
] with-compilation-unit
|
|
||||||
] when ;
|
] when ;
|
||||||
|
|
||||||
: strip-vocab-globals ( except names -- words )
|
: strip-vocab-globals ( except names -- words )
|
||||||
|
@ -237,7 +284,7 @@ IN: tools.deploy.shaker
|
||||||
|
|
||||||
"io-thread" "io.thread" lookup ,
|
"io-thread" "io.thread" lookup ,
|
||||||
|
|
||||||
"mallocs" "libc.private" lookup ,
|
"disposables" "destructors" lookup ,
|
||||||
|
|
||||||
deploy-threads? [
|
deploy-threads? [
|
||||||
"initial-thread" "threads" lookup ,
|
"initial-thread" "threads" lookup ,
|
||||||
|
@ -361,8 +408,8 @@ IN: tools.deploy.shaker
|
||||||
[ compress-object? ] [ ] "objects" compress ;
|
[ compress-object? ] [ ] "objects" compress ;
|
||||||
|
|
||||||
: remain-compiled ( old new -- old new )
|
: remain-compiled ( old new -- old new )
|
||||||
#! Quotations which were formerly compiled must remain
|
! Quotations which were formerly compiled must remain
|
||||||
#! compiled.
|
! compiled.
|
||||||
2dup [
|
2dup [
|
||||||
2dup [ quot-compiled? ] [ quot-compiled? not ] bi* and
|
2dup [ quot-compiled? ] [ quot-compiled? not ] bi* and
|
||||||
[ nip jit-compile ] [ 2drop ] if
|
[ nip jit-compile ] [ 2drop ] if
|
||||||
|
@ -383,7 +430,9 @@ SYMBOL: deploy-vocab
|
||||||
[ boot ] %
|
[ boot ] %
|
||||||
init-hooks get values concat %
|
init-hooks get values concat %
|
||||||
strip-debugger? [ , ] [
|
strip-debugger? [ , ] [
|
||||||
! Don't reference try directly
|
! Don't reference 'try' directly since we don't want
|
||||||
|
! to pull in the debugger and prettyprinter into every
|
||||||
|
! deployed app
|
||||||
[:c]
|
[:c]
|
||||||
[print-error]
|
[print-error]
|
||||||
'[
|
'[
|
||||||
|
@ -402,22 +451,22 @@ SYMBOL: deploy-vocab
|
||||||
t "quiet" set-global
|
t "quiet" set-global
|
||||||
f output-stream set-global ;
|
f output-stream set-global ;
|
||||||
|
|
||||||
: unsafe-next-method-quot ( method -- quot )
|
: next-method* ( method -- quot )
|
||||||
[ "method-class" word-prop ]
|
[ "method-class" word-prop ]
|
||||||
[ "method-generic" word-prop ] bi
|
[ "method-generic" word-prop ] bi
|
||||||
next-method 1quotation ;
|
next-method ;
|
||||||
|
|
||||||
: compute-next-methods ( -- )
|
: compute-next-methods ( -- )
|
||||||
[ standard-generic? ] instances [
|
[ standard-generic? ] instances [
|
||||||
"methods" word-prop [
|
"methods" word-prop [
|
||||||
nip dup
|
nip dup next-method* "next-method" set-word-prop
|
||||||
unsafe-next-method-quot
|
|
||||||
"next-method-quot" set-word-prop
|
|
||||||
] assoc-each
|
] assoc-each
|
||||||
] each
|
] each
|
||||||
"vocab:tools/deploy/shaker/next-methods.factor" run-file ;
|
"vocab:tools/deploy/shaker/next-methods.factor" run-file ;
|
||||||
|
|
||||||
: (clear-megamorphic-cache) ( i array -- )
|
: (clear-megamorphic-cache) ( i array -- )
|
||||||
|
! Can't do any dispatch while clearing caches since that
|
||||||
|
! might leave them in an inconsistent state.
|
||||||
2dup 1 slot < [
|
2dup 1 slot < [
|
||||||
2dup [ f ] 2dip set-array-nth
|
2dup [ f ] 2dip set-array-nth
|
||||||
[ 1 + ] dip (clear-megamorphic-cache)
|
[ 1 + ] dip (clear-megamorphic-cache)
|
||||||
|
@ -437,14 +486,15 @@ SYMBOL: deploy-vocab
|
||||||
: strip ( -- )
|
: strip ( -- )
|
||||||
init-stripper
|
init-stripper
|
||||||
strip-libc
|
strip-libc
|
||||||
|
strip-destructors
|
||||||
strip-call
|
strip-call
|
||||||
strip-cocoa
|
strip-cocoa
|
||||||
strip-debugger
|
strip-debugger
|
||||||
compute-next-methods
|
compute-next-methods
|
||||||
strip-init-hooks
|
strip-init-hooks
|
||||||
strip-c-io
|
strip-c-io
|
||||||
strip-compiler-classes
|
|
||||||
strip-default-methods
|
strip-default-methods
|
||||||
|
strip-compiler-classes
|
||||||
f 5 setenv ! we can't use the Factor debugger or Factor I/O anymore
|
f 5 setenv ! we can't use the Factor debugger or Factor I/O anymore
|
||||||
deploy-vocab get vocab-main deploy-boot-quot
|
deploy-vocab get vocab-main deploy-boot-quot
|
||||||
find-megamorphic-caches
|
find-megamorphic-caches
|
||||||
|
|
|
@ -12,7 +12,6 @@ IN: debugger
|
||||||
"threads" vocab [
|
"threads" vocab [
|
||||||
[
|
[
|
||||||
"error-in-thread" "threads" lookup
|
"error-in-thread" "threads" lookup
|
||||||
[ die 2drop ]
|
[ [ die 2drop ] define ] [ f "combination" set-word-prop ] bi
|
||||||
define
|
|
||||||
] with-compilation-unit
|
] with-compilation-unit
|
||||||
] when
|
] when
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
USE: kernel
|
||||||
|
IN: destructors.private
|
||||||
|
|
||||||
|
: register-disposable ( obj -- ) drop ; inline
|
||||||
|
|
||||||
|
: unregister-disposable ( obj -- ) drop ; inline
|
|
@ -0,0 +1 @@
|
||||||
|
Slava Pestov
|
|
@ -0,0 +1,24 @@
|
||||||
|
! Copyright (C) 2009 Slava Pestov.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: help.markup help.syntax help.tips quotations destructors ;
|
||||||
|
IN: tools.destructors
|
||||||
|
|
||||||
|
HELP: disposables.
|
||||||
|
{ $description "Print the number of disposable objects of each class." } ;
|
||||||
|
|
||||||
|
HELP: leaks
|
||||||
|
{ $values
|
||||||
|
{ "quot" quotation }
|
||||||
|
}
|
||||||
|
{ $description "Runs a quotation, printing any increases in the number of disposable objects after the quotation returns. The " { $link debug-leaks? } " variable is also switched on while the quotation runs, recording the current continuation in every newly-created disposable object." } ;
|
||||||
|
|
||||||
|
TIP: "Use the " { $link leaks } " combinator to track down resource leaks." ;
|
||||||
|
|
||||||
|
ARTICLE: "tools.destructors" "Destructor tools"
|
||||||
|
"The " { $vocab-link "tools.destructors" } " vocabulary provides words for tracking down resource leaks."
|
||||||
|
{ $subsection debug-leaks? }
|
||||||
|
{ $subsection disposables. }
|
||||||
|
{ $subsection leaks }
|
||||||
|
{ $see-also "destructors" } ;
|
||||||
|
|
||||||
|
ABOUT: "tools.destructors"
|
|
@ -0,0 +1,13 @@
|
||||||
|
USING: kernel tools.destructors tools.test destructors namespaces ;
|
||||||
|
IN: tools.destructors.tests
|
||||||
|
|
||||||
|
f debug-leaks? set-global
|
||||||
|
|
||||||
|
[ [ 3 throw ] leaks ] must-fail
|
||||||
|
|
||||||
|
[ f ] [ debug-leaks? get-global ] unit-test
|
||||||
|
|
||||||
|
[ ] [ [ ] leaks ] unit-test
|
||||||
|
|
||||||
|
[ f ] [ debug-leaks? get-global ] unit-test
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
! Copyright (C) 2009 Slava Pestov.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: assocs classes destructors fry kernel math namespaces
|
||||||
|
prettyprint sequences sets sorting continuations accessors arrays
|
||||||
|
io io.styles combinators.smart ;
|
||||||
|
IN: tools.destructors
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
: class-tally ( assoc -- assoc' )
|
||||||
|
H{ } clone [ [ keys ] dip '[ dup class _ push-at ] each ] keep ;
|
||||||
|
|
||||||
|
: (disposables.) ( assoc -- )
|
||||||
|
class-tally >alist [ first2 [ length ] keep 3array ] map [ second ] sort-with
|
||||||
|
standard-table-style [
|
||||||
|
[
|
||||||
|
[ "Disposable class" write ] with-cell
|
||||||
|
[ "Instances" write ] with-cell
|
||||||
|
[ ] with-cell
|
||||||
|
] with-row
|
||||||
|
[
|
||||||
|
[
|
||||||
|
[
|
||||||
|
[ pprint-cell ]
|
||||||
|
[ pprint-cell ]
|
||||||
|
[ [ "[ List instances ]" swap write-object ] with-cell ]
|
||||||
|
tri*
|
||||||
|
] input<sequence
|
||||||
|
] with-row
|
||||||
|
] each
|
||||||
|
] tabular-output nl ;
|
||||||
|
|
||||||
|
: sort-disposables ( seq -- seq' )
|
||||||
|
[ disposable? ] partition [ [ id>> ] sort-with ] dip append ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
: disposables. ( -- )
|
||||||
|
disposables get (disposables.) ;
|
||||||
|
|
||||||
|
: disposables-of-class. ( class -- )
|
||||||
|
[ disposables get values sort-disposables ] dip
|
||||||
|
'[ _ instance? ] filter stack. ;
|
||||||
|
|
||||||
|
: leaks ( quot -- )
|
||||||
|
disposables get clone
|
||||||
|
t debug-leaks? set-global
|
||||||
|
[
|
||||||
|
[ call disposables get clone ] dip
|
||||||
|
] [ f debug-leaks? set-global ] [ ] cleanup
|
||||||
|
assoc-diff (disposables.) ; inline
|
|
@ -0,0 +1,5 @@
|
||||||
|
IN: tools.walker
|
||||||
|
USING: help.syntax help.markup tools.continuations ;
|
||||||
|
|
||||||
|
HELP: B
|
||||||
|
{ $description "An alias for " { $link break } ", defined in the " { $vocab-link "syntax" } " vocabulary so that it is always available." } ;
|
|
@ -7,7 +7,7 @@ cocoa.views cocoa.windows combinators command-line
|
||||||
core-foundation core-foundation.run-loop core-graphics
|
core-foundation core-foundation.run-loop core-graphics
|
||||||
core-graphics.types destructors fry generalizations io.thread
|
core-graphics.types destructors fry generalizations io.thread
|
||||||
kernel libc literals locals math math.bitwise math.rectangles memory
|
kernel libc literals locals math math.bitwise math.rectangles memory
|
||||||
namespaces sequences specialized-arrays.int threads ui
|
namespaces sequences threads ui
|
||||||
ui.backend ui.backend.cocoa.views ui.clipboards ui.gadgets
|
ui.backend ui.backend.cocoa.views ui.clipboards ui.gadgets
|
||||||
ui.gadgets.worlds ui.pixel-formats ui.pixel-formats.private
|
ui.gadgets.worlds ui.pixel-formats ui.pixel-formats.private
|
||||||
ui.private words.symbol ;
|
ui.private words.symbol ;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
USING: accessors alien alien.c-types alien.strings arrays assocs
|
USING: accessors alien alien.c-types alien.strings arrays assocs
|
||||||
cocoa kernel math cocoa.messages cocoa.subclassing cocoa.classes
|
cocoa kernel math cocoa.messages cocoa.subclassing cocoa.classes
|
||||||
cocoa.views cocoa.application cocoa.pasteboard cocoa.types
|
cocoa.views cocoa.application cocoa.pasteboard cocoa.types
|
||||||
cocoa.windows sequences io.encodings.ascii ui ui.private ui.gadgets
|
cocoa.windows sequences io.encodings.utf8 ui ui.private ui.gadgets
|
||||||
ui.gadgets.private ui.gadgets.worlds ui.gestures
|
ui.gadgets.private ui.gadgets.worlds ui.gestures
|
||||||
core-foundation.strings core-graphics core-graphics.types threads
|
core-foundation.strings core-graphics core-graphics.types threads
|
||||||
combinators math.rectangles ;
|
combinators math.rectangles ;
|
||||||
|
@ -220,7 +220,7 @@ CLASS: {
|
||||||
{ "validateUserInterfaceItem:" "char" { "id" "SEL" "id" }
|
{ "validateUserInterfaceItem:" "char" { "id" "SEL" "id" }
|
||||||
[
|
[
|
||||||
nip -> action
|
nip -> action
|
||||||
2dup [ window ] [ ascii alien>string ] bi* validate-action
|
2dup [ window ] [ utf8 alien>string ] bi* validate-action
|
||||||
[ [ 2drop ] dip >c-bool ] [ SUPER-> validateUserInterfaceItem: ] if
|
[ [ 2drop ] dip >c-bool ] [ SUPER-> validateUserInterfaceItem: ] if
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,13 +46,15 @@ HOOK: (pixel-format-attribute) ui-backend ( pixel-format attribute-name -- value
|
||||||
|
|
||||||
ERROR: invalid-pixel-format-attributes world attributes ;
|
ERROR: invalid-pixel-format-attributes world attributes ;
|
||||||
|
|
||||||
TUPLE: pixel-format world handle ;
|
TUPLE: pixel-format < disposable world handle ;
|
||||||
|
|
||||||
: <pixel-format> ( world attributes -- pixel-format )
|
: <pixel-format> ( world attributes -- pixel-format )
|
||||||
2dup (make-pixel-format)
|
2dup (make-pixel-format)
|
||||||
[ nip pixel-format boa ] [ invalid-pixel-format-attributes ] if* ;
|
[ pixel-format new-disposable swap >>handle swap >>world ]
|
||||||
|
[ invalid-pixel-format-attributes ]
|
||||||
|
?if ;
|
||||||
|
|
||||||
M: pixel-format dispose
|
M: pixel-format dispose*
|
||||||
[ (free-pixel-format) ] [ f >>handle drop ] bi ;
|
[ (free-pixel-format) ] [ f >>handle drop ] bi ;
|
||||||
|
|
||||||
: pixel-format-attribute ( pixel-format attribute-name -- value )
|
: pixel-format-attribute ( pixel-format attribute-name -- value )
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
! Copyright (C) 2006, 2009 Slava Pestov.
|
! Copyright (C) 2006, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: continuations definitions generic help.topics threads
|
USING: continuations definitions generic help.topics threads
|
||||||
stack-checker summary io.pathnames io.styles kernel namespaces parser
|
stack-checker summary io.pathnames io.styles kernel namespaces
|
||||||
prettyprint quotations tools.crossref tools.annotations editors
|
parser prettyprint quotations tools.crossref tools.annotations
|
||||||
tools.profiler tools.test tools.time tools.walker vocabs vocabs.loader
|
editors tools.profiler tools.test tools.time tools.walker vocabs
|
||||||
words sequences classes compiler.errors compiler.units
|
vocabs.loader words sequences classes compiler.errors
|
||||||
accessors vocabs.parser macros.expander ui ui.tools.browser
|
compiler.units accessors vocabs.parser macros.expander ui
|
||||||
ui.tools.listener ui.tools.listener.completion ui.tools.profiler
|
ui.tools.browser ui.tools.listener ui.tools.listener.completion
|
||||||
ui.tools.inspector ui.tools.traceback ui.commands ui.gadgets.editors
|
ui.tools.profiler ui.tools.inspector ui.tools.traceback
|
||||||
ui.gestures ui.operations ui.tools.deploy models help.tips
|
ui.commands ui.gadgets.editors ui.gestures ui.operations
|
||||||
source-files.errors ;
|
ui.tools.deploy models help.tips source-files.errors destructors
|
||||||
|
libc libc.private ;
|
||||||
IN: ui.tools.operations
|
IN: ui.tools.operations
|
||||||
|
|
||||||
! Objects
|
! Objects
|
||||||
|
@ -182,6 +183,22 @@ M: word com-stack-effect 1quotation com-stack-effect ;
|
||||||
{ +listener+ t }
|
{ +listener+ t }
|
||||||
} define-operation
|
} define-operation
|
||||||
|
|
||||||
|
! Disposables
|
||||||
|
[ disposable? ] \ dispose H{ } define-operation
|
||||||
|
|
||||||
|
! Disposables with a continuation
|
||||||
|
PREDICATE: tracked-disposable < disposable
|
||||||
|
continuation>> >boolean ;
|
||||||
|
|
||||||
|
PREDICATE: tracked-malloc-ptr < malloc-ptr
|
||||||
|
continuation>> >boolean ;
|
||||||
|
|
||||||
|
: com-creation-traceback ( disposable -- )
|
||||||
|
continuation>> traceback-window ;
|
||||||
|
|
||||||
|
[ tracked-disposable? ] \ com-creation-traceback H{ { +primary+ t } } define-operation
|
||||||
|
[ tracked-malloc-ptr? ] \ com-creation-traceback H{ { +primary+ t } } define-operation
|
||||||
|
|
||||||
! Operations -> commands
|
! Operations -> commands
|
||||||
interactor
|
interactor
|
||||||
"quotation"
|
"quotation"
|
||||||
|
|
|
@ -28,6 +28,7 @@ ARTICLE: "breakpoints" "Setting breakpoints"
|
||||||
$nl
|
$nl
|
||||||
"Breakpoints can be inserted directly into code:"
|
"Breakpoints can be inserted directly into code:"
|
||||||
{ $subsection break }
|
{ $subsection break }
|
||||||
|
{ $subsection POSTPONE: B }
|
||||||
"Note that because the walker calls various core library and UI words while rendering its own user interface, setting a breakpoint on a word such as " { $link append } " or " { $link draw-gadget } " will hang the UI." ;
|
"Note that because the walker calls various core library and UI words while rendering its own user interface, setting a breakpoint on a word such as " { $link append } " or " { $link draw-gadget } " will hang the UI." ;
|
||||||
|
|
||||||
ARTICLE: "ui-walker" "UI walker"
|
ARTICLE: "ui-walker" "UI walker"
|
||||||
|
|
|
@ -6,7 +6,7 @@ destructors fry math.parser generalizations sets
|
||||||
specialized-arrays.alien specialized-arrays.direct.alien ;
|
specialized-arrays.alien specialized-arrays.direct.alien ;
|
||||||
IN: windows.com.wrapper
|
IN: windows.com.wrapper
|
||||||
|
|
||||||
TUPLE: com-wrapper callbacks vtbls disposed ;
|
TUPLE: com-wrapper < disposable callbacks vtbls ;
|
||||||
|
|
||||||
<PRIVATE
|
<PRIVATE
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ PRIVATE>
|
||||||
[ +live-wrappers+ get adjoin ] bi ;
|
[ +live-wrappers+ get adjoin ] bi ;
|
||||||
|
|
||||||
: <com-wrapper> ( implementations -- wrapper )
|
: <com-wrapper> ( implementations -- wrapper )
|
||||||
(make-callbacks) f f com-wrapper boa
|
com-wrapper new-disposable swap (make-callbacks) >>vtbls
|
||||||
dup allocate-wrapper ;
|
dup allocate-wrapper ;
|
||||||
|
|
||||||
M: com-wrapper dispose*
|
M: com-wrapper dispose*
|
||||||
|
|
|
@ -7,7 +7,7 @@ windows.offscreen windows.gdi32 windows.ole32 windows.types
|
||||||
windows.fonts opengl.textures locals windows.errors ;
|
windows.fonts opengl.textures locals windows.errors ;
|
||||||
IN: windows.uniscribe
|
IN: windows.uniscribe
|
||||||
|
|
||||||
TUPLE: script-string font string metrics ssa size image disposed ;
|
TUPLE: script-string < disposable font string metrics ssa size image ;
|
||||||
|
|
||||||
: line-offset>x ( n script-string -- x )
|
: line-offset>x ( n script-string -- x )
|
||||||
2dup string>> length = [
|
2dup string>> length = [
|
||||||
|
@ -89,7 +89,7 @@ TUPLE: script-string font string metrics ssa size image disposed ;
|
||||||
TEXTMETRIC>metrics ;
|
TEXTMETRIC>metrics ;
|
||||||
|
|
||||||
: <script-string> ( font string -- script-string )
|
: <script-string> ( font string -- script-string )
|
||||||
[ script-string new ] 2dip
|
[ script-string new-disposable ] 2dip
|
||||||
[ >>font ] [ >>string ] bi*
|
[ >>font ] [ >>string ] bi*
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,15 +1,32 @@
|
||||||
USING: help.markup help.syntax libc kernel continuations io
|
USING: help.markup help.syntax libc kernel continuations io
|
||||||
sequences ;
|
sequences classes ;
|
||||||
IN: destructors
|
IN: destructors
|
||||||
|
|
||||||
|
HELP: debug-leaks?
|
||||||
|
{ $var-description "When this variable is on, " { $link new-disposable } " stores the current continuation in the " { $link disposable } "'s " { $slot "continuation" } " slot." }
|
||||||
|
{ $see-also "tools.destructors" } ;
|
||||||
|
|
||||||
|
HELP: disposable
|
||||||
|
{ $class-description "Parent class for disposable resources. This class has three slots:"
|
||||||
|
{ $list
|
||||||
|
{ { $slot "disposed" } " - boolean. Set to true by " { $link dispose } ". Assert that it is false with " { $link check-disposed } "." }
|
||||||
|
{ { $slot "id" } " - unique identifier. Set by " { $link new-disposable } "." }
|
||||||
|
{ { $slot "continuation" } " - current continuation at construction time, for debugging. Set by " { $link new-disposable } " if " { $link debug-leaks? } " is on." }
|
||||||
|
}
|
||||||
|
"New instances must be constructed with " { $link new-disposable } " and subclasses must implement " { $link dispose* } "." } ;
|
||||||
|
|
||||||
|
HELP: new-disposable
|
||||||
|
{ $values { "class" class } { "disposable" disposable } }
|
||||||
|
{ $description "Constructs a new instance of a subclass of " { $link disposable } ". This sets the " { $slot "id" } " slot, registers the new object with the global " { $link disposables } " set, and if " { $link debug-leaks? } " is on, stores the current continuation in the " { $slot "continuation" } " slot." } ;
|
||||||
|
|
||||||
HELP: dispose
|
HELP: dispose
|
||||||
{ $values { "disposable" "a disposable object" } }
|
{ $values { "disposable" "a disposable object" } }
|
||||||
{ $contract "Releases operating system resources associated with a disposable object. Disposable objects include streams, memory mapped files, and so on."
|
{ $contract "Releases operating system resources associated with a disposable object. Disposable objects include streams, memory mapped files, and so on."
|
||||||
$nl
|
$nl
|
||||||
"No further operations can be performed on a disposable object after this call."
|
"No further operations can be performed on a disposable object after this call."
|
||||||
$nl
|
$nl
|
||||||
"Disposing an object which has already been disposed should have no effect, and in particular it should not fail with an error. To help implement this pattern, add a " { $slot "disposed" } " slot to your object and implement the " { $link dispose* } " method instead." }
|
"Disposing an object which has already been disposed should have no effect, and in particular it should not fail with an error. To help implement this pattern, inherit from the " { $link disposable } " class and implement the " { $link dispose* } " method instead." }
|
||||||
{ $notes "You must close disposable objects after you are finished working with them, to avoid leaking operating system resources. A convenient way to automate this is by using the " { $link with-disposal } " word."
|
{ $notes "You must dispose of disposable objects after you are finished working with them, to avoid leaking operating system resources. A convenient way to automate this is by using the " { $link with-disposal } " word."
|
||||||
$nl
|
$nl
|
||||||
"The default implementation assumes the object has a " { $snippet "disposed" } " slot. If the slot is set to " { $link f } ", it calls " { $link dispose* } " and sets the slot to " { $link t } "." } ;
|
"The default implementation assumes the object has a " { $snippet "disposed" } " slot. If the slot is set to " { $link f } ", it calls " { $link dispose* } " and sets the slot to " { $link t } "." } ;
|
||||||
|
|
||||||
|
@ -51,6 +68,10 @@ HELP: dispose-each
|
||||||
{ "seq" sequence } }
|
{ "seq" sequence } }
|
||||||
{ $description "Attempts to dispose of each element of a sequence and collects all of the errors into a sequence. If any errors are thrown during disposal, the last error is rethrown after all objects have been disposed." } ;
|
{ $description "Attempts to dispose of each element of a sequence and collects all of the errors into a sequence. If any errors are thrown during disposal, the last error is rethrown after all objects have been disposed." } ;
|
||||||
|
|
||||||
|
HELP: disposables
|
||||||
|
{ $var-description "Global variable holding all disposable objects which have not been disposed of yet. The " { $link new-disposable } " word adds objects here, and the " { $link dispose } " method on disposables removes them. The " { $link "tools.destructors" } " vocabulary provides some words for working with this data." }
|
||||||
|
{ $see-also "tools.destructors" } ;
|
||||||
|
|
||||||
ARTICLE: "destructors-anti-patterns" "Resource disposal anti-patterns"
|
ARTICLE: "destructors-anti-patterns" "Resource disposal anti-patterns"
|
||||||
"Words which create objects corresponding to external resources should always be used with " { $link with-disposal } ". The following code is wrong:"
|
"Words which create objects corresponding to external resources should always be used with " { $link with-disposal } ". The following code is wrong:"
|
||||||
{ $code
|
{ $code
|
||||||
|
@ -58,12 +79,9 @@ ARTICLE: "destructors-anti-patterns" "Resource disposal anti-patterns"
|
||||||
}
|
}
|
||||||
"The reason being that if " { $snippet "do stuff" } " throws an error, the resource will not be disposed of. The most important case where this can occur is with I/O streams, and the correct solution is to always use " { $link with-input-stream } " and " { $link with-output-stream } "; see " { $link "stdio" } " for details." ;
|
"The reason being that if " { $snippet "do stuff" } " throws an error, the resource will not be disposed of. The most important case where this can occur is with I/O streams, and the correct solution is to always use " { $link with-input-stream } " and " { $link with-output-stream } "; see " { $link "stdio" } " for details." ;
|
||||||
|
|
||||||
ARTICLE: "destructors" "Deterministic resource disposal"
|
ARTICLE: "destructors-using" "Using destructors"
|
||||||
"Operating system resources such as streams, memory mapped files, and so on are not managed by Factor's garbage collector and must be released when you are done with them. Failing to release a resource can lead to reduced performance and instability."
|
"Disposing of an object:"
|
||||||
$nl
|
|
||||||
"Disposable object protocol:"
|
|
||||||
{ $subsection dispose }
|
{ $subsection dispose }
|
||||||
{ $subsection dispose* }
|
|
||||||
"Utility word for scoped disposal:"
|
"Utility word for scoped disposal:"
|
||||||
{ $subsection with-disposal }
|
{ $subsection with-disposal }
|
||||||
"Utility word for disposing multiple objects:"
|
"Utility word for disposing multiple objects:"
|
||||||
|
@ -71,7 +89,23 @@ $nl
|
||||||
"Utility words for more complex disposal patterns:"
|
"Utility words for more complex disposal patterns:"
|
||||||
{ $subsection with-destructors }
|
{ $subsection with-destructors }
|
||||||
{ $subsection &dispose }
|
{ $subsection &dispose }
|
||||||
{ $subsection |dispose }
|
{ $subsection |dispose } ;
|
||||||
{ $subsection "destructors-anti-patterns" } ;
|
|
||||||
|
ARTICLE: "destructors-extending" "Writing new destructors"
|
||||||
|
"Superclass for disposable objects:"
|
||||||
|
{ $subsection disposable }
|
||||||
|
"Parametrized constructor for disposable objects:"
|
||||||
|
{ $subsection new-disposable }
|
||||||
|
"Generic disposal word:"
|
||||||
|
{ $subsection dispose* }
|
||||||
|
"Global set of disposable objects:"
|
||||||
|
{ $subsection disposables } ;
|
||||||
|
|
||||||
|
ARTICLE: "destructors" "Deterministic resource disposal"
|
||||||
|
"Operating system resources such as streams, memory mapped files, and so on are not managed by Factor's garbage collector and must be released when you are done with them. Failing to release a resource can lead to reduced performance and instability."
|
||||||
|
{ $subsection "destructors-using" }
|
||||||
|
{ $subsection "destructors-extending" }
|
||||||
|
{ $subsection "destructors-anti-patterns" }
|
||||||
|
{ $see-also "tools.destructors" } ;
|
||||||
|
|
||||||
ABOUT: "destructors"
|
ABOUT: "destructors"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
USING: destructors kernel tools.test continuations accessors
|
USING: destructors kernel tools.test continuations accessors
|
||||||
namespaces sequences ;
|
namespaces sequences destructors.private ;
|
||||||
IN: destructors.tests
|
IN: destructors.tests
|
||||||
|
|
||||||
TUPLE: dispose-error ;
|
TUPLE: dispose-error ;
|
||||||
|
@ -66,3 +66,12 @@ M: dummy-destructor dispose ( obj -- )
|
||||||
] ignore-errors destroyed?>>
|
] ignore-errors destroyed?>>
|
||||||
] unit-test
|
] unit-test
|
||||||
|
|
||||||
|
TUPLE: silly-disposable < disposable ;
|
||||||
|
|
||||||
|
M: silly-disposable dispose* drop ;
|
||||||
|
|
||||||
|
silly-disposable new-disposable "s" set
|
||||||
|
"s" get dispose
|
||||||
|
[ "s" get unregister-disposable ]
|
||||||
|
[ disposable>> silly-disposable? ]
|
||||||
|
must-fail-with
|
||||||
|
|
|
@ -1,10 +1,40 @@
|
||||||
! Copyright (C) 2007, 2008 Doug Coleman, Slava Pestov.
|
! Copyright (C) 2007, 2009 Doug Coleman, Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: accessors continuations kernel namespaces make
|
USING: accessors continuations kernel namespaces make
|
||||||
sequences vectors ;
|
sequences vectors sets assocs init math ;
|
||||||
IN: destructors
|
IN: destructors
|
||||||
|
|
||||||
TUPLE: disposable disposed ;
|
SYMBOL: disposables
|
||||||
|
|
||||||
|
[ H{ } clone disposables set-global ] "destructors" add-init-hook
|
||||||
|
|
||||||
|
ERROR: already-unregistered disposable ;
|
||||||
|
|
||||||
|
SYMBOL: debug-leaks?
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
SLOT: continuation
|
||||||
|
|
||||||
|
: register-disposable ( obj -- )
|
||||||
|
debug-leaks? get-global [ continuation >>continuation ] when
|
||||||
|
disposables get conjoin ;
|
||||||
|
|
||||||
|
: unregister-disposable ( obj -- )
|
||||||
|
disposables get 2dup key? [ delete-at ] [ drop already-unregistered ] if ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
TUPLE: disposable < identity-tuple
|
||||||
|
{ id integer }
|
||||||
|
{ disposed boolean }
|
||||||
|
continuation ;
|
||||||
|
|
||||||
|
M: disposable hashcode* nip id>> ;
|
||||||
|
|
||||||
|
: new-disposable ( class -- disposable )
|
||||||
|
new \ disposable counter >>id
|
||||||
|
dup register-disposable ; inline
|
||||||
|
|
||||||
GENERIC: dispose* ( disposable -- )
|
GENERIC: dispose* ( disposable -- )
|
||||||
|
|
||||||
|
@ -18,6 +48,13 @@ GENERIC: dispose ( disposable -- )
|
||||||
M: object dispose
|
M: object dispose
|
||||||
dup disposed>> [ drop ] [ t >>disposed dispose* ] if ;
|
dup disposed>> [ drop ] [ t >>disposed dispose* ] if ;
|
||||||
|
|
||||||
|
M: disposable dispose
|
||||||
|
dup disposed>> [ drop ] [
|
||||||
|
[ unregister-disposable ]
|
||||||
|
[ call-next-method ]
|
||||||
|
bi
|
||||||
|
] if ;
|
||||||
|
|
||||||
: dispose-each ( seq -- )
|
: dispose-each ( seq -- )
|
||||||
[
|
[
|
||||||
[ [ dispose ] curry [ , ] recover ] each
|
[ [ dispose ] curry [ , ] recover ] each
|
||||||
|
|
|
@ -153,3 +153,9 @@ USE: debugger.threads
|
||||||
"" write
|
"" write
|
||||||
] with-file-writer
|
] with-file-writer
|
||||||
] [ no-method? ] must-fail-with
|
] [ no-method? ] must-fail-with
|
||||||
|
|
||||||
|
! What happens if we close a file twice?
|
||||||
|
[ ] [
|
||||||
|
"closing-twice" unique-file ascii <file-writer>
|
||||||
|
[ dispose ] [ dispose ] bi
|
||||||
|
] unit-test
|
|
@ -6,7 +6,10 @@ io.encodings.utf8 alien.strings continuations destructors byte-arrays
|
||||||
accessors combinators ;
|
accessors combinators ;
|
||||||
IN: io.streams.c
|
IN: io.streams.c
|
||||||
|
|
||||||
TUPLE: c-stream handle disposed ;
|
TUPLE: c-stream < disposable handle ;
|
||||||
|
|
||||||
|
: new-c-stream ( handle class -- c-stream )
|
||||||
|
new-disposable swap >>handle ; inline
|
||||||
|
|
||||||
M: c-stream dispose* handle>> fclose ;
|
M: c-stream dispose* handle>> fclose ;
|
||||||
|
|
||||||
|
@ -20,7 +23,7 @@ M: c-stream stream-seek
|
||||||
|
|
||||||
TUPLE: c-writer < c-stream ;
|
TUPLE: c-writer < c-stream ;
|
||||||
|
|
||||||
: <c-writer> ( handle -- stream ) f c-writer boa ;
|
: <c-writer> ( handle -- stream ) c-writer new-c-stream ;
|
||||||
|
|
||||||
M: c-writer stream-element-type drop +byte+ ;
|
M: c-writer stream-element-type drop +byte+ ;
|
||||||
|
|
||||||
|
@ -32,7 +35,7 @@ M: c-writer stream-flush dup check-disposed handle>> fflush ;
|
||||||
|
|
||||||
TUPLE: c-reader < c-stream ;
|
TUPLE: c-reader < c-stream ;
|
||||||
|
|
||||||
: <c-reader> ( handle -- stream ) f c-reader boa ;
|
: <c-reader> ( handle -- stream ) c-reader new-c-stream ;
|
||||||
|
|
||||||
M: c-reader stream-element-type drop +byte+ ;
|
M: c-reader stream-element-type drop +byte+ ;
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,8 @@ HELP: delimiter
|
||||||
|
|
||||||
HELP: deprecated
|
HELP: deprecated
|
||||||
{ $syntax ": foo ... ; deprecated" }
|
{ $syntax ": foo ... ; deprecated" }
|
||||||
{ $description "Declares the most recently defined word as deprecated. If the " { $vocab-link "tools.deprecation" } " vocabulary is loaded, usages of deprecated words will be noted as they are made." } ;
|
{ $description "Declares the most recently defined word as deprecated. If the " { $vocab-link "tools.deprecation" } " vocabulary is loaded, usages of deprecated words will be noted by the " { $link "tools.errors" } " system." }
|
||||||
|
{ $notes "Code that uses deprecated words continues to function normally; the errors are purely informational. However, code that uses deprecated words should be updated, for the deprecated words are intended to be removed soon." } ;
|
||||||
|
|
||||||
HELP: SYNTAX:
|
HELP: SYNTAX:
|
||||||
{ $syntax "SYNTAX: foo ... ;" }
|
{ $syntax "SYNTAX: foo ... ;" }
|
||||||
|
|
|
@ -111,7 +111,7 @@ HELP: output-index
|
||||||
{ $notes "Named fragment shader outputs require OpenGL 3.0 or later and GLSL 1.30 or later, or OpenGL 2.0 or later and GLSL 1.20 or earlier with the " { $snippet "GL_EXT_gpu_shader4" } " extension." } ;
|
{ $notes "Named fragment shader outputs require OpenGL 3.0 or later and GLSL 1.30 or later, or OpenGL 2.0 or later and GLSL 1.20 or earlier with the " { $snippet "GL_EXT_gpu_shader4" } " extension." } ;
|
||||||
|
|
||||||
HELP: program
|
HELP: program
|
||||||
{ $class-description "A " { $snippet "program" } " provides a specification for linking a " { $link program-instance } " in a graphics context. Programs are defined with " { $link POSTPONE: GLSL-PROGRAM: } " and instantiated in a context with " { $link <program-instance> } "." } ;
|
{ $class-description "A " { $snippet "program" } " provides a specification for linking a " { $link program-instance } " in a graphics context. Programs are defined with " { $link POSTPONE: GLSL-PROGRAM: } " and instantiated for a context with " { $link <program-instance> } "." } ;
|
||||||
|
|
||||||
HELP: program-instance
|
HELP: program-instance
|
||||||
{ $class-description "A " { $snippet "program-instance" } " is a shader " { $link program } " that has been compiled and linked for a graphics context using " { $link <program-instance> } "." } ;
|
{ $class-description "A " { $snippet "program-instance" } " is a shader " { $link program } " that has been compiled and linked for a graphics context using " { $link <program-instance> } "." } ;
|
||||||
|
@ -120,10 +120,10 @@ HELP: refresh-program
|
||||||
{ $values
|
{ $values
|
||||||
{ "program" program }
|
{ "program" program }
|
||||||
}
|
}
|
||||||
{ $description "Rereads the source code for every " { $link shader } " in " { $link program } " and attempts to refresh all the existing " { $link shader-instance } "s and " { $link program-instance } "s for those programs. If the new source code fails to compile or link, the existing instances are untouched; otherwise, they are updated on the fly to reference the newly compiled code." } ;
|
{ $description "Rereads the source code for every " { $link shader } " in " { $link program } " and attempts to refresh all the existing " { $link shader-instance } "s and " { $link program-instance } "s for those shaders. If any of the new source code fails to compile or link, the existing valid shader and program instances will remain untouched. However, subsequent attempts to compile new shader or program instances will still attempt to use the new source code. If the compilation and linking succeed, the existing shader and program instances will be updated on the fly to reference the newly compiled code." } ;
|
||||||
|
|
||||||
HELP: shader
|
HELP: shader
|
||||||
{ $class-description "A " { $snippet "shader" } " provides a block of GLSL source code that can be compiled into a " { $link shader-instance } " in a graphics context. Shaders are defined with " { $link POSTPONE: GLSL-SHADER: } " or " { $link POSTPONE: GLSL-SHADER-FILE: } " and instantiated in a context with " { $link <shader-instance> } "." } ;
|
{ $class-description "A " { $snippet "shader" } " provides a block of GLSL source code that can be compiled into a " { $link shader-instance } " in a graphics context. Shaders are defined with " { $link POSTPONE: GLSL-SHADER: } " or " { $link POSTPONE: GLSL-SHADER-FILE: } " and instantiated for a context with " { $link <shader-instance> } "." } ;
|
||||||
|
|
||||||
HELP: shader-instance
|
HELP: shader-instance
|
||||||
{ $class-description "A " { $snippet "shader-instance" } " is a " { $link shader } " that has been compiled for a graphics context using " { $link <shader-instance> } "." } ;
|
{ $class-description "A " { $snippet "shader-instance" } " is a " { $link shader } " that has been compiled for a graphics context using " { $link <shader-instance> } "." } ;
|
||||||
|
|
|
@ -32,6 +32,20 @@ HELP: pile-alloc
|
||||||
}
|
}
|
||||||
{ $description "Requests " { $snippet "size" } " bytes from a " { $link pile } ". If the pile does not have enough space to satisfy the request, a " { $link not-enough-pile-space } " error is thrown." } ;
|
{ $description "Requests " { $snippet "size" } " bytes from a " { $link pile } ". If the pile does not have enough space to satisfy the request, a " { $link not-enough-pile-space } " error is thrown." } ;
|
||||||
|
|
||||||
|
HELP: <pile-c-array>
|
||||||
|
{ $values
|
||||||
|
{ "pile" pile } { "n" integer } { "c-type" "a C type" }
|
||||||
|
{ "alien" alien }
|
||||||
|
}
|
||||||
|
{ $description "Requests enough space from a " { $link pile } " to hold " { $snippet "n" } " values of " { $snippet "c-type" } ". If the pile does not have enough space to satisfy the request, a " { $link not-enough-pile-space } " error is thrown." } ;
|
||||||
|
|
||||||
|
HELP: <pile-c-object>
|
||||||
|
{ $values
|
||||||
|
{ "pile" pile } { "c-type" "a C type" }
|
||||||
|
{ "alien" alien }
|
||||||
|
}
|
||||||
|
{ $description "Requests enough space from a " { $link pile } " to hold a value of " { $snippet "c-type" } ". If the pile does not have enough space to satisfy the request, a " { $link not-enough-pile-space } " error is thrown." } ;
|
||||||
|
|
||||||
HELP: pile-empty
|
HELP: pile-empty
|
||||||
{ $values
|
{ $values
|
||||||
{ "pile" pile }
|
{ "pile" pile }
|
||||||
|
@ -42,6 +56,8 @@ ARTICLE: "memory.piles" "Piles"
|
||||||
"A " { $link pile } " is a block of raw memory. Portions of its memory can be allocated from the beginning of the pile in constant time, and the pile can be emptied and its pointer reset to the beginning."
|
"A " { $link pile } " is a block of raw memory. Portions of its memory can be allocated from the beginning of the pile in constant time, and the pile can be emptied and its pointer reset to the beginning."
|
||||||
{ $subsection <pile> }
|
{ $subsection <pile> }
|
||||||
{ $subsection pile-alloc }
|
{ $subsection pile-alloc }
|
||||||
|
{ $subsection <pile-c-array> }
|
||||||
|
{ $subsection <pile-c-object> }
|
||||||
{ $subsection pile-align }
|
{ $subsection pile-align }
|
||||||
{ $subsection pile-empty }
|
{ $subsection pile-empty }
|
||||||
"An example of the utility of piles is in video games. For example, the game Abuse was scripted with a Lisp dialect. In order to avoid stalls from traditional GC or heap-based allocators, the Abuse Lisp VM would allocate values from a preallocated pile over the course of a frame, and release the entire pile at the end of the frame." ;
|
"An example of the utility of piles is in video games. For example, the game Abuse was scripted with a Lisp dialect. In order to avoid stalls from traditional GC or heap-based allocators, the Abuse Lisp VM would allocate values from a preallocated pile over the course of a frame, and release the entire pile at the end of the frame." ;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
! (c)2009 Joe Groff bsd license
|
! (c)2009 Joe Groff bsd license
|
||||||
USING: accessors alien destructors kernel libc math ;
|
USING: accessors alien alien.c-types destructors kernel libc math ;
|
||||||
IN: memory.piles
|
IN: memory.piles
|
||||||
|
|
||||||
TUPLE: pile
|
TUPLE: pile
|
||||||
|
@ -28,6 +28,12 @@ M: pile dispose
|
||||||
[ + ] curry change-offset drop
|
[ + ] curry change-offset drop
|
||||||
] 2tri ;
|
] 2tri ;
|
||||||
|
|
||||||
|
: <pile-c-object> ( pile c-type -- alien )
|
||||||
|
heap-size pile-alloc ; inline
|
||||||
|
|
||||||
|
: <pile-c-array> ( pile n c-type -- alien )
|
||||||
|
heap-size * pile-alloc ; inline
|
||||||
|
|
||||||
: pile-align ( pile align -- pile )
|
: pile-align ( pile align -- pile )
|
||||||
[ align ] curry change-offset ;
|
[ align ] curry change-offset ;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue