Pass empty handles from Ruby.

This commit is contained in:
Charles Lowell 2012-06-11 05:03:51 -05:00
parent 32028f31fc
commit 6dbd647680
5 changed files with 40 additions and 1 deletions

View File

@ -27,6 +27,10 @@ namespace rr {
VALUE superclass = defineClass(supername);
this->value = defineClass(name, superclass);
}
ClassBuilder& ClassBuilder::defineConst(const char* name, VALUE value) {
rb_define_const(this->value, name, value);
return *this;
}
ClassBuilder& ClassBuilder::defineMethod(const char* name, VALUE (*impl)(int, VALUE*, VALUE)) {
rb_define_method(this->value, name, (VALUE (*)(...))impl, -1);
return *this;

View File

@ -316,6 +316,7 @@ public:
inline Value(v8::Handle<v8::Value> value) : Ref<v8::Value>(value) {}
virtual operator VALUE();
virtual operator v8::Handle<v8::Value>() const;
static VALUE Empty;
};
class Primitive: public Ref<v8::Primitive> {
@ -562,9 +563,12 @@ public:
inline Signature(VALUE value) : Ref<v8::Signature>(value) {}
};
class Template {
class Template : public Ref<v8::Template> {
public:
static void Init();
static VALUE Set(int argc, VALUE argv[], VALUE self);
inline Template(v8::Handle<v8::Template> t) : Ref<v8::Template>(t) {}
inline Template(VALUE value) : Ref<v8::Template>(value) {}
};
class ObjectTemplate : public Ref<v8::ObjectTemplate> {
@ -774,6 +778,7 @@ public:
ClassBuilder() {};
ClassBuilder(const char* name, VALUE superclass = rb_cObject);
ClassBuilder(const char* name, const char* supername);
ClassBuilder& defineConst(const char* name, VALUE value);
ClassBuilder& defineMethod(const char* name, VALUE (*impl)(int, VALUE*, VALUE));
ClassBuilder& defineMethod(const char* name, VALUE (*impl)(VALUE));
ClassBuilder& defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE));

View File

@ -2,8 +2,12 @@
namespace rr {
VALUE Value::Empty;
void Value::Init() {
Empty = rb_eval_string("Object.new");
ClassBuilder("Value").
defineConst("Empty", Empty).
defineMethod("IsUndefined", &IsUndefined).
defineMethod("IsNull", &IsNull).
defineMethod("IsTrue", &IsTrue).
@ -34,6 +38,7 @@ void Value::Init() {
defineMethod("Equals", &Equals).
defineMethod("StrictEquals", &StrictEquals)
.store(&Class);
rb_gc_register_address(&Empty);
}
VALUE Value::IsUndefined(VALUE self) {
@ -192,6 +197,9 @@ Value::operator VALUE() {
}
Value::operator v8::Handle<v8::Value>() const {
if (rb_equal(value,Empty)) {
return v8::Handle<v8::Value>();
}
switch (TYPE(value)) {
case T_FIXNUM:
return v8::Integer::New(NUM2INT(value));

View File

@ -1,7 +1,24 @@
class V8::Conversion
module Proc
def to_v8
template = V8::C::FunctionTemplate::New()
template.SetCallHandler(InvocationHandler.new, V8::C::External::New(self))
return template.GetFunction()
end
class InvocationHandler
def call(arguments)
context = V8::Context.current
proc = arguments.Data().Value()
args = ::Array.new(arguments.Length())
0.upto(args.length - 1) do |i|
args[i] = context.to_ruby arguments[i]
end
context.to_v8 proc.call(*args)
rescue Exception => e
warn "unhandled exception in ruby #{e.class}: #{e.message}"
nil
end
end
end
end

View File

@ -8,4 +8,9 @@ describe V8::C do
V8::C.send(name).should be constant
end
end
it "has a value for the Empty handle" do
V8::C::Value::Empty.should_not be_nil
V8::C::Value::Empty.should be V8::C::Value::Empty
end
end