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

Implement the rest of the Object mehods:

- GetConstructorName
- InternalFieldCount
- GetInternalField
- SetInternalField
- HasOwnProperty
- HasRealNamedProperty
- HasRealIndexedProperty
- HasRealNamedCallbackProperty
- GetRealNamedPropertyInPrototypeChain
- GetRealNamedProperty
- GetRealNamedPropertyAttributes
- GetRealNamedPropertyAttributesInPrototypeChain
- HasNamedLookupInterceptor
- HasIndexedLookupInterceptor
- SetHiddenValue
- GetHiddenValue
- DeleteHiddenValue
- Clone
- CreationContext
- IsCallable
- CallAsFunction
- CallAsConstructor
This commit is contained in:
Georgy Angelov 2015-08-02 16:57:00 +00:00
parent 200d617089
commit 5ac3483215
4 changed files with 388 additions and 5 deletions

View file

@ -8,10 +8,12 @@ namespace rr {
ObjectTemplate(VALUE self) : Ref<v8::ObjectTemplate>(self) {}
ObjectTemplate(v8::Isolate* isolate, v8::Handle<v8::ObjectTemplate> tmpl) :
Ref<v8::ObjectTemplate>(isolate, tmpl) {}
inline static void Init() {
ClassBuilder("ObjectTemplate", Template::Class).
defineSingletonMethod("New", &New).
defineMethod("NewInstance", &NewInstance).
defineMethod("SetInternalFieldCount", &SetInternalFieldCount).
store(&Class);
}
@ -20,16 +22,26 @@ namespace rr {
rb_scan_args(argc, argv, "11", &r_isolate, &r_constructor);
Isolate isolate(r_isolate);
Locker lock(isolate);
return ObjectTemplate(isolate, v8::ObjectTemplate::New(isolate));
}
static VALUE NewInstance(VALUE self , VALUE r_context) {
static VALUE NewInstance(VALUE self, VALUE r_context) {
ObjectTemplate t(self);
Context context(r_context);
Isolate isolate(context.getIsolate());
Locker lock(isolate);
v8::MaybeLocal<v8::Object> object(t->NewInstance());
return Object::Maybe(isolate, ObjectTemplate(self)->NewInstance(context));
return Object::Maybe(isolate, t->NewInstance(context));
}
static VALUE SetInternalFieldCount(VALUE self, VALUE value) {
ObjectTemplate t(self);
Locker lock(t);
t->SetInternalFieldCount(NUM2INT(value));
return Qnil;
}
};
}

View file

@ -21,6 +21,28 @@ namespace rr {
defineMethod("GetPrototype", &GetPrototype).
defineMethod("SetPrototype", &SetPrototype).
defineMethod("ObjectProtoToString", &ObjectProtoToString).
defineMethod("GetConstructorName", &GetConstructorName).
defineMethod("InternalFieldCount", &InternalFieldCount).
defineMethod("GetInternalField", &GetInternalField).
defineMethod("SetInternalField", &SetInternalField).
defineMethod("HasOwnProperty", &HasOwnProperty).
defineMethod("HasRealNamedProperty", &HasRealNamedProperty).
defineMethod("HasRealIndexedProperty", &HasRealIndexedProperty).
defineMethod("HasRealNamedCallbackProperty", &HasRealNamedCallbackProperty).
defineMethod("GetRealNamedPropertyInPrototypeChain", &GetRealNamedPropertyInPrototypeChain).
defineMethod("GetRealNamedProperty", &GetRealNamedProperty).
defineMethod("GetRealNamedPropertyAttributes", &GetRealNamedPropertyAttributes).
defineMethod("GetRealNamedPropertyAttributesInPrototypeChain", &GetRealNamedPropertyAttributesInPrototypeChain).
defineMethod("HasNamedLookupInterceptor", &HasNamedLookupInterceptor).
defineMethod("HasIndexedLookupInterceptor", &HasIndexedLookupInterceptor).
defineMethod("SetHiddenValue", &SetHiddenValue).
defineMethod("GetHiddenValue", &GetHiddenValue).
defineMethod("DeleteHiddenValue", &DeleteHiddenValue).
defineMethod("Clone", &Clone).
defineMethod("CreationContext", &CreationContext).
defineMethod("IsCallable", &IsCallable).
defineMethod("CallAsFunction", &CallAsFunction).
defineMethod("CallAsConstructor", &CallAsConstructor).
store(&Class);
}
@ -210,6 +232,192 @@ namespace rr {
return String::Maybe(object.getIsolate(), object->ObjectProtoToString(Context(r_context)));
}
VALUE Object::GetConstructorName(VALUE self) {
Object object(self);
Locker lock(object);
return String(object.getIsolate(), object->GetConstructorName());
}
VALUE Object::InternalFieldCount(VALUE self) {
Object object(self);
Locker lock(object);
return INT2FIX(object->InternalFieldCount());
}
VALUE Object::GetInternalField(VALUE self, VALUE index) {
Object object(self);
Locker lock(object);
return Value(object.getIsolate(), object->GetInternalField(NUM2INT(index)));
}
VALUE Object::SetInternalField(VALUE self, VALUE index, VALUE value) {
Object object(self);
Locker lock(object);
object->SetInternalField(NUM2INT(index), *Value(value));
return Qnil;
}
VALUE Object::HasOwnProperty(VALUE self, VALUE r_context, VALUE key) {
Object object(self);
Locker lock(object);
return Bool::Maybe(object->HasOwnProperty(Context(r_context), *Name(key)));
}
VALUE Object::HasRealNamedProperty(VALUE self, VALUE r_context, VALUE key) {
Object object(self);
Locker lock(object);
return Bool::Maybe(object->HasRealNamedProperty(Context(r_context), *Name(key)));
}
VALUE Object::HasRealIndexedProperty(VALUE self, VALUE r_context, VALUE index) {
Object object(self);
Locker lock(object);
return Bool::Maybe(object->HasRealIndexedProperty(Context(r_context), NUM2INT(index)));
}
VALUE Object::HasRealNamedCallbackProperty(VALUE self, VALUE r_context, VALUE key) {
Object object(self);
Locker lock(object);
return Bool::Maybe(object->HasRealNamedCallbackProperty(Context(r_context), *Name(key)));
}
VALUE Object::GetRealNamedPropertyInPrototypeChain(VALUE self, VALUE r_context, VALUE key) {
Object object(self);
Locker lock(object);
return Value::Maybe(object.getIsolate(), object->GetRealNamedPropertyInPrototypeChain(
Context(r_context),
*Name(key)
));
}
VALUE Object::GetRealNamedProperty(VALUE self, VALUE r_context, VALUE key) {
Object object(self);
Locker lock(object);
return Value::Maybe(object.getIsolate(), object->GetRealNamedProperty(
Context(r_context),
*Name(key)
));
}
VALUE Object::GetRealNamedPropertyAttributes(VALUE self, VALUE r_context, VALUE key) {
Object object(self);
Locker lock(object);
return Enum<v8::PropertyAttribute>::Maybe(object->GetRealNamedPropertyAttributes(
Context(r_context),
*Name(key)
));
}
VALUE Object::GetRealNamedPropertyAttributesInPrototypeChain(VALUE self, VALUE r_context, VALUE key) {
Object object(self);
Locker lock(object);
return Enum<v8::PropertyAttribute>::Maybe(object->GetRealNamedPropertyAttributesInPrototypeChain(
Context(r_context),
*Name(key)
));
}
VALUE Object::HasNamedLookupInterceptor(VALUE self) {
Object object(self);
Locker lock(object);
return Bool(object->HasNamedLookupInterceptor());
}
VALUE Object::HasIndexedLookupInterceptor(VALUE self) {
Object object(self);
Locker lock(object);
return Bool(object->HasIndexedLookupInterceptor());
}
VALUE Object::SetHiddenValue(VALUE self, VALUE key, VALUE value) {
Object object(self);
Locker lock(object);
return Bool(object->SetHiddenValue(String(key), Value(value)));
}
VALUE Object::GetHiddenValue(VALUE self, VALUE key) {
Object object(self);
Locker lock(object);
return Value(object.getIsolate(), object->GetHiddenValue(String(key)));
}
VALUE Object::DeleteHiddenValue(VALUE self, VALUE key) {
Object object(self);
Locker lock(object);
return Bool(object->DeleteHiddenValue(String(key)));
}
VALUE Object::Clone(VALUE self) {
Object object(self);
Locker lock(object);
return Object(object.getIsolate(), object->Clone());
}
VALUE Object::CreationContext(VALUE self) {
Object object(self);
Locker lock(object);
return Context(object->CreationContext());
}
VALUE Object::IsCallable(VALUE self) {
Object object(self);
Locker lock(object);
return Bool(object->IsCallable());
}
VALUE Object::CallAsFunction(int argc, VALUE* argv, VALUE self) {
VALUE r_context, recv, r_argv;
rb_scan_args(argc, argv, "30", &r_context, &recv, &r_argv);
Object object(self);
v8::Isolate* isolate = object.getIsolate();
Locker lock(isolate);
std::vector< v8::Handle<v8::Value> > vector(Value::convertRubyArray(isolate, r_argv));
return Value::Maybe(isolate, object->CallAsFunction(
Context(r_context),
Value(recv),
RARRAY_LENINT(r_argv),
&vector[0]
));
}
VALUE Object::CallAsConstructor(VALUE self, VALUE r_context, VALUE argv) {
Object object(self);
v8::Isolate* isolate = object.getIsolate();
Locker lock(isolate);
std::vector< v8::Handle<v8::Value> > vector(Value::convertRubyArray(isolate, argv));
return Value::Maybe(isolate, object->CallAsConstructor(
Context(r_context),
RARRAY_LENINT(argv),
&vector[0]
));
}
Object::operator VALUE() {
Isolate isolate(getIsolate());
Locker lock(isolate);

View file

@ -27,6 +27,35 @@ namespace rr {
static VALUE SetPrototype(VALUE self, VALUE r_context, VALUE prototype);
static VALUE ObjectProtoToString(VALUE self, VALUE r_context);
static VALUE GetConstructorName(VALUE self);
static VALUE InternalFieldCount(VALUE self);
static VALUE GetInternalField(VALUE self, VALUE index);
static VALUE SetInternalField(VALUE self, VALUE index, VALUE value);
static VALUE HasOwnProperty(VALUE self, VALUE r_context, VALUE key);
static VALUE HasRealNamedProperty(VALUE self, VALUE r_context, VALUE key);
static VALUE HasRealIndexedProperty(VALUE self, VALUE r_context, VALUE index);
static VALUE HasRealNamedCallbackProperty(VALUE self, VALUE r_context, VALUE key);
static VALUE GetRealNamedPropertyInPrototypeChain(VALUE self, VALUE r_context, VALUE key);
static VALUE GetRealNamedProperty(VALUE self, VALUE r_context, VALUE key);
static VALUE GetRealNamedPropertyAttributes(VALUE self, VALUE r_context, VALUE key);
static VALUE GetRealNamedPropertyAttributesInPrototypeChain(VALUE self, VALUE r_context, VALUE key);
static VALUE HasNamedLookupInterceptor(VALUE self);
static VALUE HasIndexedLookupInterceptor(VALUE self);
static VALUE SetHiddenValue(VALUE self, VALUE key, VALUE value);
static VALUE GetHiddenValue(VALUE self, VALUE key);
static VALUE DeleteHiddenValue(VALUE self, VALUE key);
static VALUE Clone(VALUE self);
static VALUE CreationContext(VALUE self);
static VALUE IsCallable(VALUE self);
static VALUE CallAsFunction(int argc, VALUE* argv, VALUE self);
static VALUE CallAsConstructor(VALUE self, VALUE r_context, VALUE argv);
inline Object(VALUE value) : Ref<v8::Object>(value) {}
inline Object(v8::Isolate* isolate, v8::Handle<v8::Object> object) : Ref<v8::Object>(isolate, object) {}

View file

@ -272,6 +272,14 @@ describe V8::C::Object do
expect(names).to be_successful
expect(names.FromJust.Get(@ctx, 0)).to v8_eq o_key
has_own = o.HasOwnProperty(@ctx, o_key)
expect(has_own.IsJust).to be true
expect(has_own.FromJust).to be true
has_own = o.HasOwnProperty(@ctx, prototype_key)
expect(has_own.IsJust).to be true
expect(has_own.FromJust).to be false
end
it 'can enumerate all properties' do
@ -294,12 +302,138 @@ describe V8::C::Object do
it 'can return a string representation of simple objects' do
a = V8::C::Array.New(@isolate)
a.Set(@ctx, 0, 2)
a.Set(@ctx, 1, 3)
str = a.ObjectProtoToString(@ctx)
expect(str).to be_successful
expect(str.FromJust.Utf8Value).to eq '[object Array]'
end
end
describe '#GetConstructorName' do
it 'can return the constructor name of an array' do
a = V8::C::Array.New(@isolate)
expect(a.GetConstructorName().Utf8Value).to eq 'Array'
end
end
context 'with internal fields' do
let(:o) do
template = V8::C::ObjectTemplate.New(@isolate)
template.SetInternalFieldCount(2)
template.NewInstance(@ctx).FromJust
end
let(:value_one) { V8::C::String.NewFromUtf8(@isolate, 'value 1') }
let(:value_two) { V8::C::String.NewFromUtf8(@isolate, 'value 2') }
before do
o.SetInternalField(0, value_one)
o.SetInternalField(1, value_two)
end
it 'can get and set internal fields' do
expect(o.GetInternalField(0)).to strict_eq value_one
expect(o.GetInternalField(1)).to strict_eq value_two
end
it 'can get the internal field count' do
expect(o.InternalFieldCount).to eq 2
end
end
context 'with hidden values' do
let(:o) { V8::C::Object.New @isolate }
let(:key_one) { V8::C::String.NewFromUtf8(@isolate, 'key 1') }
let(:key_two) { V8::C::String.NewFromUtf8(@isolate, 'key 2') }
let(:value_one) { V8::C::String.NewFromUtf8(@isolate, 'value 1') }
let(:value_two) { V8::C::String.NewFromUtf8(@isolate, 'value 2') }
before do
o.SetHiddenValue(key_one, value_one)
o.SetHiddenValue(key_two, value_two)
end
it 'can get and set hidden values' do
expect(o.GetHiddenValue(key_one)).to strict_eq value_one
expect(o.GetHiddenValue(key_two)).to strict_eq value_two
end
it 'can delete hidden values' do
expect(o.DeleteHiddenValue(key_one)).to be true
expect(o.GetHiddenValue(key_one)).to be nil
end
end
describe '#Clone' do
let(:o) { V8::C::Object.New @isolate }
let(:key) { V8::C::String.NewFromUtf8(@isolate, 'key') }
let(:value) { V8::C::String.NewFromUtf8(@isolate, 'value') }
before do
o.Set(@ctx, key, value)
end
it 'can clone an object' do
clone = o.Clone
expect(clone).to_not strict_eq o
expect(clone.Get(@ctx, key)).to strict_eq value
end
end
describe '#CreationContext' do
it 'returns a context' do
o = V8::C::Object.New @isolate
expect(o.CreationContext).to be_a V8::C::Context
end
end
describe '#IsCallable' do
it 'returns false for plain objects' do
o = V8::C::Object.New @isolate
expect(o.IsCallable).to be false
end
it 'returns true for functions' do
fn = V8::C::Function.New @isolate, proc { }, V8::C::Object::New(@isolate)
expect(fn.IsCallable).to be true
end
end
describe 'callable objects' do
let(:value) { V8::C::String.NewFromUtf8(@isolate, 'value') }
let(:one) { V8::C::String.NewFromUtf8(@isolate, 'one') }
let(:two) { V8::C::String.NewFromUtf8(@isolate, 'two') }
let(:fn) do
source = '(function(one, two) {this.one = one; this.two = two; return this;})'
source = V8::C::String.NewFromUtf8(@isolate, source.to_s)
script = V8::C::Script.Compile(@ctx, source)
result = script.FromJust.Run(@ctx)
result.FromJust
end
it 'can be called as functions' do
object = V8::C::Object::New(@isolate)
result = fn.CallAsFunction(@ctx, object, [one, two]).FromJust
expect(result).to strict_eq object
expect(object.Get(@ctx, one)).to strict_eq one
expect(object.Get(@ctx, two)).to strict_eq two
end
it 'can be called as constructors' do
result = fn.CallAsConstructor(@ctx, [one, two]).FromJust
expect(result).to be_a V8::C::Object
expect(result.Get(@ctx, one)).to strict_eq one
expect(result.Get(@ctx, two)).to strict_eq two
end
end
end