therubyracer 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of therubyracer might be problematic. Click here for more details.
- data/Doxyfile +1514 -0
- data/History.txt +4 -0
- data/Manifest.txt +48 -0
- data/README.rdoc +49 -0
- data/Rakefile +36 -0
- data/docs/data_conversion.txt +18 -0
- data/ext/v8/convert_ruby.cpp +8 -0
- data/ext/v8/convert_ruby.h +106 -0
- data/ext/v8/convert_string.cpp +10 -0
- data/ext/v8/convert_string.h +73 -0
- data/ext/v8/convert_v8.cpp +9 -0
- data/ext/v8/convert_v8.h +113 -0
- data/ext/v8/converters.cpp +4 -0
- data/ext/v8/converters.h +17 -0
- data/ext/v8/extconf.rb +25 -0
- data/ext/v8/v8.cpp +70 -0
- data/ext/v8/v8_cxt.cpp +55 -0
- data/ext/v8/v8_cxt.h +16 -0
- data/ext/v8/v8_func.cpp +10 -0
- data/ext/v8/v8_func.h +11 -0
- data/ext/v8/v8_msg.cpp +11 -0
- data/ext/v8/v8_msg.h +9 -0
- data/ext/v8/v8_obj.cpp +29 -0
- data/ext/v8/v8_obj.h +11 -0
- data/ext/v8/v8_ref.cpp +27 -0
- data/ext/v8/v8_ref.h +31 -0
- data/ext/v8/v8_script.cpp +21 -0
- data/ext/v8/v8_script.h +8 -0
- data/ext/v8/v8_standalone.cpp +70 -0
- data/ext/v8/v8_standalone.h +31 -0
- data/ext/v8/v8_str.cpp +17 -0
- data/ext/v8/v8_str.h +9 -0
- data/ext/v8/v8_template.cpp +55 -0
- data/ext/v8/v8_template.h +11 -0
- data/lib/v8.rb +10 -0
- data/lib/v8/context.rb +41 -0
- data/lib/v8/object.rb +12 -0
- data/lib/v8/to.rb +25 -0
- data/script/console +10 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/redjs/README.txt +8 -0
- data/spec/redjs/jsapi_spec.rb +376 -0
- data/spec/redjs_helper.rb +3 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +14 -0
- data/tasks/rspec.rake +21 -0
- data/therubyracer.gemspec +34 -0
- metadata +118 -0
data/ext/v8/converters.h
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#ifndef __converters_h__
|
2
|
+
#define __converters_h__
|
3
|
+
|
4
|
+
#include "convert_ruby.h"
|
5
|
+
#include "convert_string.h"
|
6
|
+
#include "convert_v8.h"
|
7
|
+
|
8
|
+
typedef RubyValueSource<V8LocalDest, v8::Local<v8::Value> > convert_rb_to_v8_t;
|
9
|
+
typedef V8HandleSource<RubyValueDest, VALUE> convert_v8_to_rb_t;
|
10
|
+
|
11
|
+
typedef RubyValueSource<StringDest, std::string> convert_rb_to_string_t;
|
12
|
+
typedef V8HandleSource<StringDest, std::string> convert_v8_to_string_t;
|
13
|
+
|
14
|
+
extern convert_v8_to_rb_t V82RB;
|
15
|
+
extern convert_rb_to_v8_t RB2V8;
|
16
|
+
|
17
|
+
#endif
|
data/ext/v8/extconf.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
#!/opt/local/bin/ruby
|
2
|
+
require 'mkmf'
|
3
|
+
|
4
|
+
dir_config('v8')
|
5
|
+
have_library('v8') or raise "unable to find libv8"
|
6
|
+
|
7
|
+
create_makefile('v8')
|
8
|
+
|
9
|
+
# now add a few extra targets
|
10
|
+
File.open("Makefile", "a") do |makefile|
|
11
|
+
makefile.print <<EOF
|
12
|
+
|
13
|
+
test: all
|
14
|
+
@echo running spec...
|
15
|
+
spec -O spec/spec.opts spec/therubyracer_spec.rb
|
16
|
+
|
17
|
+
docs/cpp:
|
18
|
+
mkdir -p docs/cpp
|
19
|
+
|
20
|
+
docs: all docs/cpp
|
21
|
+
@echo Generate C++ docs to docs/cpp/html
|
22
|
+
doxygen Doxyfile
|
23
|
+
|
24
|
+
EOF
|
25
|
+
end
|
data/ext/v8/v8.cpp
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
#include "v8_cxt.h"
|
2
|
+
#include "v8_str.h"
|
3
|
+
#include "v8_obj.h"
|
4
|
+
#include "v8_msg.h"
|
5
|
+
#include "v8_func.h"
|
6
|
+
#include "v8_script.h"
|
7
|
+
#include "v8_template.h"
|
8
|
+
#include "v8_standalone.h"
|
9
|
+
|
10
|
+
#include <stdio.h>
|
11
|
+
|
12
|
+
extern "C" {
|
13
|
+
/**
|
14
|
+
* ruby init method for the extension
|
15
|
+
*/
|
16
|
+
void Init_v8();
|
17
|
+
}
|
18
|
+
|
19
|
+
VALUE rb_mModule;
|
20
|
+
VALUE rb_cV8;
|
21
|
+
|
22
|
+
extern "C" {
|
23
|
+
void Init_v8() {
|
24
|
+
|
25
|
+
ruby_call_symbol = ID2SYM(rb_intern("call"));
|
26
|
+
ruby_respond_to_ID = rb_intern("respond_to?");
|
27
|
+
ruby_proc_class = rb_eval_string("::Proc");
|
28
|
+
ruby_method_class = rb_eval_string("::Method");
|
29
|
+
|
30
|
+
rb_mModule = rb_define_module("V8");
|
31
|
+
rb_define_singleton_method(rb_mModule, "what_is_this?", (VALUE(*)(...)) v8_what_is_this, 1);
|
32
|
+
|
33
|
+
//native module setup
|
34
|
+
VALUE rb_mNative = rb_define_module_under(rb_mModule, "C");
|
35
|
+
|
36
|
+
//native context
|
37
|
+
VALUE V8__C__Context = rb_define_class_under(rb_mNative, "Context", rb_cObject);
|
38
|
+
rb_define_singleton_method(V8__C__Context, "new", (VALUE(*)(...)) v8_Context_New, -1);
|
39
|
+
rb_define_method(V8__C__Context, "Global", (VALUE(*)(...)) v8_cxt_Global, 0);
|
40
|
+
rb_define_method(V8__C__Context, "open", (VALUE(*)(...)) v8_cxt_open, 0);
|
41
|
+
rb_define_method(V8__C__Context, "eval", (VALUE(*)(...)) v8_cxt_eval, 1);
|
42
|
+
|
43
|
+
//native String
|
44
|
+
VALUE V8__C__String = rb_define_class_under(rb_mNative, "String", rb_cObject);
|
45
|
+
rb_define_singleton_method(V8__C__String, "new", (VALUE(*)(...)) v8_str_new, 1);
|
46
|
+
rb_define_method(V8__C__String, "to_s", (VALUE(*)(...)) v8_str_to_s, 0);
|
47
|
+
|
48
|
+
VALUE V8__C__Script = rb_define_class_under(rb_mNative, "Script", rb_cObject);
|
49
|
+
rb_define_singleton_method(V8__C__Script, "new", (VALUE(*)(...)) v8_script_new, 1);
|
50
|
+
rb_define_method(V8__C__Script, "Run", (VALUE(*)(...)) v8_script_Run, 0);
|
51
|
+
|
52
|
+
VALUE V8__C__Template = rb_define_class_under(rb_mNative, "Template", rb_cObject);
|
53
|
+
rb_define_method(V8__C__Template, "Set", (VALUE(*)(...))v8_Template_Set, 2);
|
54
|
+
|
55
|
+
VALUE V8__C__ObjectTemplate = rb_define_class_under(rb_mNative, "ObjectTemplate", V8__C__Template);
|
56
|
+
rb_define_singleton_method(V8__C__ObjectTemplate, "new", (VALUE(*)(...))v8_ObjectTemplate_New, 0);
|
57
|
+
|
58
|
+
VALUE V8__C__FunctionTemplate = rb_define_class_under(rb_mNative, "FunctionTemplate", V8__C__Template);
|
59
|
+
rb_define_singleton_method(V8__C__FunctionTemplate, "new", (VALUE(*)(...))v8_FunctionTemplate_New, -1);
|
60
|
+
rb_define_method(V8__C__FunctionTemplate, "GetFunction", (VALUE(*)(...))v8_FunctionTemplate_GetFunction, 0);
|
61
|
+
|
62
|
+
V8_C_Object = rb_define_class_under(rb_mNative, "Object", rb_cObject);
|
63
|
+
rb_define_singleton_method(V8_C_Object, "new", (VALUE(*)(...))v8_Object_New, 0);
|
64
|
+
rb_define_method(V8_C_Object, "Get", (VALUE(*)(...))v8_Object_Get, 1);
|
65
|
+
rb_define_method(V8_C_Object, "Set", (VALUE(*)(...))v8_Object_Set, 2);
|
66
|
+
|
67
|
+
V8_C_Message = rb_define_class_under(rb_mNative, "Message", rb_cObject);
|
68
|
+
V8_C_Function = rb_define_class_under(rb_mNative, "Function", V8_C_Object);
|
69
|
+
}
|
70
|
+
}
|
data/ext/v8/v8_cxt.cpp
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
#include "v8_cxt.h"
|
2
|
+
#include "v8_msg.h"
|
3
|
+
#include "converters.h"
|
4
|
+
|
5
|
+
using namespace v8;
|
6
|
+
|
7
|
+
VALUE v8_Context_New(int argc, VALUE *argv, VALUE self) {
|
8
|
+
HandleScope handles;
|
9
|
+
VALUE scope;
|
10
|
+
rb_scan_args(argc,argv, "01", &scope);
|
11
|
+
if (NIL_P(scope)) {
|
12
|
+
return V8_Ref_Create(self, Context::New());
|
13
|
+
} else {
|
14
|
+
Local<ObjectTemplate> t = V8_Ref_Get<ObjectTemplate>(scope);
|
15
|
+
return V8_Ref_Create(self, Context::New(0, t));
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
VALUE v8_cxt_Global(VALUE self) {
|
20
|
+
HandleScope handles;
|
21
|
+
convert_v8_to_rb_t v82rb;
|
22
|
+
Local<Context> cxt = V8_Ref_Get<Context>(self);
|
23
|
+
Local<Value> global = *cxt->Global();
|
24
|
+
return v82rb(global);
|
25
|
+
}
|
26
|
+
|
27
|
+
VALUE v8_cxt_open(VALUE self) {
|
28
|
+
HandleScope handles;
|
29
|
+
TryCatch exceptions;
|
30
|
+
Local<Context> cxt = V8_Ref_Get<Context>(self);
|
31
|
+
Context::Scope enter(cxt);
|
32
|
+
if (rb_block_given_p()) {
|
33
|
+
VALUE result = rb_yield(self);
|
34
|
+
if (exceptions.HasCaught()) {
|
35
|
+
return V8_Wrap_Message(exceptions.Message());
|
36
|
+
} else {
|
37
|
+
return result;
|
38
|
+
}
|
39
|
+
return result;
|
40
|
+
} else {
|
41
|
+
return Qnil;
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
VALUE v8_cxt_eval(VALUE self, VALUE source) {
|
46
|
+
HandleScope handles;
|
47
|
+
Local<Context> cxt = V8_Ref_Get<Context>(self);
|
48
|
+
Context::Scope enter(cxt);
|
49
|
+
Local<Value> source_str = RB2V8(source);
|
50
|
+
Local<Script> script = Script::Compile(source_str->ToString());
|
51
|
+
Local<Value> result = script->Run();
|
52
|
+
return V82RB(result);
|
53
|
+
}
|
54
|
+
|
55
|
+
|
data/ext/v8/v8_cxt.h
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#ifndef _RUBY_V8_CXT_
|
2
|
+
#define _RUBY_V8_CXT_
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
#include "v8.h"
|
6
|
+
#include "v8_ref.h"
|
7
|
+
|
8
|
+
extern VALUE rb_cV8;
|
9
|
+
extern VALUE V8_C_Object;
|
10
|
+
|
11
|
+
VALUE v8_Context_New(int argc, VALUE *argv, VALUE self);
|
12
|
+
VALUE v8_cxt_Global(VALUE self);
|
13
|
+
VALUE v8_cxt_open(VALUE self);
|
14
|
+
VALUE v8_cxt_eval(VALUE self, VALUE source);
|
15
|
+
|
16
|
+
#endif
|
data/ext/v8/v8_func.cpp
ADDED
data/ext/v8/v8_func.h
ADDED
data/ext/v8/v8_msg.cpp
ADDED
data/ext/v8/v8_msg.h
ADDED
data/ext/v8/v8_obj.cpp
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#include "v8_obj.h"
|
2
|
+
#include "v8_ref.h"
|
3
|
+
#include "converters.h"
|
4
|
+
|
5
|
+
using namespace v8;
|
6
|
+
|
7
|
+
VALUE V8_C_Object;
|
8
|
+
|
9
|
+
VALUE v8_Object_New(VALUE clazz) {
|
10
|
+
HandleScope handles;
|
11
|
+
return V8_Ref_Create(clazz, Object::New());
|
12
|
+
}
|
13
|
+
|
14
|
+
VALUE v8_Object_Get(VALUE self, VALUE key) {
|
15
|
+
HandleScope handles;
|
16
|
+
Local<Object> obj = V8_Ref_Get<Object>(self);
|
17
|
+
VALUE keystr = rb_funcall(key,rb_intern("to_s"), 0);
|
18
|
+
Local<Value> value = obj->Get(RB2V8(keystr));
|
19
|
+
return V82RB(value);
|
20
|
+
}
|
21
|
+
|
22
|
+
VALUE v8_Object_Set(VALUE self, VALUE key, VALUE value) {
|
23
|
+
HandleScope handles;
|
24
|
+
convert_rb_to_v8_t rb2v8;
|
25
|
+
Local<Object> obj = V8_Ref_Get<Object>(self);
|
26
|
+
VALUE keystr = rb_funcall(key, rb_intern("to_s"), 0);
|
27
|
+
obj->Set(rb2v8(keystr), rb2v8(value));
|
28
|
+
return Qnil;
|
29
|
+
}
|
data/ext/v8/v8_obj.h
ADDED
data/ext/v8/v8_ref.cpp
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#include <v8_ref.h>
|
2
|
+
#include "stdio.h"
|
3
|
+
using namespace v8;
|
4
|
+
|
5
|
+
|
6
|
+
v8_ref::v8_ref(Handle<void> object, VALUE ref) : handle(Persistent<void>::New(object)), references(ref) {
|
7
|
+
//printf("Allocating v8 reference\n");
|
8
|
+
}
|
9
|
+
|
10
|
+
v8_ref::~v8_ref() {
|
11
|
+
//printf("Disposing v8 reference\n");
|
12
|
+
handle.Dispose();
|
13
|
+
}
|
14
|
+
|
15
|
+
void v8_ref_mark(v8_ref* ref) {
|
16
|
+
if (ref->references != 0) {
|
17
|
+
rb_gc_mark(ref->references);
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
void v8_ref_free(v8_ref* ref) {
|
22
|
+
delete ref;
|
23
|
+
}
|
24
|
+
|
25
|
+
VALUE V8_Ref_Create(VALUE ruby_class, v8::Handle<void> handle, VALUE ref) {
|
26
|
+
return Data_Wrap_Struct(ruby_class, v8_ref_mark, v8_ref_free, new v8_ref(handle, ref));
|
27
|
+
}
|
data/ext/v8/v8_ref.h
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
#ifndef _RUBY_V8_REF_
|
2
|
+
#define _RUBY_V8_REF_
|
3
|
+
|
4
|
+
#include <v8.h>
|
5
|
+
#include "ruby.h"
|
6
|
+
|
7
|
+
//the v8_ref wraps a v8 handle so that ruby can hold a reference to it.
|
8
|
+
|
9
|
+
struct v8_ref {
|
10
|
+
//takes a handle object and adds a new persistent handle for
|
11
|
+
//the referenced object
|
12
|
+
v8_ref(v8::Handle<void> object, VALUE ref = 0);
|
13
|
+
virtual ~v8_ref();
|
14
|
+
v8::Persistent<void> handle;
|
15
|
+
VALUE references;
|
16
|
+
};
|
17
|
+
|
18
|
+
|
19
|
+
//memory management
|
20
|
+
void v8_ref_mark(v8_ref* ref);
|
21
|
+
void v8_ref_free(v8_ref* ref);
|
22
|
+
|
23
|
+
VALUE V8_Ref_Create(VALUE ruby_class, v8::Handle<void> handle, VALUE ref = 0);
|
24
|
+
|
25
|
+
template <class T> v8::Local<T> V8_Ref_Get(VALUE object) {
|
26
|
+
v8_ref* ref = 0;
|
27
|
+
Data_Get_Struct(object, struct v8_ref, ref);
|
28
|
+
return (T *)*ref->handle;
|
29
|
+
}
|
30
|
+
|
31
|
+
#endif
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#include "v8.h"
|
2
|
+
#include "v8_ref.h"
|
3
|
+
#include "v8_script.h"
|
4
|
+
#include "converters.h"
|
5
|
+
|
6
|
+
using namespace v8;
|
7
|
+
|
8
|
+
|
9
|
+
VALUE v8_script_new(VALUE self, VALUE source) {
|
10
|
+
HandleScope handles;
|
11
|
+
Local<String> src = V8_Ref_Get<String>(source);
|
12
|
+
return V8_Ref_Create(self, Script::New(src));
|
13
|
+
}
|
14
|
+
|
15
|
+
VALUE v8_script_Run(VALUE self) {
|
16
|
+
HandleScope handles;
|
17
|
+
Local<Script> script = V8_Ref_Get<Script>(self);
|
18
|
+
convert_v8_to_rb_t toValue;
|
19
|
+
Local<Value> result = script->Run();
|
20
|
+
return toValue(result);
|
21
|
+
}
|
data/ext/v8/v8_script.h
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
#include "v8_standalone.h"
|
2
|
+
|
3
|
+
VALUE ruby_call_symbol;
|
4
|
+
VALUE ruby_respond_to_ID;
|
5
|
+
|
6
|
+
VALUE ruby_proc_class;
|
7
|
+
VALUE ruby_method_class;
|
8
|
+
|
9
|
+
|
10
|
+
bool is_callable(VALUE& object) {
|
11
|
+
return Qtrue == rb_funcall(object, ruby_respond_to_ID, 1, ruby_call_symbol);
|
12
|
+
}
|
13
|
+
|
14
|
+
bool is_function(VALUE& object) {
|
15
|
+
VALUE klass = RDATA(object)->basic.klass;
|
16
|
+
return klass == ruby_proc_class || klass == ruby_method_class;
|
17
|
+
}
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Debugging aid
|
21
|
+
*/
|
22
|
+
VALUE v8_what_is_this(VALUE self, VALUE object) {
|
23
|
+
VALUE boolean;
|
24
|
+
switch (TYPE(object)) {
|
25
|
+
case T_NIL:
|
26
|
+
printf("nil\n");
|
27
|
+
break;
|
28
|
+
case T_OBJECT:
|
29
|
+
printf("ordinary object\n");
|
30
|
+
if (is_callable(object)) {
|
31
|
+
printf("responds to call!<br/>");
|
32
|
+
}
|
33
|
+
break;
|
34
|
+
case T_CLASS:
|
35
|
+
printf("class[%s]<br/>", rb_class2name(object));
|
36
|
+
break;
|
37
|
+
case T_MODULE: printf("module\n"); break;
|
38
|
+
case T_FLOAT: printf("floating point number\n"); break;
|
39
|
+
case T_STRING: printf("string\n"); break;
|
40
|
+
case T_REGEXP: printf("regular expression\n"); break;
|
41
|
+
case T_ARRAY: printf("array\n"); break;
|
42
|
+
case T_FIXNUM: printf("Fixnum(31bit integer)\n"); break;
|
43
|
+
case T_HASH: printf("associative array\n"); break;
|
44
|
+
case T_STRUCT: printf("(Ruby) structure\n"); break;
|
45
|
+
case T_BIGNUM: printf("multi precision integer\n"); break;
|
46
|
+
case T_FILE: printf("IO\n"); break;
|
47
|
+
case T_TRUE: printf("true\n"); break;
|
48
|
+
case T_FALSE: printf("false\n"); break;
|
49
|
+
case T_DATA:
|
50
|
+
printf("data... inspecting\n");
|
51
|
+
if (is_function(object)) {
|
52
|
+
printf("It's a function!!!<br/>");
|
53
|
+
}
|
54
|
+
if (is_callable(object)) {
|
55
|
+
printf("Responds to call!<br/>");
|
56
|
+
} else {
|
57
|
+
printf("Does *NOT* respond to call<br/>");
|
58
|
+
}
|
59
|
+
v8_what_is_this(Qnil, RDATA(object)->basic.klass);
|
60
|
+
break;
|
61
|
+
case T_SYMBOL: printf("symbol\n"); break;
|
62
|
+
|
63
|
+
default:
|
64
|
+
printf("I have no idea!!!\n");
|
65
|
+
rb_raise(rb_eTypeError, "not valid value");
|
66
|
+
break;
|
67
|
+
}
|
68
|
+
|
69
|
+
return Qnil;
|
70
|
+
}
|