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

use methods, not direct storage to access constants

This commit is contained in:
Charles Lowell 2011-04-11 13:32:14 -05:00
parent 314817fbea
commit 3879db8769
13 changed files with 79 additions and 140 deletions

View file

@ -34,9 +34,15 @@ VALUE rr_define_const(const char *name, VALUE value) {
return value;
}
VALUE rr_const_get(const char *name) {
VALUE V8 = rb_define_module("V8");
VALUE V8_C = rb_define_module_under(V8, "C");
return rb_const_get(V8_C, rb_intern(name));
}
VALUE rr_v82rb(Handle<Value> value) {
if (value.IsEmpty()) {
return rr_cV8_C_Empty;
return rr_v8_value_empty();
}
if (value->IsUndefined() || value->IsNull()) {
return Qnil;

View file

@ -10,6 +10,7 @@
VALUE rr_define_class(const char *name, VALUE superclass = rb_cObject);
VALUE rr_define_module(const char *name);
VALUE rr_define_const(const char *name, VALUE value);
VALUE rr_const_get(const char *name);
VALUE rr_v82rb(v8::Handle<v8::Value> value);
VALUE rr_v82rb(v8::Handle<v8::Boolean> value);

View file

@ -37,7 +37,7 @@ namespace {
}
void rr_init_v8_array() {
ArrayClass = rr_define_class("Array", rr_cV8_C_Object);
ArrayClass = rr_define_class("Array", rr_v8_object_class());
rr_define_singleton_method(ArrayClass, "New", New, -1);
rr_define_method(ArrayClass, "Length", Length, 0);
rr_define_method(ArrayClass, "CloneElementAt", CloneElementAt, 1);

View file

@ -23,7 +23,7 @@ namespace {
}
void rr_init_v8_date() {
DateClass = rr_define_class("Date", rr_cV8_C_Value);
DateClass = rr_define_class("Date", rr_v8_value_class());
rr_define_singleton_method(DateClass, "New", New, 1);
rr_define_method(DateClass, "NumberValue", NumberValue, 0);
}

View file

@ -33,7 +33,7 @@ namespace {
}
void rr_init_v8_external() {
ExternalClass = rr_define_class("External", rr_cV8_C_Value);
ExternalClass = rr_define_class("External", rr_v8_value_class());
references = rb_hash_new();
rb_define_const(ExternalClass, "OBJECTS_REFERENCED_FROM_WITHIN_V8", references);
rr_define_singleton_method(ExternalClass, "New", New, 1);

View file

@ -37,7 +37,7 @@ namespace {
for (int i = 0; i < argc; i++) {
argv[i] = args->Get(i);
}
return rr_v8_handle_new(rr_cV8_C_Object, function->NewInstance(argc, argv));
return rr_v8_handle_new(rr_v8_object_class(), function->NewInstance(argc, argv));
}
VALUE GetName(VALUE self) {
HandleScope scope;
@ -55,7 +55,7 @@ namespace {
}
void rr_init_function() {
FunctionClass = rr_define_class("Function", rr_cV8_C_Object);
FunctionClass = rr_define_class("Function", rr_v8_object_class());
rr_define_method(FunctionClass, "Call", Call, 2);
rr_define_method(FunctionClass, "NewInstance", NewInstance, 1);
rr_define_method(FunctionClass, "GetName", GetName, 0);

View file

@ -8,14 +8,14 @@ using namespace v8;
#include <cstdio>
VALUE rr_cV8_C_Object;
namespace {
VALUE ObjectClass;
Persistent<Object>& unwrap(VALUE object) {
return rr_v8_handle<Object>(object);
}
VALUE Get(VALUE self, VALUE key) {
HandleScope handles;
Persistent<Object> obj(unwrap(self));
@ -25,7 +25,7 @@ namespace {
return rr_v82rb(obj->Get(rr_rb2v8(key)->ToString()));
}
}
VALUE New(VALUE rbclass) {
HandleScope handles;
if (!Context::InContext()) {
@ -34,7 +34,7 @@ namespace {
}
return rr_v8_handle_new(rbclass, Object::New());
}
VALUE Set(VALUE self, VALUE key, VALUE value) {
HandleScope handles;
Persistent<Object> obj = unwrap(self);
@ -47,7 +47,7 @@ namespace {
VALUE GetPropertyNames(VALUE self) {
HandleScope handles;
Persistent<Object> object = unwrap(self);
Persistent<Object> object = unwrap(self);
Local<Value> names = object->GetPropertyNames();
return rr_v82rb(names);
}
@ -75,21 +75,25 @@ namespace {
}
}
VALUE rr_v8_object_class() {
return ObjectClass;
}
void rr_init_object() {
rr_cV8_C_Object = rr_define_class("Object", rr_cV8_C_Value);
rr_define_singleton_method(rr_cV8_C_Object, "New", New, 0);
rr_define_method(rr_cV8_C_Object, "Get", Get, 1);
rr_define_method(rr_cV8_C_Object, "Set", Set, 2);
rr_define_method(rr_cV8_C_Object, "GetPropertyNames", GetPropertyNames, 0);
rr_define_method(rr_cV8_C_Object, "GetHiddenValue", GetHiddenValue, 1);
rr_define_method(rr_cV8_C_Object, "SetHiddenValue", SetHiddenValue, 2);
rr_define_method(rr_cV8_C_Object, "GetPrototype", GetPrototype, 0);
rr_define_method(rr_cV8_C_Object, "SetPrototype", SetPrototype, 1);
ObjectClass = rr_define_class("Object", rr_v8_value_class());
rr_define_singleton_method(ObjectClass, "New", New, 0);
rr_define_method(ObjectClass, "Get", Get, 1);
rr_define_method(ObjectClass, "Set", Set, 2);
rr_define_method(ObjectClass, "GetPropertyNames", GetPropertyNames, 0);
rr_define_method(ObjectClass, "GetHiddenValue", GetHiddenValue, 1);
rr_define_method(ObjectClass, "SetHiddenValue", SetHiddenValue, 2);
rr_define_method(ObjectClass, "GetPrototype", GetPrototype, 0);
rr_define_method(ObjectClass, "SetPrototype", SetPrototype, 1);
}
VALUE rr_reflect_v8_object(Handle<Value> value) {
Local<Object> object(Object::Cast(*value));
Local<Value> peer = object->GetHiddenValue(String::NewSymbol("TheRubyRacer::RubyObject"));
return peer.IsEmpty() ? rr_v8_handle_new(rr_cV8_C_Object, object) : (VALUE)External::Unwrap(peer);
return peer.IsEmpty() ? rr_v8_handle_new(ObjectClass, object) : (VALUE)External::Unwrap(peer);
}

View file

@ -3,9 +3,9 @@
#include "rr.h"
extern VALUE rr_cV8_C_Object;
void rr_init_object();
VALUE rr_v8_object_class();
VALUE rr_reflect_v8_object(v8::Handle<v8::Value> value);
#endif

View file

@ -43,7 +43,7 @@ VALUE rr_reflect_v8_string(Handle<Value> value) {
}
void rr_init_string() {
StringClass = rr_define_class("String", rr_cV8_C_Value);
StringClass = rr_define_class("String", rr_v8_value_class());
rr_define_singleton_method(StringClass, "New", New, 1);
rr_define_singleton_method(StringClass, "NewSymbol", NewSymbol, 1);
rr_define_method(StringClass, "Utf8Value", Utf8Value, 0);

View file

@ -3,11 +3,14 @@
using namespace v8;
namespace {
VALUE ValueClass;
Persistent<Value>& unwrap(VALUE value) {
return rr_v8_handle<Value>(value);
}
VALUE IsEmpty(VALUE value) {
return value == rr_cV8_C_Empty ? Qtrue : Qfalse;
return value == rr_v8_value_empty() ? Qtrue : Qfalse;
}
VALUE IsUndefined(VALUE self) {
HandleScope scope;
@ -123,45 +126,50 @@ namespace {
}
}
VALUE rr_cV8_C_Value;
VALUE rr_cV8_C_Empty;
VALUE rr_v8_value_class() {
return ValueClass;
}
VALUE rr_v8_value_empty() {
return rr_const_get("Empty");
}
void rr_init_value() {
rr_cV8_C_Value = rr_define_class("Value");
rr_cV8_C_Empty = rr_define_const("Empty", rr_v8_handle_new(rr_cV8_C_Value, Handle<Value>()));
ValueClass = rr_define_class("Value");
rr_define_const("Empty", rr_v8_handle_new(ValueClass, Handle<Value>()));
rr_define_method(rr_cV8_C_Value, "IsEmpty", IsEmpty, 0);
rr_define_method(rr_cV8_C_Value, "IsUndefined", IsUndefined, 0);
rr_define_method(rr_cV8_C_Value, "IsNull", IsNull, 0);
rr_define_method(rr_cV8_C_Value, "IsTrue", IsTrue, 0);
rr_define_method(rr_cV8_C_Value, "IsFalse", IsFalse, 0);
rr_define_method(rr_cV8_C_Value, "IsString", IsString, 0);
rr_define_method(rr_cV8_C_Value, "IsFunction", IsFunction, 0);
rr_define_method(rr_cV8_C_Value, "IsArray", IsArray, 0);
rr_define_method(rr_cV8_C_Value, "IsObject", IsObject, 0);
rr_define_method(rr_cV8_C_Value, "IsBoolean", IsBoolean, 0);
rr_define_method(rr_cV8_C_Value, "IsNumber", IsNumber, 0);
rr_define_method(rr_cV8_C_Value, "IsExternal", IsExternal, 0);
rr_define_method(rr_cV8_C_Value, "IsInt32", IsInt32, 0);
rr_define_method(rr_cV8_C_Value, "IsUint32", IsUint32, 0);
rr_define_method(rr_cV8_C_Value, "IsDate", IsDate, 0);
rr_define_method(ValueClass, "IsEmpty", IsEmpty, 0);
rr_define_method(ValueClass, "IsUndefined", IsUndefined, 0);
rr_define_method(ValueClass, "IsNull", IsNull, 0);
rr_define_method(ValueClass, "IsTrue", IsTrue, 0);
rr_define_method(ValueClass, "IsFalse", IsFalse, 0);
rr_define_method(ValueClass, "IsString", IsString, 0);
rr_define_method(ValueClass, "IsFunction", IsFunction, 0);
rr_define_method(ValueClass, "IsArray", IsArray, 0);
rr_define_method(ValueClass, "IsObject", IsObject, 0);
rr_define_method(ValueClass, "IsBoolean", IsBoolean, 0);
rr_define_method(ValueClass, "IsNumber", IsNumber, 0);
rr_define_method(ValueClass, "IsExternal", IsExternal, 0);
rr_define_method(ValueClass, "IsInt32", IsInt32, 0);
rr_define_method(ValueClass, "IsUint32", IsUint32, 0);
rr_define_method(ValueClass, "IsDate", IsDate, 0);
rr_define_method(rr_cV8_C_Value, "ToBoolean", ToBoolean, 0);
rr_define_method(rr_cV8_C_Value, "ToNumber", ToNumber, 0);
rr_define_method(rr_cV8_C_Value, "ToString", ToString, 0);
rr_define_method(rr_cV8_C_Value, "ToDetailString", ToDetailString, 0);
rr_define_method(rr_cV8_C_Value, "ToObject", ToObject, 0);
rr_define_method(rr_cV8_C_Value, "ToInteger", ToInteger, 0);
rr_define_method(rr_cV8_C_Value, "ToUint32", ToUint32, 0);
rr_define_method(rr_cV8_C_Value, "ToArrayIndex", ToArrayIndex, 0);
rr_define_method(ValueClass, "ToBoolean", ToBoolean, 0);
rr_define_method(ValueClass, "ToNumber", ToNumber, 0);
rr_define_method(ValueClass, "ToString", ToString, 0);
rr_define_method(ValueClass, "ToDetailString", ToDetailString, 0);
rr_define_method(ValueClass, "ToObject", ToObject, 0);
rr_define_method(ValueClass, "ToInteger", ToInteger, 0);
rr_define_method(ValueClass, "ToUint32", ToUint32, 0);
rr_define_method(ValueClass, "ToArrayIndex", ToArrayIndex, 0);
rr_define_method(rr_cV8_C_Value, "Equals", Equals, 1);
rr_define_method(rr_cV8_C_Value, "StrictEquals", StrictEquals, 1);
rr_define_method(ValueClass, "Equals", Equals, 1);
rr_define_method(ValueClass, "StrictEquals", StrictEquals, 1);
rr_define_method(rr_cV8_C_Value, "BooleanValue", BooleanValue, 0);
rr_define_method(rr_cV8_C_Value, "NumberValue", NumberValue, 0);
rr_define_method(ValueClass, "BooleanValue", BooleanValue, 0);
rr_define_method(ValueClass, "NumberValue", NumberValue, 0);
}
VALUE rr_wrap_v8_value(Handle<Value>& value) {
return rr_v8_handle_new(rr_cV8_C_Value, value);
return rr_v8_handle_new(ValueClass, value);
}

View file

@ -3,8 +3,8 @@
#include "rr.h"
extern VALUE rr_cV8_C_Value;
extern VALUE rr_cV8_C_Empty;
void rr_init_value();
VALUE rr_wrap_v8_value(v8::Handle<v8::Value>& value);
VALUE rr_v8_value_class();
VALUE rr_v8_value_empty();
#endif

View file

@ -8,16 +8,6 @@ describe V8::C::Handle do
@cxt = V8::Context.new
end
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

View file

@ -1,70 +0,0 @@
require 'spec_helper'
require 'weakref'
describe "Memory Usage" do
context "the low level C interface" do
context "at the very minimum" do
it "does not leak a context" do
weak :context, V8::C::Context::New()
end
it "does not leak a simple object either" do
cxt = V8::C::Context::New()
cxt.Enter()
begin
weak :object, V8::C::Object::New()
ensure
cxt.Exit()
end
end
end
context "a ruby proxy for a JavaScript object" do
it "holds a strong reference to the JavaScript object" do
# pending
handle = c::Handle::New(c::Context::New())
handle.MakeWeak()
handle.IsWeak().should be_true
gc do
handle.IsEmpty().should be_true
end
end
end
end
before(:all) {@stress = GC.stress; GC.stress = true}
after(:all) {GC.stress = @stress}
before do
@refs = {}
end
after do
gc do
for name, ref in @refs
if ref.weakref_alive?
fail "reference #{name} was not garbage collected"
end
end
end
end
private
def weak(name, ref)
@refs[name] = WeakRef.new(ref)
end
def gc
while !V8::C::V8::IdleNotification();end
GC.start
yield
end
def c
V8::C
end
end if GC.respond_to?(:stress=)