Skip to content

Commit

Permalink
Showing 7 changed files with 248 additions and 0 deletions.
95 changes: 95 additions & 0 deletions lib/ruby/truffle/truffle/truffle/execjs.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Copyright (c) 2016 Oracle and/or its affiliates. All rights reserved. This
# code is released under a tri EPL/GPL/LGPL license. You can use it,
# redistribute it and/or modify it under the terms of the:
#
# Eclipse Public License version 1.0
# GNU General Public License version 2
# GNU Lesser General Public License version 2.1

# Designed for ExecJS 2.6.0, but I'll allow it to try to work with anything for now

require 'execjs/runtime'
require 'json'

module ExecJS

class TruffleRuntime < Runtime

JS_MIME_TYPE = 'application/javascript'

class Context < Runtime::Context

STRINGIFY = Truffle::Interop.eval(JS_MIME_TYPE, 'JSON.stringify')
PARSE = Truffle::Interop.eval(JS_MIME_TYPE, 'JSON.parse')

def initialize(runtime, source = '')
exec source
end

def exec(source, options = {})
Truffle::Interop.eval JS_MIME_TYPE, source
nil
end

def eval(source, options = {})
unbox(Truffle::Interop.eval(JS_MIME_TYPE, source))
end

def call(identifier, *args)
function = Truffle::Interop.eval(JS_MIME_TYPE, identifier)
unbox(function.call(function, *args.map { |arg| box(arg) }))
end

private

def unbox(value)
if Truffle::Interop.boxed_primitive?(value)
Truffle::Interop.unbox_value(value)
else
JSON.parse(Truffle::Interop.java_string_to_ruby(STRINGIFY.call(STRINGIFY, value)))
end
end

def box(value)
if Truffle::Interop.boxed_primitive?(value) || value.is_a?(String)
value
else
PARSE.call(PARSE, JSON.generate(value))
end
end

end

def name
'Truffle'
end

def available?
defined?(Truffle::Interop) && Truffle::Interop.eval(JS_MIME_TYPE, 'true')
rescue RubyTruffleError
false
end

end

# Monkey patches

module Runtimes

@runtimes = nil

class << self

alias_method :original_runtimes, :runtimes

def runtimes
@runtimes ||= ([TruffleRuntime.new] + original_runtimes)
end

end

end

self.runtime = Runtimes.autodetect

end
16 changes: 16 additions & 0 deletions test/truffle/integration/execjs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/env bash

set -e

# Run with for example JRUBY_OPTS='-J-cp ..../trufflejs.jar'

if [[ $JRUBY_OPTS != *"trufflejs.jar"* ]]
then
echo 'No trufflejs.jar found in $JRUBY_OPTS - skipping ExecJS integration test'
exit 0
fi

bin/jruby -X-T bin/gem install execjs -v 2.6.0
ruby -X+T -Ilib/ruby/gems/shared/gems/execjs-2.6.0/lib test/truffle/integration/execjs/checkruntime.rb
ruby -X+T -Ilib/ruby/gems/shared/gems/execjs-2.6.0/lib test/truffle/integration/execjs/simple.rb
ruby -X+T -Ilib/ruby/gems/shared/gems/execjs-2.6.0/lib test/truffle/integration/execjs/coffeescript.rb
4 changes: 4 additions & 0 deletions test/truffle/integration/execjs/checkruntime.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
require 'execjs'
require 'truffle/execjs'

exit 1 unless ExecJS.runtime.name == 'Truffle'
12 changes: 12 additions & 0 deletions test/truffle/integration/execjs/coffeescript.js

Large diffs are not rendered by default.

34 changes: 34 additions & 0 deletions test/truffle/integration/execjs/coffeescript.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Example from the ExecJS README.md

# Copyright (c) 2015-2016 Sam Stephenson
# Copyright (c) 2015-2016 Josh Peek
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

require "execjs"
require "truffle/execjs"

# Not using the remote file as we can't inflate the data it gives us at the moment
#require "open-uri"
source = File.read(File.join(File.dirname(__FILE__), 'coffeescript.js')) # open("http://coffeescript.org/extras/coffee-script.js").read

context = ExecJS.compile(source)
exit 1 unless context.call("CoffeeScript.compile", "square = (x) -> x * x", bare: true) == "var square;\n\nsquare = function(x) {\n return x * x;\n};\n"
# => "var square;\nsquare = function(x) {\n return x * x;\n};"
27 changes: 27 additions & 0 deletions test/truffle/integration/execjs/simple.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Example from the ExecJS README.md

# Copyright (c) 2015-2016 Sam Stephenson
# Copyright (c) 2015-2016 Josh Peek
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

require "execjs"
require "truffle/execjs"
exit 1 unless ExecJS.eval("'red yellow blue'.split(' ')") == ["red", "yellow", "blue"]
Original file line number Diff line number Diff line change
@@ -113,6 +113,36 @@ public IsBoxedPrimitiveNode(RubyContext context, SourceSection sourceSection) {
this.node = Message.IS_BOXED.createNode();
}

@Specialization
public boolean isBoxedPrimitive(VirtualFrame frame, boolean receiver) {
return receiver;
}

@Specialization
public boolean isBoxedPrimitive(VirtualFrame frame, byte receiver) {
return true;
}

@Specialization
public boolean isBoxedPrimitive(VirtualFrame frame, short receiver) {
return true;
}

@Specialization
public boolean isBoxedPrimitive(VirtualFrame frame, long receiver) {
return true;
}

@Specialization
public boolean isBoxedPrimitive(VirtualFrame frame, float receiver) {
return true;
}

@Specialization
public boolean isBoxedPrimitive(VirtualFrame frame, double receiver) {
return true;
}

@Specialization
public boolean isBoxedPrimitive(VirtualFrame frame, CharSequence receiver) {
return true;
@@ -277,6 +307,36 @@ public UnboxValueNode(RubyContext context, SourceSection sourceSection) {
this.node = Message.UNBOX.createNode();
}

@Specialization
public boolean unbox(VirtualFrame frame, boolean receiver) {
return receiver;
}

@Specialization
public byte unbox(VirtualFrame frame, byte receiver) {
return receiver;
}

@Specialization
public short unbox(VirtualFrame frame, short receiver) {
return receiver;
}

@Specialization
public long unbox(VirtualFrame frame, long receiver) {
return receiver;
}

@Specialization
public float unbox(VirtualFrame frame, float receiver) {
return receiver;
}

@Specialization
public double unbox(VirtualFrame frame, double receiver) {
return receiver;
}

@Specialization
public DynamicObject executeForeign(VirtualFrame frame, CharSequence receiver) {
// TODO CS-21-Dec-15 this shouldn't be needed - we need to convert j.l.String to Ruby's String automatically

0 comments on commit 25600ba

Please sign in to comment.