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