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

function.call() now assumes global "this" object. use function.methodcall(thisObj,...) to change the context. fuction.new() invokes function as javascript constructor.

This commit is contained in:
Charles Lowell 2010-06-03 12:51:06 +03:00
parent 946af8f3d4
commit b82d5b7154
4 changed files with 26 additions and 17 deletions

View file

@ -47,16 +47,15 @@ namespace {
Local<Value> result = function->Call(thisObject, f_argc, arguments); Local<Value> result = function->Call(thisObject, f_argc, arguments);
return rr_v82rb(result); return rr_v82rb(result);
} }
VALUE NewInstance(int argc, VALUE *argv, VALUE self) { VALUE NewInstance(VALUE self, VALUE argc, VALUE args) {
HandleScope handles; HandleScope scope;
VALUE f_argv; Local<Function> function = unwrap(self);
rb_scan_args(argc, argv, "*", &f_argv); Handle<Array> arguments = V8_Ref_Get<Array>(args);
Local<Function> function = V8_Ref_Get<Function>(self); Handle<Value> argv[arguments->Length()];
Local<Value> arguments[argc]; for (int i = 0; i < arguments->Length(); i++) {
for (int i = 0; i < argc; i++) { argv[i] = arguments->Get(i);
arguments[i] = *rr_rb2v8(rb_ary_entry(f_argv, i));
} }
return rr_v82rb(function->NewInstance(argc, arguments)); return rr_v82rb(function->NewInstance(NUM2INT(argc), argv));
} }
VALUE GetName(VALUE self) { VALUE GetName(VALUE self) {
return rr_v82rb(unwrap(self)->GetName()); return rr_v82rb(unwrap(self)->GetName());
@ -74,7 +73,7 @@ namespace {
void rr_init_func() { void rr_init_func() {
FunctionClass = rr_define_class("Function", rr_cV8_C_Object); FunctionClass = rr_define_class("Function", rr_cV8_C_Object);
rr_define_method(FunctionClass, "Call", Call, -1); rr_define_method(FunctionClass, "Call", Call, -1);
rr_define_method(FunctionClass, "NewInstance", NewInstance, -1); rr_define_method(FunctionClass, "NewInstance", NewInstance, 2);
rr_define_method(FunctionClass, "GetName", GetName, 0); rr_define_method(FunctionClass, "GetName", GetName, 0);
rr_define_method(FunctionClass, "SetName", SetName, 1); rr_define_method(FunctionClass, "SetName", SetName, 1);
// rr_define_method(FunctionClass, "GetScriptOrigin", GetScriptOrigin, 0); // rr_define_method(FunctionClass, "GetScriptOrigin", GetScriptOrigin, 0);

View file

@ -1,7 +1,7 @@
module V8 module V8
class Function < V8::Object class Function < V8::Object
def call(thisObject, *args) def methodcall(thisObject, *args)
err = nil err = nil
return_value = nil return_value = nil
C::TryCatch.try do |try| C::TryCatch.try do |try|
@ -15,6 +15,16 @@ module V8
return return_value return return_value
end end
def call(*args)
self.methodcall(@context.Global(), *args)
end
def new(*args)
@context.enter do
To.rb(@native.NewInstance(args.length, To.v8(args)))
end
end
def self.rubycall(rubycode, *args) def self.rubycall(rubycode, *args)
begin begin
To.v8(rubycode.call(*args)) To.v8(rubycode.call(*args))

View file

@ -45,7 +45,7 @@ module V8
end end
when ::Time when ::Time
C::Date::New(value) C::Date::New(value)
when nil,Numeric,TrueClass,FalseClass when nil,Numeric,TrueClass,FalseClass, C::Value
value value
else else
rubyobject = C::ObjectTemplate::New() rubyobject = C::ObjectTemplate::New()

View file

@ -6,21 +6,21 @@ describe C::Function do
it "is callable" do it "is callable" do
Context.new do |cxt| Context.new do |cxt|
f = cxt.eval('(function() {return "Hello World"})', '<eval>'); f = cxt.eval('(function() {return "Hello World"})', '<eval>');
f.call(nil).should == "Hello World" f.call().should == "Hello World"
end end
end end
it "receives proper argument length from ruby" do it "receives proper argument length from ruby" do
Context.new do |cxt| Context.new do |cxt|
f = cxt.eval('(function() {return arguments.length})', 'eval') f = cxt.eval('(function() {return arguments.length})', 'eval')
f.call(nil,1, 2, 3).should == 3 f.call(1, 2, 3).should == 3
end end
end end
it "maps all arguments from ruby" do it "maps all arguments from ruby" do
Context.new do |cxt| Context.new do |cxt|
f = cxt.eval('(function(one, two, three) {return one + two + three})', 'eval') f = cxt.eval('(function(one, two, three) {return one + two + three})', 'eval')
f.call(nil, 1,2,3).should == 6 f.call(1,2,3).should == 6
end end
end end
@ -28,7 +28,7 @@ describe C::Function do
Context.new do |cxt| Context.new do |cxt|
Object.new.tap do |this| Object.new.tap do |this|
f = cxt.eval('(function() {return this})', 'eval') f = cxt.eval('(function() {return this})', 'eval')
f.call(this).should be(this) f.methodcall(this).should be(this)
end end
end end
end end
@ -37,7 +37,7 @@ describe C::Function do
Context.new do |cxt| Context.new do |cxt|
@f = cxt.eval('(function() {return "Call Me"})', 'eval') @f = cxt.eval('(function() {return "Call Me"})', 'eval')
end end
@f.call(nil).should == "Call Me" @f.call().should == "Call Me"
end end
it "is reflected properly" do it "is reflected properly" do