1
0
Fork 0
mirror of https://github.com/rubyjs/therubyrhino synced 2023-03-27 23:21:34 -04:00

add ability to evaluate javascript bytes straight off an IO object without slurping it completely into memory

This commit is contained in:
Charles Lowell 2009-11-20 09:38:31 -06:00
parent f6eb4ff3da
commit 2a1bdf7859
3 changed files with 65 additions and 3 deletions

View file

@ -21,6 +21,16 @@ Embed the Mozilla Rhino Javascript interpreter into Ruby
# evaluate some simple javascript
eval_js "7 * 6" #=> 42
# evaluate bytes read from any File/IO object:
File.open("mysource.js") do |file|
eval_js file, "mysource.js"
#or in the context of a controlled scope
Rhino::Context.open do |context|
context['foo'] = 'some global variable referenced in mysource.js'
context.eval(file, "mysource.js")
end
# evaluate a ruby function from javascript

View file

@ -76,14 +76,17 @@ module Rhino
end
# Evaluate a string of javascript in this context:
# * <tt>source</tt> - the javascript source code to evaluate
# * <tt>source</tt> - the javascript source code to evaluate. This can be either a string or an IO object.
# * <tt>source_name</tt> - associated name for this source code. Mainly useful for backtraces.
# * <tt>line_number</tt> - associate this number with the first line of executing source. Mainly useful for backtraces
def eval(source, source_name = "<eval>", line_number = 1)
source = source.to_s
begin
scope = To.javascript(@scope)
result = @native.evaluateString(scope, source, source_name, line_number, nil)
if IO === source || StringIO === source
result = @native.evaluateReader(scope, IOReader.new(source), source_name, line_number, nil)
else
result = @native.evaluateString(scope, source.to_s, source_name, line_number, nil)
end
To.ruby result
rescue J::RhinoException => e
raise Rhino::RhinoError, e
@ -99,6 +102,30 @@ module Rhino
end
end
class IOReader < Java::JavaIo::Reader #:nodoc:
def initialize(io)
@io = io
end
def read(charbuffer, offset, length)
begin
str = @io.read(length)
if str.nil?
return -1
else
jstring = Java::JavaLang::String.new(str)
for i in 0 .. jstring.length - 1
charbuffer[i + offset] = jstring.charAt(i)
end
return jstring.length
end
rescue StandardError => e
raise Java::JavaIo::IOException.new, "Failed reading from ruby IO object"
end
end
end
class ContextFactory < J::ContextFactory # :nodoc:

View file

@ -123,4 +123,29 @@ describe Rhino::Context do
Context.new(nil)
}.should raise_error
end
describe "compilation" do
it "can take an IO object in the eval method instead of a string" do
source = StringIO.new(<<-EOJS)
/*
* we want to have a fairly verbose function so that we can be assured tha
* we overflow the buffer size so that we see that the reader is chunking
* it's payload in at least several fragments.
*
* That's why we're wasting space here
*/
function five() {
return 5
}
foo = 'bar'
five();
EOJS
Context.open do |cxt|
cxt.eval(source, "StringIO").should == 5
cxt['foo'].should == "bar"
end
end
end
end