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:
parent
314817fbea
commit
3879db8769
13 changed files with 79 additions and 140 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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=)
|
Loading…
Add table
Add a link
Reference in a new issue