1
0
Fork 0
mirror of https://github.com/rails/execjs synced 2023-03-27 23:21:20 -04:00

Initial support for duktape

This commit is contained in:
Joshua Peek 2014-12-06 12:25:40 -08:00
parent 0dcad9a755
commit d8c5ac2751
4 changed files with 75 additions and 0 deletions

View file

@ -3,6 +3,7 @@ source 'https://rubygems.org'
gemspec
group :test do
gem 'duktape'
gem 'therubyracer', platform: :mri
gem 'therubyrhino', ">=1.73.3", platform: :jruby
end

View file

@ -0,0 +1,67 @@
require "execjs/runtime"
require "json"
module ExecJS
class DuktapeRuntime < Runtime
class Context < Runtime::Context
def initialize(runtime, source = "")
@ctx = Duktape::Context.new
# Disable CJS
exec("module = exports = require = undefined")
exec(source)
end
def exec(source, options = {})
source = encode(source)
js = <<-JS
(function(program, execJS) { return execJS(program); })(function() { #{source}
}, function(program) {
try {
return JSON.stringify(['ok', program()]);
} catch (err) {
return JSON.stringify(['err', '' + err]);
}
});
JS
if json = @ctx.eval_string(js, '(execjs)')
status, value = ::JSON.parse(json, create_additions: false)
if status == "ok"
value
elsif value =~ /SyntaxError:/
raise RuntimeError, value
else
raise ProgramError, value
end
end
rescue Duktape::ContextError => e
raise RuntimeError, e.message
end
def eval(source, options = {})
source = encode(source)
if /\S/ =~ source
exec("return eval(#{::JSON.generate("(#{source})", quirks_mode: true)})")
end
end
def call(identifier, *args)
eval "#{identifier}.apply(this, #{::JSON.generate(args)})"
end
end
def name
"Duktape"
end
def available?
require "duktape"
true
rescue LoadError
false
end
end
end

View file

@ -1,5 +1,6 @@
require "execjs/module"
require "execjs/disabled_runtime"
require "execjs/duktape_runtime"
require "execjs/external_runtime"
require "execjs/johnson_runtime"
require "execjs/mustang_runtime"
@ -10,6 +11,8 @@ module ExecJS
module Runtimes
Disabled = DisabledRuntime.new
Duktape = DuktapeRuntime.new
RubyRacer = RubyRacerRuntime.new
RubyRhino = RubyRhinoRuntime.new
@ -78,6 +81,7 @@ module ExecJS
@runtimes ||= [
RubyRacer,
RubyRhino,
Duktape,
Johnson,
Mustang,
Node,

View file

@ -171,6 +171,9 @@ class TestExecJS < Test
end
def test_coffeescript
# Skip coffeescript on Duktape for now
skip if ExecJS.runtime.is_a?(ExecJS::DuktapeRuntime)
assert source = File.read(File.expand_path("../fixtures/coffee-script.js", __FILE__))
context = ExecJS.compile(source)
assert_equal 64, context.call("CoffeeScript.eval", "((x) -> x * x)(8)")