     @native = false
     @name = @method.full_signature()
 
-  serialize: (visited) ->
-    name: @name
-    pc: @pc
-    loader: @method.cls?.loader.serialize(visited)
-    native: @native
-    stack: (obj?.serialize?(visited) ? obj for obj in @stack)
-    locals: (obj?.serialize?(visited) ? obj for obj in @locals)
+  snap: (visited) ->
+    rv =
+      name: @name
+      pc: @pc
+      native: @native
+
+    serialize: =>
+      rv.loader = @method.cls?.loader.serialize(visited)
+      rv.stack = (obj?.serialize?(visited) ? obj for obj in @stack)
+      rv.locals = (obj?.serialize?(visited) ? obj for obj in @locals)
+      rv
 
   # Creates a "native stack frame". Handler is called with no arguments for
   # normal execution, error_handler is called with the uncaught exception.

    @curr_thread.$meta_stack = new root.CallStack [args]
    debug "### finished runtime state initialization ###"

  dump_state: ->
    fs = node?.fs ? require 'fs'
    # 4th parameter to writeFileSync ensures this is not stored in localStorage in the browser
    fs.writeFileSync "./core-#{thread_name @, @curr_thread}.json",
      (JSON.stringify @meta_stack().serialize({})), 'utf8', true

  choose_next_thread: (blacklist) ->
    unless blacklist?

    if initial_stack?
      @_cs[0].stack = initial_stack

  snap: ->
    visited = {}
    snapshots = (frame.snap(visited) for frame in @_cs)
    serialize: -> ss.serialize() for ss in snapshots

  length: -> @_cs.length
  push: (sf) -> @_cs.push sf
