Move some low-level interpreter words to continuations
							parent
							
								
									ac9ee43702
								
							
						
					
					
						commit
						c8042a0e72
					
				| 
						 | 
				
			
			@ -102,24 +102,6 @@ HELP: callcc1
 | 
			
		|||
{ $values { "quot" "a quotation with stack effect " { $snippet "( continuation -- )" } } { "obj" "an object provided when resuming the continuation" } }
 | 
			
		||||
{ $description "Applies the quotation to the current continuation, which is reified from the point immediately after which the caller returns. The " { $link continue-with } " word resumes the continuation, passing a value back to the original execution context." } ;
 | 
			
		||||
 | 
			
		||||
HELP: set-walker-hook
 | 
			
		||||
{ $values { "quot" "a quotation with stack effect " { $snippet "( continuation -- )" } ", or " { $link f } } }
 | 
			
		||||
{ $description "Sets a quotation to be called when a continuation is resumed." }
 | 
			
		||||
{ $notes "The single-stepper uses this hook to support single-stepping through code which makes use of continuations." } ;
 | 
			
		||||
 | 
			
		||||
HELP: walker-hook
 | 
			
		||||
{ $values { "quot" "a quotation with stack effect " { $snippet "( obj -- )" } ", or " { $link f } } }
 | 
			
		||||
{ $description "Outputs a quotation to be called when a continuation is resumed, or " { $link f } " if no hook is set. If a hook was set prior to this word being called, it will be reset to " { $link f } "."
 | 
			
		||||
$nl
 | 
			
		||||
"The following words do not perform their usual action and instead just call the walker hook if one is set:"
 | 
			
		||||
    { $list
 | 
			
		||||
        { { $link callcc0 } " will call the hook, passing it the continuation to resume." }
 | 
			
		||||
        { { $link callcc1 } " will call the hook, passing it a " { $snippet "{ obj continuation }" } " pair." }
 | 
			
		||||
        { { $link stop } " will call the hook, passing it " { $link f } "." }
 | 
			
		||||
    }
 | 
			
		||||
"The walker hook must take appropriate action so that the callers of these words see the behavior that they expect." }
 | 
			
		||||
{ $notes "The single-stepper uses this hook to support single-stepping through code which makes use of continuations." } ;
 | 
			
		||||
 | 
			
		||||
HELP: (continue-with)
 | 
			
		||||
{ $values { "obj" "an object to pass to the continuation's execution context" } { "continuation" continuation } }
 | 
			
		||||
{ $description "Resumes a continuation reified by " { $link callcc1 } " without invoking " { $link walker-hook } ". The object will be placed on the data stack when the continuation resumes." } ;
 | 
			
		||||
| 
						 | 
				
			
			@ -214,3 +196,6 @@ $low-level-note ;
 | 
			
		|||
 | 
			
		||||
HELP: init-error-handler
 | 
			
		||||
{ $description "Called on startup to initialize the catch stack and set a pair of hooks which allow the Factor VM to signal errors to library code." } ;
 | 
			
		||||
 | 
			
		||||
HELP: break
 | 
			
		||||
{ $description "Suspends execution of the current thread and starts the single stepper by calling " { $link break-hook } "." } ;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,9 +20,12 @@ SYMBOL: restarts
 | 
			
		|||
: (catch) ( quot -- newquot )
 | 
			
		||||
    [ swap >c call c> drop ] curry ; inline
 | 
			
		||||
 | 
			
		||||
: dummy
 | 
			
		||||
    #! Defeat an optimization.
 | 
			
		||||
    f ;
 | 
			
		||||
: dummy ( -- obj )
 | 
			
		||||
    #! Optimizing compiler assumes stack won't be messed with
 | 
			
		||||
    #! in-transit. To ensure that a value is actually reified
 | 
			
		||||
    #! on the stack, we put it in a non-inline word together
 | 
			
		||||
    #! with a declaration.
 | 
			
		||||
    f { object } declare ;
 | 
			
		||||
 | 
			
		||||
PRIVATE>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -70,12 +73,16 @@ C: <continuation> continuation
 | 
			
		|||
 | 
			
		||||
: callcc1 ( quot -- obj ) [ ] ifcc ; inline
 | 
			
		||||
 | 
			
		||||
: set-walker-hook ( quot -- ) 3 setenv ; inline
 | 
			
		||||
 | 
			
		||||
: walker-hook ( -- quot ) 3 getenv f set-walker-hook ; inline
 | 
			
		||||
 | 
			
		||||
<PRIVATE
 | 
			
		||||
 | 
			
		||||
: (continue) ( continuation -- )
 | 
			
		||||
    >continuation<
 | 
			
		||||
    set-catchstack
 | 
			
		||||
    set-namestack
 | 
			
		||||
    set-retainstack
 | 
			
		||||
    >r set-datastack r>
 | 
			
		||||
    set-callstack ;
 | 
			
		||||
 | 
			
		||||
: (continue-with) ( obj continuation -- )
 | 
			
		||||
    swap 4 setenv
 | 
			
		||||
    >continuation<
 | 
			
		||||
| 
						 | 
				
			
			@ -87,6 +94,10 @@ C: <continuation> continuation
 | 
			
		|||
 | 
			
		||||
PRIVATE>
 | 
			
		||||
 | 
			
		||||
: set-walker-hook ( quot -- ) 3 setenv ; inline
 | 
			
		||||
 | 
			
		||||
: walker-hook ( -- quot ) 3 getenv f set-walker-hook ; inline
 | 
			
		||||
 | 
			
		||||
