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

basic skeleton for more uniform treatment of handles.

This commit is contained in:
Charles Lowell 2011-04-08 09:54:57 -05:00
parent 0ffce72fe1
commit 54be41c883
4 changed files with 82 additions and 23 deletions

View file

@ -1,49 +1,73 @@
#include "rr.h"
#include "v8_ref.h"
#include "v8_handle.h"
using namespace v8;
v8_handle::v8_handle(Handle<void> handle) : handle(Persistent<void>::New(handle)) {}
v8_handle::~v8_handle() {
handle.Dispose();
handle.Clear();
}
namespace {
void gc_mark(v8_handle* handle) {}
void gc_free(v8_handle* handle) {
delete handle;
}
VALUE New(VALUE self, VALUE handle) {
return rr_v8_ref_create(self, rr_v8_handle(handle));
if (RTEST(handle)) {
v8_ref* ref = 0;
Data_Get_Struct(handle, struct v8_ref, ref);
return rr_v8_handle_new(self, ref->handle);
} else {
return rr_v8_handle_new(self, Handle<void>());
}
}
VALUE IsEmpty(VALUE self) {
return rr_v82rb(rr_v8_handle(self).IsEmpty());
return rr_v82rb(rr_v8_handle<void>(self).IsEmpty());
}
VALUE Clear(VALUE self) {
rr_v8_handle(self).Clear();
rr_v8_handle<void>(self).Clear();
return Qnil;
}
VALUE Dispose(VALUE self) {
rr_v8_handle(self).Dispose();
rr_v8_handle<void>(self).Dispose();
return Qnil;
}
void NoopWeakReferenceCallback(Persistent<Value> object, void* parameter) {}
VALUE MakeWeak(VALUE self) {
rr_v8_handle(self).MakeWeak(0, NoopWeakReferenceCallback);
rr_v8_handle<void>(self).MakeWeak(0, NoopWeakReferenceCallback);
return Qnil;
}
VALUE ClearWeak(VALUE self) {
rr_v8_handle(self).ClearWeak();
rr_v8_handle<void>(self).ClearWeak();
return Qnil;
}
VALUE IsNearDeath(VALUE self) {
return rr_v82rb(rr_v8_handle(self).IsNearDeath());
return rr_v82rb(rr_v8_handle<void>(self).IsNearDeath());
}
VALUE IsWeak(VALUE self) {
return rr_v82rb(rr_v8_handle(self).IsWeak());
return rr_v82rb(rr_v8_handle<void>(self).IsWeak());
}
VALUE NewContext(VALUE self) {
Persistent<Context> cxt(Context::New(0));
return rr_v8_handle_new(self, cxt);
cxt.Dispose();
}
}
void rr_init_handle() {
@ -56,5 +80,11 @@ void rr_init_handle() {
rr_define_method(HandleClass, "ClearWeak", ClearWeak, 0);
rr_define_method(HandleClass, "IsNearDeath", IsNearDeath, 0);
rr_define_method(HandleClass, "IsWeak", IsWeak, 0);
rr_define_singleton_method(HandleClass, "NewContext", NewContext, 0);
}
VALUE rr_v8_handle_new(VALUE klass, v8::Handle<void> handle) {
return Data_Wrap_Struct(klass, gc_mark, gc_free, new v8_handle(handle));
}

View file

@ -1,8 +1,22 @@
#ifndef _RR_V8_HANDLE_
#define _RR_V8_HANDLE_
#include <v8.h>
#include "ruby.h"
struct v8_handle {
v8_handle(v8::Handle<void> object);
virtual ~v8_handle();
v8::Persistent<void> handle;
};
void rr_init_handle();
VALUE rr_v8_handle_new(v8::Local<void>& handle);
VALUE rr_v8_handle_new(v8::Persistent<void>& handle);
template <class T> v8::Persistent<T>& rr_v8_handle(VALUE value) {
v8_handle* handle = 0;
Data_Get_Struct(value, struct v8_handle, handle);
return handle->handle;
}
VALUE rr_v8_handle_new(VALUE rbclass, v8::Handle<void> handle);
#endif

24
spec/ext/handle_spec.rb Normal file
View file

@ -0,0 +1,24 @@
require 'spec_helper'
describe V8::C::Handle do
it "can get a new context" do
cxt = c::Handle::NewContext()
cxt.IsEmpty().should be_false
cxt.MakeWeak()
gc
cxt.IsNearDeath().should be_true
# cxt.Clear()
cxt.IsEmpty().should be_true
end
def c
V8::C
end
def gc
while (!V8::C::V8::IdleNotification()); end
yield if block_given?
end
end

View file

@ -23,19 +23,12 @@ describe "Memory Usage" do
context "a ruby proxy for a JavaScript object" do
it "holds a strong reference to the JavaScript object" do
pending
cxt = V8::C::Context::New()
handle = c::Handle::New(cxt)
# pending
handle = c::Handle::New(c::Context::New())
handle.MakeWeak()
handle.IsWeak().should be_true
gc do
handle.IsEmpty().should be_false
handle.IsNearDeath().should be_false
handle.IsWeak().should be_true
end
cxt = nil
gc do
# handle.IsEmpty().should be_true
handle.IsNearDeath().should be_true
handle.IsEmpty().should be_true
end
end
end
@ -65,10 +58,8 @@ describe "Memory Usage" do
end
def gc
GC.start
while !V8::C::V8::IdleNotification();end
GC.start
while !V8::C::V8::IdleNotification();end
yield
end