class Rhino::Context
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 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 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 Context.open do |cxt| cxt['num'] = 10 cxt.eval('num') # => 10 cxt.eval('++num') # => 11 end cxt.eval('num') # => 5 end
Notes¶ ↑
While there are many similarities between Rhino::Context
and Java::org.mozilla.javascript.Context, they are not the same thing and should not be confused.
Constants
- CODE_GENERATION_ERROR_MESSAGE
- CODE_GENERATION_TRACE_CLASS_NAME
- CODE_GENERATION_TRACE_METHOD_NAME
Attributes
Public Class Methods
# File lib/rhino/context.rb, line 53 def self.default_factory @@default_factory ||= ContextFactory.new end
# File lib/rhino/context.rb, line 57 def self.default_factory=(factory) @@default_factory = factory end
# File lib/rhino/context.rb, line 71 def self.default_javascript_version @@default_javascript_version end
# File lib/rhino/context.rb, line 75 def self.default_javascript_version=(version) @@default_javascript_version = version end
# File lib/rhino/context.rb, line 62 def self.default_optimization_level @@default_optimization_level end
# File lib/rhino/context.rb, line 66 def self.default_optimization_level=(level) @@default_optimization_level = level end
# File lib/rhino/context.rb, line 46 def eval(javascript) new.eval(javascript) end
initalize a new context with a fresh set of standard objects. All operations on the context should be performed in the block that is passed.
# File lib/rhino/context.rb, line 42 def open(options = {}, &block) new(options).open(&block) end
Public Instance Methods
Read a value from the global scope of this context
# File lib/rhino/context.rb, line 125 def [](key) @scope[key] 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.
# File lib/rhino/context.rb, line 131 def []=(key, val) @scope[key] = val end
Evaluate a string of javascript in this context:
-
source
- the javascript source code to evaluate. This can be either a string or an IO object. -
source_name
- associated name for this source code. Mainly useful for backtraces. -
line_number
- associate this number with the first line of executing source. Mainly useful for backtraces
# File lib/rhino/context.rb, line 139 def eval(source, source_name = "<eval>", line_number = 1) open do 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 Rhino.to_ruby(result) end end
Returns the ContextFactory used while creating this context.
# File lib/rhino/context.rb, line 120 def factory @native.getFactory end
# File lib/rhino/context.rb, line 172 def instruction_limit restrictable? ? @native.instruction_limit : false end
Set the maximum number of instructions that this context will execute. If this instruction limit is exceeded, then a #Rhino::RunawayScriptError will be raised.
# File lib/rhino/context.rb, line 179 def instruction_limit=(limit) if restrictable? @native.instruction_limit = limit else raise "setting an instruction_limit has no effect on this context, use " << "Context.open(:restrictable => true) to gain a restrictable instance" end end
Get the JS
interpreter version. Returns a number e.g. 1.7, nil if unknown and 0 for default.
# File lib/rhino/context.rb, line 225 def javascript_version case const_value = @native.getLanguageVersion when -1 then nil # VERSION_UNKNOWN when 0 then 0 # VERSION_DEFAULT else const_value / 100.0 # VERSION_1_1 (1.1 = 110 / 100) end end
Sets interpreter mode a.k.a. JS
language version e.g. 1.7 (if supported).
# File lib/rhino/context.rb, line 235 def javascript_version=(version) const = version.to_s.gsub('.', '_').upcase const = "VERSION_#{const}" if const[0, 7] != 'VERSION' if JS::Context.constants.find { |c| c.to_s == const } const_value = JS::Context.const_get(const) @native.setLanguageVersion(const_value) const_value else @native.setLanguageVersion(JS::Context::VERSION_DEFAULT) nil end end
Read the contents of filename
and evaluate it as javascript. Returns the result of evaluating the javascript. e.g.
Context.open
do |cxt|
cxt.load("path/to/some/lib.js")
end
# File lib/rhino/context.rb, line 161 def load(filename) File.open(filename) do |file| evaluate file, filename, 1 end end
Enter this context for operations. Some methods such as eval() will fail unless the context is open.
# File lib/rhino/context.rb, line 251 def open(&block) do_open(&block) rescue JS::RhinoException => e if code_generation_error?(e) Rhino.warn "[INFO] Rhino byte-code generation failed forcing #{@native} into interpreted mode" self.optimization_level = -1 retry end raise Rhino::JSError.new(e) end
# File lib/rhino/context.rb, line 205 def optimization_level @native.getOptimizationLevel end
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. By using the -1 optimization level, you tell Rhino
to run in interpretative mode, taking a hit to performance but escaping the Java
bytecode limit.
# File lib/rhino/context.rb, line 213 def optimization_level=(level) if JS::Context.isValidOptimizationLevel(level) @native.setOptimizationLevel(level) level else @native.setOptimizationLevel(0) nil end end
Returns true if this context supports restrictions.
# File lib/rhino/context.rb, line 168 def restrictable? @native.is_a?(RestrictableContextFactory::Context) end
# File lib/rhino/context.rb, line 188 def timeout_limit restrictable? ? @native.timeout_limit : false end
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 context is still attempted to run code, a #Rhino::ScriptTimeoutError will be raised.
# File lib/rhino/context.rb, line 196 def timeout_limit=(limit) if restrictable? @native.timeout_limit = limit else raise "setting an timeout_limit has no effect on this context, use " << "Context.open(:restrictable => true) to gain a restrictable instance" end end
Private Instance Methods
# File lib/rhino/context.rb, line 279 def code_generation_error?(exception) # :nodoc if exception.class == Rhino::JS::EvaluatorException if exception.message.index(CODE_GENERATION_ERROR_MESSAGE) return true end # NOTE: unfortunately Rhino localizes the error messages! # and the ClassFileFormatException is not kept as a cause class_name = CODE_GENERATION_TRACE_CLASS_NAME method_name = CODE_GENERATION_TRACE_METHOD_NAME for trace in exception.getStackTrace() if class_name == trace.class_name && method_name == trace.method_name return true end end end false end
# File lib/rhino/context.rb, line 264 def do_open # :nodoc factory.enterContext(@native) begin yield self ensure factory.exit end end