1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
require "execjs/runtime"
module ExecJS
class MiniRacerRuntime < Runtime
class Context < Runtime::Context
def initialize(runtime, source = "", options={})
source = source.encode(Encoding::UTF_8)
@context = ::MiniRacer::Context.new
@context.eval("delete this.console");
translate do
@context.eval(source)
end
end
def exec(source, options = {})
source = source.encode(Encoding::UTF_8)
if /\S/ =~ source
eval "(function(){#{source}})()"
end
end
def eval(source, options = {})
source = source.encode(Encoding::UTF_8)
if /\S/ =~ source
translate do
@context.eval("(#{source})")
end
end
end
def call(identifier, *args)
# TODO optimise generate
eval "#{identifier}.apply(this, #{::JSON.generate(args)})"
end
private
def strip_functions!(value)
if Array === value
value.map! do |v|
if MiniRacer::JavaScriptFunction === value
nil
else
strip_functions!(v)
end
end
elsif Hash === value
value.each do |k,v|
if MiniRacer::JavaScriptFunction === v
value.delete k
else
value[k] = strip_functions!(v)
end
end
value
elsif MiniRacer::JavaScriptFunction === value
nil
else
value
end
end
def translate
begin
strip_functions! yield
rescue MiniRacer::RuntimeError => e
ex = ProgramError.new e.message
if backtrace = e.backtrace
backtrace = backtrace.map { |line|
if line =~ /JavaScript at/
line.sub("JavaScript at ", "")
.sub("<anonymous>", "(execjs)")
.strip
else
line
end
}
ex.set_backtrace backtrace
end
raise ex
rescue MiniRacer::ParseError => e
ex = RuntimeError.new e.message
ex.set_backtrace(["(execjs):1"] + e.backtrace)
raise ex
end
end
end
def name
"mini_racer (V8)"
end
def available?
require "mini_racer"
true
rescue LoadError
false
end
end
end
|