mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
start building out ruby interface
This commit is contained in:
parent
f5d62ec4a0
commit
a0af37906c
18 changed files with 192 additions and 16 deletions
|
@ -3,7 +3,8 @@
|
||||||
|
|
||||||
#include <ruby.h>
|
#include <ruby.h>
|
||||||
#include <v8.h>
|
#include <v8.h>
|
||||||
#include <stdio.h>
|
#include "v8_ref.h"
|
||||||
|
#include "v8_obj.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,7 +95,7 @@ class RubyValueDest {
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE pushObject(v8::Handle<v8::Object>& value) {
|
VALUE pushObject(v8::Handle<v8::Object>& value) {
|
||||||
return Qnil;
|
return V8_Ref_Create(V8_C_Object, value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,10 @@ template<class T, class R> class V8HandleSource {
|
||||||
~V8HandleSource() {}
|
~V8HandleSource() {}
|
||||||
|
|
||||||
R operator() (v8::Handle<v8::Value>& value) {
|
R operator() (v8::Handle<v8::Value>& value) {
|
||||||
|
|
||||||
|
if (value.IsEmpty()) {
|
||||||
|
return dest.pushNull();
|
||||||
|
}
|
||||||
|
|
||||||
if (value->IsUndefined()) {
|
if (value->IsUndefined()) {
|
||||||
return dest.pushNull();
|
return dest.pushNull();
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#include "v8_cxt.h"
|
#include "v8_cxt.h"
|
||||||
#include "v8_str.h"
|
#include "v8_str.h"
|
||||||
|
#include "v8_obj.h"
|
||||||
|
#include "v8_msg.h"
|
||||||
|
#include "v8_func.h"
|
||||||
#include "v8_script.h"
|
#include "v8_script.h"
|
||||||
#include "v8_template.h"
|
#include "v8_template.h"
|
||||||
#include "v8_standalone.h"
|
#include "v8_standalone.h"
|
||||||
|
@ -51,6 +54,15 @@ extern "C" {
|
||||||
rb_define_singleton_method(V8__C__ObjectTemplate, "new", (VALUE(*)(...))v8_ObjectTemplate_New, 0);
|
rb_define_singleton_method(V8__C__ObjectTemplate, "new", (VALUE(*)(...))v8_ObjectTemplate_New, 0);
|
||||||
|
|
||||||
VALUE V8__C__FunctionTemplate = rb_define_class_under(rb_mNative, "FunctionTemplate", V8__C__Template);
|
VALUE V8__C__FunctionTemplate = rb_define_class_under(rb_mNative, "FunctionTemplate", V8__C__Template);
|
||||||
rb_define_singleton_method(V8__C__FunctionTemplate, "new", (VALUE(*)(...))v8_FunctionTemplate_New, -1);
|
rb_define_singleton_method(V8__C__FunctionTemplate, "new", (VALUE(*)(...))v8_FunctionTemplate_New, -1);
|
||||||
|
rb_define_method(V8__C__FunctionTemplate, "GetFunction", (VALUE(*)(...))v8_FunctionTemplate_GetFunction, 0);
|
||||||
|
|
||||||
|
V8_C_Object = rb_define_class_under(rb_mNative, "Object", rb_cObject);
|
||||||
|
rb_define_singleton_method(V8_C_Object, "new", (VALUE(*)(...))v8_Object_New, 0);
|
||||||
|
rb_define_method(V8_C_Object, "Get", (VALUE(*)(...))v8_Object_Get, 1);
|
||||||
|
rb_define_method(V8_C_Object, "Set", (VALUE(*)(...))v8_Object_Set, 2);
|
||||||
|
|
||||||
|
V8_C_Message = rb_define_class_under(rb_mNative, "Message", rb_cObject);
|
||||||
|
V8_C_Function = rb_define_class_under(rb_mNative, "Function", V8_C_Object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
#include "v8_cxt.h"
|
#include "v8_cxt.h"
|
||||||
#include "ruby.h"
|
#include "v8_msg.h"
|
||||||
|
#include "converters.h"
|
||||||
|
|
||||||
using namespace v8;
|
using namespace v8;
|
||||||
|
|
||||||
|
@ -17,18 +17,31 @@ VALUE v8_Context_New(int argc, VALUE *argv, VALUE self) {
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE v8_cxt_Global(VALUE self) {
|
VALUE v8_cxt_Global(VALUE self) {
|
||||||
|
HandleScope handles;
|
||||||
|
convert_v8_to_rb_t v82rb;
|
||||||
Local<Context> cxt = V8_Ref_Get<Context>(self);
|
Local<Context> cxt = V8_Ref_Get<Context>(self);
|
||||||
cxt->Global();
|
Local<Value> global = *cxt->Global();
|
||||||
return Qnil;
|
return v82rb(global);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE v8_cxt_open(VALUE self) {
|
VALUE v8_cxt_open(VALUE self) {
|
||||||
HandleScope handles;
|
HandleScope handles;
|
||||||
|
TryCatch exceptions;
|
||||||
Local<Context> cxt = V8_Ref_Get<Context>(self);
|
Local<Context> cxt = V8_Ref_Get<Context>(self);
|
||||||
Context::Scope enter(cxt);
|
Context::Scope enter(cxt);
|
||||||
if (rb_block_given_p()) {
|
if (rb_block_given_p()) {
|
||||||
return rb_yield(self);
|
printf("<div>About to execute Ruby Block</div>");
|
||||||
|
VALUE result = rb_yield(self);
|
||||||
|
printf("<div>Ruby Block was executed</div>\n");
|
||||||
|
if (exceptions.HasCaught()) {
|
||||||
|
return V8_Wrap_Message(exceptions.Message());
|
||||||
|
} else {
|
||||||
|
printf("<div>No exception</div>");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
} else {
|
} else {
|
||||||
|
printf("<div>No block given!</div>");
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
#include "v8.h"
|
#include "v8.h"
|
||||||
#include "v8_ref.h"
|
#include "v8_ref.h"
|
||||||
|
|
||||||
|
extern VALUE rb_cV8;
|
||||||
|
extern VALUE V8_C_Object;
|
||||||
|
|
||||||
VALUE v8_Context_New(int argc, VALUE *argv, VALUE self);
|
VALUE v8_Context_New(int argc, VALUE *argv, VALUE self);
|
||||||
VALUE v8_cxt_Global(VALUE self);
|
VALUE v8_cxt_Global(VALUE self);
|
||||||
VALUE v8_cxt_open(VALUE self);
|
VALUE v8_cxt_open(VALUE self);
|
||||||
|
|
10
ext/v8/v8_func.cpp
Normal file
10
ext/v8/v8_func.cpp
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
#include "v8_func.h"
|
||||||
|
|
||||||
|
using namespace v8;
|
||||||
|
|
||||||
|
VALUE V8_C_Function;
|
||||||
|
|
||||||
|
VALUE V8_Wrap_Function(Handle<Function> f) {
|
||||||
|
return V8_Ref_Create(V8_C_Function, f);
|
||||||
|
}
|
11
ext/v8/v8_func.h
Normal file
11
ext/v8/v8_func.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef _RUBY_V8_FUNCTION_
|
||||||
|
#define _RUBY_V8_FUNCTION_
|
||||||
|
|
||||||
|
#include "v8.h"
|
||||||
|
#include "ruby.h"
|
||||||
|
#include "v8_ref.h"
|
||||||
|
|
||||||
|
extern VALUE V8_C_Function;
|
||||||
|
|
||||||
|
VALUE V8_Wrap_Function(v8::Handle<v8::Function> f);
|
||||||
|
#endif
|
11
ext/v8/v8_msg.cpp
Normal file
11
ext/v8/v8_msg.cpp
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
#include "v8_msg.h"
|
||||||
|
#include "v8_ref.h"
|
||||||
|
|
||||||
|
using namespace v8;
|
||||||
|
|
||||||
|
VALUE V8_C_Message;
|
||||||
|
|
||||||
|
VALUE V8_Wrap_Message(Handle<v8::Message> msg) {
|
||||||
|
return V8_Ref_Create(V8_C_Message, msg);
|
||||||
|
}
|
9
ext/v8/v8_msg.h
Normal file
9
ext/v8/v8_msg.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef _RUBY_V8_MESSAGE_
|
||||||
|
#define _RUBY_V8_MESSAGE_
|
||||||
|
|
||||||
|
#include "v8.h"
|
||||||
|
#include "ruby.h"
|
||||||
|
|
||||||
|
extern VALUE V8_C_Message;
|
||||||
|
VALUE V8_Wrap_Message(v8::Handle<v8::Message> msg);
|
||||||
|
#endif
|
31
ext/v8/v8_obj.cpp
Normal file
31
ext/v8/v8_obj.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include "v8_obj.h"
|
||||||
|
#include "v8_ref.h"
|
||||||
|
#include "converters.h"
|
||||||
|
|
||||||
|
using namespace v8;
|
||||||
|
|
||||||
|
VALUE V8_C_Object;
|
||||||
|
|
||||||
|
VALUE v8_Object_New(VALUE clazz) {
|
||||||
|
HandleScope handles;
|
||||||
|
return V8_Ref_Create(clazz, Object::New());
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE v8_Object_Get(VALUE self, VALUE key) {
|
||||||
|
HandleScope handles;
|
||||||
|
convert_rb_to_v8_t rb2v8;
|
||||||
|
convert_v8_to_rb_t v82rb;
|
||||||
|
Local<Object> obj = V8_Ref_Get<Object>(self);
|
||||||
|
VALUE keystr = rb_funcall(key,rb_intern("to_s"), 0);
|
||||||
|
Local<Value> value = obj->Get(rb2v8(keystr));
|
||||||
|
return v82rb(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE v8_Object_Set(VALUE self, VALUE key, VALUE value) {
|
||||||
|
HandleScope handles;
|
||||||
|
convert_rb_to_v8_t rb2v8;
|
||||||
|
Local<Object> obj = V8_Ref_Get<Object>(self);
|
||||||
|
VALUE keystr = rb_funcall(key, rb_intern("to_s"), 0);
|
||||||
|
obj->Set(rb2v8(keystr), rb2v8(value));
|
||||||
|
return Qnil;
|
||||||
|
}
|
11
ext/v8/v8_obj.h
Normal file
11
ext/v8/v8_obj.h
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef _RUBY_V8_OBJECT_
|
||||||
|
#define _RUBY_V8_OBJECT_
|
||||||
|
|
||||||
|
#include "ruby.h"
|
||||||
|
|
||||||
|
extern VALUE V8_C_Object;
|
||||||
|
|
||||||
|
VALUE v8_Object_New(VALUE clazz);
|
||||||
|
VALUE v8_Object_Get(VALUE self, VALUE key);
|
||||||
|
VALUE v8_Object_Set(VALUE self, VALUE key, VALUE value);
|
||||||
|
#endif
|
|
@ -1,6 +1,7 @@
|
||||||
#include <ruby.h>
|
#include <ruby.h>
|
||||||
#include <v8.h>
|
#include <v8.h>
|
||||||
#include "v8_ref.h"
|
#include "v8_ref.h"
|
||||||
|
#include "v8_func.h"
|
||||||
#include "v8_template.h"
|
#include "v8_template.h"
|
||||||
#include "converters.h"
|
#include "converters.h"
|
||||||
|
|
||||||
|
@ -49,3 +50,9 @@ VALUE v8_FunctionTemplate_New(int argc, VALUE *argv, VALUE self) {
|
||||||
return V8_Ref_Create(self,t,code);
|
return V8_Ref_Create(self,t,code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE v8_FunctionTemplate_GetFunction(VALUE self) {
|
||||||
|
HandleScope handles;
|
||||||
|
Local<FunctionTemplate> t = V8_Ref_Get<FunctionTemplate>(self);
|
||||||
|
return V8_Wrap_Function(t->GetFunction());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,5 +6,6 @@ VALUE v8_Template_Set(VALUE self, VALUE name, VALUE value);
|
||||||
VALUE v8_ObjectTemplate_New(VALUE clazz);
|
VALUE v8_ObjectTemplate_New(VALUE clazz);
|
||||||
|
|
||||||
VALUE v8_FunctionTemplate_New(int argc, VALUE *argv, VALUE self);
|
VALUE v8_FunctionTemplate_New(int argc, VALUE *argv, VALUE self);
|
||||||
|
VALUE v8_FunctionTemplate_GetFunction(VALUE self);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -4,5 +4,7 @@ $:.unshift(File.dirname(__FILE__)) unless
|
||||||
module V8
|
module V8
|
||||||
VERSION = '0.4.0'
|
VERSION = '0.4.0'
|
||||||
require 'v8/v8' #native glue
|
require 'v8/v8' #native glue
|
||||||
|
require 'v8/to'
|
||||||
require 'v8/context'
|
require 'v8/context'
|
||||||
|
require 'v8/object'
|
||||||
end
|
end
|
|
@ -8,24 +8,39 @@ module V8
|
||||||
|
|
||||||
def open(&block)
|
def open(&block)
|
||||||
@native.open do
|
@native.open do
|
||||||
block.call(self) if block
|
block.call(self).tap do |result|
|
||||||
|
# puts ERB::Util.h(result)
|
||||||
|
raise JavascriptError.new(result) if result.kind_of?(C::Message)
|
||||||
|
end
|
||||||
end if block_given?
|
end if block_given?
|
||||||
end
|
end
|
||||||
|
|
||||||
def eval(javascript)
|
def eval(javascript)
|
||||||
self.open do
|
source = V8::C::String.new(javascript.to_s)
|
||||||
source = V8::C::String.new(javascript.to_s)
|
script = V8::C::Script.new(source)
|
||||||
script = V8::C::Script.new(source)
|
To.ruby(script.Run())
|
||||||
script.Run()
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def evaluate(*args)
|
def evaluate(*args)
|
||||||
self.eval(*args)
|
self.eval(*args)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def []=(key, value)
|
||||||
|
value.tap do
|
||||||
|
@native.Global().tap do |scope|
|
||||||
|
scope.Set(key.to_s, To.v8(value))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def self.open(&block)
|
def self.open(&block)
|
||||||
new.open(&block)
|
new.open(&block)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class ContextError < StandardError
|
||||||
|
end
|
||||||
|
class JavascriptError < StandardError
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
12
lib/v8/object.rb
Normal file
12
lib/v8/object.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
module V8
|
||||||
|
class Object
|
||||||
|
def initialize(native)
|
||||||
|
@native = native
|
||||||
|
end
|
||||||
|
|
||||||
|
def [](key)
|
||||||
|
To.ruby(@native.Get(To.v8(key)))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
23
lib/v8/to.rb
Normal file
23
lib/v8/to.rb
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
|
||||||
|
module V8
|
||||||
|
module To
|
||||||
|
class << self
|
||||||
|
def ruby(value)
|
||||||
|
case value
|
||||||
|
when V8::C::Object then V8::Object.new(value)
|
||||||
|
else
|
||||||
|
value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def v8(value)
|
||||||
|
case value
|
||||||
|
when String then C::String.new(value)
|
||||||
|
when Proc then C::FunctionTemplate.new(&value).GetFunction()
|
||||||
|
else
|
||||||
|
value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6dbd4cd8edefb3e396dc6cdf90351f44f27297c9
|
Subproject commit 540f43d897b928539bbb49243e899294dff9a0b5
|
Loading…
Reference in a new issue