mirror of
https://github.com/rubyjs/mini_racer
synced 2023-03-27 23:21:28 -04:00
Adding a warmup
method on snapshots
Which maps to V8's `V8::WarmUpSnapshotDataBlob` (see http://v8.paulfryzel.com/docs/master/classv8_1_1_v8.html#abee465cc67755cfaacf0297c3093fb47) Added unit tests on it.
This commit is contained in:
parent
764a0846f5
commit
edeaa9d183
3 changed files with 72 additions and 1 deletions
|
@ -330,6 +330,27 @@ static VALUE rb_snapshot_load(VALUE self, VALUE str) {
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE rb_snapshot_warmup(VALUE self, VALUE str) {
|
||||
SnapshotInfo* snapshot_info;
|
||||
Data_Get_Struct(self, SnapshotInfo, snapshot_info);
|
||||
|
||||
init_v8();
|
||||
|
||||
StartupData cold_startup_data = {snapshot_info->data, snapshot_info->raw_size};
|
||||
StartupData warm_startup_data = V8::WarmUpSnapshotDataBlob(cold_startup_data, RSTRING_PTR(str));
|
||||
|
||||
if (warm_startup_data.data == NULL && warm_startup_data.raw_size == 0) {
|
||||
rb_raise(rb_eSnapshotError, "Could not warm up snapshot, most likely the source is incorrect");
|
||||
} else {
|
||||
delete[] snapshot_info->data;
|
||||
|
||||
snapshot_info->data = warm_startup_data.data;
|
||||
snapshot_info->raw_size = warm_startup_data.raw_size;
|
||||
}
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE rb_context_init_with_snapshot(VALUE self, VALUE snapshot) {
|
||||
ContextInfo* context_info;
|
||||
Data_Get_Struct(self, ContextInfo, context_info);
|
||||
|
@ -718,6 +739,7 @@ extern "C" {
|
|||
rb_define_alloc_func(rb_cExternalFunction, allocate_external_function);
|
||||
|
||||
rb_define_method(rb_cSnapshot, "size", (VALUE(*)(...))&rb_snapshot_size, 0);
|
||||
rb_define_method(rb_cSnapshot, "warmup", (VALUE(*)(...))&rb_snapshot_warmup, 1);
|
||||
rb_define_private_method(rb_cSnapshot, "load", (VALUE(*)(...))&rb_snapshot_load, 1);
|
||||
}
|
||||
|
||||
|
|
|
@ -116,8 +116,9 @@ module MiniRacer
|
|||
|
||||
end
|
||||
|
||||
# `size` and `warmup` public methods are defined in the C class
|
||||
class Snapshot
|
||||
def initialize(str)
|
||||
def initialize(str = '')
|
||||
# defined in the C class
|
||||
load(str)
|
||||
end
|
||||
|
|
|
@ -309,4 +309,52 @@ raise FooError, "I like foos"
|
|||
MiniRacer::Snapshot.new('var foo = bar;')
|
||||
end
|
||||
end
|
||||
|
||||
def test_an_empty_snapshot_is_valid
|
||||
MiniRacer::Snapshot.new('')
|
||||
MiniRacer::Snapshot.new
|
||||
end
|
||||
|
||||
def test_snapshots_can_be_warmed_up_with_no_side_effects
|
||||
# shamelessly insipired by https://github.com/v8/v8/blob/5.3.254/test/cctest/test-serialize.cc#L792-L854
|
||||
snapshot_source = <<-JS
|
||||
function f() { return Math.sin(1); }
|
||||
var a = 5;
|
||||
JS
|
||||
|
||||
snapshot = MiniRacer::Snapshot.new(snapshot_source)
|
||||
|
||||
warmump_source = <<-JS
|
||||
Math.tan(1);
|
||||
var a = f();
|
||||
Math.sin = 1;
|
||||
JS
|
||||
|
||||
snapshot.warmup(warmump_source)
|
||||
|
||||
context = MiniRacer::Context.new(snapshot: snapshot)
|
||||
|
||||
assert_equal 5, context.eval("a")
|
||||
assert_equal "function", context.eval("typeof(Math.sin)")
|
||||
end
|
||||
|
||||
def test_invalid_warmup_sources_throw_an_exception
|
||||
assert_raises(MiniRacer::SnapshotError) do
|
||||
MiniRacer::Snapshot.new('Math.sin = 1;').warmup('var a = Math.sin(1);')
|
||||
end
|
||||
end
|
||||
|
||||
def test_warming_up_with_invalid_source_does_not_affect_the_snapshot_internal_state
|
||||
snapshot = MiniRacer::Snapshot.new('Math.sin = 1;')
|
||||
|
||||
begin
|
||||
snapshot.warmup('var a = Math.sin(1);')
|
||||
rescue
|
||||
# do nothing
|
||||
end
|
||||
|
||||
context = MiniRacer::Context.new(snapshot: snapshot)
|
||||
|
||||
assert_equal 1, context.eval("Math.sin")
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue