class ExecJS::GraalJSRuntime::Context
def call(source, *args)
def call(source, *args) source = source.encode(Encoding::UTF_8) source = "(#{source})" if /\S/.match?(source) translate do function = eval_in_context(source) function.call(*convert_ruby_to_js(args)) end end
def convert_js_to_ruby(value)
def convert_js_to_ruby(value) case value when true, false, Integer, Float value else if value.nil? nil elsif value.respond_to?(:call) nil elsif value.respond_to?(:to_str) value.to_str elsif value.respond_to?(:to_ary) value.to_ary.map do |e| if e.respond_to?(:call) nil else convert_js_to_ruby(e) end end else object = value h = {} object.instance_variables.each do |member| v = object[member] unless v.respond_to?(:call) h[member.to_s] = convert_js_to_ruby(v) end end h end end end
def convert_ruby_to_js(value)
def convert_ruby_to_js(value) case value when nil, true, false, Integer, Float value when String, Symbol Truffle::Interop.as_truffle_string value when Array value.map { |e| convert_ruby_to_js(e) } when Hash h = @js_object.new value.each_pair do |k,v| h[convert_ruby_to_js(k)] = convert_ruby_to_js(v) end h else raise TypeError, "Unknown how to convert to JS: #{value.inspect}" end end
def eval(source, options = {})
def eval(source, options = {}) source = source.encode(Encoding::UTF_8) source = "(#{source})" if /\S/.match?(source) translate do eval_in_context(source) end end
def exec(source, options = {})
def exec(source, options = {}) source = source.encode(Encoding::UTF_8) source = "(function(){#{source}})()" if /\S/.match?(source) translate do eval_in_context(source) end end
def initialize(runtime, source = "", options = {})
def initialize(runtime, source = "", options = {}) @context = Polyglot::InnerContext.new @context.eval('js', 'delete this.console') @js_object = @context.eval('js', 'Object') source = source.encode(Encoding::UTF_8) unless source.empty? translate do eval_in_context(source) end end end
def translate
def translate convert_js_to_ruby yield rescue ForeignException => e if e.message && e.message.start_with?('SyntaxError:') error_class = ExecJS::RuntimeError else error_class = ExecJS::ProgramError end backtrace = (e.backtrace || []).map { |line| line.sub('(eval)', '(execjs)') } raise error_class, e.message, backtrace end