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.

@@ -0,0 +1,4 @@
1
+ #include "converters.h"
2
+
3
+ convert_v8_to_rb_t V82RB;
4
+ convert_rb_to_v8_t RB2V8;
@@ -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
@@ -0,0 +1,10 @@
1
+
2
+ #include "v8_func.h"
3
+
4
+ using namespace v8;
5
+
6
+ VALUE V8_C_Function;
7
+
8
+ VALUE V8_Wrap_Function(Handle<Function> f) {
9
+ return V8_Ref_Create(V8_C_Function, f);
10
+ }
data/ext/v8/v8_func.h ADDED
@@ -0,0 +1,11 @@
1
+ #ifndef _RUBY_V8_FUNCTION_
2
+ #define _RUBY_V8_FUNCTION_
3
+
4
+ #include "v8.h"
5
+ #include "ruby.h"
6
+ #include "v8_ref.h"
7
+
8
+ extern VALUE V8_C_Function;
9
+
10
+ VALUE V8_Wrap_Function(v8::Handle<v8::Function> f);
11
+ #endif
data/ext/v8/v8_msg.cpp ADDED
@@ -0,0 +1,11 @@
1
+
2
+ #include "v8_msg.h"
3
+ #include "v8_ref.h"
4
+
5
+ using namespace v8;
6
+
7
+ VALUE V8_C_Message;
8
+
9
+ VALUE V8_Wrap_Message(Handle<v8::Message> msg) {
10
+ return V8_Ref_Create(V8_C_Message, msg);
11
+ }
data/ext/v8/v8_msg.h ADDED
@@ -0,0 +1,9 @@
1
+ #ifndef _RUBY_V8_MESSAGE_
2
+ #define _RUBY_V8_MESSAGE_
3
+
4
+ #include "v8.h"
5
+ #include "ruby.h"
6
+
7
+ extern VALUE V8_C_Message;
8
+ VALUE V8_Wrap_Message(v8::Handle<v8::Message> msg);
9
+ #endif
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
@@ -0,0 +1,11 @@
1
+ #ifndef _RUBY_V8_OBJECT_
2
+ #define _RUBY_V8_OBJECT_
3
+
4
+ #include "ruby.h"
5
+
6
+ extern VALUE V8_C_Object;
7
+
8
+ VALUE v8_Object_New(VALUE clazz);
9
+ VALUE v8_Object_Get(VALUE self, VALUE key);
10
+ VALUE v8_Object_Set(VALUE self, VALUE key, VALUE value);
11
+ #endif
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
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef _RUBY_V8_SCRIPT_
2
+ #define _RUBY_V8_SCRIPT_
3
+
4
+ #include "ruby.h"
5
+
6
+ VALUE v8_script_new(VALUE self, VALUE source);
7
+ VALUE v8_script_Run(VALUE self);
8
+ #endif
@@ -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
+ }