class ExecJS::ExternalRuntime::Context

def call(identifier, *args)

def call(identifier, *args)
  eval "#{identifier}.apply(this, #{::JSON.generate(args)})"
end

def create_tempfile(basename)

See Tempfile.create on Ruby 2.1
def create_tempfile(basename)
  tmpfile = nil
  Dir::Tmpname.create(basename) do |tmpname|
    mode    = File::WRONLY | File::CREAT | File::EXCL
    tmpfile = File.open(tmpname, mode, 0600)
  end
  tmpfile
end

def eval(source, options = {})

def eval(source, options = {})
  source = source.encode(Encoding::UTF_8)
  if /\S/ =~ source
    exec("return eval(#{::JSON.generate("(#{source})", quirks_mode: true)})")
  end
end

def exec(source, options = {})

def exec(source, options = {})
  source = source.encode(Encoding::UTF_8)
  source = "#{@source}\n#{source}" if @source != ""
  source = @runtime.compile_source(source)
  tmpfile = write_to_tempfile(source)
  if ExecJS.cygwin?
    filepath = `cygpath -m #{tmpfile.path}`.rstrip
  else
    filepath = tmpfile.path
  end
  begin
    extract_result(@runtime.exec_runtime(filepath), filepath)
  ensure
    File.unlink(tmpfile)
  end
end

def extract_result(output, filename)

def extract_result(output, filename)
  status, value, stack = output.empty? ? [] : ::JSON.parse(output, create_additions: false)
  if status == "ok"
    value
  else
    stack ||= ""
    real_filename = File.realpath(filename)
    stack = stack.split("\n").map do |line|
      line.sub(" at ", "")
          .sub(real_filename, "(execjs)")
          .sub(filename, "(execjs)")
          .strip
    end
    stack.reject! { |line| ["eval code", "eval code@", "eval@[native code]"].include?(line) }
    stack.shift unless stack[0].to_s.include?("(execjs)")
    error_class = value =~ /SyntaxError:/ ? RuntimeError : ProgramError
    error = error_class.new(value)
    error.set_backtrace(stack + caller)
    raise error
  end
end

def initialize(runtime, source = "", options = {})

def initialize(runtime, source = "", options = {})
  source = source.encode(Encoding::UTF_8)
  @runtime = runtime
  @source  = source
  # Test compile context source
  exec("")
end

def write_to_tempfile(contents)

def write_to_tempfile(contents)
  tmpfile = create_tempfile(['execjs', 'js'])
  tmpfile.write(contents)
  tmpfile.close
  tmpfile
end