Class: RustyRacer::ExecJSRuntime::Context
- Inherits:
-
ExecJS::Runtime::Context
- Object
- ExecJS::Runtime::Context
- RustyRacer::ExecJSRuntime::Context
- Defined in:
- lib/rusty_racer/execjs.rb
Constant Summary collapse
- LOCATION =
filenamefor every JS run, so a thrown error's stack (which rusty_racer surfaces as the Ruby backtrace) reads "(execjs):line:col" — ExecJS's test suite asserts the backtrace mentions "(execjs):". '(execjs)'
Instance Method Summary collapse
-
#call(identifier, *args) ⇒ Object
Evaluate
identifierto a function and call it with the global object asthisand the (JSON-marshalled) args. -
#eval(source, _options = {}) ⇒ Object
Evaluate an expression and return its (JSON-projected) value.
-
#exec(source, _options = {}) ⇒ Object
Run statements in a function body and return what they
return(nil when nothing is returned), per ExecJS. -
#initialize(_runtime, source = '', _options = {}) ⇒ Context
constructor
A new instance of Context.
Constructor Details
#initialize(_runtime, source = '', _options = {}) ⇒ Context
Returns a new instance of Context.
32 33 34 35 36 37 38 39 40 41 |
# File 'lib/rusty_racer/execjs.rb', line 32 def initialize(_runtime, source = '', = {}) @isolate = RustyRacer::Isolate.new @context = @isolate.context # ExecJS guarantees a bare global (no browser/Node ambient): V8 installs a # default `console`, so drop it to match the contract (consumers attach # their own if needed), exactly as the mini_racer runtime does. @context.eval('delete globalThis.console') source = encode(source) translate { @context.eval(source, filename: LOCATION) } if /\S/.match?(source) end |
Instance Method Details
#call(identifier, *args) ⇒ Object
Evaluate identifier to a function and call it with the global object as
this and the (JSON-marshalled) args. identifier is arbitrary JS — a
name path ("a.b.fn"), a member expression, or a function literal — so it
is applied rather than looked up. The newline guards a trailing comment as
in eval/exec.
71 72 73 |
# File 'lib/rusty_racer/execjs.rb', line 71 def call(identifier, *args) eval("(#{encode(identifier)}\n).apply(this, #{JSON.generate(args)})") end |
#eval(source, _options = {}) ⇒ Object
Evaluate an expression and return its (JSON-projected) value. Blank source
is nil. The expression is parenthesised so a leading { reads as an
object literal (and a trailing // comment can't swallow the closing
parens — hence the newline), then routed through JSON.stringify for ExecJS
semantics.
56 57 58 59 60 61 62 63 64 |
# File 'lib/rusty_racer/execjs.rb', line 56 def eval(source, = {}) source = encode(source) return unless /\S/.match?(source) json = translate { @context.eval("JSON.stringify((#{source}\n))", filename: LOCATION) } # JSON.stringify yields `undefined` (-> nil here) for a function/undefined # result; otherwise a JSON string to parse back. json.nil? ? nil : JSON.parse(json) end |
#exec(source, _options = {}) ⇒ Object
Run statements in a function body and return what they return (nil when
nothing is returned), per ExecJS. The trailing newline before } ends any
// line comment the source closes with, so it can't eat the wrapper.
46 47 48 49 |
# File 'lib/rusty_racer/execjs.rb', line 46 def exec(source, = {}) source = encode(source) eval("(function(){#{source}\n})()") if /\S/.match?(source) end |