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
|
# evaluate some simple javascript
|
||||||
eval_js "7 * 6" #=> 42
|
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
|
# evaluate a ruby function from javascript
|
||||||
|
|
||||||
|
|
|
@ -76,14 +76,17 @@ module Rhino
|
||||||
end
|
end
|
||||||
|
|
||||||
# Evaluate a string of javascript in this context:
|
# 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>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
|
# * <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)
|
def eval(source, source_name = "<eval>", line_number = 1)
|
||||||
source = source.to_s
|
|
||||||
begin
|
begin
|
||||||
scope = To.javascript(@scope)
|
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
|
To.ruby result
|
||||||
rescue J::RhinoException => e
|
rescue J::RhinoException => e
|
||||||
raise Rhino::RhinoError, e
|
raise Rhino::RhinoError, e
|
||||||
|
@ -99,6 +102,30 @@ module Rhino
|
||||||
end
|
end
|
||||||
|
|
||||||
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:
|
class ContextFactory < J::ContextFactory # :nodoc:
|
||||||
|
|
||||||
|
|
|
@ -123,4 +123,29 @@ describe Rhino::Context do
|
||||||
Context.new(nil)
|
Context.new(nil)
|
||||||
}.should raise_error
|
}.should raise_error
|
||||||
end
|
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
|
end
|
Loading…
Reference in a new issue