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:
parent
f6eb4ff3da
commit
2a1bdf7859
3 changed files with 65 additions and 3 deletions
10
README.rdoc
10
README.rdoc
|
@ -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
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
Loading…
Reference in a new issue