README on runtime flags + more tests on them
Also changed the API for them.
This commit is contained in:
parent
42475db467
commit
3762c8c2fd
41
README.md
41
README.md
|
@ -88,6 +88,47 @@ puts context.eval("counter")
|
|||
|
||||
```
|
||||
|
||||
### V8 Runtime flags
|
||||
|
||||
It is possible to set V8 Runtime flags:
|
||||
|
||||
```ruby
|
||||
MiniRacer::Platform.set_flags! :noconcurrent_recompilation, max_inlining_levels: 10
|
||||
```
|
||||
|
||||
This can come in handy if you want to use MiniRacer with Unicorn, which doesn't seem to alwatys appreciate V8's liberal use of threading:
|
||||
```ruby
|
||||
MiniRacer::Platform.set_flags! :noconcurrent_recompilation, :noconcurrent_sweeping
|
||||
```
|
||||
|
||||
Or else to unlock experimental features in V8, for example tail recursion optimization:
|
||||
```ruby
|
||||
MiniRacer::Platform.set_flags! :harmony
|
||||
|
||||
js = <<-JS
|
||||
'use strict';
|
||||
var f = function f(n){
|
||||
if (n <= 0) {
|
||||
return 'foo';
|
||||
}
|
||||
return f(n - 1);
|
||||
}
|
||||
|
||||
f(1e6);
|
||||
JS
|
||||
|
||||
context = MiniRacer::Context.new
|
||||
|
||||
context.eval js
|
||||
# => "foo"
|
||||
```
|
||||
The same code without the harmony runtime flag results in a `MiniRacer::RuntimeError: RangeError: Maximum call stack size exceeded` exception.
|
||||
Please refer to http://node.green/ as a reference on other harmony features.
|
||||
|
||||
A list of all V8 runtime flags can be found using `node --v8-options`, or else by perusing [the V8 source code for flags (make sure to use the right version of V8)](https://github.com/v8/v8/blob/master/src/flag-definitions.h).
|
||||
|
||||
Note that runtime flags must be set before any other operation (e.g. creating a context, a snapshot or an isolate), otherwise an exception will be thrown.
|
||||
|
||||
## Performance
|
||||
|
||||
The `bench` folder contains benchmark.
|
||||
|
|
|
@ -60,7 +60,7 @@ static VALUE rb_cDateTime = Qnil;
|
|||
static Platform* current_platform = NULL;
|
||||
static std::mutex platform_lock;
|
||||
|
||||
static VALUE rb_platform_set_flag(VALUE _klass, VALUE flag_as_str) {
|
||||
static VALUE rb_platform_set_flag_as_str(VALUE _klass, VALUE flag_as_str) {
|
||||
bool platform_already_initialized = false;
|
||||
|
||||
platform_lock.lock();
|
||||
|
@ -775,7 +775,7 @@ extern "C" {
|
|||
rb_define_method(rb_cSnapshot, "warmup", (VALUE(*)(...))&rb_snapshot_warmup, 1);
|
||||
rb_define_private_method(rb_cSnapshot, "load", (VALUE(*)(...))&rb_snapshot_load, 1);
|
||||
|
||||
rb_define_singleton_method(rb_cPlatform, "set_flag!", (VALUE(*)(...))&rb_platform_set_flag, 1);
|
||||
rb_define_singleton_method(rb_cPlatform, "set_flag_as_str!", (VALUE(*)(...))&rb_platform_set_flag_as_str, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -40,8 +40,36 @@ module MiniRacer
|
|||
end
|
||||
end
|
||||
|
||||
# `::set_flag!` is defined in the C class
|
||||
class Platform; end
|
||||
# `::` is defined in the C class
|
||||
class Platform
|
||||
class << self
|
||||
def set_flags!(*args, **kwargs)
|
||||
flags_to_strings([args, kwargs]).each do |flag|
|
||||
# defined in the C class
|
||||
set_flag_as_str!(flag)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def flags_to_strings(flags)
|
||||
flags.flatten.map { |flag| flag_to_string(flag) }.flatten
|
||||
end
|
||||
|
||||
# normalize flags to strings, and adds leading dashes if needed
|
||||
def flag_to_string(flag)
|
||||
if flag.is_a?(Hash)
|
||||
flag.map do |key, value|
|
||||
"#{flag_to_string(key)} #{value}"
|
||||
end
|
||||
else
|
||||
str = flag.to_s
|
||||
str = "--#{str}" unless str.start_with?('--')
|
||||
str
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# eval is defined in the C class
|
||||
class Context
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
require 'test_helper'
|
||||
|
||||
class MiniRacerTest < Minitest::Test
|
||||
# see `test_platform_set_flags_works` below
|
||||
MiniRacer::Platform.set_flags! :use_strict
|
||||
|
||||
def test_that_it_has_a_version_number
|
||||
refute_nil ::MiniRacer::VERSION
|
||||
|
@ -25,7 +27,7 @@ class MiniRacerTest < Minitest::Test
|
|||
def test_object
|
||||
context = MiniRacer::Context.new
|
||||
# remember JavaScript is quirky {"1" : 1} magically turns to {1: 1} cause magic
|
||||
assert_equal({1 => 2, "two" => "two"}, context.eval('a={"1" : 2, "two" : "two"}'))
|
||||
assert_equal({1 => 2, "two" => "two"}, context.eval('var a={"1" : 2, "two" : "two"}; a'))
|
||||
end
|
||||
|
||||
def test_it_returns_runtime_error
|
||||
|
@ -77,7 +79,7 @@ class MiniRacerTest < Minitest::Test
|
|||
|
||||
def test_returns_javascript_function
|
||||
context = MiniRacer::Context.new
|
||||
assert_equal MiniRacer::JavaScriptFunction, context.eval("a = function(){}").class
|
||||
assert_same MiniRacer::JavaScriptFunction, context.eval("var a = function(){}; a").class
|
||||
end
|
||||
|
||||
def test_it_handles_malformed_js
|
||||
|
@ -108,18 +110,19 @@ class MiniRacerTest < Minitest::Test
|
|||
|
||||
def test_can_attach_functions
|
||||
context = MiniRacer::Context.new
|
||||
context.eval 'var adder'
|
||||
context.attach("adder", proc{|a,b| a+b})
|
||||
assert_equal 3, context.eval('adder(1,2)')
|
||||
end
|
||||
|
||||
def test_es6_arrow_functions
|
||||
context = MiniRacer::Context.new
|
||||
assert_equal 42, context.eval('adder=(x,y)=>x+y; adder(21,21);')
|
||||
assert_equal 42, context.eval('var adder=(x,y)=>x+y; adder(21,21);')
|
||||
end
|
||||
|
||||
def test_concurrent_access
|
||||
context = MiniRacer::Context.new
|
||||
context.eval('counter=0; plus=()=>counter++;')
|
||||
context.eval('var counter=0; var plus=()=>counter++;')
|
||||
|
||||
(1..10).map do
|
||||
Thread.new {
|
||||
|
@ -154,18 +157,21 @@ raise FooError, "I like foos"
|
|||
|
||||
def test_attached_on_object
|
||||
context = MiniRacer::Context.new
|
||||
context.eval 'var minion'
|
||||
context.attach("minion.speak", proc{"banana"})
|
||||
assert_equal "banana", context.eval("minion.speak()")
|
||||
end
|
||||
|
||||
def test_attached_on_nested_object
|
||||
context = MiniRacer::Context.new
|
||||
context.eval 'var minion'
|
||||
context.attach("minion.kevin.speak", proc{"banana"})
|
||||
assert_equal "banana", context.eval("minion.kevin.speak()")
|
||||
end
|
||||
|
||||
def test_return_arrays
|
||||
context = MiniRacer::Context.new
|
||||
context.eval 'var nose'
|
||||
context.attach("nose.type", proc{["banana",["nose"]]})
|
||||
assert_equal ["banana", ["nose"]], context.eval("nose.type()")
|
||||
end
|
||||
|
@ -259,13 +265,14 @@ raise FooError, "I like foos"
|
|||
|
||||
def test_can_attach_method
|
||||
context = MiniRacer::Context.new
|
||||
context.eval 'var Echo'
|
||||
context.attach("Echo.say", Echo.method(:say))
|
||||
assert_equal "hello", context.eval("Echo.say('hello')")
|
||||
end
|
||||
|
||||
def test_attach_error
|
||||
context = MiniRacer::Context.new
|
||||
context.eval("minion = 2")
|
||||
context.eval("var minion = 2")
|
||||
assert_raises do
|
||||
begin
|
||||
context.attach("minion.kevin.speak", proc{"banana"})
|
||||
|
@ -358,12 +365,53 @@ raise FooError, "I like foos"
|
|||
assert_equal 1, context.eval("Math.sin")
|
||||
end
|
||||
|
||||
def test_platform_set_flag_raises_an_exception_if_already_initialized
|
||||
def test_platform_set_flags_raises_an_exception_if_already_initialized
|
||||
# makes sure it's initialized
|
||||
MiniRacer::Snapshot.new
|
||||
|
||||
assert_raises(MiniRacer::PlatformAlreadyInitialized) do
|
||||
MiniRacer::Platform.set_flag!("--noconcurrent_recompilation")
|
||||
MiniRacer::Platform.set_flags! :noconcurrent_recompilation
|
||||
end
|
||||
end
|
||||
|
||||
def test_platform_set_flags_works
|
||||
context = MiniRacer::Context.new
|
||||
|
||||
assert_raises(MiniRacer::RuntimeError) do
|
||||
# should fail because of strict mode set for all these tests
|
||||
context.eval 'x = 28'
|
||||
end
|
||||
end
|
||||
|
||||
class TestPlatform < MiniRacer::Platform
|
||||
def self.public_flags_to_strings(flags)
|
||||
flags_to_strings(flags)
|
||||
end
|
||||
end
|
||||
|
||||
def test_platform_flags_to_strings
|
||||
flags = [
|
||||
:flag1,
|
||||
[[[:flag2]]],
|
||||
{key1: :value1},
|
||||
{key2: 42,
|
||||
key3: 8.7},
|
||||
'--i_already_have_leading_hyphens',
|
||||
[:'--me_too',
|
||||
'i_dont']
|
||||
]
|
||||
|
||||
expected_string_flags = [
|
||||
'--flag1',
|
||||
'--flag2',
|
||||
'--key1 value1',
|
||||
'--key2 42',
|
||||
'--key3 8.7',
|
||||
'--i_already_have_leading_hyphens',
|
||||
'--me_too',
|
||||
'--i_dont'
|
||||
]
|
||||
|
||||
assert_equal expected_string_flags, TestPlatform.public_flags_to_strings(flags)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue