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

avoid the dynamic interface proxy creation on factory.call(ContextAction) (fixes #30)

This commit is contained in:
kares 2014-07-15 18:20:50 +02:00
parent 5b033dc5e5
commit a2e907ae25

View file

@ -46,23 +46,23 @@ module Rhino
def eval(javascript) def eval(javascript)
new.eval(javascript) new.eval(javascript)
end end
end end
@@default_factory = nil @@default_factory = nil
def self.default_factory def self.default_factory
@@default_factory ||= ContextFactory.new @@default_factory ||= ContextFactory.new
end end
def self.default_factory=(factory) def self.default_factory=(factory)
@@default_factory = factory @@default_factory = factory
end end
@@default_optimization_level = java.lang.Integer.getInteger('rhino.opt.level') @@default_optimization_level = java.lang.Integer.getInteger('rhino.opt.level')
def self.default_optimization_level def self.default_optimization_level
@@default_optimization_level @@default_optimization_level
end end
def self.default_optimization_level=(level) def self.default_optimization_level=(level)
@@default_optimization_level = level @@default_optimization_level = level
end end
@ -71,35 +71,22 @@ module Rhino
def self.default_javascript_version def self.default_javascript_version
@@default_javascript_version @@default_javascript_version
end end
def self.default_javascript_version=(version) def self.default_javascript_version=(version)
@@default_javascript_version = version @@default_javascript_version = version
end end
attr_reader :scope attr_reader :scope
# Create a new javascript environment for executing javascript and ruby code. # Create a new javascript environment for executing javascript and ruby code.
# * <tt>:sealed</tt> - if this is true, then the standard objects such as Object, Function, Array will not be able to be modified # * <tt>:sealed</tt> - if this is true, then the standard objects such as Object, Function, Array will not be able to be modified
# * <tt>:with</tt> - use this ruby object as the root scope for all javascript that is evaluated # * <tt>:with</tt> - use this ruby object as the root scope for all javascript that is evaluated
# * <tt>:java</tt> - if true, java packages will be accessible from within javascript # * <tt>:java</tt> - if true, java packages will be accessible from within javascript
def initialize(options = {}) #:nodoc: def initialize(options = {}) #:nodoc:
factory = options[:factory] || factory = options[:factory] ||
(options[:restrictable] ? RestrictableContextFactory.instance : self.class.default_factory) (options[:restrictable] ? RestrictableContextFactory.instance : self.class.default_factory)
factory.call do |context| @options = options
@native = context factory.call(self) # org.mozilla.javascript.ContextAction (invokes #run)
@global = @native.initStandardObjects(nil, options[:sealed] == true)
if with = options[:with]
@scope = Rhino.to_javascript(with)
@scope.setParentScope(@global)
else
@scope = @global
end
unless options[:java]
for package in ["Packages", "java", "javax", "org", "com", "edu", "net"]
@global.delete(package)
end
end
end
if optimization_level = options[:optimization_level] || self.class.default_optimization_level if optimization_level = options[:optimization_level] || self.class.default_optimization_level
self.optimization_level = optimization_level self.optimization_level = optimization_level
end end
@ -108,12 +95,32 @@ module Rhino
end end
yield(self) if block_given? yield(self) if block_given?
end end
include JS::ContextAction
# org.mozilla.javascript.ContextAction public Object run(Context context);
def run(context) # :nodoc:
@native = context
@global = @native.initStandardObjects(nil, @options[:sealed] == true)
if with = @options[:with]
@scope = Rhino.to_javascript(with)
@scope.setParentScope(@global)
else
@scope = @global
end
unless @options[:java]
@global.delete('Packages')
@global.delete('java'); @global.delete('javax')
@global.delete('org'); @global.delete('com')
@global.delete('edu'); @global.delete('net')
end
end
# Returns the ContextFactory used while creating this context. # Returns the ContextFactory used while creating this context.
def factory def factory
@native.getFactory @native.getFactory
end end
# Read a value from the global scope of this context # Read a value from the global scope of this context
def [](key) def [](key)
@scope[key] @scope[key]
@ -139,7 +146,7 @@ module Rhino
Rhino.to_ruby(result) Rhino.to_ruby(result)
end end
end end
def evaluate(*args) # :nodoc: def evaluate(*args) # :nodoc:
eval(*args) # an alias eval(*args) # an alias
end end
@ -161,11 +168,11 @@ module Rhino
def restrictable? def restrictable?
@native.is_a?(RestrictableContextFactory::Context) @native.is_a?(RestrictableContextFactory::Context)
end end
def instruction_limit def instruction_limit
restrictable? ? @native.instruction_limit : false restrictable? ? @native.instruction_limit : false
end end
# Set the maximum number of instructions that this context will execute. # Set the maximum number of instructions that this context will execute.
# If this instruction limit is exceeded, then a #Rhino::RunawayScriptError # If this instruction limit is exceeded, then a #Rhino::RunawayScriptError
# will be raised. # will be raised.
@ -173,7 +180,7 @@ module Rhino
if restrictable? if restrictable?
@native.instruction_limit = limit @native.instruction_limit = limit
else else
raise "setting an instruction_limit has no effect on this context, use " + raise "setting an instruction_limit has no effect on this context, use " <<
"Context.open(:restrictable => true) to gain a restrictable instance" "Context.open(:restrictable => true) to gain a restrictable instance"
end end
end end
@ -181,7 +188,7 @@ module Rhino
def timeout_limit def timeout_limit
restrictable? ? @native.timeout_limit : false restrictable? ? @native.timeout_limit : false
end end
# Set the duration (in seconds e.g. 1.5) this context is allowed to execute. # Set the duration (in seconds e.g. 1.5) this context is allowed to execute.
# After the timeout passes (no matter if any JS has been evaluated) and this # After the timeout passes (no matter if any JS has been evaluated) and this
# context is still attempted to run code, a #Rhino::ScriptTimeoutError will # context is still attempted to run code, a #Rhino::ScriptTimeoutError will
@ -190,15 +197,15 @@ module Rhino
if restrictable? if restrictable?
@native.timeout_limit = limit @native.timeout_limit = limit
else else
raise "setting an timeout_limit has no effect on this context, use " + raise "setting an timeout_limit has no effect on this context, use " <<
"Context.open(:restrictable => true) to gain a restrictable instance" "Context.open(:restrictable => true) to gain a restrictable instance"
end end
end end
def optimization_level def optimization_level
@native.getOptimizationLevel @native.getOptimizationLevel
end end
# Set the optimization level that this context will use. This is sometimes necessary # Set the optimization level that this context will use. This is sometimes necessary
# in Rhino, if the bytecode size of the compiled javascript exceeds the 64KB limit. # in Rhino, if the bytecode size of the compiled javascript exceeds the 64KB limit.
# By using the -1 optimization level, you tell Rhino to run in interpretative mode, # By using the -1 optimization level, you tell Rhino to run in interpretative mode,
@ -213,7 +220,7 @@ module Rhino
end end
end end
# Get the JS interpreter version. # Get the JS interpreter version.
# Returns a number e.g. 1.7, nil if unknown and 0 for default. # Returns a number e.g. 1.7, nil if unknown and 0 for default.
def javascript_version def javascript_version
case const_value = @native.getLanguageVersion case const_value = @native.getLanguageVersion
@ -223,7 +230,7 @@ module Rhino
end end
end end
alias :version :javascript_version alias :version :javascript_version
# Sets interpreter mode a.k.a. JS language version e.g. 1.7 (if supported). # Sets interpreter mode a.k.a. JS language version e.g. 1.7 (if supported).
def javascript_version=(version) def javascript_version=(version)
const = version.to_s.gsub('.', '_').upcase const = version.to_s.gsub('.', '_').upcase
@ -237,9 +244,9 @@ module Rhino
nil nil
end end
end end
alias :version= :javascript_version= alias :version= :javascript_version=
# Enter this context for operations. # Enter this context for operations.
# Some methods such as eval() will fail unless the context is open. # Some methods such as eval() will fail unless the context is open.
def open(&block) def open(&block)
do_open(&block) do_open(&block)
@ -251,9 +258,9 @@ module Rhino
end end
raise Rhino::JSError.new(e) raise Rhino::JSError.new(e)
end end
private private
def do_open # :nodoc def do_open # :nodoc
factory.enterContext(@native) factory.enterContext(@native)
begin begin
@ -262,7 +269,7 @@ module Rhino
factory.exit factory.exit
end end
end end
CODE_GENERATION_ERROR_MESSAGE = 'generated bytecode for method exceeds 64K limit' # :nodoc CODE_GENERATION_ERROR_MESSAGE = 'generated bytecode for method exceeds 64K limit' # :nodoc
CODE_GENERATION_TRACE_CLASS_NAME = 'org.mozilla.javascript.optimizer.Codegen' # :nodoc CODE_GENERATION_TRACE_CLASS_NAME = 'org.mozilla.javascript.optimizer.Codegen' # :nodoc
@ -316,7 +323,7 @@ module Rhino
return jstr.length return jstr.length
end end
end end
end end
ContextFactory = JS::ContextFactory # :nodoc: backward compatibility ContextFactory = JS::ContextFactory # :nodoc: backward compatibility
@ -327,24 +334,24 @@ module Rhino
def self.instance def self.instance
@@instance ||= new @@instance ||= new
end end
# protected Context makeContext() # protected Context makeContext()
def makeContext def makeContext
Context.new(self) Context.new(self)
end end
# protected void observeInstructionCount(Context context, int instructionCount) # protected void observeInstructionCount(Context context, int instructionCount)
def observeInstructionCount(context, count) def observeInstructionCount(context, count)
context.check!(count) if context.is_a?(Context) context.check!(count) if context.is_a?(Context)
end end
# protected Object doTopCall(Callable callable, Context context, # protected Object doTopCall(Callable callable, Context context,
# Scriptable scope, Scriptable thisObj, Object[] args) # Scriptable scope, Scriptable thisObj, Object[] args)
def doTopCall(callable, context, scope, this, args) def doTopCall(callable, context, scope, this, args)
context.reset! if context.is_a?(Context) context.reset! if context.is_a?(Context)
super super
end end
class Context < JS::Context # :nodoc: class Context < JS::Context # :nodoc:
def initialize(factory) def initialize(factory)
@ -353,7 +360,7 @@ module Rhino
end end
attr_reader :instruction_limit attr_reader :instruction_limit
def instruction_limit=(limit) def instruction_limit=(limit)
treshold = getInstructionObserverThreshold treshold = getInstructionObserverThreshold
if limit && (treshold == 0 || treshold > limit) if limit && (treshold == 0 || treshold > limit)
@ -363,11 +370,11 @@ module Rhino
end end
attr_reader :instruction_count attr_reader :instruction_count
TIMEOUT_INSTRUCTION_TRESHOLD = 42 TIMEOUT_INSTRUCTION_TRESHOLD = 42
attr_reader :timeout_limit attr_reader :timeout_limit
def timeout_limit=(limit) # in seconds def timeout_limit=(limit) # in seconds
treshold = getInstructionObserverThreshold treshold = getInstructionObserverThreshold
if limit && (treshold == 0 || treshold > TIMEOUT_INSTRUCTION_TRESHOLD) if limit && (treshold == 0 || treshold > TIMEOUT_INSTRUCTION_TRESHOLD)
@ -375,9 +382,9 @@ module Rhino
end end
@timeout_limit = limit @timeout_limit = limit
end end
attr_reader :start_time attr_reader :start_time
def check!(count = nil) def check!(count = nil)
@instruction_count += count if count @instruction_count += count if count
check_instruction_limit! check_instruction_limit!
@ -389,7 +396,7 @@ module Rhino
raise RunawayScriptError, "script exceeded allowable instruction count: #{instruction_limit}" raise RunawayScriptError, "script exceeded allowable instruction count: #{instruction_limit}"
end end
end end
def check_timeout_limit!(count = nil) def check_timeout_limit!(count = nil)
if timeout_limit if timeout_limit
elapsed_time = Time.now.to_f - start_time.to_f elapsed_time = Time.now.to_f - start_time.to_f
@ -410,17 +417,17 @@ module Rhino
end end
end end
end end
def reset! def reset!
@instruction_count = 0 @instruction_count = 0
@start_time = Time.now @start_time = Time.now
self self
end end
end end
end end
class ContextError < StandardError # :nodoc: class ContextError < StandardError # :nodoc:
end end
@ -429,5 +436,5 @@ module Rhino
class ScriptTimeoutError < ContextError # :nodoc: class ScriptTimeoutError < ContextError # :nodoc:
end end
end end