mirror of
https://github.com/rubyjs/therubyrhino
synced 2023-03-27 23:21:34 -04:00
add referential integrity to objects being passed into Rhino.
This commit is contained in:
parent
478d81831f
commit
3e31402a77
3 changed files with 47 additions and 24 deletions
|
@ -5,23 +5,23 @@ module Rhino
|
|||
# ==Overview
|
||||
# All Javascript must be executed in a context which represents the execution environment in
|
||||
# which scripts will run. The environment consists of the standard javascript objects
|
||||
# and functions like Object, String, Array, etc... as well as any objects or functions which
|
||||
# and functions like Object, String, Array, etc... as well as any objects or functions which
|
||||
# have been defined in it. e.g.
|
||||
#
|
||||
#
|
||||
# Context.open do |cxt|
|
||||
# cxt['num'] = 5
|
||||
# cxt.eval('num + 5') #=> 10
|
||||
# end
|
||||
#
|
||||
#
|
||||
# == Multiple Contexts.
|
||||
# The same object may appear in any number of contexts, but only one context may be executing javascript code
|
||||
# The same object may appear in any number of contexts, but only one context may be executing javascript code
|
||||
# in any given thread. If a new context is opened in a thread in which a context is already opened, the second
|
||||
# context will "mask" the old context e.g.
|
||||
#
|
||||
# six = 6
|
||||
# Context.open do |cxt|
|
||||
# cxt['num'] = 5
|
||||
# cxt.eval('num') # => 5
|
||||
# cxt.eval('num') # => 5
|
||||
# Context.open do |cxt|
|
||||
# cxt['num'] = 10
|
||||
# cxt.eval('num') # => 10
|
||||
|
@ -44,11 +44,11 @@ module Rhino
|
|||
def open(options = {}, &block)
|
||||
new(options).open(&block)
|
||||
end
|
||||
|
||||
|
||||
def eval(javascript)
|
||||
new.eval(javascript)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
# Create a new javascript environment for executing javascript and ruby code.
|
||||
|
@ -78,8 +78,8 @@ module Rhino
|
|||
@scope[k]
|
||||
end
|
||||
|
||||
# Set a value in the global scope of this context. This value will be visible to all the
|
||||
# javascript that is executed in this context.
|
||||
# Set a value in the global scope of this context. This value will be visible to all the
|
||||
# javascript that is executed in this context.
|
||||
def []=(k, v)
|
||||
@scope[k] = v
|
||||
end
|
||||
|
@ -103,7 +103,7 @@ module Rhino
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def evaluate(*args) # :nodoc:
|
||||
self.eval(*args)
|
||||
end
|
||||
|
@ -186,7 +186,7 @@ module Rhino
|
|||
end
|
||||
|
||||
class ContextError < StandardError # :nodoc:
|
||||
|
||||
|
||||
end
|
||||
|
||||
class JavascriptError < StandardError # :nodoc:
|
||||
|
@ -203,6 +203,8 @@ module Rhino
|
|||
end
|
||||
end
|
||||
|
||||
JSError = JavascriptError
|
||||
|
||||
class RunawayScriptError < StandardError # :nodoc:
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
module Rhino
|
||||
|
||||
# Wraps a function that has been defined in Javascript so that it can
|
||||
|
||||
# Wraps a function that has been defined in Javascript so that it can
|
||||
# be referenced and called from javascript. e.g.
|
||||
#
|
||||
# plus = Rhino::Context.open do |cx|
|
||||
|
@ -9,15 +9,21 @@ module Rhino
|
|||
# end
|
||||
# plus.call(5,4) # => 9
|
||||
#
|
||||
class NativeFunction < NativeObject
|
||||
class NativeFunction < NativeObject
|
||||
def call(*args)
|
||||
begin
|
||||
cxt = J::Context.enter()
|
||||
scope = @j.getParentScope() || cxt.initStandardObjects()
|
||||
@j.call(cxt, scope, scope, args.map {|o| To.javascript(o)})
|
||||
ensure
|
||||
J::Context.exit()
|
||||
end
|
||||
cxt = J::Context.enter()
|
||||
scope = @j.getParentScope() || cxt.initStandardObjects()
|
||||
@j.call(cxt, scope, scope, args.map {|o| To.javascript(o)})
|
||||
ensure
|
||||
J::Context.exit()
|
||||
end
|
||||
|
||||
def methodcall(this, *args)
|
||||
cxt = J::Context.enter()
|
||||
scope = @j.getParentScope() || cxt.initStandardObjects()
|
||||
@j.call(cxt, scope, To.javascript(this), args.map {|o| To.javascript(o)})
|
||||
ensure
|
||||
J::Context.exit()
|
||||
end
|
||||
end
|
||||
end
|
|
@ -3,6 +3,8 @@ module Rhino
|
|||
module To
|
||||
JS_UNDEF = [J::Scriptable::NOT_FOUND, J::Undefined]
|
||||
|
||||
module_function
|
||||
|
||||
def ruby(object)
|
||||
case object
|
||||
when *JS_UNDEF then nil
|
||||
|
@ -10,8 +12,8 @@ module Rhino
|
|||
when J::NativeArray then array(object)
|
||||
when J::NativeDate then Time.at(object.getJSTimeValue() / 1000)
|
||||
when J::Regexp::NativeRegExp then object
|
||||
when J::Function then NativeFunction.new(object)
|
||||
when J::Scriptable then NativeObject.new(object)
|
||||
when J::Function then r2j(object) {|o| NativeFunction.new(o)}
|
||||
when J::Scriptable then r2j(object) {|o| NativeObject.new(o)}
|
||||
else object
|
||||
end
|
||||
end
|
||||
|
@ -43,6 +45,19 @@ module Rhino
|
|||
native_object.j
|
||||
end
|
||||
|
||||
module_function :ruby, :javascript, :array, :ruby_hash_to_native
|
||||
@@r2j = {}
|
||||
|
||||
def r2j(value)
|
||||
if ref = @@r2j[value.object_id]
|
||||
if peer = ref.get()
|
||||
return peer
|
||||
end
|
||||
else
|
||||
yield(value).tap do |peer|
|
||||
@@r2j[value.object_id] = java.lang.ref.WeakReference.new(peer)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue