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:
parent
42ae80285f
commit
e21bedf3a9
5 changed files with 82 additions and 22 deletions
|
@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
34
ext/v8/rr.h
34
ext/v8/rr.h
|
@ -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> {
|
||||
|
|
|
@ -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
|
|
@ -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
20
spec/c/script_spec.rb
Normal 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
|
Loading…
Add table
Reference in a new issue