<magnus--> http://www.caddr.com/macho/archives/sbcl-devel/2005-3/4764.html\r
<magnus--> http://clozure.com/cgi-bin/viewcvs.cgi/ccl/lisp-kernel/lisp-exceptions.c?rev=1.9&content-type=text/vnd.viewcvs-markup\r
\r
+\r
- alien-global type wrong\r
- simplifier:\r
- dead loads not optimized out\r
- tiled window manager\r
- c primitive arrays: or just specialized arrays\r
float, complex, byte, char, cell...\r
-- generational gc\r
- add a socket timeout\r
- virtual hosts\r
- keep alive\r
: infer-alien-invoke ( -- )
\ alien-invoke "infer-effect" word-prop car ensure-d
- pop-literal
- pop-literal >r
- pop-literal
- pop-literal -rot
+ pop-literal nip
+ pop-literal nip >r
+ pop-literal nip
+ pop-literal nip -rot
r> swap alien-invoke-node ;
: parameters [ alien-parameters get reverse ] bind ;
: infer-alien-global ( -- )
\ alien-global "infer-effect" word-prop car ensure-d
- pop-literal
- pop-literal
- pop-literal -rot
+ pop-literal nip
+ pop-literal nip
+ pop-literal nip -rot
alien-global-node ;
: linearize-alien-global ( node -- )
set-stack-effect ;
2 [
- [ "execute" "words" " word -- " ]
+ [ "execute" "words" [ [ word ] [ ] ] ]
[ "call" "kernel" [ [ general-list ] [ ] ] ]
[ "ifte" "kernel" [ [ object general-list general-list ] [ ] ] ]
[ "cons" "lists" [ [ object object ] [ cons ] ] ]
! Copyright (C) 2004, 2005 Slava Pestov.
IN: compiler
USING: compiler-backend compiler-frontend errors inference
-kernel lists namespaces prettyprint stdio words ;
+kernel lists math namespaces prettyprint stdio words ;
: supported-cpu? ( -- ? )
cpu "unknown" = not ;
1 rel-type, relocating cons intern-literal rel, ;
: rel-address ( rel/abs 16/16 -- )
- #! Relocate address just compiled. If flag is true,
- #! relative, and there is nothing to do.
- over [ 2drop ] [ 2 rel-type, relocating 0 rel, ] ifte ;
+ #! Relocate address just compiled.
+ over 1 = [ 2drop ] [ 2 rel-type, relocating 0 rel, ] ifte ;
: rel-word ( word rel/abs 16/16 -- )
pick primitive? [
] [
rot drop rel-address
] ifte ;
+
+: rel-userenv ( n 16/16 -- )
+ 0 swap 3 rel-type, relocating rel, ;
+
+: rel-cards ( 16/16 -- )
+ 0 swap 4 rel-type, compiled-offset cell 2 * - rel, 0 rel, ;
: write-barrier ( reg -- )
#! Mark the card pointed to by vreg.
dup card-bits SHR
- card-offset 2list card-mark OR ;
+ card-offset 2list card-mark OR
+ 0 rel-cards ;
M: %set-slot generate-node ( vop -- )
#! the untagged object is in vop-dest, the new value is in
cell * "userenv" f dlsym + ;
M: %getenv generate-node ( vop -- )
- dup vop-dest v>operand swap vop-literal userenv@ unit MOV ;
+ dup vop-dest v>operand swap vop-literal
+ [ userenv@ unit MOV ] keep 0 rel-userenv ;
M: %setenv generate-node ( vop -- )
- dup vop-literal userenv@ unit swap vop-source v>operand MOV ;
+ dup vop-literal
+ [ userenv@ unit swap vop-source v>operand MOV ] keep
+ 0 rel-userenv ;
#! for the given branch.
[
[
- branches-can-fail? [
+ inferring-base-case get [
[ infer-branch , ] [ [ drop ] when ] catch
] [
infer-branch ,
] each
] make-list ;
-: unify-dataflow ( inputs instruction effectlist -- )
+: unify-dataflow ( input instruction effectlist -- )
[ [ get-dataflow ] bind ] map
- swap dataflow, [ node-consume-d set ] bind ;
+ swap dataflow, [ unit node-consume-d set ] bind ;
-: infer-branches ( inputs instruction branchlist -- )
+: infer-branches ( input instruction branchlist -- )
#! Recursive stack effect inference is done here. If one of
#! the branches has an undecidable stack effect, we set the
- #! base case to this stack effect and try again. The inputs
- #! parameter is a vector.
+ #! base case to this stack effect and try again.
(infer-branches) dup unify-effects unify-dataflow ;
: (with-block) ( [[ label quot ]] quot -- node )
r> call
] (with-block) ;
-: infer-quot-value ( value -- )
- gensym dup pick literal-value cons [
- drop
- dup value-recursion recursive-state set
- literal-value dup infer-quot
- ] with-block drop handle-terminator ;
-
-: boolean-value? ( value -- ? )
- #! Return if the value's boolean valuation is known.
- value-class
- dup \ f = swap
- builtin-supertypes
- \ f builtin-supertypes intersection not
- or ;
-
-: boolean-value ( value -- ? )
- #! Only valid if boolean? returns true.
- value-class \ f = not ;
-
-: static-branch? ( value -- ? )
- drop f ;
-! boolean-value? branches-can-fail? not and ;
-
-: static-ifte ( true false -- )
- #! If the branch taken is statically known, just infer
- #! along that branch.
- dataflow-drop, pop-d boolean-value [ drop ] [ nip ] ifte
- infer-quot-value ;
-
: dynamic-ifte ( true false -- )
#! If branch taken is computed, infer along both paths and
#! unify.
- 2list >r 1 meta-d get vector-tail* \ ifte r>
+ 2list >r peek-d \ ifte r>
pop-d [
dup \ general-t <class-tie> ,
\ f <class-tie> ,
[ object general-list general-list ] ensure-d
dataflow-drop, pop-d
dataflow-drop, pop-d swap
- peek-d static-branch? [
- static-ifte
- ] [
- dynamic-ifte
- ] ifte ;
+ dynamic-ifte ;
\ ifte [ infer-ifte ] "infer" set-word-prop
0 recursive-state get <literal>
[ set-value-literal-ties ] keep ;
-: static-dispatch? ( -- )
- peek-d literal? branches-can-fail? not and ;
-
USE: kernel-internals
-: static-dispatch ( vtable -- )
- >r pop-literal r>
- dup literal-value swap value-recursion
- >r nth r> <literal> infer-quot-value ;
-
: dynamic-dispatch ( vtable -- )
- >r 1 meta-d get vector-tail* \ dispatch r>
- vtable>list
+ >r peek-d \ dispatch r>
+ vtable>list
pop-d <dispatch-index>
over length [ <literal-tie> ] project-with
zip infer-branches ;
: infer-dispatch ( -- )
#! Infer effects for all branches, unify.
[ object vector ] ensure-d
- dataflow-drop, pop-d static-dispatch? [
- static-dispatch
- ] [
- dynamic-dispatch
- ] ifte ;
+ dataflow-drop, pop-d dynamic-dispatch ;
\ dispatch [ infer-dispatch ] "infer" set-word-prop
-\ dispatch [ [ fixnum vector ] [ ] ]
-"infer-effect" set-word-prop
+\ dispatch [ [ fixnum vector ] [ ] ] "infer-effect" set-word-prop
USING: errors generic interpreter kernel lists math namespaces
prettyprint sequences strings unparser vectors words ;
-: max-recursion 0 ;
-
-! This variable takes a value from 0 up to max-recursion.
+! This variable takes a boolean value.
SYMBOL: inferring-base-case
-: branches-can-fail? ( -- ? )
- inferring-base-case get max-recursion > ;
-
! Word properties that affect inference:
! - infer-effect -- must be set. controls number of inputs
! expected, and number of outputs produced.
: value-types ( value -- list )
value-class builtin-supertypes ;
-: pop-literal ( -- obj )
- dataflow-drop, pop-d literal-value ;
+: pop-literal ( -- rstate obj )
+ dataflow-drop, pop-d dup value-recursion swap literal-value ;
: (ensure-types) ( typelist n stack -- )
pick [
0 <vector> d-in set
recursive-state set
dataflow-graph off
- 0 inferring-base-case set ;
+ inferring-base-case off ;
GENERIC: apply-object
[ tuck builtin-type <class-tie> cons ] project-with
[ cdr class-tie-class ] subset ;
-: literal-type ( -- )
- dataflow-drop, pop-d value-types car
- apply-literal ;
-
-: computed-type ( -- )
+: infer-type ( -- )
\ type #call dataflow, [
peek-d type-value-map >r
1 0 node-inputs
] bind ;
\ type [
- [ object ] ensure-d
- literal-type? [ literal-type ] [ computed-type ] ifte
+ [ object ] ensure-d infer-type
] "infer" set-word-prop
] with-scope consume/produce
] [
[
- >r branches-can-fail? [
+ >r inferring-base-case get [
drop
] [
t "no-effect" set-word-prop
apply-default
] ifte ;
-: literal-type? ( -- ? )
- peek-d value-types dup length 1 = >r [ tuple ] = not r> and ;
-
-: dynamic-dispatch-warning ( word -- )
- "Dynamic dispatch for " swap word-name cat2
- inference-warning ;
-
-! M: generic apply-word ( word -- )
-! #! If the type of the value at the top of the stack is
-! #! known, inline the method body.
-! [ object ] ensure-d
-! literal-type? branches-can-fail? not and [
-! inline-compound 2drop
-! ] [
-! dup dynamic-dispatch-warning apply-default ;
-! ] ifte ;
-
: with-recursion ( quot -- )
[
- inferring-base-case [ 1 + ] change
+ inferring-base-case on
call
] [
- inferring-base-case [ 1 - ] change
+ inferring-base-case off
rethrow
] catch ;
#! Handle a recursive call, by either applying a previously
#! inferred base case, or raising an error. If the recursive
#! call is to a local block, emit a label call node.
- inferring-base-case get max-recursion > [
+ inferring-base-case get [
drop no-base-case
] [
- inferring-base-case get max-recursion = [
- base-case
- ] [
- [ drop inline-compound 2drop ] with-recursion
- ] ifte
+ base-case
] ifte ;
M: word apply-object ( word -- )
apply-word
] ifte* ;
-: infer-call ( -- )
- [ general-list ] ensure-d
- dataflow-drop, pop-d infer-quot-value ;
+: infer-quot-value ( rstate quot -- )
+ gensym dup pick cons [
+ drop
+ swap recursive-state set
+ dup infer-quot
+ ] with-block drop handle-terminator ;
+
+\ call [
+ [ general-list ] ensure-d pop-literal infer-quot-value
+] "infer" set-word-prop
-\ call [ infer-call ] "infer" set-word-prop
+\ execute [
+ [ word ] ensure-d pop-literal unit infer-quot-value
+] "infer" set-word-prop
! These hacks will go away soon
\ * [ [ number number ] [ number ] ] "infer-effect" set-word-prop
if(offset == 0x7f)
{
if(c == 0xff)
- critical_error("bad card",c);
+ critical_error("bad card",ptr);
else
return;
}
return c & CARD_BASE_MASK;
}
-#define ADDR_TO_CARD(a) (CARD*)((((CELL)a-heap_start)>>CARD_BITS)+(CELL)cards)
-#define CARD_TO_ADDR(c) (CELL*)((((CELL)c-(CELL)cards)<<CARD_BITS)+heap_start)
+CELL cards_offset;
+
+#define ADDR_TO_CARD(a) (CARD*)(((CELL)a >> CARD_BITS) + cards_offset)
+#define CARD_TO_ADDR(c) (CELL*)(((CELL)c - cards_offset)<<CARD_BITS)
/* this is an inefficient write barrier. compiled definitions use a more
efficient one hand-coded in assembly. the write barrier must be called
void factorbug(void)
{
+ fcntl(0,F_SETFL,0);
+ fcntl(1,F_SETFL,0);
+
fprintf(stderr,"Factor low-level debugger\n");
fprintf(stderr,"d <addr> <count> -- dump memory\n");
fprintf(stderr,". <addr> -- print object at <addr>\n");
userenv[CPU_ENV] = tag_object(from_c_string(FACTOR_CPU_STRING));
userenv[OS_ENV] = tag_object(from_c_string(FACTOR_OS_STRING));
userenv[GEN_ENV] = tag_fixnum(GC_GENERATIONS);
- userenv[CARD_OFF_ENV] = tag_cell((CELL)cards - (heap_start >> CARD_BITS));
+ userenv[CARD_OFF_ENV] = tag_cell(cards_offset);
}
INLINE bool factor_arg(const char* str, const char* arg, CELL* value)
cards = alloc_guarded(cards_size);
cards_end = cards + cards_size;
+ cards_offset = (CELL)cards - (heap_start >> CARD_BITS);
alloter = heap_start;
case F_ABSOLUTE:
return original + (compiling.base - code_relocation_base);
case F_USERENV:
- return (CELL)&userenv;
+ return (CELL)&userenv[rel->argument];
case F_CARDS:
- return ((CELL)cards - heap_start);
+ return cards_offset;
default:
critical_error("Unsupported rel",rel->type);
return -1;
CELL original;
CELL new_value;
+ code_fixup(&rel->offset);
+
if(REL_16_16(rel))
original = reloc_get_16_16(rel->offset);
else
/* to_c_string can fill up the heap */
maybe_garbage_collection();
- code_fixup(&rel->offset);
new_value = compute_code_rel(rel,original);
if(REL_RELATIVE(rel))