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:
parent
0ffce72fe1
commit
54be41c883
4 changed files with 82 additions and 23 deletions
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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
24
spec/ext/handle_spec.rb
Normal 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
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue