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

towards equivalence classes in type conversion

This commit is contained in:
Charles Lowell 2012-05-15 16:24:58 -05:00
parent 42ae80285f
commit e21bedf3a9
5 changed files with 82 additions and 22 deletions

View file

@ -38,7 +38,6 @@ VALUE Object::Set(VALUE self, VALUE key, VALUE value) {
} else {
return Convert(Object(self)->Set((v8::Handle<v8::Value>)Value(key), Value(value)));
}
}
VALUE Object::ForceSet(VALUE self, VALUE key, VALUE value) {
@ -47,9 +46,9 @@ VALUE Object::ForceSet(VALUE self, VALUE key, VALUE value) {
VALUE Object::Get(VALUE self, VALUE key) {
if (rb_obj_is_kind_of(key, rb_cNumeric)) {
return Convert(Object(self)->Get(NUM2UINT(key)));
return Value(Object(self)->Get(NUM2UINT(key)));
} else {
return Convert(Object(self)->Get((v8::Handle<v8::Value>)Value(key)));
return Value(Object(self)->Get((v8::Handle<v8::Value>)Value(key)));
}
}

View file

@ -52,22 +52,22 @@ private:
*/
template <class T> class Ref {
public:
Ref(VALUE wrapper) {
Holder* holder = NULL;
Data_Get_Struct(wrapper, class Holder, holder) ;
this->holder = holder;
Ref(VALUE value) {
this->value = value;
}
Ref(v8::Handle<T> handle) {
this->holder = new Holder(handle, Class);
this->handle = handle;
}
virtual operator VALUE() {
return holder->value;
virtual operator VALUE() const {
return (new Holder(handle, Class))->value;
}
virtual operator v8::Handle<T>() {
virtual operator v8::Handle<T>() const {
Holder* holder = NULL;
Data_Get_Struct(this->value, class Holder, holder);
return holder->handle;
}
inline v8::Handle<T> operator->() const { return holder->handle; }
v8::Handle<T> GetHandle() {return holder->handle;}
inline v8::Handle<T> operator->() const { return *this;}
inline v8::Handle<T> GetHandle() const { return *this;}
class Holder {
friend class Ref;
@ -88,10 +88,9 @@ public:
GC::Finalize(holder);
}
};
Ref(Holder* holder) {
this->holder = holder;
};
Holder* holder;
VALUE value;
v8::Handle<T> handle;
static VALUE Class;
};
template <class T> VALUE Ref<T>::Class;
@ -105,15 +104,16 @@ private:
static VALUE DoCall(VALUE code);
};
class Phantom : public Ref<void> {
class Phantom {
public:
inline Phantom(void* reference) : Ref<void>((Ref<void>::Holder*)reference) {}
inline Phantom(void* reference) : holder((Ref<void>::Holder*)reference) {}
inline bool NotNull() {
return this->holder != NULL;
}
inline void destroy() {
delete holder;
}
Ref<void>::Holder* holder;
};
class Context : public Ref<v8::Context> {
@ -177,6 +177,8 @@ public:
static VALUE Equals(VALUE self, VALUE other);
static VALUE StrictEquals(VALUE self, VALUE other);
inline Value(VALUE value) : Ref<v8::Value>(value) {}
inline Value(v8::Handle<v8::Value> value) : Ref<v8::Value>(value) {}
virtual operator VALUE();
};
class String: public Ref<v8::String> {

View file

@ -5,7 +5,8 @@ namespace rr {
void Script::Init() {
ClassBuilder("Script").
defineSingletonMethod("New", &New).
defineMethod("Run", &Run);
defineMethod("Run", &Run).
store(&Class);
}
VALUE Script::New(VALUE klass, VALUE source, VALUE filename) {
@ -13,7 +14,7 @@ VALUE Script::New(VALUE klass, VALUE source, VALUE filename) {
}
VALUE Script::Run(VALUE self) {
return Convert(Script(self)->Run());
return Value(Script(self)->Run());
}
} //namespace rr

View file

@ -5,7 +5,8 @@ namespace rr {
void Value::Init() {
ClassBuilder("Value").
defineMethod("Equals", &Equals).
defineMethod("StrictEquals", &StrictEquals);
defineMethod("StrictEquals", &StrictEquals)
.store(&Class);
}
VALUE Value::Equals(VALUE self, VALUE other) {
@ -15,4 +16,41 @@ VALUE Value::Equals(VALUE self, VALUE other) {
VALUE Value::StrictEquals(VALUE self, VALUE other) {
return Convert(Value(self)->StrictEquals(Value(other)));
}
Value::operator VALUE() {
if (handle.IsEmpty() || handle->IsUndefined() || handle->IsNull()) {
return Qnil;
}
if (handle->IsExternal()) {
return External((v8::Handle<v8::External>)v8::External::Cast(*handle));
}
if (handle->IsUint32()) {
return UINT2NUM(handle->Uint32Value());
}
if (handle->IsInt32()) {
return INT2FIX(handle->Int32Value());
}
if (handle->IsBoolean()) {
return handle->BooleanValue() ? Qtrue : Qfalse;
}
if (handle->IsNumber()) {
return rb_float_new(handle->NumberValue());
}
if (handle->IsString()) {
return String(handle->ToString());
}
// if (handle->IsFunction()) {
// // return Function(handle);
// }
// if (handle->IsArray()) {
// // return Array(handle);
// }
// if (handle->IsDate()) {
// // return rr_reflect_v8_date(handle);
// }
if (handle->IsObject()) {
return Object(handle->ToObject());
}
return Ref<v8::Value>::operator VALUE();
}
}

20
spec/c/script_spec.rb Normal file
View file

@ -0,0 +1,20 @@
require 'spec_helper'
describe V8::C::External do
before do
@cxt = V8::C::Context::New()
@cxt.Enter()
end
after do
@cxt.Exit()
end
it "can run a script and return a polymorphic result" do
V8::C::HandleScope() do
source = V8::C::String::New("(new Object())")
filename = V8::C::String::New("<eval>")
script = V8::C::Script::New(source, filename)
result = script.Run()
result.should be_kind_of V8::C::Object
end
end
end