therubyracer 0.4.0 → 0.4.1

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.

@@ -4,6 +4,8 @@ Manifest.txt
4
4
  README.rdoc
5
5
  Rakefile
6
6
  docs/data_conversion.txt
7
+ ext/v8/callbacks.cpp
8
+ ext/v8/callbacks.h
7
9
  ext/v8/convert_ruby.cpp
8
10
  ext/v8/convert_ruby.h
9
11
  ext/v8/convert_string.cpp
data/Rakefile CHANGED
@@ -26,6 +26,7 @@ end
26
26
 
27
27
  Rake::ExtensionTask.new("v8", $hoe.spec) do |ext|
28
28
  ext.lib_dir = "lib/v8"
29
+ ext.source_pattern = "*.{cpp,h}"
29
30
  end
30
31
 
31
32
  require 'newgem/tasks'
@@ -0,0 +1,25 @@
1
+ #include <ruby.h>
2
+
3
+ #include "callbacks.h"
4
+ #include "converters.h"
5
+
6
+ using namespace v8;
7
+
8
+ Handle<Value> RacerRubyInvocationCallback(const Arguments& args) {
9
+ VALUE code = (VALUE)External::Unwrap(args.Data());
10
+ if (NIL_P(code)) {
11
+ return Null();
12
+ } else {
13
+ VALUE* arguments = new VALUE[args.Length()];
14
+ for(int c=0;c<args.Length(); ++c) {
15
+ Handle<Value> val = args[c];
16
+ arguments[c] = V82RB(val);
17
+ }
18
+
19
+ VALUE result = rb_funcall2(code, rb_intern("call"), args.Length(), arguments);
20
+ delete [] arguments;
21
+
22
+ Handle<Value> convertedResult = RB2V8(result);
23
+ return convertedResult ;
24
+ }
25
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef CALLBACKS_H_8VK3LWBG
2
+ #define CALLBACKS_H_8VK3LWBG
3
+
4
+ #include <v8.h>
5
+
6
+ v8::Handle<v8::Value> RacerRubyInvocationCallback(const v8::Arguments& args);
7
+
8
+ #endif /* end of include guard: CALLBACKS_H_8VK3LWBG */
@@ -2,9 +2,6 @@
2
2
  #define __convert_ruby_h__
3
3
 
4
4
  #include <ruby.h>
5
- #include <v8.h>
6
- #include "v8_ref.h"
7
- #include "v8_obj.h"
8
5
  #include <string>
9
6
 
10
7
  /**
@@ -44,13 +41,6 @@ template<class DEST, class RET> class RubyValueSource {
44
41
  return dest.pushBool(true);
45
42
  case T_FALSE:
46
43
  return dest.pushBool(false);
47
- case T_DATA:
48
- VALUE clsProc = rb_eval("::Proc");
49
- VALUE clsMethod = rb_eval("::Method");
50
- VALUE smartMatch = rb_intern("===");
51
- if (RTEST(rb_funcall(clsProc, smartMatch, value)) || RTEST(rbfuncall(clsMethod, smartMatch, value))) {
52
-
53
- }
54
44
  }
55
45
  return dest.pushUndefined();
56
46
  }
@@ -96,10 +86,6 @@ class RubyValueDest {
96
86
  VALUE pushUndefined() {
97
87
  return Qnil;
98
88
  }
99
-
100
- VALUE pushObject(v8::Handle<v8::Object>& value) {
101
- return V8_Ref_Create(V8_C_Object, value);
102
- }
103
89
  };
104
90
 
105
91
 
@@ -15,57 +15,69 @@ template<class T, class R> class V8HandleSource {
15
15
  V8HandleSource() {}
16
16
  ~V8HandleSource() {}
17
17
 
18
- R operator() (v8::Handle<v8::Value>& value) {
18
+ bool operator() (v8::Handle<v8::Value>& value, R& result) {
19
+
20
+ // a bit klunky, but alternative is to evaluate what type the
21
+ // object is twice, which is unappealing
19
22
 
20
23
  if (value.IsEmpty()) {
21
- return dest.pushNull();
24
+ result = dest.pushNull();
25
+ return true;
22
26
  }
23
27
 
24
28
  if (value->IsUndefined()) {
25
- return dest.pushNull();
29
+ result = dest.pushNull();
30
+ return true;
26
31
  }
27
32
 
28
33
  if(value->IsNull()) {
29
- return dest.pushNull();
34
+ result = dest.pushNull();
35
+ return true;
30
36
  }
31
37
 
32
38
  if(value->IsTrue()) {
33
- return dest.pushBool(true);
39
+ result = dest.pushBool(true);
40
+ return true;
34
41
  }
35
42
 
36
43
  if(value->IsFalse()) {
37
- return dest.pushBool(false);
44
+ result = dest.pushBool(false);
45
+ return true;
38
46
  }
39
47
 
40
48
  if(value->IsString()) {
41
49
  v8::Local<v8::String> str = value->ToString();
42
- char buffer[1024];
43
- int strlen = str->Length();
44
- std::string output(strlen, 0);
45
- for (int total = 0; total < strlen;) {
46
- int written = str->WriteAscii(buffer, total, 1024);
47
- output.replace(total, written, buffer);
48
- total += written;
49
- }
50
- return dest.pushString(output);
50
+ result = convertString(str);
51
+ return true;
51
52
  }
52
53
 
53
54
  if(value->IsInt32()) {
54
- return dest.pushInt(value->Int32Value());
55
+ result = dest.pushInt(value->Int32Value());
56
+ return true;
55
57
  }
56
58
 
57
59
  if(value->IsNumber()) {
58
- return dest.pushDouble(value->NumberValue());
60
+ result = dest.pushDouble(value->NumberValue());
61
+ return true;
59
62
  }
60
63
 
61
- if (value->IsObject()) {
62
- v8::Local<v8::Object> object(v8::Object::Cast(*value));
63
- return dest.pushObject(object);
64
+ result = dest.pushNull();
65
+ return false;
66
+ }
67
+
68
+ R convertString(v8::Local<v8::String>& str) {
69
+ char buffer[1024];
70
+ int strlen = str->Length();
71
+ std::string output(strlen, 0);
72
+ for (int total = 0; total < strlen;) {
73
+ int written = str->WriteAscii(buffer, total, 1024);
74
+ output.replace(total, written, buffer);
75
+ total += written;
64
76
  }
65
-
66
- return dest.pushNull();
77
+ return dest.pushString(output);
67
78
  }
68
79
 
80
+
69
81
  };
70
82
 
71
83
  /**
@@ -103,10 +115,6 @@ public:
103
115
  v8::Local<v8::Value> pushUndefined() {
104
116
  return v8::Local<v8::Value>::New(v8::Undefined());
105
117
  }
106
-
107
- // v8:Local<v8:Value> pushFunction(Function) {
108
- //
109
- // }
110
118
  };
111
119
 
112
120
 
@@ -1,4 +1,61 @@
1
1
  #include "converters.h"
2
+ #include "callbacks.h"
3
+ #include "v8_ref.h"
4
+ #include "v8_obj.h"
2
5
 
3
- convert_v8_to_rb_t V82RB;
4
- convert_rb_to_v8_t RB2V8;
6
+ using namespace v8;
7
+
8
+ namespace {
9
+ std::string UNDEFINED_STR("undefined");
10
+ }
11
+
12
+ VALUE V82RB(Handle<Value>& value) {
13
+ convert_v8_to_rb_t convert;
14
+ VALUE result;
15
+ if(convert(value, result)) {
16
+ return result;
17
+ }
18
+
19
+ if (value->IsObject()) {
20
+ Local<Object> object(Object::Cast(*value));
21
+ return V8_Ref_Create(V8_C_Object, value);
22
+ }
23
+
24
+ return Qnil;
25
+ }
26
+
27
+ Local<Value> RB2V8(VALUE value) {
28
+
29
+ VALUE valueClass = rb_class_of(value);
30
+
31
+ if(valueClass == rb_cProc || valueClass == rb_cMethod) {
32
+ Local<FunctionTemplate> t = FunctionTemplate::New(RacerRubyInvocationCallback, External::Wrap((void *)value));
33
+ return t->GetFunction();
34
+ }
35
+
36
+ convert_rb_to_v8_t convert;
37
+ return convert(value);
38
+ }
39
+
40
+ std::string RB2String(VALUE value) {
41
+ convert_rb_to_string_t convert;
42
+ return convert(value);
43
+ }
44
+
45
+ std::string V82String(Handle<Value>& value) {
46
+ convert_v8_to_string_t convert;
47
+ std::string result;
48
+ if(convert(value, result)) {
49
+ return result;
50
+ }
51
+
52
+ if (value->IsObject()) {
53
+ Local<Object> object(Object::Cast(*value));
54
+ Local<String> str = object->ToString();
55
+ if(convert(value, result)) {
56
+ return result;
57
+ }
58
+ }
59
+
60
+ return UNDEFINED_STR;
61
+ }
@@ -4,6 +4,7 @@
4
4
  #include "convert_ruby.h"
5
5
  #include "convert_string.h"
6
6
  #include "convert_v8.h"
7
+ #include <cstring>
7
8
 
8
9
  typedef RubyValueSource<V8LocalDest, v8::Local<v8::Value> > convert_rb_to_v8_t;
9
10
  typedef V8HandleSource<RubyValueDest, VALUE> convert_v8_to_rb_t;
@@ -11,7 +12,10 @@ typedef V8HandleSource<RubyValueDest, VALUE> convert_v8_to_rb_t;
11
12
  typedef RubyValueSource<StringDest, std::string> convert_rb_to_string_t;
12
13
  typedef V8HandleSource<StringDest, std::string> convert_v8_to_string_t;
13
14
 
14
- extern convert_v8_to_rb_t V82RB;
15
- extern convert_rb_to_v8_t RB2V8;
15
+ VALUE V82RB(v8::Handle<v8::Value>& value);
16
+ v8::Local<v8::Value> RB2V8(VALUE value);
17
+
18
+ std::string RB2String(VALUE value);
19
+ std::string V82String(v8::Handle<v8::Value>& value);
16
20
 
17
21
  #endif
@@ -65,6 +65,8 @@ extern "C" {
65
65
  rb_define_method(V8_C_Object, "Set", (VALUE(*)(...))v8_Object_Set, 2);
66
66
 
67
67
  V8_C_Message = rb_define_class_under(rb_mNative, "Message", rb_cObject);
68
+ rb_define_method(V8_C_Message, "Get", (VALUE(*)(...))v8_Message_Get, 0);
69
+
68
70
  V8_C_Function = rb_define_class_under(rb_mNative, "Function", V8_C_Object);
69
71
  }
70
72
  }
@@ -18,25 +18,17 @@ VALUE v8_Context_New(int argc, VALUE *argv, VALUE self) {
18
18
 
19
19
  VALUE v8_cxt_Global(VALUE self) {
20
20
  HandleScope handles;
21
- convert_v8_to_rb_t v82rb;
22
21
  Local<Context> cxt = V8_Ref_Get<Context>(self);
23
22
  Local<Value> global = *cxt->Global();
24
- return v82rb(global);
23
+ return V82RB(global);
25
24
  }
26
25
 
27
26
  VALUE v8_cxt_open(VALUE self) {
28
27
  HandleScope handles;
29
- TryCatch exceptions;
30
28
  Local<Context> cxt = V8_Ref_Get<Context>(self);
31
29
  Context::Scope enter(cxt);
32
30
  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;
31
+ return rb_yield(self);
40
32
  } else {
41
33
  return Qnil;
42
34
  }
@@ -44,12 +36,17 @@ VALUE v8_cxt_open(VALUE self) {
44
36
 
45
37
  VALUE v8_cxt_eval(VALUE self, VALUE source) {
46
38
  HandleScope handles;
39
+ TryCatch exceptions;
47
40
  Local<Context> cxt = V8_Ref_Get<Context>(self);
48
41
  Context::Scope enter(cxt);
49
42
  Local<Value> source_str = RB2V8(source);
50
43
  Local<Script> script = Script::Compile(source_str->ToString());
51
44
  Local<Value> result = script->Run();
52
- return V82RB(result);
45
+ if (exceptions.HasCaught()) {
46
+ return V8_Ref_Create(V8_C_Message, exceptions.Message());
47
+ } else {
48
+ return V82RB(result);
49
+ }
53
50
  }
54
51
 
55
52
 
@@ -1,4 +1,4 @@
1
-
1
+ #include "converters.h"
2
2
  #include "v8_msg.h"
3
3
  #include "v8_ref.h"
4
4
 
@@ -8,4 +8,10 @@ VALUE V8_C_Message;
8
8
 
9
9
  VALUE V8_Wrap_Message(Handle<v8::Message> msg) {
10
10
  return V8_Ref_Create(V8_C_Message, msg);
11
+ }
12
+
13
+ VALUE v8_Message_Get(VALUE self) {
14
+ Local<Message> message = V8_Ref_Get<Message>(self);
15
+ Local<Value> str = message->Get();
16
+ return V82RB(str);
11
17
  }
@@ -6,4 +6,5 @@
6
6
 
7
7
  extern VALUE V8_C_Message;
8
8
  VALUE V8_Wrap_Message(v8::Handle<v8::Message> msg);
9
+ VALUE v8_Message_Get(VALUE self);
9
10
  #endif
@@ -4,6 +4,8 @@
4
4
 
5
5
  using namespace v8;
6
6
 
7
+ #include <cstdio>
8
+
7
9
  VALUE V8_C_Object;
8
10
 
9
11
  VALUE v8_Object_New(VALUE clazz) {
@@ -21,9 +23,9 @@ VALUE v8_Object_Get(VALUE self, VALUE key) {
21
23
 
22
24
  VALUE v8_Object_Set(VALUE self, VALUE key, VALUE value) {
23
25
  HandleScope handles;
24
- convert_rb_to_v8_t rb2v8;
25
26
  Local<Object> obj = V8_Ref_Get<Object>(self);
26
27
  VALUE keystr = rb_funcall(key, rb_intern("to_s"), 0);
27
- obj->Set(rb2v8(keystr), rb2v8(value));
28
+
29
+ obj->Set(RB2V8(keystr), RB2V8(value));
28
30
  return Qnil;
29
31
  }
@@ -15,7 +15,6 @@ VALUE v8_script_new(VALUE self, VALUE source) {
15
15
  VALUE v8_script_Run(VALUE self) {
16
16
  HandleScope handles;
17
17
  Local<Script> script = V8_Ref_Get<Script>(self);
18
- convert_v8_to_rb_t toValue;
19
18
  Local<Value> result = script->Run();
20
- return toValue(result);
19
+ return V82RB(result);
21
20
  }
@@ -4,27 +4,9 @@
4
4
  #include "v8_func.h"
5
5
  #include "v8_template.h"
6
6
  #include "converters.h"
7
+ #include "callbacks.h"
7
8
 
8
9
  using namespace v8;
9
-
10
- Handle<Value> RubyInvocationCallback(const Arguments& args) {
11
- VALUE code = (VALUE)External::Unwrap(args.Data());
12
- if (NIL_P(code)) {
13
- return Null();
14
- } else {
15
- VALUE* arguments = new VALUE[args.Length()];
16
- for(int c=0;c<args.Length(); ++c) {
17
- Handle<Value> val = args[c];
18
- arguments[c] = V82RB(val);
19
- }
20
-
21
- VALUE result = rb_funcall2(code, rb_intern("call"), args.Length(), arguments);
22
- delete [] arguments;
23
-
24
- Handle<Value> convertedResult = RB2V8(result);
25
- return convertedResult ;
26
- }
27
- }
28
10
 
29
11
  VALUE v8_Template_Set(VALUE self, VALUE name, VALUE value) {
30
12
  HandleScope handles;
@@ -43,7 +25,7 @@ VALUE v8_FunctionTemplate_New(int argc, VALUE *argv, VALUE self) {
43
25
  VALUE code;
44
26
  rb_scan_args(argc, argv, "00&", &code);
45
27
  HandleScope handles;
46
- Local<FunctionTemplate> t = FunctionTemplate::New(RubyInvocationCallback, External::Wrap((void *)code));
28
+ Local<FunctionTemplate> t = FunctionTemplate::New(RacerRubyInvocationCallback, External::Wrap((void *)code));
47
29
  return V8_Ref_Create(self,t,code);
48
30
  }
49
31
 
data/lib/v8.rb CHANGED
@@ -2,7 +2,7 @@ $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
4
  module V8
5
- VERSION = '0.4.0'
5
+ VERSION = '0.4.1'
6
6
  require 'v8/v8' #native glue
7
7
  require 'v8/to'
8
8
  require 'v8/context'
@@ -6,14 +6,15 @@ module V8
6
6
 
7
7
  def open(&block)
8
8
  @native.open do
9
- block.call(self).tap do |result|
10
- raise JavascriptError.new(result) if result.kind_of?(C::Message)
11
- end
9
+ block.call(self)
12
10
  end if block_given?
13
11
  end
14
12
 
15
13
  def eval(javascript)
16
- To.ruby @native.eval(javascript)
14
+ @native.eval(javascript).tap do |result|
15
+ raise JavascriptError.new(result) if result.kind_of?(C::Message)
16
+ return To.ruby(result)
17
+ end
17
18
  end
18
19
 
19
20
  def evaluate(*args)
@@ -36,6 +37,8 @@ module V8
36
37
  class ContextError < StandardError
37
38
  end
38
39
  class JavascriptError < StandardError
39
-
40
+ def initialize(v8_message)
41
+ super(v8_message.Get())
42
+ end
40
43
  end
41
44
  end
@@ -1,4 +1,3 @@
1
- require 'rubygems'
2
1
  require "#{File.dirname(__FILE__)}/../redjs_helper.rb"
3
2
 
4
3
  describe "Ruby Javascript API" do
@@ -101,7 +100,7 @@ describe "Ruby Javascript API" do
101
100
 
102
101
  it "can embed a closure into a context and call it" do
103
102
  Context.open do |cxt|
104
- cxt["say"] = C::FunctionTemplate.new {|word, times| word * times}
103
+ cxt["say"] = lambda {|word, times| word * times}
105
104
  cxt.eval("say('Hello',2)").should == "HelloHello"
106
105
  end
107
106
  end
@@ -2,11 +2,11 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{therubyracer}
5
- s.version = "0.4.0"
5
+ s.version = "0.4.1"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Charles Lowell", "Bill Robertson"]
9
- s.date = %q{2009-12-22}
9
+ s.date = %q{2010-01-09}
10
10
  s.description = %q{Embed the V8 Javascript interpreter into Ruby.}
11
11
  s.email = ["cowboyd@thefrontside.net", "billrobertson42@gmail.com"]
12
12
  s.extensions = ["ext/v8/extconf.rb"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: therubyracer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charles Lowell
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-12-22 00:00:00 +02:00
13
+ date: 2010-01-09 00:00:00 +02:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -42,6 +42,8 @@ files:
42
42
  - README.rdoc
43
43
  - Rakefile
44
44
  - docs/data_conversion.txt
45
+ - ext/v8/callbacks.cpp
46
+ - ext/v8/callbacks.h
45
47
  - ext/v8/convert_ruby.cpp
46
48
  - ext/v8/convert_ruby.h
47
49
  - ext/v8/convert_string.cpp