     if initial_stack?
       @_cs[0].stack = initial_stack
 
-  serialize: (visited) -> frame.serialize(visited) for frame in @_cs
+  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

    @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)

  # 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: (snapshot=@meta_stack().snap(), suffix) ->
    suffix = if suffix? then "-#{suffix}" else ''
    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}#{suffix}.json",
      (JSON.stringify snapshot.serialize()), 'utf8', true

  choose_next_thread: (blacklist) ->
    unless blacklist?
