diff options
Diffstat (limited to 'qemu/roms/SLOF/slof/fs/instance.fs')
-rw-r--r-- | qemu/roms/SLOF/slof/fs/instance.fs | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/qemu/roms/SLOF/slof/fs/instance.fs b/qemu/roms/SLOF/slof/fs/instance.fs new file mode 100644 index 000000000..9e5c9215e --- /dev/null +++ b/qemu/roms/SLOF/slof/fs/instance.fs @@ -0,0 +1,193 @@ +\ ***************************************************************************** +\ * Copyright (c) 2004, 2011 IBM Corporation +\ * All rights reserved. +\ * This program and the accompanying materials +\ * are made available under the terms of the BSD License +\ * which accompanies this distribution, and is available at +\ * http://www.opensource.org/licenses/bsd-license.php +\ * +\ * Contributors: +\ * IBM Corporation - initial implementation +\ ****************************************************************************/ + +\ Support for device node instances. + +0 VALUE my-self + +400 CONSTANT max-instance-size + +STRUCT + /n FIELD instance>node + /n FIELD instance>parent + /n FIELD instance>args + /n FIELD instance>args-len + /n FIELD instance>size + /n FIELD instance>#units + /n FIELD instance>unit1 \ For instance-specific "my-unit" + /n FIELD instance>unit2 + /n FIELD instance>unit3 + /n FIELD instance>unit4 +CONSTANT /instance-header + +: >instance ( offset -- myself+offset ) + my-self 0= ABORT" No instance!" + dup my-self instance>size @ >= ABORT" Instance access out of bounds!" + my-self + +; + +: (create-instance-var) ( initial-value -- ) + get-node + dup node>instance-size @ cell+ max-instance-size + >= ABORT" Instance is bigger than max-instance-size!" + dup node>instance-template @ ( iv phandle tmp-ih ) + swap node>instance-size dup @ ( iv tmp-ih *instance-size instance-size ) + dup , \ compile current instance ptr + swap 1 cells swap +! ( iv tmp-ih instance-size ) + + ! +; + +: create-instance-var ( "name" initial-value -- ) + CREATE (create-instance-var) PREVIOUS +; + +: (create-instance-buf) ( buffersize -- ) + aligned \ align size to multiples of cells + dup get-node node>instance-size @ + ( buffersize' newinstancesize ) + max-instance-size > ABORT" Instance is bigger than max-instance-size!" + get-node node>instance-template @ get-node node>instance-size @ + + over erase \ clear according to IEEE 1275 + get-node node>instance-size @ ( buffersize' old-instance-size ) + dup , \ compile current instance ptr + + get-node node>instance-size ! \ store new size +; + +: create-instance-buf ( "name" buffersize -- ) + CREATE (create-instance-buf) PREVIOUS +; + +VOCABULARY instance-words ALSO instance-words DEFINITIONS + +: VARIABLE 0 create-instance-var DOES> [ here ] @ >instance ; +: VALUE create-instance-var DOES> [ here ] @ >instance @ ; +: DEFER 0 create-instance-var DOES> [ here ] @ >instance @ execute ; +: BUFFER: create-instance-buf DOES> [ here ] @ >instance ; + +PREVIOUS DEFINITIONS + +\ Save XTs of the above instance-words (put on the stack with "[ here ]") +CONSTANT <instancebuffer> +CONSTANT <instancedefer> +CONSTANT <instancevalue> +CONSTANT <instancevariable> + +\ check whether a value or a defer word is an +\ instance word: It must be a CREATE word and +\ the DOES> part must do >instance as first thing + +: (instance?) ( xt -- xt true|false ) + dup @ <create> = IF + dup cell+ @ cell+ @ ['] >instance = + ELSE + false + THEN +; + +\ This word does instance values in compile mode. +\ It corresponds to DOTO from engine.in +: (doito) ( value R:*CFA -- ) + r> cell+ dup >r + @ cell+ cell+ @ >instance ! +; +' (doito) CONSTANT <(doito)> + +: to ( value wordname<> -- ) + ' (instance?) + state @ IF + \ compile mode handling normal or instance value + IF ['] (doito) ELSE ['] DOTO THEN + , , EXIT + THEN + IF + cell+ cell+ @ >instance ! \ interp mode instance value + ELSE + cell+ ! \ interp mode normal value + THEN +; IMMEDIATE + +: behavior ( defer-xt -- contents-xt ) + dup cell+ @ <instancedefer> = IF \ Is defer-xt an INSTANCE DEFER ? + 2 cells + @ >instance @ + ELSE + behavior + THEN +; + +: INSTANCE ALSO instance-words ; + +: my-parent my-self instance>parent @ ; +: my-args my-self instance>args 2@ swap ; + +\ copy args from original instance to new created +: set-my-args ( old-addr len -- ) + dup IF \ IF len > 0 ( old-addr len ) + dup alloc-mem \ | allocate space for new args ( old-addr len new-addr ) + 2dup my-self instance>args 2! \ | write into instance struct ( old-addr len new-addr ) + swap move \ | and copy the args ( ) + ELSE \ ELSE ( old-addr len ) + my-self instance>args 2! \ | set new args to zero, too ( ) + THEN \ FI +; + +\ Current node has already been set, when this is called. +: create-instance-data ( -- instance ) + get-node dup node>instance-template @ ( phandle instance-template ) + swap node>instance-size @ ( instance-template instance-size ) + dup >r + dup alloc-mem dup >r swap move r> ( instance ) + dup instance>size r> swap ! \ Store size for destroy-instance + dup instance>#units 0 swap ! \ Use node unit by default +; +: create-instance ( -- ) + my-self create-instance-data + dup to my-self instance>parent ! + get-node my-self instance>node ! +; + +: destroy-instance ( instance -- ) + dup instance>args @ ?dup IF \ Free instance args? + over instance>args-len @ free-mem + THEN + dup instance>size @ free-mem +; + +: ihandle>phandle ( ihandle -- phandle ) + dup 0= ABORT" no current instance" instance>node @ +; + +: push-my-self ( ihandle -- ) r> my-self >r >r to my-self ; +: pop-my-self ( -- ) r> r> to my-self >r ; +: call-package push-my-self execute pop-my-self ; +: $call-static ( ... str len node -- ??? ) +\ cr ." call for " 3dup -rot type ." on node " . + find-method IF execute ELSE -1 throw THEN +; + +: $call-my-method ( str len -- ) + my-self ihandle>phandle $call-static +; + +: $call-method ( str len ihandle -- ) + push-my-self + ['] $call-my-method CATCH ?dup IF + pop-my-self THROW + THEN + pop-my-self +; + +0 VALUE calling-child + +: $call-parent + my-self ihandle>phandle TO calling-child + my-parent $call-method + 0 TO calling-child +; |