1
0
Fork 0
mirror of https://github.com/rubyjs/therubyracer synced 2023-03-27 23:21:42 -04:00

Merge pull request #3 from stormbreakerbg/implement-script-origin

Implement script origin
This commit is contained in:
Georgy Angelov 2015-07-09 16:20:01 +03:00
commit 6d667fd1b3
13 changed files with 237 additions and 25 deletions

View file

@ -3,7 +3,7 @@
#define EXTERNAL_H
namespace rr {
class External : Ref<v8::External> {
class External : public Ref<v8::External> {
public:
static void Init();
@ -13,6 +13,8 @@ namespace rr {
inline External(VALUE value) : Ref<v8::External>(value) {}
inline External(v8::Isolate* isolate, v8::Handle<v8::External> handle) :
Ref<v8::External>(isolate, handle) {}
inline External(v8::Isolate* isolate, v8::Handle<v8::Value> value) :
External(isolate, v8::Handle<v8::External>::Cast<v8::Value>(value)) {}
struct Container {
Container(VALUE v) : object(v) {}

View file

@ -12,7 +12,9 @@ namespace rr {
defineMethod("GetInferredName", &GetInferredName).
defineMethod("GetScriptLineNumber", &GetScriptLineNumber).
defineMethod("GetScriptColumnNumber", &GetScriptColumnNumber).
defineMethod("GetScriptId", &GetScriptId).
defineMethod("IsBuiltin", &IsBuiltin).
defineMethod("ScriptId", &ScriptId).
defineMethod("GetBoundFunction", &GetBoundFunction).
defineMethod("GetScriptOrigin", &GetScriptOrigin).
store(&Class);
@ -81,15 +83,32 @@ namespace rr {
return INT2FIX(function->GetScriptColumnNumber());
}
VALUE Function::GetScriptId(VALUE self) {
VALUE Function::IsBuiltin(VALUE self) {
Function function(self);
Locker lock(function);
return Bool(function->IsBuiltin());
}
VALUE Function::ScriptId(VALUE self) {
Function function(self);
Locker lock(function.getIsolate());
return INT2FIX(function->ScriptId());
}
VALUE Function::GetBoundFunction(VALUE self) {
Function function(self);
Locker lock(function);
return Value(function.getIsolate(), function->GetBoundFunction());
}
VALUE Function::GetScriptOrigin(VALUE self) {
return not_implemented("GetScriptOrigin");
Function function(self);
Locker lock(function);
return ScriptOrigin(function, function->GetScriptOrigin());
}
}

View file

@ -12,9 +12,12 @@ namespace rr {
static VALUE SetName(VALUE self, VALUE name);
static VALUE GetName(VALUE self);
static VALUE GetInferredName(VALUE self);
static VALUE GetDisplayName(VALUE self);
static VALUE GetScriptLineNumber(VALUE self);
static VALUE GetScriptColumnNumber(VALUE self);
static VALUE GetScriptId(VALUE self);
static VALUE IsBuiltin(VALUE self);
static VALUE ScriptId(VALUE self);
static VALUE GetBoundFunction(VALUE self);
static VALUE GetScriptOrigin(VALUE self);
inline Function(VALUE value) : Ref<v8::Function>(value) {}

View file

@ -19,6 +19,7 @@ extern "C" {
String::Init();
Function::Init();
Script::Init();
ScriptOrigin::Init();
Array::Init();
External::Init();

View file

@ -97,7 +97,7 @@ namespace rr {
isolate(isolate), cell(new v8::Persistent<T>(isolate, handle)) {}
virtual ~Holder() {
Isolate(isolate).scheduleDelete<T>(cell);
Isolate(isolate).scheduleReleaseObject<T>(cell);
}
v8::Isolate* isolate;

View file

@ -41,7 +41,8 @@ inline VALUE not_implemented(const char* message) {
// This one is named v8_string to avoid name collisions with C's string.h
#include "rr_string.h"
#include "function.h"
#include "script.h"
#include "script-origin.h"
#include "function.h"
#endif

51
ext/v8/script-origin.cc Normal file
View file

@ -0,0 +1,51 @@
#include "rr.h"
namespace rr {
VALUE ScriptOrigin::Class;
void ScriptOrigin::Init() {
ClassBuilder("ScriptOrigin").
defineSingletonMethod("new", &initialize).
defineMethod("ResourceName", &ResourceName).
defineMethod("ResourceLineOffset", &ResourceLineOffset).
defineMethod("ResourceColumnOffset", &ResourceColumnOffset).
defineMethod("ScriptID", &ScriptID).
defineMethod("SourceMapUrl", &SourceMapUrl).
store(&Class);
}
VALUE ScriptOrigin::initialize(int argc, VALUE argv[], VALUE self) {
Container* container = new Container();
rb_scan_args(argc, argv, "17",
&container->name,
&container->line_offset,
&container->column_offset,
&container->is_shared_cross_origin,
&container->script_id,
&container->is_embedder_debug_script,
&container->source_map_url,
&container->is_opaque);
return ScriptOrigin(container);
}
VALUE ScriptOrigin::ResourceName(VALUE self) {
return ScriptOrigin(self).container->name;
}
VALUE ScriptOrigin::ResourceLineOffset(VALUE self) {
return ScriptOrigin(self).container->line_offset;
}
VALUE ScriptOrigin::ResourceColumnOffset(VALUE self) {
return ScriptOrigin(self).container->column_offset;
}
VALUE ScriptOrigin::ScriptID(VALUE self) {
return ScriptOrigin(self).container->script_id;
}
VALUE ScriptOrigin::SourceMapUrl(VALUE self) {
return ScriptOrigin(self).container->source_map_url;
}
}

95
ext/v8/script-origin.h Normal file
View file

@ -0,0 +1,95 @@
// -*- mode: c++ -*-
#ifndef SCRIPT_ORIGIN_H
#define SCRIPT_ORIGIN_H
namespace rr {
class ScriptOrigin {
struct Container {
inline Container() {}
Container(VALUE name_,
VALUE line_offset_,
VALUE column_offset_,
VALUE is_shared_cross_origin_,
VALUE script_id_,
VALUE is_embedder_debug_script_,
VALUE source_map_url_,
VALUE is_opaque_) :
name(name_),
line_offset(line_offset_),
column_offset(column_offset_),
is_shared_cross_origin(is_shared_cross_origin_),
script_id(script_id_),
is_embedder_debug_script(is_embedder_debug_script_),
source_map_url(source_map_url_),
is_opaque(is_opaque_) {}
VALUE name;
VALUE line_offset;
VALUE column_offset;
VALUE is_shared_cross_origin; //option
VALUE script_id;
VALUE is_embedder_debug_script; //option
VALUE source_map_url;
VALUE is_opaque; //option
};
struct Integer : public Equiv {
Integer(v8::Handle<v8::Integer> value) :
Equiv(INT2FIX(value->IntegerValue())) {
}
};
public:
static void Init();
ScriptOrigin(VALUE value) {
Data_Get_Struct(value, struct Container, container);
}
ScriptOrigin(Container* container_) :
container(container_) {
}
ScriptOrigin(v8::Isolate* isolate, v8::ScriptOrigin origin) :
ScriptOrigin(new Container(
Value(isolate, origin.ResourceName()),
Integer(origin.ResourceLineOffset()),
Integer(origin.ResourceColumnOffset()),
Bool(origin.Options().IsSharedCrossOrigin()),
Integer(origin.ScriptID()),
Bool(origin.Options().IsEmbedderDebugScript()),
Value(isolate, origin.SourceMapUrl()),
Bool(origin.Options().IsOpaque()))) {
}
static void mark(Container* container) {
rb_gc_mark(container->name);
rb_gc_mark(container->line_offset);
rb_gc_mark(container->column_offset);
rb_gc_mark(container->script_id);
rb_gc_mark(container->source_map_url);
rb_gc_mark(container->is_shared_cross_origin);
rb_gc_mark(container->is_embedder_debug_script);
rb_gc_mark(container->is_opaque);
}
static VALUE initialize(int argc, VALUE argv[], VALUE self);
static void deallocate(Container* container) {
delete container;
}
inline operator VALUE() {
return Data_Wrap_Struct(Class, &mark, &deallocate, container);
}
static VALUE ResourceName(VALUE self);
static VALUE ResourceLineOffset(VALUE self);
static VALUE ResourceColumnOffset(VALUE self);
static VALUE ScriptID(VALUE self);
static VALUE SourceMapUrl(VALUE self);
static VALUE Class;
private:
Container* container;
};
}
#endif /* SCRIPT_ORIGIN_H */

View file

@ -1,7 +1,6 @@
#include "rr.h"
namespace rr {
void Script::Init() {
ClassBuilder("Script").
defineSingletonMethod("Compile", &Compile).
@ -12,11 +11,6 @@ namespace rr {
store(&Class);
// TODO
// ClassBuilder("ScriptOrigin").
// defineSingletonMethod("new", &ScriptOrigin::initialize).
// store(&ScriptOrigin::Class);
// TODO
// ClassBuilder("ScriptData").
// defineSingletonMethod("PreCompile", &ScriptData::PreCompile).
@ -27,6 +21,7 @@ namespace rr {
// store(&ScriptData::Class);
}
VALUE Script::Compile(int argc, VALUE argv[], VALUE self) {
VALUE source, rb_context, origin;
rb_scan_args(argc, argv, "21", &source, &rb_context, &origin);
@ -44,5 +39,4 @@ namespace rr {
return Value::handleToRubyObject(context->GetIsolate(), Script(self)->Run());
}
}

View file

@ -1,6 +1,9 @@
// -*- mode: c++ -*-
#ifndef RR_SCRIPT
#define RR_SCRIPT
#include "rr.h"
namespace rr {
class Script : public Ref<v8::Script> {
@ -13,7 +16,5 @@ namespace rr {
inline Script(VALUE value) : Ref<v8::Script>(value) {}
inline Script(v8::Isolate* isolate, v8::Handle<v8::Script> script) : Ref<v8::Script>(isolate, script) {}
};
}
#endif

View file

@ -166,10 +166,9 @@ namespace rr {
return Qfalse;
}
// TODO
// if (handle->IsExternal()) {
// return External((v8::Handle<v8::External>)v8::External::Cast(*handle));
// }
if (handle->IsExternal()) {
return External(isolate, handle);
}
if (handle->IsUint32()) {
return UInt32(handle->Uint32Value());

View file

@ -3,6 +3,14 @@ require 'c_spec_helper'
describe V8::C::Function do
requires_v8_context
it "has a script origin" do
fn = run '(function() { return "foo" })'
origin = fn.GetScriptOrigin()
expect(origin.ResourceName().ToString().Utf8Value()).to eql 'undefined'
expect(origin.ResourceLineOffset()).to eql 0
expect(origin.ResourceColumnOffset()).to eql 0
end
it 'can be called' do
fn = run '(function() { return "foo" })'
expect(fn.Call(@ctx.Global, []).Utf8Value).to eq 'foo'
@ -26,12 +34,12 @@ describe V8::C::Function do
expect(fn.NewInstance.Get(V8::C::String.NewFromUtf8(@isolate, 'foo')).Utf8Value).to eq 'foo'
end
# it 'can be called as a constructor with arguments' do
# fn = run '(function(foo) {this.foo = foo})'
# object = fn.NewInstance([V8::C::String.NewFromUtf8(@isolate, 'bar')])
it 'can be called as a constructor with arguments' do
fn = run '(function(foo) {this.foo = foo})'
object = fn.NewInstance([V8::C::String.NewFromUtf8(@isolate, 'bar')])
# expect(object.Get(V8::C::String.NewFromUtf8(@isolate, 'foo')).Utf8Value).to eq 'bar'
# end
expect(object.Get(V8::C::String.NewFromUtf8(@isolate, 'foo')).Utf8Value).to eq 'bar'
end
# TODO
# it 'doesn\'t kill the world if invoking it throws a javascript exception' do

View file

@ -0,0 +1,38 @@
require 'c_spec_helper'
describe V8::C::ScriptOrigin do
requires_v8_context
describe "with only a name" do
let(:origin) { V8::C::ScriptOrigin.new V8::C::String::NewFromUtf8(@isolate, "bob.js") }
it "it hase a resource name" do
expect(origin.ResourceName().Utf8Value).to eql "bob.js"
end
it "has nil for all the other values" do
expect(origin.ResourceLineOffset()).to be_nil
expect(origin.ResourceColumnOffset()).to be_nil
expect(origin.ScriptID()).to be_nil
expect(origin.SourceMapUrl()).to be_nil
end
end
describe "with all the other options" do
let(:origin) do
V8::C::ScriptOrigin.new(
V8::C::String::NewFromUtf8(@isolate, "bob.js"), 5, 25,
true, 100, true,
V8::C::String::NewFromUtf8(@isolate, "http://foo/bob.js.map"),
false
)
end
it "maps the correct values" do
expect(origin.ResourceName().Utf8Value()).to eql 'bob.js'
expect(origin.ResourceLineOffset()).to eql 5
expect(origin.ResourceColumnOffset()).to eql 25
expect(origin.ScriptID()).to eql 100
expect(origin.SourceMapUrl().Utf8Value()).to eql "http://foo/bob.js.map"
end
end
end