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:
parent
0dcad9a755
commit
d8c5ac2751
4 changed files with 75 additions and 0 deletions
1
Gemfile
1
Gemfile
|
@ -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
|
||||
|
|
67
lib/execjs/duktape_runtime.rb
Normal file
67
lib/execjs/duktape_runtime.rb
Normal 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
|
|
@ -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,
|
||||
|
|
|
@ -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)")
|
||||
|
|
Loading…
Add table
Reference in a new issue