Merge git://factorcode.org/git/factor
commit
615958c636
|
@ -34,8 +34,22 @@ GENERIC: loc>operand ( loc -- reg addressing )
|
|||
M: ds-loc loc>operand ds-loc-n cells neg ds-reg swap <+/-> ;
|
||||
M: rs-loc loc>operand rs-loc-n cells neg rs-reg swap <+/-> ;
|
||||
|
||||
: load-cell ( reg -- )
|
||||
[
|
||||
"end" define-label
|
||||
! Load target address
|
||||
PC 0 <+> LDR
|
||||
! Skip an instruction
|
||||
"end" get B
|
||||
! The target address
|
||||
0 ,
|
||||
! Continue here
|
||||
"end" resolve-label
|
||||
] with-scope ;
|
||||
|
||||
M: arm-backend load-indirect ( obj reg -- )
|
||||
PC 0 <+> LDR rc-indirect-arm-pc rel-literal ;
|
||||
tuck load-cell rc-absolute-cell rel-literal
|
||||
dup 0 <+> LDR ;
|
||||
|
||||
M: immediate load-literal
|
||||
over v>operand small-enough? [
|
||||
|
@ -67,17 +81,7 @@ M: arm-backend %epilogue ( n -- )
|
|||
SP SP rot ADD ;
|
||||
|
||||
: compile-dlsym ( symbol dll reg -- )
|
||||
[
|
||||
"end" define-label
|
||||
! Load target address
|
||||
PC 0 <+> LDR
|
||||
! Skip an instruction
|
||||
"end" get B
|
||||
! The target address
|
||||
0 , rc-absolute rel-dlsym
|
||||
! Continue here
|
||||
"end" resolve-label
|
||||
] with-scope ;
|
||||
load-cell rc-absolute rel-dlsym ;
|
||||
|
||||
: %alien-global ( symbol dll reg -- )
|
||||
[ compile-dlsym ] keep dup 0 <+> LDR ;
|
||||
|
|
|
@ -1,22 +1,25 @@
|
|||
USING: help.markup help.syntax generic.math generic.standard
|
||||
words classes definitions kernel alien combinators sequences ;
|
||||
words classes definitions kernel alien combinators sequences
|
||||
math ;
|
||||
IN: generic
|
||||
|
||||
ARTICLE: "method-order" "Method ordering"
|
||||
"It is possible that two classes have a non-empty intersection and neither is a subclass of the other. This means there is no canonical linear ordering of classes."
|
||||
ARTICLE: "method-order" "Method precedence"
|
||||
"Consider the case where a generic word has methods on two classes, say A and B, which share a non-empty intersection. If the generic word is called on an object which is an instance of both A and B, a choice of method must be made. If A is a subclass of B, the method for A to be called; this makes sense, because we're defining general behavior for instances of B, and refining it for instances of A. Conversely, if B is a subclass of A, then we expect B's method to be called. However, if neither is a subclass of the other, we have an ambiguous situation and undefined behavior will result. Either the method for A or B will be called, and there is no way to predict ahead of time."
|
||||
$nl
|
||||
"Consider the following set of definitions:"
|
||||
"The generic word system linearly orders all the methods on a generic word by their class. Conceptually, method dispatch is implemented by testing the object against the predicate word for every class, in order. If methods are defined on overlapping classes, this order will fail to be unique and the problem described above can occur."
|
||||
$nl
|
||||
"Here is an example:"
|
||||
{ $code
|
||||
"GENERIC: explain"
|
||||
"M: general-t explain drop \"a true value\" print ;"
|
||||
"M: c-ptr explain drop \"a tagged immediate\" print ;"
|
||||
"M: number explain drop \"an integer\" print ;"
|
||||
"M: sequence explain drop \"a sequence\" print ;"
|
||||
"M: object explain drop \"an object\" print ;"
|
||||
}
|
||||
"Neither " { $link general-t } " nor " { $link sequence } " are subclasses of each other, yet their intersection is non-empty. So the generic word system will place " { $link object } " first in the method order, however either " { $link general-t } " or " { $link sequence } " may come next, and it is pretty much a random choice that depends on hashing:"
|
||||
{ $example "\\ bar order ." "{ object general-t sequence }" }
|
||||
"Therefore, the outcome of calling " { $snippet "bar" } " with " { $link f } " on the stack is undefined."
|
||||
$nl
|
||||
"As you can see above, the " { $link order } " word can be useful to clarify method dispatch."
|
||||
"Neither " { $link number } " nor " { $link sequence } " are subclasses of each other, yet their intersection is the non-empty " { $link integer } " class. As a result, the outcome of calling " { $snippet "bar" } " with an " { $link integer } " on the stack is undefined - either one of the two methods may be called. This situation can lead to subtle bugs. To avoid it, explicitly disambiguate the method order by defining a method on the intersection. If in this case we want integers to behave like numbers, we would also define:"
|
||||
{ $code "M: integer explain drop \"an integer\" print ;" }
|
||||
"On the other hand, if we want integers to behave like sequences here, we could define:"
|
||||
{ $code "M: integer explain drop \"a sequence\" print ;" }
|
||||
"The " { $link order } " word can be useful to clarify method dispatch order."
|
||||
{ $subsection order } ;
|
||||
|
||||
ARTICLE: "generic-introspection" "Generic word introspection"
|
||||
|
|
|
@ -13,25 +13,28 @@ $nl
|
|||
"USING: sequences io ;"
|
||||
""
|
||||
": append"
|
||||
" #! Prints a message, then calls sequences::append."
|
||||
" \"foe::append calls sequences::append\" print append ;"
|
||||
" \"foe::append calls sequences::append\" print append ;"
|
||||
""
|
||||
"IN: fee"
|
||||
""
|
||||
": append"
|
||||
" #! Infinite recursion! Calls fee::append."
|
||||
" \"fee::append calls fee::append\" print append ;"
|
||||
" \"fee::append calls fee::append\" print append ;"
|
||||
""
|
||||
"IN: fox"
|
||||
"USE: foe"
|
||||
""
|
||||
": append"
|
||||
" #! Redefining fee::append to call foe::append."
|
||||
" \"fee::append calls foe::append\" print append ;"
|
||||
" \"fox::append calls foe::append\" print append ;"
|
||||
""
|
||||
"\"1234\" \"5678\" append print"
|
||||
""
|
||||
"USE: fox"
|
||||
"\"1234\" \"5678\" append print"
|
||||
}
|
||||
"When placed in a source file and run, the above code produces the following output:"
|
||||
{ $code
|
||||
"foe::append calls sequences::append"
|
||||
"12345678"
|
||||
"fee::append calls foe::append"
|
||||
"foe::append calls sequences::append"
|
||||
"12345678"
|
||||
|
|
|
@ -238,6 +238,7 @@ ARTICLE: "cookbook-pitfalls" "Pitfalls to avoid"
|
|||
{ "When a source file uses two vocabularies which define words with the same name, the order of the vocabularies in the " { $link POSTPONE: USE: } " or " { $link POSTPONE: USING: } " forms is important. The parser prints warnings when vocabularies shadow words from other vocabularies; see " { $link "vocabulary-search-shadow" } ". The " { $vocab-link "qualified" } " vocabulary implements qualified naming, which can be used to resolve ambiguities." }
|
||||
{ "If a literal object appears in a word definition, the object itself is pushed on the stack when the word executes, not a copy. If you intend to mutate this object, you must " { $link clone } " it first. See " { $link "syntax-literals" } "." }
|
||||
{ "For a discussion of potential issues surrounding the " { $link f } " object, see " { $link "booleans" } "." }
|
||||
{ "Factor's object system is quite flexible. Careless usage of union, mixin and predicate classes can lead to similar problems to those caused by ``multiple inheritance'' in other languages. In particular, it is possible to have two classes such that they have a non-empty intersection and yet neither is a subclass of the other. If a generic word defines methods on two such classes, method precedence is undefined for objects that are instances of both classes. See " { $link "method-order" } " for details." }
|
||||
{ "Performance-sensitive code should have a static stack effect so that it can be compiled by the optimizing word compiler, which generates more efficient code than the non-optimizing quotation compiler. See " { $link "inference" } " and " { $link "compiler" } "."
|
||||
$nl
|
||||
"This means that methods defined on performance sensitive, frequently-called core generic words such as " { $link nth } " should have static stack effects which are consistent with each other, since a generic word will only have a static stack effect if all methods do."
|
||||
|
|
|
@ -94,7 +94,7 @@ SYMBOL: mouse-captured
|
|||
: handle-wm-paint ( hWnd uMsg wParam lParam -- )
|
||||
#! wParam and lParam are unused
|
||||
#! only paint if width/height both > 0
|
||||
3drop window dup draw-world ;
|
||||
3drop window draw-world ;
|
||||
|
||||
: handle-wm-size ( hWnd uMsg wParam lParam -- )
|
||||
[ lo-word ] keep hi-word make-RECT get-RECT-dimensions 2array
|
||||
|
@ -414,7 +414,7 @@ SYMBOL: hWnd
|
|||
[ wglMakeCurrent win32-error=0/f ] keep ;
|
||||
|
||||
: setup-gl ( hwnd -- hDC hRC )
|
||||
get-dc dup setup-pixel-format get-rc ;
|
||||
get-dc dup setup-pixel-format dup get-rc ;
|
||||
|
||||
M: windows-ui-backend (open-world-window) ( world -- )
|
||||
[ rect-dim first2 create-window dup setup-gl ] keep
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
USING: sequences rss arrays concurrency kernel sorting
|
||||
html.elements io assocs namespaces math threads vocabs html
|
||||
furnace http.server.templating calendar math.parser splitting
|
||||
continuations debugger ;
|
||||
continuations debugger system ;
|
||||
IN: webapps.planet
|
||||
|
||||
TUPLE: posting author title date link body ;
|
||||
|
@ -108,8 +108,11 @@ SYMBOL: cached-postings
|
|||
{ "Slava Pestov" "http://factor-language.blogspot.com/atom.xml" "http://factor-language.blogspot.com/" }
|
||||
} default-blogroll set-global
|
||||
|
||||
SYMBOL: last-update
|
||||
|
||||
: update-thread ( -- )
|
||||
[ update-cached-postings ] try
|
||||
millis last-update set-global
|
||||
[ update-cached-postings ] in-thread
|
||||
10 60 * 1000 * sleep
|
||||
update-thread ;
|
||||
|
||||
|
|
Loading…
Reference in New Issue