mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
ability to compile ScriptData to speed compilation
This commit is contained in:
parent
4a977ac1ee
commit
71a74e4da2
4 changed files with 121 additions and 6 deletions
51
ext/v8/rr.h
51
ext/v8/rr.h
|
@ -4,6 +4,9 @@
|
|||
#include <v8.h>
|
||||
#include <ruby.h>
|
||||
#include <vector>
|
||||
#ifdef HAVE_RUBY_ENCODING_H
|
||||
#include "ruby/encoding.h"
|
||||
#endif
|
||||
|
||||
namespace rr {
|
||||
|
||||
|
@ -70,6 +73,28 @@ private:
|
|||
T defaultValue;
|
||||
};
|
||||
|
||||
/**
|
||||
* A pointer to V8 object managed by Ruby
|
||||
*/
|
||||
|
||||
template <class T> class Pointer {
|
||||
public:
|
||||
inline Pointer(T* t) : pointer(t) {};
|
||||
inline Pointer() {};
|
||||
inline operator T*() {return pointer;}
|
||||
inline T* operator ->() {return pointer;}
|
||||
inline operator VALUE() {
|
||||
return Data_Wrap_Struct(Class, 0, &release, pointer);
|
||||
}
|
||||
static void release(T* pointer) {
|
||||
delete pointer;
|
||||
}
|
||||
static VALUE Class;
|
||||
protected:
|
||||
T* pointer;
|
||||
};
|
||||
template <class T> VALUE Pointer<T>::Class;
|
||||
|
||||
/**
|
||||
* A Reference to a V8 managed object
|
||||
*/
|
||||
|
@ -196,10 +221,34 @@ private:
|
|||
};
|
||||
};
|
||||
|
||||
class ScriptOrigin : public Pointer<v8::ScriptOrigin> {
|
||||
public:
|
||||
inline ScriptOrigin(v8::ScriptOrigin* o) : Pointer<v8::ScriptOrigin>(o) {};
|
||||
inline ScriptOrigin(VALUE value) {
|
||||
Data_Get_Struct(value, class v8::ScriptOrigin, pointer);
|
||||
}
|
||||
|
||||
static VALUE initialize(int argc, VALUE argv[], VALUE self);
|
||||
};
|
||||
|
||||
class ScriptData : public Pointer<v8::ScriptData> {
|
||||
public:
|
||||
inline ScriptData(v8::ScriptData* d) : Pointer<v8::ScriptData>(d) {};
|
||||
inline ScriptData(VALUE value) {
|
||||
Data_Get_Struct(value, class v8::ScriptData, pointer);
|
||||
}
|
||||
|
||||
static VALUE PreCompile(VALUE self, VALUE input, VALUE length);
|
||||
static VALUE New(VALUE self, VALUE data, VALUE length);
|
||||
static VALUE Length(VALUE self);
|
||||
static VALUE Data(VALUE self);
|
||||
static VALUE HasError(VALUE self);
|
||||
};
|
||||
|
||||
class Script : public Ref<v8::Script> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE New(VALUE klass, VALUE source, VALUE filename);
|
||||
static VALUE New(int argc, VALUE argv[], VALUE self);
|
||||
static VALUE Run(VALUE self);
|
||||
|
||||
inline Script(VALUE value) : Ref<v8::Script>(value) {}
|
||||
|
|
|
@ -7,10 +7,62 @@ void Script::Init() {
|
|||
defineSingletonMethod("New", &New).
|
||||
defineMethod("Run", &Run).
|
||||
store(&Class);
|
||||
ClassBuilder("ScriptOrigin").
|
||||
defineSingletonMethod("new", &ScriptOrigin::initialize).
|
||||
store(&ScriptOrigin::Class);
|
||||
ClassBuilder("ScriptData").
|
||||
defineSingletonMethod("PreCompile", &ScriptData::PreCompile).
|
||||
defineSingletonMethod("New", &ScriptData::New).
|
||||
defineMethod("Length", &ScriptData::Length).
|
||||
defineMethod("Data", &ScriptData::Data).
|
||||
defineMethod("HasError", &ScriptData::HasError).
|
||||
store(&ScriptData::Class);
|
||||
}
|
||||
|
||||
VALUE Script::New(VALUE klass, VALUE source, VALUE filename) {
|
||||
return Script(v8::Script::New(String(source), Value(filename)));
|
||||
VALUE ScriptOrigin::initialize(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE name; VALUE line_offset; VALUE column_offset;
|
||||
rb_scan_args(argc, argv, "12", &name, &line_offset, &column_offset);
|
||||
v8::Handle<v8::Integer> loff = v8::Integer::New(RTEST(line_offset) ? NUM2INT(line_offset) : 0);
|
||||
v8::Handle<v8::Integer> coff = v8::Integer::New(RTEST(column_offset) ? NUM2INT(column_offset) : 0);
|
||||
return ScriptOrigin(new v8::ScriptOrigin(*String(name), loff, coff));
|
||||
}
|
||||
|
||||
VALUE ScriptData::PreCompile(VALUE self, VALUE input, VALUE length) {
|
||||
#ifdef HAVE_RUBY_ENCODING_H
|
||||
if (!rb_equal(rb_enc_from_encoding(rb_utf8_encoding()), rb_obj_encoding(input))) {
|
||||
rb_warn("ScriptData::Precompile only accepts UTF-8 encoded source, not: %s", RSTRING_PTR(rb_inspect(rb_obj_encoding(input))));
|
||||
}
|
||||
#endif
|
||||
return ScriptData(v8::ScriptData::PreCompile(RSTRING_PTR(input), NUM2INT(length)));
|
||||
}
|
||||
VALUE ScriptData::New(VALUE self, VALUE data, VALUE length) {
|
||||
return ScriptData(v8::ScriptData::New(RSTRING_PTR(data), NUM2INT(length)));
|
||||
}
|
||||
VALUE ScriptData::Length(VALUE self) {
|
||||
return ScriptData(self)->Length();
|
||||
}
|
||||
VALUE ScriptData::Data(VALUE self) {
|
||||
ScriptData data(self);
|
||||
#ifdef HAVE_RUBY_ENCODING_H
|
||||
return rb_enc_str_new(data->Data(), data->Length(), rb_enc_find("BINARY"));
|
||||
#else
|
||||
return rb_str_new(data->Data(), data->Length());
|
||||
#endif
|
||||
}
|
||||
|
||||
VALUE ScriptData::HasError(VALUE self) {
|
||||
return ScriptData(self)->HasError();
|
||||
}
|
||||
|
||||
VALUE Script::New(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE source; VALUE origin; VALUE pre_data; VALUE script_data;
|
||||
rb_scan_args(argc, argv, "13", &source, &origin, &pre_data, &script_data);
|
||||
if (argc == 2) {
|
||||
VALUE filename = origin;
|
||||
return Script(v8::Script::New(String(source), Value(filename)));
|
||||
} else {
|
||||
return Script(v8::Script::New(String(source), ScriptOrigin(origin), ScriptData(pre_data), String(script_data)));
|
||||
}
|
||||
}
|
||||
|
||||
VALUE Script::Run(VALUE self) {
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#include "rr.h"
|
||||
#ifdef HAVE_RUBY_ENCODING_H
|
||||
#include "ruby/encoding.h"
|
||||
#endif
|
||||
|
||||
namespace rr {
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# encoding: UTF-8
|
||||
require 'spec_helper'
|
||||
|
||||
describe V8::C::Script do
|
||||
|
@ -8,4 +9,20 @@ describe V8::C::Script do
|
|||
result = script.Run()
|
||||
result.should be_kind_of V8::C::Array
|
||||
end
|
||||
|
||||
it "can accept precompiled script data" do
|
||||
source = "7 * 6"
|
||||
name = V8::C::String::New("<spec>")
|
||||
origin = V8::C::ScriptOrigin.new(name)
|
||||
data = V8::C::ScriptData::PreCompile(source, source.length)
|
||||
data.HasError().should be_false
|
||||
script = V8::C::Script::New(V8::C::String::New(source), origin, data)
|
||||
script.Run().should eql 42
|
||||
end
|
||||
|
||||
it "can detect errors in the script data" do
|
||||
source = "^ = ;"
|
||||
data = V8::C::ScriptData::PreCompile(source, source.length)
|
||||
data.HasError().should be_true
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue