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:
commit
6d667fd1b3
13 changed files with 237 additions and 25 deletions
|
@ -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) {}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {}
|
||||
|
|
|
@ -19,6 +19,7 @@ extern "C" {
|
|||
String::Init();
|
||||
Function::Init();
|
||||
Script::Init();
|
||||
ScriptOrigin::Init();
|
||||
Array::Init();
|
||||
External::Init();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
51
ext/v8/script-origin.cc
Normal 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
95
ext/v8/script-origin.h
Normal 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 */
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
38
spec/c/script_origin_spec.rb
Normal file
38
spec/c/script_origin_spec.rb
Normal 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
|
Loading…
Add table
Reference in a new issue