mirror of
https://github.com/rubyjs/therubyracer
synced 2023-03-27 23:21:42 -04:00
move eval() implementation into C. make global stateless converters
This commit is contained in:
parent
6838c68de5
commit
47103149c9
10 changed files with 33 additions and 26 deletions
|
@ -44,10 +44,13 @@ template<class DEST, class RET> class RubyValueSource {
|
||||||
return dest.pushBool(true);
|
return dest.pushBool(true);
|
||||||
case T_FALSE:
|
case T_FALSE:
|
||||||
return dest.pushBool(false);
|
return dest.pushBool(false);
|
||||||
// case T_DATA:
|
case T_DATA:
|
||||||
// if (rb_is_function(value)) {
|
VALUE clsProc = rb_eval("::Proc");
|
||||||
// return dest.pushCode(new Code<RubyCaller>)
|
VALUE clsMethod = rb_eval("::Method");
|
||||||
// }
|
VALUE smartMatch = rb_intern("===");
|
||||||
|
if (RTEST(rb_funcall(clsProc, smartMatch, value)) || RTEST(rbfuncall(clsMethod, smartMatch, value))) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return dest.pushUndefined();
|
return dest.pushUndefined();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,4 +11,7 @@ typedef V8HandleSource<RubyValueDest, VALUE> convert_v8_to_rb_t;
|
||||||
typedef RubyValueSource<StringDest, std::string> convert_rb_to_string_t;
|
typedef RubyValueSource<StringDest, std::string> convert_rb_to_string_t;
|
||||||
typedef V8HandleSource<StringDest, std::string> convert_v8_to_string_t;
|
typedef V8HandleSource<StringDest, std::string> convert_v8_to_string_t;
|
||||||
|
|
||||||
|
extern convert_v8_to_rb_t V82RB;
|
||||||
|
extern convert_rb_to_v8_t RB2V8;
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -28,6 +28,7 @@ extern "C" {
|
||||||
ruby_method_class = rb_eval_string("::Method");
|
ruby_method_class = rb_eval_string("::Method");
|
||||||
|
|
||||||
rb_mModule = rb_define_module("V8");
|
rb_mModule = rb_define_module("V8");
|
||||||
|
rb_define_singleton_method(rb_mModule, "what_is_this?", (VALUE(*)(...)) v8_what_is_this, 1);
|
||||||
|
|
||||||
//native module setup
|
//native module setup
|
||||||
VALUE rb_mNative = rb_define_module_under(rb_mModule, "C");
|
VALUE rb_mNative = rb_define_module_under(rb_mModule, "C");
|
||||||
|
@ -37,6 +38,7 @@ extern "C" {
|
||||||
rb_define_singleton_method(V8__C__Context, "new", (VALUE(*)(...)) v8_Context_New, -1);
|
rb_define_singleton_method(V8__C__Context, "new", (VALUE(*)(...)) v8_Context_New, -1);
|
||||||
rb_define_method(V8__C__Context, "Global", (VALUE(*)(...)) v8_cxt_Global, 0);
|
rb_define_method(V8__C__Context, "Global", (VALUE(*)(...)) v8_cxt_Global, 0);
|
||||||
rb_define_method(V8__C__Context, "open", (VALUE(*)(...)) v8_cxt_open, 0);
|
rb_define_method(V8__C__Context, "open", (VALUE(*)(...)) v8_cxt_open, 0);
|
||||||
|
rb_define_method(V8__C__Context, "eval", (VALUE(*)(...)) v8_cxt_eval, 1);
|
||||||
|
|
||||||
//native String
|
//native String
|
||||||
VALUE V8__C__String = rb_define_class_under(rb_mNative, "String", rb_cObject);
|
VALUE V8__C__String = rb_define_class_under(rb_mNative, "String", rb_cObject);
|
||||||
|
|
|
@ -30,20 +30,26 @@ VALUE v8_cxt_open(VALUE self) {
|
||||||
Local<Context> cxt = V8_Ref_Get<Context>(self);
|
Local<Context> cxt = V8_Ref_Get<Context>(self);
|
||||||
Context::Scope enter(cxt);
|
Context::Scope enter(cxt);
|
||||||
if (rb_block_given_p()) {
|
if (rb_block_given_p()) {
|
||||||
printf("<div>About to execute Ruby Block</div>");
|
|
||||||
VALUE result = rb_yield(self);
|
VALUE result = rb_yield(self);
|
||||||
printf("<div>Ruby Block was executed</div>\n");
|
|
||||||
if (exceptions.HasCaught()) {
|
if (exceptions.HasCaught()) {
|
||||||
return V8_Wrap_Message(exceptions.Message());
|
return V8_Wrap_Message(exceptions.Message());
|
||||||
} else {
|
} else {
|
||||||
printf("<div>No exception</div>");
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
printf("<div>No block given!</div>");
|
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE v8_cxt_eval(VALUE self, VALUE source) {
|
||||||
|
HandleScope handles;
|
||||||
|
Local<Context> cxt = V8_Ref_Get<Context>(self);
|
||||||
|
Context::Scope enter(cxt);
|
||||||
|
Local<Value> source_str = RB2V8(source);
|
||||||
|
Local<Script> script = Script::Compile(source_str->ToString());
|
||||||
|
Local<Value> result = script->Run();
|
||||||
|
return V82RB(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,5 +11,6 @@ extern VALUE V8_C_Object;
|
||||||
VALUE v8_Context_New(int argc, VALUE *argv, VALUE self);
|
VALUE v8_Context_New(int argc, VALUE *argv, VALUE self);
|
||||||
VALUE v8_cxt_Global(VALUE self);
|
VALUE v8_cxt_Global(VALUE self);
|
||||||
VALUE v8_cxt_open(VALUE self);
|
VALUE v8_cxt_open(VALUE self);
|
||||||
|
VALUE v8_cxt_eval(VALUE self, VALUE source);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -13,12 +13,10 @@ VALUE v8_Object_New(VALUE clazz) {
|
||||||
|
|
||||||
VALUE v8_Object_Get(VALUE self, VALUE key) {
|
VALUE v8_Object_Get(VALUE self, VALUE key) {
|
||||||
HandleScope handles;
|
HandleScope handles;
|
||||||
convert_rb_to_v8_t rb2v8;
|
|
||||||
convert_v8_to_rb_t v82rb;
|
|
||||||
Local<Object> obj = V8_Ref_Get<Object>(self);
|
Local<Object> obj = V8_Ref_Get<Object>(self);
|
||||||
VALUE keystr = rb_funcall(key,rb_intern("to_s"), 0);
|
VALUE keystr = rb_funcall(key,rb_intern("to_s"), 0);
|
||||||
Local<Value> value = obj->Get(rb2v8(keystr));
|
Local<Value> value = obj->Get(RB2V8(keystr));
|
||||||
return v82rb(value);
|
return V82RB(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE v8_Object_Set(VALUE self, VALUE key, VALUE value) {
|
VALUE v8_Object_Set(VALUE self, VALUE key, VALUE value) {
|
||||||
|
|
|
@ -11,20 +11,17 @@ Handle<Value> RubyInvocationCallback(const Arguments& args) {
|
||||||
VALUE code = (VALUE)External::Unwrap(args.Data());
|
VALUE code = (VALUE)External::Unwrap(args.Data());
|
||||||
if (NIL_P(code)) {
|
if (NIL_P(code)) {
|
||||||
return Null();
|
return Null();
|
||||||
} else {
|
} else {
|
||||||
convert_v8_to_rb_t arg_cvt;
|
|
||||||
convert_rb_to_v8_t ret_cvt;
|
|
||||||
|
|
||||||
VALUE* arguments = new VALUE[args.Length()];
|
VALUE* arguments = new VALUE[args.Length()];
|
||||||
for(int c=0;c<args.Length(); ++c) {
|
for(int c=0;c<args.Length(); ++c) {
|
||||||
Handle<Value> val = args[c];
|
Handle<Value> val = args[c];
|
||||||
arguments[c] = arg_cvt(val);
|
arguments[c] = V82RB(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE result = rb_funcall2(code, rb_intern("call"), args.Length(), arguments);
|
VALUE result = rb_funcall2(code, rb_intern("call"), args.Length(), arguments);
|
||||||
delete [] arguments;
|
delete [] arguments;
|
||||||
|
|
||||||
Handle<Value> convertedResult = ret_cvt(result);
|
Handle<Value> convertedResult = RB2V8(result);
|
||||||
return convertedResult ;
|
return convertedResult ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
module V8
|
module V8
|
||||||
# This doesn't do anything at the moment. But the ruby interface will go here
|
|
||||||
# The native interface is under the V8::C module.
|
|
||||||
class Context
|
class Context
|
||||||
def initialize
|
def initialize
|
||||||
@native = C::Context.new
|
@native = C::Context.new
|
||||||
|
@ -9,16 +7,13 @@ module V8
|
||||||
def open(&block)
|
def open(&block)
|
||||||
@native.open do
|
@native.open do
|
||||||
block.call(self).tap do |result|
|
block.call(self).tap do |result|
|
||||||
# puts ERB::Util.h(result)
|
|
||||||
raise JavascriptError.new(result) if result.kind_of?(C::Message)
|
raise JavascriptError.new(result) if result.kind_of?(C::Message)
|
||||||
end
|
end
|
||||||
end if block_given?
|
end if block_given?
|
||||||
end
|
end
|
||||||
|
|
||||||
def eval(javascript)
|
def eval(javascript)
|
||||||
source = V8::C::String.new(javascript.to_s)
|
To.ruby @native.eval(javascript)
|
||||||
script = V8::C::Script.new(source)
|
|
||||||
To.ruby(script.Run())
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def evaluate(*args)
|
def evaluate(*args)
|
||||||
|
@ -28,7 +23,7 @@ module V8
|
||||||
def []=(key, value)
|
def []=(key, value)
|
||||||
value.tap do
|
value.tap do
|
||||||
@native.Global().tap do |scope|
|
@native.Global().tap do |scope|
|
||||||
scope.Set(key.to_s, To.v8(value))
|
scope.Set(key.to_s, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,7 @@ module V8
|
||||||
end
|
end
|
||||||
|
|
||||||
def [](key)
|
def [](key)
|
||||||
To.ruby(@native.Get(To.v8(key)))
|
To.ruby(@native.Get(key))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
|
@ -5,6 +5,7 @@ module V8
|
||||||
def ruby(value)
|
def ruby(value)
|
||||||
case value
|
case value
|
||||||
when V8::C::Object then V8::Object.new(value)
|
when V8::C::Object then V8::Object.new(value)
|
||||||
|
when V8::C::String then "Wonkers!"
|
||||||
else
|
else
|
||||||
value
|
value
|
||||||
end
|
end
|
||||||
|
@ -14,6 +15,7 @@ module V8
|
||||||
case value
|
case value
|
||||||
when String then C::String.new(value)
|
when String then C::String.new(value)
|
||||||
when Proc then C::FunctionTemplate.new(&value).GetFunction()
|
when Proc then C::FunctionTemplate.new(&value).GetFunction()
|
||||||
|
when Method then C::FunctionTemplate.new(&value.to_proc).GetFunction()
|
||||||
else
|
else
|
||||||
value
|
value
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue