mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
support for accessors, equivalence classes
This commit is contained in:
parent
72068651f9
commit
7f659ef385
7 changed files with 457 additions and 26 deletions
190
benchmarks.rb
Normal file
190
benchmarks.rb
Normal file
|
@ -0,0 +1,190 @@
|
|||
require "v8"
|
||||
require "Benchmark"
|
||||
|
||||
TIMES=10
|
||||
OBJECTS=100
|
||||
|
||||
|
||||
js= <<JS
|
||||
|
||||
function createTest()
|
||||
{
|
||||
var test = {};
|
||||
test.objects = [];
|
||||
test.seed = 49734321;
|
||||
test.summ;
|
||||
|
||||
test.random = function()
|
||||
{
|
||||
// Robert Jenkins' 32 bit integer hash function.
|
||||
test.seed = ((test.seed + 0x7ed55d16) + (test.seed << 12)) & 0xffffffff;
|
||||
test.seed = ((test.seed ^ 0xc761c23c) ^ (test.seed >>> 19)) & 0xffffffff;
|
||||
test.seed = ((test.seed + 0x165667b1) + (test.seed << 5)) & 0xffffffff;
|
||||
test.seed = ((test.seed + 0xd3a2646c) ^ (test.seed << 9)) & 0xffffffff;
|
||||
test.seed = ((test.seed + 0xfd7046c5) + (test.seed << 3)) & 0xffffffff;
|
||||
test.seed = ((test.seed ^ 0xb55a4f09) ^ (test.seed >>> 16)) & 0xffffffff;
|
||||
return (test.seed & 0xfffffff) / 0x10000000;
|
||||
};
|
||||
|
||||
test.init = function()
|
||||
{
|
||||
test.objects = [];
|
||||
for(var i=0; i<#{OBJECTS}; i++)
|
||||
{
|
||||
var hash = {};
|
||||
for(var j=0; j<10; j++)
|
||||
{
|
||||
var isString = test.random();
|
||||
var key = "str" + test.random();
|
||||
var value;
|
||||
if(isString < 0.5)
|
||||
value = "str" + test.random();
|
||||
else
|
||||
value = test.random();
|
||||
hash[key] = value;
|
||||
}
|
||||
test.objects[i] = hash;
|
||||
}
|
||||
return test.objects.length;
|
||||
}
|
||||
|
||||
test.findSum = function()
|
||||
{
|
||||
test.summ = 0;
|
||||
var length = test.objects.length;
|
||||
for(var i=0; i<length; i++)
|
||||
{
|
||||
var hash = test.objects[i];
|
||||
for (var k in hash)
|
||||
{
|
||||
if (hash.hasOwnProperty(k) && (typeof(hash[k]) == "number"))
|
||||
{
|
||||
test.summ += hash[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
return test.summ;
|
||||
};
|
||||
|
||||
test.finalCheck = function()
|
||||
{
|
||||
var summ = 0;
|
||||
var length = test.objects.length;
|
||||
for(var i=0; i<length; i++)
|
||||
{
|
||||
var hash = test.objects[i];
|
||||
for (var k in hash)
|
||||
{
|
||||
if (hash.hasOwnProperty(k) && (typeof(hash[k]) == "number"))
|
||||
{
|
||||
summ += hash[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
return summ == -test.summ;
|
||||
};
|
||||
|
||||
test.getObject = function(index)
|
||||
{
|
||||
if(!test.objects[index]) return {};
|
||||
return test.objects[index];
|
||||
}
|
||||
|
||||
test.setObject = function(index, object)
|
||||
{
|
||||
test.objects[index] = object;
|
||||
}
|
||||
|
||||
return test;
|
||||
}
|
||||
|
||||
JS
|
||||
|
||||
|
||||
|
||||
def profile
|
||||
# RubyProf.profile do
|
||||
Benchmark.realtime do
|
||||
yield
|
||||
end
|
||||
end
|
||||
|
||||
def get_res result
|
||||
#result.threads[0].top_method.total_time
|
||||
result.to_f
|
||||
end
|
||||
|
||||
|
||||
|
||||
def call_test(suite, name, times = 1)
|
||||
cxt = nil
|
||||
V8::C::HandleScope() do
|
||||
cxt = suite.CreationContext()
|
||||
cxt.Enter()
|
||||
times.times do
|
||||
test = suite.Get(V8::C::String::New(name))
|
||||
test.Call(suite, 0, [])
|
||||
end
|
||||
end
|
||||
ensure
|
||||
cxt.Exit() if cxt
|
||||
end
|
||||
|
||||
#RubyProf.measure_mode = RubyProf::CPU_TIME
|
||||
puts "init js context..."
|
||||
cxt = V8::Context.new
|
||||
cxt.eval(js)
|
||||
|
||||
suite = cxt.eval('var test = createTest(); test;')
|
||||
|
||||
puts "run init test"
|
||||
result =profile do
|
||||
call_test suite, 'init', TIMES
|
||||
end
|
||||
|
||||
puts "init time: #{get_res(result) / TIMES} sec."
|
||||
|
||||
puts "run findSum test"
|
||||
call_test(suite, 'init')
|
||||
|
||||
result =profile do
|
||||
call_test suite, 'findSum', TIMES
|
||||
end
|
||||
|
||||
puts "findSum time: #{get_res(result) / TIMES} sec."
|
||||
|
||||
|
||||
puts "run Objects iversion in ruby test"
|
||||
call_test suite, 'init'
|
||||
|
||||
result =profile do
|
||||
cxt.native.Enter()
|
||||
V8::C::HandleScope() do
|
||||
TIMES.times do |j|
|
||||
for i in 0..(OBJECTS-1) do
|
||||
obj = suite.Get(V8::C::String::New("objects")).Get(i)
|
||||
names = obj.GetPropertyNames()
|
||||
for k in 0..names.Length() - 1 do
|
||||
name = names.Get(k)
|
||||
value = obj.Get(name)
|
||||
if value.instance_of? Float
|
||||
value = value * -1
|
||||
end
|
||||
suite.Get(V8::C::String::New("objects")).Set(i, obj)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
cxt.native.Exit()
|
||||
end
|
||||
|
||||
puts "Objects time: #{get_res(result) / TIMES} sec."
|
||||
|
||||
puts "run finalCheck test"
|
||||
call_test suite, 'init'
|
||||
|
||||
result =profile do
|
||||
call_test suite, 'finalCheck', TIMES
|
||||
end
|
||||
|
||||
puts "final check time: #{get_res(result) / TIMES} sec."
|
|
@ -12,9 +12,14 @@ namespace rr {
|
|||
store(&Info::Class);
|
||||
}
|
||||
|
||||
Accessor::Accessor(VALUE get, VALUE set, VALUE data) {
|
||||
Accessor::Accessor(VALUE getter, VALUE setter, VALUE data_) : get(getter), set(setter), data(data_) {}
|
||||
|
||||
Accessor::Accessor(VALUE get, VALUE set, VALUE query, VALUE deleter, VALUE enumerator, VALUE data) {
|
||||
this->get = get;
|
||||
this->set = set;
|
||||
this->query = query;
|
||||
this->deleter = deleter;
|
||||
this->enumerator = enumerator;
|
||||
this->data = data;
|
||||
}
|
||||
|
||||
|
@ -28,14 +33,6 @@ namespace rr {
|
|||
}
|
||||
}
|
||||
|
||||
Accessor::operator v8::AccessorGetter() {
|
||||
return &Getter;
|
||||
}
|
||||
|
||||
Accessor::operator v8::AccessorSetter() {
|
||||
return RTEST(this->set) ? &Setter : 0;
|
||||
}
|
||||
|
||||
Accessor::operator v8::Handle<v8::Value>() {
|
||||
v8::Local<v8::Object> wrapper = v8::Object::New();
|
||||
wrap(wrapper, 0, this->get);
|
||||
|
@ -55,6 +52,7 @@ namespace rr {
|
|||
return External::unwrap(external);
|
||||
}
|
||||
|
||||
|
||||
VALUE Accessor::Info::This(VALUE self) {
|
||||
return Object(Info(self)->This());
|
||||
}
|
||||
|
@ -67,13 +65,44 @@ namespace rr {
|
|||
return Accessor(Info(self)->Data()).data;
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Accessor::Getter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
|
||||
v8::Handle<v8::Value> Accessor::AccessorGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
|
||||
return Info(info).get(property);
|
||||
}
|
||||
|
||||
void Accessor::Setter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
|
||||
void Accessor::AccessorSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
|
||||
Info(info).set(property, value);
|
||||
}
|
||||
v8::Handle<v8::Value> Accessor::NamedPropertyGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
|
||||
return Info(info).get(property);
|
||||
}
|
||||
v8::Handle<v8::Value> Accessor::NamedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
|
||||
return Info(info).set(property, value);
|
||||
}
|
||||
v8::Handle<v8::Integer> Accessor::NamedPropertyQuery(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
|
||||
return Info(info).query(property);
|
||||
}
|
||||
v8::Handle<v8::Boolean> Accessor::NamedPropertyDeleter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
|
||||
return Info(info).remove(property);
|
||||
}
|
||||
v8::Handle<v8::Array> Accessor::NamedPropertyEnumerator(const v8::AccessorInfo& info) {
|
||||
return Info(info).enumerateNames();
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Accessor::IndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) {
|
||||
return Info(info).get(index);
|
||||
}
|
||||
v8::Handle<v8::Value> Accessor::IndexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
|
||||
return Info(info).set(index, value);
|
||||
}
|
||||
v8::Handle<v8::Integer> Accessor::IndexedPropertyQuery(uint32_t index, const v8::AccessorInfo& info) {
|
||||
return Info(info).query(index);
|
||||
}
|
||||
v8::Handle<v8::Boolean> Accessor::IndexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info) {
|
||||
return Info(info).remove(index);
|
||||
}
|
||||
v8::Handle<v8::Array> Accessor::IndexedPropertyEnumerator(const v8::AccessorInfo& info) {
|
||||
return Info(info).enumerateIndices();
|
||||
}
|
||||
|
||||
Accessor::Info::Info(const v8::AccessorInfo& info) {
|
||||
this->info = &info;
|
||||
|
@ -88,10 +117,51 @@ namespace rr {
|
|||
return Value(rb_funcall(accessor.get, rb_intern("call"), 2, (VALUE)String(property), (VALUE)*this));
|
||||
}
|
||||
|
||||
void Accessor::Info::set(v8::Local<v8::String> property, v8::Local<v8::Value> value) {
|
||||
v8::Handle<v8::Value> Accessor::Info::set(v8::Local<v8::String> property, v8::Local<v8::Value> value) {
|
||||
Accessor accessor(info->Data());
|
||||
rb_funcall(accessor.set, rb_intern("call"), 3, (VALUE)String(property), (VALUE)Value(value), (VALUE)*this);
|
||||
return Value(rb_funcall(accessor.set, rb_intern("call"), 3, (VALUE)String(property), (VALUE)Value(value), (VALUE)*this));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Integer> Accessor::Info::query(v8::Local<v8::String> property) {
|
||||
Accessor accessor(info->Data());
|
||||
return v8::Integer::New(Int(rb_funcall(accessor.query, rb_intern("call"), 2, (VALUE)String(property), (VALUE)*this)));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Boolean> Accessor::Info::remove(v8::Local<v8::String> property) {
|
||||
Accessor accessor(info->Data());
|
||||
return v8::Boolean::New(Bool(rb_funcall(accessor.deleter, rb_intern("call"), 2, (VALUE)String(property), (VALUE)*this)));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Array> Accessor::Info::enumerateNames() {
|
||||
Accessor accessor(info->Data());
|
||||
return Array(rb_funcall(accessor.enumerator, rb_intern("call"), 1, (VALUE)*this));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Accessor::Info::get(uint32_t index) {
|
||||
Accessor accessor(info->Data());
|
||||
return Value(rb_funcall(accessor.get, rb_intern("call"), 2, (VALUE)String(index), (VALUE)*this));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Value> Accessor::Info::set(uint32_t index, v8::Local<v8::Value> value) {
|
||||
Accessor accessor(info->Data());
|
||||
return Value(rb_funcall(accessor.set, rb_intern("call"), 3, UINT2NUM(index), (VALUE)Value(value), (VALUE)*this));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Integer> Accessor::Info::query(uint32_t index) {
|
||||
Accessor accessor(info->Data());
|
||||
return v8::Integer::New(Int(rb_funcall(accessor.query, rb_intern("call"), 2, UINT2NUM(index), (VALUE)*this)));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Boolean> Accessor::Info::remove(uint32_t index) {
|
||||
Accessor accessor(info->Data());
|
||||
return v8::Boolean::New(Bool(rb_funcall(accessor.deleter, rb_intern("call"), 2, UINT2NUM(index), (VALUE)*this)));
|
||||
}
|
||||
|
||||
v8::Handle<v8::Array> Accessor::Info::enumerateIndices() {
|
||||
Accessor accessor(info->Data());
|
||||
return Array(rb_funcall(accessor.enumerator, rb_intern("call"), 1, (VALUE)*this));
|
||||
}
|
||||
|
||||
Accessor::Info::operator VALUE() {
|
||||
return Data_Wrap_Struct(Class, 0, 0, (void*)this->info);
|
||||
}
|
||||
|
|
|
@ -21,12 +21,12 @@ namespace rr {
|
|||
} else {
|
||||
VALUE argc; VALUE argv;
|
||||
rb_scan_args(i,v,"2", &argc, &argv);
|
||||
std::vector< v8::Handle<v8::Value> > arguments(Int(argc));
|
||||
std::vector< v8::Handle<v8::Value> > arguments(Int(argc).toInt());
|
||||
return Object(Function(self)->NewInstance(Int(argc), Value::array(argv, arguments)));
|
||||
}
|
||||
}
|
||||
VALUE Function::Call(VALUE self, VALUE receiver, VALUE argc, VALUE argv) {
|
||||
std::vector< v8::Handle<v8::Value> > arguments(Int(argc));
|
||||
std::vector< v8::Handle<v8::Value> > arguments(Int(argc).toInt());
|
||||
return Value(Function(self)->Call(Object(receiver), Int(argc), Value::array(argv, arguments)));
|
||||
}
|
||||
|
||||
|
|
|
@ -121,7 +121,14 @@ VALUE Object::SetAccessor(int argc, VALUE* argv, VALUE self) {
|
|||
VALUE name; VALUE get; VALUE set; VALUE data; VALUE settings; VALUE attribs;
|
||||
rb_scan_args(argc, argv, "24", &name, &get, &set, &data, &settings, &attribs);
|
||||
Accessor access(get, set, data);
|
||||
return Bool(Object(self)->SetAccessor(String(name), access, access, access, AccessControl(settings), PropertyAttribute(attribs)));
|
||||
return Bool(Object(self)->SetAccessor(
|
||||
String(name),
|
||||
access.accessorGetter(),
|
||||
access.accessorSetter(),
|
||||
access,
|
||||
AccessControl(settings),
|
||||
PropertyAttribute(attribs))
|
||||
);
|
||||
}
|
||||
|
||||
Object::operator VALUE() {
|
||||
|
|
93
ext/v8/rr.h
93
ext/v8/rr.h
|
@ -8,12 +8,38 @@
|
|||
namespace rr {
|
||||
|
||||
#define Void(expr) expr; return Qnil;
|
||||
|
||||
VALUE Bool(bool b);
|
||||
int Int(VALUE v);
|
||||
uint32_t UInt32(VALUE num);
|
||||
VALUE not_implemented(const char* message);
|
||||
|
||||
class Equiv {
|
||||
public:
|
||||
Equiv(VALUE val) : value(val) {}
|
||||
inline operator VALUE() {return value;}
|
||||
protected:
|
||||
VALUE value;
|
||||
};
|
||||
|
||||
class Bool : public Equiv {
|
||||
public:
|
||||
Bool(VALUE val) : Equiv(val) {}
|
||||
Bool(bool b) : Equiv(b ? Qtrue : Qfalse) {}
|
||||
inline operator bool() {return RTEST(value);}
|
||||
};
|
||||
|
||||
class Int : public Equiv {
|
||||
public:
|
||||
Int(VALUE val) : Equiv(val) {}
|
||||
Int(int i) : Equiv(INT2FIX(i)) {}
|
||||
inline operator int() {return RTEST(value) ? NUM2INT(value) : 0;}
|
||||
inline int toInt() {return (int)*this;}
|
||||
};
|
||||
|
||||
class UInt32 : public Equiv {
|
||||
public:
|
||||
UInt32(VALUE val) : Equiv(val) {}
|
||||
UInt32(uint32_t ui) : Equiv(UINT2NUM(ui)) {}
|
||||
inline operator uint32_t() {return RTEST(value) ? NUM2UINT(value) : 0;}
|
||||
};
|
||||
|
||||
class GC {
|
||||
public:
|
||||
class Queue {
|
||||
|
@ -224,12 +250,25 @@ class Accessor {
|
|||
public:
|
||||
static void Init();
|
||||
Accessor(VALUE get, VALUE set, VALUE data);
|
||||
Accessor(VALUE get, VALUE set, VALUE query, VALUE deleter, VALUE enumerator, VALUE data);
|
||||
Accessor(v8::Handle<v8::Value> value);
|
||||
operator v8::AccessorGetter();
|
||||
operator v8::AccessorSetter();
|
||||
|
||||
inline v8::AccessorGetter accessorGetter() {return &AccessorGetter;}
|
||||
inline v8::AccessorSetter accessorSetter() {return RTEST(set) ? &AccessorSetter : 0;}
|
||||
|
||||
inline v8::NamedPropertyGetter namedPropertyGetter() {return &NamedPropertyGetter;}
|
||||
inline v8::NamedPropertySetter namedPropertySetter() {return RTEST(set) ? &NamedPropertySetter : 0;}
|
||||
inline v8::NamedPropertyQuery namedPropertyQuery() {return RTEST(query) ? &NamedPropertyQuery : 0;}
|
||||
inline v8::NamedPropertyDeleter namedPropertyDeleter() {return RTEST(deleter) ? &NamedPropertyDeleter : 0;}
|
||||
inline v8::NamedPropertyEnumerator namedPropertyEnumerator() {return RTEST(enumerator) ? &NamedPropertyEnumerator : 0;}
|
||||
|
||||
inline v8::IndexedPropertyGetter indexedPropertyGetter() {return &IndexedPropertyGetter;}
|
||||
inline v8::IndexedPropertySetter indexedPropertySetter() {return RTEST(set) ? &IndexedPropertySetter : 0;}
|
||||
inline v8::IndexedPropertyQuery indexedPropertyQuery() {return RTEST(query) ? &IndexedPropertyQuery : 0;}
|
||||
inline v8::IndexedPropertyDeleter indexedPropertyDeleter() {return RTEST(deleter) ? &IndexedPropertyDeleter : 0;}
|
||||
inline v8::IndexedPropertyEnumerator indexedPropertyEnumerator() {return RTEST(enumerator) ? &IndexedPropertyEnumerator : 0;}
|
||||
|
||||
operator v8::Handle<v8::Value>();
|
||||
static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property, const v8::AccessorInfo& info);
|
||||
static void Setter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
|
||||
|
||||
class Info {
|
||||
public:
|
||||
|
@ -241,7 +280,15 @@ public:
|
|||
operator VALUE();
|
||||
inline const v8::AccessorInfo* operator->() {return this->info;}
|
||||
v8::Handle<v8::Value> get(v8::Local<v8::String> property);
|
||||
void set(v8::Local<v8::String> property, v8::Local<v8::Value> value);
|
||||
v8::Handle<v8::Value> set(v8::Local<v8::String> property, v8::Local<v8::Value> value);
|
||||
v8::Handle<v8::Integer> query(v8::Local<v8::String> property);
|
||||
v8::Handle<v8::Boolean> remove(v8::Local<v8::String> property);
|
||||
v8::Handle<v8::Array> enumerateNames();
|
||||
v8::Handle<v8::Value> get(uint32_t index);
|
||||
v8::Handle<v8::Value> set(uint32_t index, v8::Local<v8::Value> value);
|
||||
v8::Handle<v8::Integer> query(uint32_t index);
|
||||
v8::Handle<v8::Boolean> remove(uint32_t index);
|
||||
v8::Handle<v8::Array> enumerateIndices();
|
||||
|
||||
static VALUE Class;
|
||||
private:
|
||||
|
@ -249,10 +296,28 @@ public:
|
|||
};
|
||||
friend class Info;
|
||||
private:
|
||||
static v8::Handle<v8::Value> AccessorGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info);
|
||||
static void AccessorSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
|
||||
|
||||
static v8::Handle<v8::Value> NamedPropertyGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Value> NamedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Integer> NamedPropertyQuery(v8::Local<v8::String> property, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Boolean> NamedPropertyDeleter(v8::Local<v8::String> property, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Array> NamedPropertyEnumerator(const v8::AccessorInfo& info);
|
||||
|
||||
static v8::Handle<v8::Value> IndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Value> IndexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Integer> IndexedPropertyQuery(uint32_t index, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Boolean> IndexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info);
|
||||
static v8::Handle<v8::Array> IndexedPropertyEnumerator(const v8::AccessorInfo& info);
|
||||
|
||||
void wrap(v8::Handle<v8::Object> wrapper, int index, VALUE value);
|
||||
VALUE unwrap(v8::Handle<v8::Object> wrapper, int index);
|
||||
VALUE get;
|
||||
VALUE set;
|
||||
VALUE query;
|
||||
VALUE deleter;
|
||||
VALUE enumerator;
|
||||
VALUE data;
|
||||
};
|
||||
|
||||
|
@ -392,6 +457,16 @@ public:
|
|||
class ObjectTemplate : public Ref<v8::ObjectTemplate> {
|
||||
public:
|
||||
static void Init();
|
||||
static VALUE New(VALUE self);
|
||||
static VALUE NewInstance(VALUE self);
|
||||
static VALUE SetAccessor(int argc, VALUE argv[], VALUE self);
|
||||
static VALUE SetNamedPropertyHandler(int argc, VALUE argv[], VALUE self);
|
||||
static VALUE SetIndexedPropertyHandler(int argc, VALUE argv[], VALUE self);
|
||||
static VALUE SetCallAsFunctionHandler(int argc, VALUE argv[], VALUE self);
|
||||
static VALUE MarkAsUndetectable(VALUE self);
|
||||
static VALUE SetAccessCheckCallbacks(int argc, VALUE argv[], VALUE self);
|
||||
static VALUE InternalFieldCount(VALUE self);
|
||||
static VALUE SetInternalFieldCount(VALUE self, VALUE count);
|
||||
|
||||
inline ObjectTemplate(VALUE value) : Ref<v8::ObjectTemplate>(value) {}
|
||||
inline ObjectTemplate(v8::Handle<v8::ObjectTemplate> t) : Ref<v8::ObjectTemplate>(t) {}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace rr {
|
|||
VALUE Signature::New(int length, VALUE args[], VALUE self) {
|
||||
VALUE receiver; VALUE argc; VALUE argv;
|
||||
rb_scan_args(length, args, "03", &receiver, &argc, &argv);
|
||||
std::vector< v8::Handle<v8::FunctionTemplate> > parameters(Int(argc));
|
||||
std::vector< v8::Handle<v8::FunctionTemplate> > parameters(Int(argc).toInt());
|
||||
return Signature(v8::Signature::New(FunctionTemplate(receiver), Int(argc), FunctionTemplate::array(argv, parameters)));
|
||||
}
|
||||
}
|
|
@ -9,9 +9,98 @@ namespace rr {
|
|||
|
||||
void ObjectTemplate::Init() {
|
||||
ClassBuilder("ObjectTemplate", "Template").
|
||||
defineSingletonMethod("New", &New).
|
||||
defineMethod("NewInstance", &NewInstance).
|
||||
defineMethod("SetAccessor", &SetAccessor).
|
||||
defineMethod("SetNamedPropertyHandler", &SetNamedPropertyHandler).
|
||||
defineMethod("SetIndexedPropertyHandler", &SetIndexedPropertyHandler).
|
||||
defineMethod("SetCallAsFunctionHandler", &SetCallAsFunctionHandler).
|
||||
defineMethod("MarkAsUndetectable", &MarkAsUndetectable).
|
||||
defineMethod("SetAccessCheckCallbacks", &SetAccessCheckCallbacks).
|
||||
defineMethod("InternalFieldCount", &InternalFieldCount).
|
||||
defineMethod("SetInternalFieldCount", &SetInternalFieldCount).
|
||||
store(&Class);
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::New(VALUE self) {
|
||||
return ObjectTemplate(v8::ObjectTemplate::New());
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::NewInstance(VALUE self) {
|
||||
return Object(ObjectTemplate(self)->NewInstance());
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::SetAccessor(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE name; VALUE get; VALUE set; VALUE data; VALUE settings; VALUE attribs;
|
||||
rb_scan_args(argc, argv, "24", &name, &get, &set, &data, &settings, &attribs);
|
||||
Accessor accessor(get, set, data);
|
||||
ObjectTemplate(self)->SetAccessor(
|
||||
String(name),
|
||||
accessor.accessorGetter(),
|
||||
accessor.accessorSetter(),
|
||||
accessor,
|
||||
AccessControl(settings),
|
||||
PropertyAttribute(attribs)
|
||||
);
|
||||
Void();
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::SetNamedPropertyHandler(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE get; VALUE set; VALUE query; VALUE deleter; VALUE enumerator; VALUE data;
|
||||
rb_scan_args(argc, argv, "15", &get, &set, &query, &deleter, &enumerator, &data);
|
||||
Accessor accessor(get,set,query,deleter,enumerator,data);
|
||||
ObjectTemplate(self)->SetNamedPropertyHandler(
|
||||
accessor.namedPropertyGetter(),
|
||||
accessor.namedPropertySetter(),
|
||||
accessor.namedPropertyQuery(),
|
||||
accessor.namedPropertyDeleter(),
|
||||
accessor.namedPropertyEnumerator(),
|
||||
accessor
|
||||
);
|
||||
Void();
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::SetIndexedPropertyHandler(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE get; VALUE set; VALUE query; VALUE deleter; VALUE enumerator; VALUE data;
|
||||
rb_scan_args(argc, argv, "15", &get, &set, &query, &deleter, &enumerator, &data);
|
||||
Accessor accessor(get,set,query,deleter,enumerator,data);
|
||||
ObjectTemplate(self)->SetIndexedPropertyHandler(
|
||||
accessor.indexedPropertyGetter(),
|
||||
accessor.indexedPropertySetter(),
|
||||
accessor.indexedPropertyQuery(),
|
||||
accessor.indexedPropertyDeleter(),
|
||||
accessor.indexedPropertyEnumerator(),
|
||||
accessor
|
||||
);
|
||||
Void();
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::SetCallAsFunctionHandler(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE callback; VALUE data;
|
||||
rb_scan_args(argc, argv, "11", &callback, &data);
|
||||
Invocation invocation(callback, data);
|
||||
Void(ObjectTemplate(self)->SetCallAsFunctionHandler(invocation, invocation));
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::MarkAsUndetectable(VALUE self) {
|
||||
Void(ObjectTemplate(self)->MarkAsUndetectable());
|
||||
}
|
||||
|
||||
|
||||
VALUE ObjectTemplate::SetAccessCheckCallbacks(int argc, VALUE argv[], VALUE self) {
|
||||
VALUE named_handler; VALUE indexed_handler; VALUE data; VALUE turned_on_by_default;
|
||||
rb_scan_args(argc, argv, "22", &named_handler, &indexed_handler, &data, &turned_on_by_default);
|
||||
return not_implemented("ObjectTemplate::SetAccessCheckCallbacks");
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::InternalFieldCount(VALUE self) {
|
||||
return INT2FIX(ObjectTemplate(self)->InternalFieldCount());
|
||||
}
|
||||
|
||||
VALUE ObjectTemplate::SetInternalFieldCount(VALUE self, VALUE count) {
|
||||
Void(ObjectTemplate(self)->SetInternalFieldCount(Int(count)));
|
||||
}
|
||||
|
||||
void FunctionTemplate::Init() {
|
||||
ClassBuilder("FunctionTemplate", "Template").
|
||||
defineSingletonMethod("New", &New).
|
||||
|
|
Loading…
Add table
Reference in a new issue