: continue-with ( obj continuation -- )
 | 
			
		||||
    [
 | 
			
		||||
        walker-hook [ >r 2array r> ] when* (continue-with)
 | 
			
		||||
| 
						 | 
				
			
			@ -170,3 +181,19 @@ M: condition compute-restarts
 | 
			
		|||
    "kernel-error" 6 setenv ;
 | 
			
		||||
 | 
			
		||||
PRIVATE>
 | 
			
		||||
 | 
			
		||||
! Debugging support
 | 
			
		||||
: with-walker-hook ( continuation -- )
 | 
			
		||||
    [ swap set-walker-hook (continue) ] curry callcc1 ;
 | 
			
		||||
 | 
			
		||||
SYMBOL: break-hook
 | 
			
		||||
 | 
			
		||||
: break ( -- )
 | 
			
		||||
    continuation callstack
 | 
			
		||||
    over set-continuation-call
 | 
			
		||||
    walker-hook [ (continue-with) ] [ break-hook get call ] if* ;
 | 
			
		||||
 | 
			
		||||
GENERIC: (step-into) ( obj -- )
 | 
			
		||||
 | 
			
		||||
M: wrapper (step-into) wrapped break ;
 | 
			
		||||
M: object (step-into) break ;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,9 +24,6 @@ ABOUT: "meta-interpreter"
 | 
			
		|||
HELP: interpreter
 | 
			
		||||
{ $class-description "An interpreter instance." } ;
 | 
			
		||||
 | 
			
		||||
HELP: break
 | 
			
		||||
{ $description "Suspends execution of the current thread and starts the single stepper by calling " { $link break-hook } "." } ;
 | 
			
		||||
 | 
			
		||||
HELP: step
 | 
			
		||||
{ $values { "interpreter" interpreter } }
 | 
			
		||||
{ $description "Evaluates the object in the single stepper using Factor evaluation semantics:"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,29 @@
 | 
			
		|||
USING: tools.interpreter io io.streams.string kernel math
 | 
			
		||||
math.private namespaces prettyprint sequences tools.test
 | 
			
		||||
continuations math.parser threads arrays
 | 
			
		||||
tools.interpreter.debug ;
 | 
			
		||||
tools.interpreter.private tools.interpreter.debug ;
 | 
			
		||||
IN: temporary
 | 
			
		||||
 | 
			
		||||
[ [ + ] ] [
 | 
			
		||||
    [ \ + (step-into) ] (remove-breakpoints)
 | 
			
		||||
] unit-test
 | 
			
		||||
 | 
			
		||||
[ [ (step-into) ] ] [
 | 
			
		||||
    [ (step-into) ] (remove-breakpoints)
 | 
			
		||||
] unit-test
 | 
			
		||||
 | 
			
		||||
[ [ 3 ] ] [
 | 
			
		||||
    [ 3 (step-into) ] (remove-breakpoints)
 | 
			
		||||
] unit-test
 | 
			
		||||
 | 
			
		||||
[ [ 2 2 + . ] ] [
 | 
			
		||||
    [ 2 2 \ + (step-into) . ] (remove-breakpoints)
 | 
			
		||||
] unit-test
 | 
			
		||||
 | 
			
		||||
[ [ 2 2 + . ] ] [
 | 
			
		||||
    [ 2 break 2 \ + (step-into) . ] (remove-breakpoints)
 | 
			
		||||
] unit-test
 | 
			
		||||
 | 
			
		||||
[ "Ooops" throw ] break-hook set
 | 
			
		||||
 | 
			
		||||
[ { } ] [
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,13 +10,6 @@ TUPLE: interpreter continuation ;
 | 
			
		|||
 | 
			
		||||
: <interpreter> interpreter construct-empty ;
 | 
			
		||||
 | 
			
		||||
SYMBOL: break-hook
 | 
			
		||||
 | 
			
		||||
: break ( -- )
 | 
			
		||||
    continuation callstack
 | 
			
		||||
    over set-continuation-call
 | 
			
		||||
    walker-hook [ continue-with ] [ break-hook get call ] if* ;
 | 
			
		||||
 | 
			
		||||
GENERIC# restore 1 ( obj interpreter -- )
 | 
			
		||||
 | 
			
		||||
M: f restore
 | 
			
		||||
| 
						 | 
				
			
			@ -58,6 +51,8 @@ M: pair restore
 | 
			
		|||
: (step-into-continuation)
 | 
			
		||||
    continuation callstack over set-continuation-call break ;
 | 
			
		||||
 | 
			
		||||
M: word (step-into) (step-into-execute) ;
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
    { call [ (step-into-call) ] }
 | 
			
		||||
    { (throw) [ (step-into-call) ] }
 | 
			
		||||
| 
						 | 
				
			
			@ -76,14 +71,6 @@ M: pair restore
 | 
			
		|||
    "step-into" set-word-prop
 | 
			
		||||
] each
 | 
			
		||||
 | 
			
		||||
: (continue) ( continuation -- )
 | 
			
		||||
    >continuation<
 | 
			
		||||
    set-catchstack
 | 
			
		||||
    set-namestack
 | 
			
		||||
    set-retainstack
 | 
			
		||||
    >r set-datastack r>
 | 
			
		||||
    set-callstack ;
 | 
			
		||||
 | 
			
		||||
! Stepping
 | 
			
		||||
: change-innermost-frame ( quot interpreter -- )
 | 
			
		||||
    interpreter-continuation [
 | 
			
		||||
| 
						 | 
				
			
			@ -99,16 +86,8 @@ M: pair restore
 | 
			
		|||
: (step) ( interpreter quot -- )
 | 
			
		||||
    swap
 | 
			
		||||
    [ change-innermost-frame ] keep
 | 
			
		||||
    [
 | 
			
		||||
        set-walker-hook
 | 
			
		||||
        interpreter-continuation (continue)
 | 
			
		||||
    ] callcc1 swap restore ;
 | 
			
		||||
 | 
			
		||||
GENERIC: (step-into) ( obj -- )
 | 
			
		||||
 | 
			
		||||
M: word (step-into) (step-into-execute) ;
 | 
			
		||||
M: wrapper (step-into) wrapped break ;
 | 
			
		||||
M: object (step-into) break ;
 | 
			
		||||
    [ interpreter-continuation with-walker-hook ] keep
 | 
			
		||||
    restore ;
 | 
			
		||||
 | 
			
		||||
PRIVATE>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue