Preserve state across hot code reload!!
This commit is contained in:
parent
a5dbc5fcfc
commit
1db882c150
BIN
8Bitsy.dsk
BIN
8Bitsy.dsk
Binary file not shown.
25
asm/asm.fnl
25
asm/asm.fnl
|
@ -115,7 +115,7 @@
|
|||
; takes the form [:op args]
|
||||
; pdat - a parsed dat; takes the form {:type type :addr addr ...}
|
||||
(local dat-parser {})
|
||||
(fn new-block [last-symbol] {:type :block :pdats [] :symbols {} :globals {} : last-symbol})
|
||||
(fn new-block [last-symbol] {:type :block :pdats [] :preserved {} :symbols {} :globals {} : last-symbol})
|
||||
|
||||
(fn parse-dats [block dats]
|
||||
(each [_ dat (ipairs dats)]
|
||||
|
@ -139,7 +139,10 @@
|
|||
(table.insert block.pdats pdat)
|
||||
(when pdat.globals
|
||||
(each [name _ (pairs pdat.globals)]
|
||||
(tset block.globals name (length block.pdats))))))))
|
||||
(tset block.globals name (length block.pdats))))
|
||||
(when pdat.preserved
|
||||
(each [name pdat-preserved (pairs pdat.preserved)]
|
||||
(tset block.preserved name pdat-preserved)))))))
|
||||
block)
|
||||
|
||||
(fn dat-parser.op [op]
|
||||
|
@ -166,6 +169,13 @@
|
|||
nil)
|
||||
|
||||
(fn dat-parser.align [pad] {:type :pad :align (. pad 2)})
|
||||
(fn dat-parser.hot-preserve [[_ label & dats] block]
|
||||
(let [preserve-block (new-block)]
|
||||
(tset block.preserved label preserve-block)
|
||||
(tset preserve-block.globals label true)
|
||||
(parse-dats preserve-block [label])
|
||||
(parse-dats preserve-block dats)
|
||||
preserve-block))
|
||||
|
||||
(local pdat-processor {
|
||||
:op {}
|
||||
|
@ -338,6 +348,17 @@
|
|||
(self.dbgfile:close)
|
||||
(set self.dbgfile nil))
|
||||
self)
|
||||
:read-hotswap
|
||||
(fn [self machine]
|
||||
(let [hotswap {}]
|
||||
(each [_ block (pairs self.org-to-block)]
|
||||
(each [label pdat (pairs block.preserved)]
|
||||
(tset hotswap label (machine:read pdat.addr pdat.size))))
|
||||
hotswap))
|
||||
:write-hotswap
|
||||
(fn [self machine hotswap]
|
||||
(each [label bytes (pairs hotswap)]
|
||||
(machine:write (self:lookup-addr label) bytes)))
|
||||
:upload
|
||||
(fn [self machine]
|
||||
(if machine.upload (machine:upload self)
|
||||
|
|
|
@ -385,8 +385,9 @@
|
|||
|
||||
(fn vm.var [self name init]
|
||||
(self.code:append name [:jsr :$dovar]
|
||||
(if (= (type init) :table) init
|
||||
[:dw init])))
|
||||
[:hot-preserve (.. :G-HOT-PRESERVE- name)
|
||||
(if (= (type init) :table) init
|
||||
[:dw init])]))
|
||||
|
||||
(vm:def :$doconst ; usage: [jsr :$doconst] followed by two bytes
|
||||
(vm:reserve)
|
||||
|
|
|
@ -132,7 +132,7 @@
|
|||
[:jmp (if (= (or map.moveword "") "") :move-noop map.moveword)]
|
||||
[:jmp (if (= (or map.loadword "") "") :next map.loadword)]))
|
||||
|
||||
(vm.code:append :map-ptr [:db 0] :map-page [:db 0])
|
||||
(vm.code:append :map-ptr [:db 0] [:hot-preserve :map-page [:db 0]])
|
||||
(vm:word :map :lit :map-ptr :get)
|
||||
(vm:word :entity-count :map 240 :+ :bget)
|
||||
(vm:word :map-player-yx-ptr 241 :+)
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -45,7 +45,7 @@
|
|||
[:vm :hires
|
||||
:lit :map1 :load-level
|
||||
(vm:forever
|
||||
(vm:hotswap-sync :lit :map1 :load-level)
|
||||
(vm:hotswap-sync :full-redraw)
|
||||
:interactive-eval-checkpoint
|
||||
:handle-key
|
||||
)
|
||||
|
|
|
@ -87,6 +87,20 @@
|
|||
(when self.monitor (self.monitor:shutdown-session))
|
||||
(when (nrepl:connected?) (nrepl:disconnect))
|
||||
(set self.breakpoints {}))
|
||||
(fn Machine.read [self addr len]
|
||||
(-> (self:coro-eval
|
||||
(.. "(let [bencode (require :bencode)
|
||||
addr " addr "
|
||||
len " len "
|
||||
mem (. manager.machine.devices ::maincpu :spaces :program)]
|
||||
(var bytes \"\")
|
||||
(print :reading len :from addr)
|
||||
(for [i 1 len]
|
||||
(set bytes (.. bytes (string.char (mem:read_u8 (+ addr i -1))))))
|
||||
bytes)"))
|
||||
; result is piped through fennelview; have to eval it to turn it back into bytes
|
||||
; would be nice if io.write worked
|
||||
(fennel.eval)))
|
||||
(fn Machine.write [self addr bytes]
|
||||
(if (> (bytes:len) 0x1000)
|
||||
(do (self:write addr (bytes:sub 1 0x1000))
|
||||
|
@ -103,11 +117,11 @@
|
|||
(self:eval "(manager.machine:soft_reset)")
|
||||
(self:eval (string.format "(emu.keypost \"CALL-151\\n %xG\\n\")" (prg:lookup-addr prg.start-symbol))))
|
||||
(fn Machine.reboot [self] (self:eval "(manager.machine:hard_reset)"))
|
||||
(fn Machine.coro-eval [self code]
|
||||
(fn Machine.coro-eval [self code ?handlers]
|
||||
(var result nil)
|
||||
(local append-to-result #(set result (.. (or result "") $2)))
|
||||
(self:eval code
|
||||
(self:coro-handlers (coroutine.running) {:value append-to-result :out append-to-result}))
|
||||
(self:coro-handlers (coroutine.running) {:value append-to-result :out append-to-result} ?handlers))
|
||||
(coroutine.yield)
|
||||
(or result "<no result>"))
|
||||
(fn Machine.dbgcmd [self cmd ?handlers]
|
||||
|
@ -130,10 +144,14 @@
|
|||
(fn Machine.hotswap [self prg-old prg-new]
|
||||
(local addr (prg-old:lookup-addr :debug-stub))
|
||||
(self:set-bp addr
|
||||
(fn [] (self:clear-bp addr)
|
||||
(prg-new:upload self)
|
||||
(self:jump (prg-new:lookup-addr :on-hotswap))
|
||||
(self:continue))))
|
||||
#(util.in-coro (fn []
|
||||
(self:clear-bp addr)
|
||||
(local hotswap (prg-old:read-hotswap self))
|
||||
(prg-new:upload self)
|
||||
(prg-new:write-hotswap self hotswap)
|
||||
(self:jump (prg-new:lookup-addr :on-hotswap))
|
||||
(self:continue)))))
|
||||
|
||||
(fn Machine.overlay [self prg-overlay]
|
||||
(self:step)
|
||||
(prg-overlay:upload self)
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
(fn Session.shutdown-session [self]
|
||||
(set self.queue [])
|
||||
(set self.in-progress false)
|
||||
(set self.sesion nil))
|
||||
(set self.session nil))
|
||||
|
||||
(fn Session.cleanup-handlers [self]
|
||||
{:status/done #(self:done-msg)
|
||||
|
@ -63,9 +63,11 @@
|
|||
(fn Session.eval [self code ?handlers]
|
||||
(self:send {:op :eval : code} ?handlers))
|
||||
|
||||
(fn Session.input-handler [self input]
|
||||
{:status/need-input #(self:send-oob {:op :stdin :stdin input})})
|
||||
|
||||
(fn Session.eval-input [self code input ?handlers]
|
||||
(self:send {:op :eval : code}
|
||||
(lume.merge (or ?handlers {})
|
||||
{:status/need-input #(self:send-oob {:op :stdin :stdin input})})))
|
||||
(lume.merge (or ?handlers {}) (self:input-handler input))))
|
||||
|
||||
Session
|
||||
|
|
Loading…
Reference in a new issue