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 <v8.h>
|
||||
#include <stdio.h>
|
||||
#include "v8_ref.h"
|
||||
#include "v8_obj.h"
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
|
@ -94,7 +95,7 @@ class RubyValueDest {
|
|||
}
|
||||
|
||||
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() {}
|
||||
|
||||
R operator() (v8::Handle<v8::Value>& value) {
|
||||
|
||||
if (value.IsEmpty()) {
|
||||
return dest.pushNull();
|
||||
}
|
||||
|
||||
if (value->IsUndefined()) {
|
||||
return dest.pushNull();
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include "v8_cxt.h"
|
||||
#include "v8_str.h"
|
||||
#include "v8_obj.h"
|
||||
#include "v8_msg.h"
|
||||
#include "v8_func.h"
|
||||
#include "v8_script.h"
|
||||
#include "v8_template.h"
|
||||
#include "v8_standalone.h"
|
||||
|
@ -51,6 +54,15 @@ extern "C" {
|
|||
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);
|
||||
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 "ruby.h"
|
||||
#include "v8_msg.h"
|
||||
#include "converters.h"
|
||||
|
||||
using namespace v8;
|
||||
|
||||
|
@ -17,18 +17,31 @@ VALUE v8_Context_New(int argc, VALUE *argv, VALUE self) {
|
|||
}
|
||||
|
||||
VALUE v8_cxt_Global(VALUE self) {
|
||||
HandleScope handles;
|
||||
convert_v8_to_rb_t v82rb;
|
||||
Local<Context> cxt = V8_Ref_Get<Context>(self);
|
||||
cxt->Global();
|
||||
return Qnil;
|
||||
Local<Value> global = *cxt->Global();
|
||||
return v82rb(global);
|
||||
}
|
||||
|
||||
VALUE v8_cxt_open(VALUE self) {
|
||||
HandleScope handles;
|
||||
TryCatch exceptions;
|
||||
Local<Context> cxt = V8_Ref_Get<Context>(self);
|
||||
Context::Scope enter(cxt);
|
||||
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 {
|
||||
printf("<div>No block given!</div>");
|
||||
return Qnil;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
#include "v8.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_cxt_Global(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 <v8.h>
|
||||
#include "v8_ref.h"
|
||||
#include "v8_func.h"
|
||||
#include "v8_template.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);
|
||||
}
|
||||
|
||||
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_FunctionTemplate_New(int argc, VALUE *argv, VALUE self);
|
||||
VALUE v8_FunctionTemplate_GetFunction(VALUE self);
|
||||
|
||||
#endif
|
|
@ -4,5 +4,7 @@ $:.unshift(File.dirname(__FILE__)) unless
|
|||
module V8
|
||||
VERSION = '0.4.0'
|
||||
require 'v8/v8' #native glue
|
||||
require 'v8/to'
|
||||
require 'v8/context'
|
||||
require 'v8/object'
|
||||
end
|
|
@ -8,24 +8,39 @@ module V8
|
|||
|
||||
def open(&block)
|
||||
@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
|
||||
|
||||
def eval(javascript)
|
||||
self.open do
|
||||
source = V8::C::String.new(javascript.to_s)
|
||||
script = V8::C::Script.new(source)
|
||||
script.Run()
|
||||
end
|
||||
source = V8::C::String.new(javascript.to_s)
|
||||
script = V8::C::Script.new(source)
|
||||
To.ruby(script.Run())
|
||||
end
|
||||
|
||||
def evaluate(*args)
|
||||
self.eval(*args)
|
||||
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)
|
||||
new.open(&block)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ContextError < StandardError
|
||||
end
|
||||
class JavascriptError < StandardError
|
||||
|
||||
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