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

scope[R]

Public Class Methods

default_factory() click to toggle source
# File lib/rhino/context.rb, line 53
def self.default_factory
  @@default_factory ||= ContextFactory.new
end
default_factory=(factory) click to toggle source
# File lib/rhino/context.rb, line 57
def self.default_factory=(factory)
  @@default_factory = factory
end
default_javascript_version() click to toggle source
# File lib/rhino/context.rb, line 71
def self.default_javascript_version
  @@default_javascript_version
end
default_javascript_version=(version) click to toggle source
# File lib/rhino/context.rb, line 75
def self.default_javascript_version=(version)
  @@default_javascript_version = version
end
default_optimization_level() click to toggle source
# File lib/rhino/context.rb, line 62
def self.default_optimization_level
  @@default_optimization_level
end
default_optimization_level=(level) click to toggle source
# File lib/rhino/context.rb, line 66
def self.default_optimization_level=(level)
  @@default_optimization_level = level
end
eval(javascript) click to toggle source
# File lib/rhino/context.rb, line 46
def eval(javascript)
  new.eval(javascript)
end
open(options = {}, &block) click to toggle source

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

[](key) click to toggle source

Read a value from the global scope of this context

# File lib/rhino/context.rb, line 125
def [](key)
  @scope[key]
end
[]=(key, val) click to toggle source

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
eval(source, source_name = "<eval>", line_number = 1) click to toggle source

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
factory() click to toggle source

Returns the ContextFactory used while creating this context.

# File lib/rhino/context.rb, line 120
def factory
  @native.getFactory
end
instruction_limit() click to toggle source
# File lib/rhino/context.rb, line 172
def instruction_limit
  restrictable? ? @native.instruction_limit : false
end
instruction_limit=(limit) click to toggle source

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
javascript_version() click to toggle source

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
Also aliased as: version
javascript_version=(version) click to toggle source

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
Also aliased as: version=
load(filename) click to toggle source

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
open(&block) click to toggle source

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
optimization_level() click to toggle source
# File lib/rhino/context.rb, line 205
def optimization_level
  @native.getOptimizationLevel
end
optimization_level=(level) click to toggle source

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
restrictable?() click to toggle source

Returns true if this context supports restrictions.

# File lib/rhino/context.rb, line 168
def restrictable?
  @native.is_a?(RestrictableContextFactory::Context)
end
timeout_limit() click to toggle source
# File lib/rhino/context.rb, line 188
def timeout_limit
  restrictable? ? @native.timeout_limit : false
end
timeout_limit=(limit) click to toggle source

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
version()
Alias for: javascript_version
version=(version)
Alias for: javascript_version=

Private Instance Methods

code_generation_error?(exception) click to toggle source
# 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
do_open() { |self| ... } click to toggle source
# File lib/rhino/context.rb, line 264
def do_open # :nodoc
  factory.enterContext(@native)
  begin
    yield self
  ensure
    factory.exit
  end
end