mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
implement arguments from ruby with pure wrappers.
This commit is contained in:
parent
8f57a60a21
commit
204f121e0d
3 changed files with 54 additions and 105 deletions
|
@ -7,122 +7,75 @@ using namespace v8;
|
|||
namespace {
|
||||
VALUE ArgumentsClass;
|
||||
VALUE AccessorInfoClass;
|
||||
|
||||
struct Wrap {
|
||||
Persistent<Object> thisObj;
|
||||
Persistent<Object> holder;
|
||||
Persistent<Value> data;
|
||||
Wrap(Handle<Object> thisObj, Handle<Object> holder, Handle<Value> data);
|
||||
virtual ~Wrap();
|
||||
};
|
||||
|
||||
Wrap::Wrap(Handle<Object> thisObj_, Handle<Object> holder_, Handle<Value> data_) :
|
||||
thisObj(Persistent<Object>::New(thisObj_)),
|
||||
holder(Persistent<Object>::New(holder_)),
|
||||
data(Persistent<Value>::New(data_)) {}
|
||||
Wrap::~Wrap() {
|
||||
thisObj.Dispose();
|
||||
holder.Dispose();
|
||||
data.Dispose();
|
||||
}
|
||||
void gc_wrap_mark(Wrap *wrapper) {}
|
||||
void gc_wrap_free(Wrap *wrapper) {
|
||||
delete wrapper;
|
||||
}
|
||||
|
||||
struct WrapArguments : Wrap {
|
||||
int length;
|
||||
Persistent<Function> callee;
|
||||
bool isConstructCall;
|
||||
Persistent<Array> values;
|
||||
WrapArguments(const Arguments& arguments);
|
||||
virtual ~WrapArguments();
|
||||
};
|
||||
|
||||
WrapArguments::WrapArguments(const Arguments& arguments) : Wrap(arguments.This(), arguments.Holder(), arguments.Data()),
|
||||
callee(Persistent<Function>::New(arguments.Callee())),
|
||||
values(Persistent<Array>::New(Array::New(arguments.Length()))) {
|
||||
length = arguments.Length();
|
||||
isConstructCall = arguments.IsConstructCall();
|
||||
for (int i = 0; i < arguments.Length(); i++) {
|
||||
values->Set(Integer::New(i), arguments[i]);
|
||||
}
|
||||
}
|
||||
|
||||
WrapArguments::~WrapArguments() {
|
||||
callee.Dispose();
|
||||
values.Dispose();
|
||||
}
|
||||
|
||||
Wrap *info(VALUE value) {
|
||||
Wrap *wrap = 0;
|
||||
Data_Get_Struct(value, struct Wrap, wrap);
|
||||
return wrap;
|
||||
}
|
||||
|
||||
WrapArguments* args(VALUE value) {
|
||||
WrapArguments *wrap = 0;
|
||||
Data_Get_Struct(value, struct WrapArguments, wrap);
|
||||
return wrap;
|
||||
}
|
||||
|
||||
VALUE Length(VALUE self) {
|
||||
return rr_v82rb(args(self)->length);
|
||||
}
|
||||
VALUE Get(VALUE self, VALUE index) {
|
||||
int i = NUM2INT(index);
|
||||
return rr_v82rb(args(self)->values->Get(i));
|
||||
}
|
||||
VALUE Callee(VALUE self) {
|
||||
return rr_v82rb(args(self)->callee);
|
||||
}
|
||||
VALUE This(VALUE self) {
|
||||
return rr_v82rb(info(self)->thisObj);
|
||||
}
|
||||
VALUE Holder(VALUE self) {
|
||||
return rr_v82rb(info(self)->holder);
|
||||
}
|
||||
VALUE IsConstructCall(VALUE self) {
|
||||
return rr_v82rb(args(self)->isConstructCall);
|
||||
}
|
||||
VALUE _Data(VALUE self) {
|
||||
return rb_iv_get(self, "data");
|
||||
}
|
||||
|
||||
namespace Accessor {
|
||||
AccessorInfo *info(VALUE value) {
|
||||
AccessorInfo* i = 0;
|
||||
Data_Get_Struct(value, class AccessorInfo, i);
|
||||
return i;
|
||||
}
|
||||
VALUE This(VALUE self) {
|
||||
return rr_v82rb(info(self)->This());
|
||||
}
|
||||
VALUE Holder(VALUE self) {
|
||||
return rr_v82rb(info(self)->Holder());
|
||||
}
|
||||
}
|
||||
|
||||
struct WrapAccessorInfo : Wrap {
|
||||
WrapAccessorInfo(const AccessorInfo& info);
|
||||
};
|
||||
WrapAccessorInfo::WrapAccessorInfo(const AccessorInfo& info) : Wrap(info.This(), info.Holder(), info.Data()) {}
|
||||
|
||||
namespace Args {
|
||||
Arguments* args(VALUE value) {
|
||||
Arguments *arguments = 0;
|
||||
Data_Get_Struct(value, class Arguments, arguments);
|
||||
return arguments;
|
||||
}
|
||||
VALUE This(VALUE self) {
|
||||
return rr_v82rb(args(self)->This());
|
||||
}
|
||||
|
||||
VALUE Holder(VALUE self) {
|
||||
return rr_v82rb(args(self)->Holder());
|
||||
}
|
||||
|
||||
VALUE Length(VALUE self) {
|
||||
return rr_v82rb(args(self)->Length());
|
||||
}
|
||||
VALUE Get(VALUE self, VALUE index) {
|
||||
int i = NUM2INT(index);
|
||||
return rr_v82rb((*args(self))[i]);
|
||||
}
|
||||
VALUE Callee(VALUE self) {
|
||||
return rr_v82rb(args(self)->Callee());
|
||||
}
|
||||
VALUE IsConstructCall(VALUE self) {
|
||||
return rr_v82rb(args(self)->IsConstructCall());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void rr_init_v8_callbacks() {
|
||||
AccessorInfoClass = rr_define_class("AccessorInfo");
|
||||
rr_define_method(AccessorInfoClass, "This", This, 0);
|
||||
rr_define_method(AccessorInfoClass, "Holder", Holder, 0);
|
||||
rr_define_method(AccessorInfoClass, "This", Accessor::This, 0);
|
||||
rr_define_method(AccessorInfoClass, "Holder", Accessor::Holder, 0);
|
||||
rr_define_method(AccessorInfoClass, "Data", _Data, 0);
|
||||
|
||||
ArgumentsClass = rr_define_class("Arguments");
|
||||
rr_define_method(ArgumentsClass, "This", This, 0);
|
||||
rr_define_method(ArgumentsClass, "Holder", Holder, 0);
|
||||
rr_define_method(ArgumentsClass, "This", Args::This, 0);
|
||||
rr_define_method(ArgumentsClass, "Holder", Args::Holder, 0);
|
||||
rr_define_method(ArgumentsClass, "Data", _Data, 0);
|
||||
rr_define_method(ArgumentsClass, "Length", Length, 0);
|
||||
rr_define_method(ArgumentsClass, "Callee", Callee, 0);
|
||||
rr_define_method(ArgumentsClass, "IsConstructCall", IsConstructCall, 0);
|
||||
rr_define_method(ArgumentsClass, "[]", Get, 1);
|
||||
rr_define_method(ArgumentsClass, "Length", Args::Length, 0);
|
||||
rr_define_method(ArgumentsClass, "Callee", Args::Callee, 0);
|
||||
rr_define_method(ArgumentsClass, "IsConstructCall", Args::IsConstructCall, 0);
|
||||
rr_define_method(ArgumentsClass, "[]", Args::Get, 1);
|
||||
}
|
||||
|
||||
VALUE rr_v82rb(const AccessorInfo& info) {
|
||||
return Data_Wrap_Struct(AccessorInfoClass, gc_wrap_mark, gc_wrap_free, new WrapAccessorInfo(info));
|
||||
return Data_Wrap_Struct(AccessorInfoClass, 0, 0, (void*)&info);
|
||||
}
|
||||
VALUE rr_v82rb(const Arguments& arguments) {
|
||||
return Data_Wrap_Struct(ArgumentsClass, gc_wrap_mark, gc_wrap_free, new WrapArguments(arguments));
|
||||
}
|
||||
VALUE rr_v8_arguments_new(const Arguments& arguments) {
|
||||
return Data_Wrap_Struct(ArgumentsClass, 0, 0, new WrapArguments(arguments));
|
||||
}
|
||||
void rr_v8_arguments_destroy(VALUE args) {
|
||||
WrapArguments* arguments = 0;
|
||||
Data_Get_Struct(args, struct WrapArguments, arguments);
|
||||
free(arguments);
|
||||
return Data_Wrap_Struct(ArgumentsClass, 0, 0, (void*)&arguments);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,5 @@
|
|||
void rr_init_v8_callbacks();
|
||||
VALUE rr_v82rb(const v8::AccessorInfo& info);
|
||||
VALUE rr_v82rb(const v8::Arguments& arguments);
|
||||
VALUE rr_v8_arguments_new(const v8::Arguments& arguments);
|
||||
void rr_v8_arguments_destroy(VALUE args);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -60,11 +60,9 @@ namespace {
|
|||
Handle<External> v8_data_wrapper = Handle<External>::Cast(args.Data());
|
||||
v8_callback_data* v8_data = (v8_callback_data*)v8_data_wrapper->Value();
|
||||
if (RTEST(v8_data->handler)) {
|
||||
// VALUE rb_args = rr_v82rb(args);
|
||||
VALUE rb_args = rr_v8_arguments_new(args);
|
||||
VALUE rb_args = rr_v82rb(args);
|
||||
rb_iv_set(rb_args, "data", v8_data->data);
|
||||
VALUE result = rb_funcall(v8_data->handler, rb_intern("call"), 1, rb_args);
|
||||
rr_v8_arguments_destroy(rb_args);
|
||||
return rr_rb2v8(result);
|
||||
} else {
|
||||
return Handle<Value>();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue