h8 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,162 @@
1
+ #include <h8.h>
2
+ #include <include/libplatform/libplatform.h>
3
+
4
+ using namespace h8;
5
+
6
+ extern "C" {
7
+ void Init_h8(void);
8
+ }
9
+
10
+ VALUE h8_exception;
11
+ VALUE context_class;
12
+ VALUE value_class;
13
+
14
+ ID id_is_a;
15
+
16
+ static void rvalue_free(void* ptr) {
17
+ delete (JsGate*) ptr;
18
+ }
19
+
20
+ void h8::rvalue_mark(void* ptr) {
21
+ JsGate *gate = (JsGate*)ptr;
22
+ rb_gc_mark(gate->h8->self);
23
+ }
24
+
25
+ VALUE rvalue_alloc(VALUE klass) {
26
+ return Data_Wrap_Struct(klass, h8::rvalue_mark, rvalue_free, new JsGate);
27
+ }
28
+
29
+ inline JsGate* rv(VALUE self) {
30
+ JsGate *gate;
31
+ Data_Get_Struct(self, JsGate, gate);
32
+ return gate;
33
+ }
34
+
35
+ static VALUE rvalue_to_s(VALUE self) {
36
+ return rv(self)->to_s();
37
+ }
38
+
39
+ static VALUE rvalue_to_i(VALUE self) {
40
+ return rv(self)->to_i();
41
+ }
42
+
43
+ static VALUE rvalue_is_int(VALUE self) {
44
+ return rv(self)->is_int();
45
+ }
46
+
47
+ static VALUE rvalue_is_float(VALUE self) {
48
+ return rv(self)->is_float();
49
+ }
50
+
51
+ static VALUE rvalue_to_f(VALUE self) {
52
+ return rv(self)->to_f();
53
+ }
54
+
55
+ static VALUE rvalue_is_undefined(VALUE self) {
56
+ return rv(self)->is_undefined();
57
+ }
58
+
59
+ static VALUE rvalue_get_attr(VALUE self,VALUE name) {
60
+ return rv(self)->get_attribute(name);
61
+ }
62
+
63
+ static VALUE rvalue_get_index(VALUE self,VALUE index) {
64
+ return rv(self)->get_index(index);
65
+ }
66
+
67
+ static VALUE rvalue_is_string(VALUE self) {
68
+ return rv(self)->is_string();
69
+ }
70
+
71
+ static VALUE rvalue_is_array(VALUE self) {
72
+ return rv(self)->is_array();
73
+ }
74
+
75
+ static VALUE rvalue_is_object(VALUE self) {
76
+ return rv(self)->is_object();
77
+ }
78
+
79
+ static VALUE rvalue_is_function(VALUE self) {
80
+ return rv(self)->is_function();
81
+ }
82
+
83
+ static VALUE rvalue_call(VALUE self, VALUE args) {
84
+ return rv(self)->call(args);
85
+ }
86
+
87
+ static VALUE rvalue_apply(VALUE self, VALUE to,VALUE args) {
88
+ return rv(self)->apply(to,args);
89
+ }
90
+
91
+ //------------ context ----------------------------------------------------------------
92
+
93
+ inline H8* rc(VALUE self) {
94
+ H8 *prcxt;
95
+ Data_Get_Struct(self, H8, prcxt);
96
+ return prcxt;
97
+ }
98
+
99
+ static VALUE context_eval(VALUE self, VALUE script) {
100
+ H8* cxt = rc(self);
101
+ H8::Scope s(cxt);
102
+ return cxt->eval_to_ruby(StringValueCStr(script));
103
+ }
104
+
105
+ static VALUE context_set_var(VALUE self, VALUE name,VALUE value) {
106
+ rc(self)->set_var(name, value);
107
+ return Qnil;
108
+ }
109
+
110
+ static void context_free(void* ptr) {
111
+ delete (H8*) ptr;
112
+ }
113
+
114
+ VALUE h8::context_alloc(VALUE klass) {
115
+ H8 *h8 = new H8;
116
+ h8->self = Data_Wrap_Struct(klass, 0, context_free, h8);
117
+ return h8->self;
118
+ }
119
+
120
+ void init_v8() {
121
+ v8::V8::InitializeICU();
122
+ v8::Platform* platform = v8::platform::CreateDefaultPlatform();
123
+ v8::V8::InitializePlatform(platform);
124
+ v8::V8::Initialize();
125
+ }
126
+
127
+ void Init_h8(void) {
128
+ init_v8();
129
+
130
+ id_is_a = rb_intern("is_a?");
131
+
132
+ VALUE h8 = rb_define_module("H8");
133
+
134
+ context_class = rb_define_class_under(h8, "Context", rb_cObject);
135
+ rb_define_alloc_func(context_class, context_alloc);
136
+ rb_define_method(context_class, "eval", (ruby_method) context_eval, 1);
137
+ rb_define_method(context_class, "set_var", (ruby_method) context_set_var, 2);
138
+
139
+ value_class = rb_define_class_under(h8, "Value", rb_cObject);
140
+ rb_define_alloc_func(value_class, rvalue_alloc);
141
+ rb_define_method(value_class, "to_s", (ruby_method) rvalue_to_s, 0);
142
+ rb_define_method(value_class, "to_i", (ruby_method) rvalue_to_i, 0);
143
+ rb_define_method(value_class, "to_f", (ruby_method) rvalue_to_f, 0);
144
+ rb_define_method(value_class, "integer?", (ruby_method) rvalue_is_int, 0);
145
+ rb_define_method(value_class, "float?", (ruby_method) rvalue_is_float, 0);
146
+ rb_define_method(value_class, "string?", (ruby_method) rvalue_is_string,
147
+ 0);
148
+ rb_define_method(value_class, "array?", (ruby_method) rvalue_is_array, 0);
149
+ rb_define_method(value_class, "object?", (ruby_method) rvalue_is_object, 0);
150
+ rb_define_method(value_class, "function?", (ruby_method) rvalue_is_function, 0);
151
+ rb_define_method(value_class, "undefined?", (ruby_method) rvalue_is_undefined,
152
+ 0);
153
+ rb_define_method(value_class, "_get_attr", (ruby_method) rvalue_get_attr,
154
+ 1);
155
+ rb_define_method(value_class, "_get_index", (ruby_method) rvalue_get_index,
156
+ 1);
157
+ rb_define_method(value_class, "_call", (ruby_method) rvalue_call, 1);
158
+ rb_define_method(value_class, "_apply", (ruby_method) rvalue_apply, 2);
159
+
160
+ h8_exception = rb_define_class_under(h8, "Error", rb_eStandardError);
161
+
162
+ }
@@ -0,0 +1,138 @@
1
+ // Coypright iCodici SnC.
2
+ // Copyright Joyent, Inc. and other Node contributors.
3
+ //
4
+ // Permission is hereby granted, free of charge, to any person obtaining a
5
+ // copy of this software and associated documentation files (the
6
+ // "Software"), to deal in the Software without restriction, including
7
+ // without limitation the rights to use, copy, modify, merge, publish,
8
+ // distribute, sublicense, and/or sell copies of the Software, and to permit
9
+ // persons to whom the Software is furnished to do so, subject to the
10
+ // following conditions:
11
+ //
12
+ // The above copyright notice and this permission notice shall be included
13
+ // in all copies or substantial portions of the Software.
14
+ //
15
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16
+ // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
18
+ // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
19
+ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20
+ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21
+ // USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ #ifndef SRC_OBJECT_WRAP_H_
24
+ #define SRC_OBJECT_WRAP_H_
25
+
26
+ #include "v8.h"
27
+ #include <assert.h>
28
+
29
+
30
+ namespace h8 {
31
+
32
+ class ObjectWrap {
33
+ public:
34
+ ObjectWrap() {
35
+ refs_ = 0;
36
+ }
37
+
38
+
39
+ virtual ~ObjectWrap() {
40
+ if (persistent().IsEmpty())
41
+ return;
42
+ assert(persistent().IsNearDeath());
43
+ persistent().ClearWeak();
44
+ persistent().Reset();
45
+ }
46
+
47
+
48
+ template <class T>
49
+ static inline T* Unwrap(v8::Handle<v8::Object> handle) {
50
+ assert(!handle.IsEmpty());
51
+ assert(handle->InternalFieldCount() > 0);
52
+ // Cast to ObjectWrap before casting to T. A direct cast from void
53
+ // to T won't work right when T has more than one base class.
54
+ void* ptr = handle->GetAlignedPointerFromInternalField(0);
55
+ ObjectWrap* wrap = static_cast<ObjectWrap*>(ptr);
56
+ return static_cast<T*>(wrap);
57
+ }
58
+
59
+
60
+ inline v8::Local<v8::Object> handle() {
61
+ return handle(v8::Isolate::GetCurrent());
62
+ }
63
+
64
+
65
+ inline v8::Local<v8::Object> handle(v8::Isolate* isolate) {
66
+ return v8::Local<v8::Object>::New(isolate, persistent());
67
+ }
68
+
69
+
70
+ inline v8::Persistent<v8::Object>& persistent() {
71
+ return handle_;
72
+ }
73
+
74
+
75
+ protected:
76
+ inline void Wrap(v8::Handle<v8::Object> handle) {
77
+ assert(persistent().IsEmpty());
78
+ assert(handle->InternalFieldCount() > 0);
79
+ handle->SetAlignedPointerInInternalField(0, this);
80
+ persistent().Reset(v8::Isolate::GetCurrent(), handle);
81
+ MakeWeak();
82
+ }
83
+
84
+
85
+ inline void MakeWeak(void) {
86
+ persistent().SetWeak(this, WeakCallback);
87
+ persistent().MarkIndependent();
88
+ }
89
+
90
+ /* Ref() marks the object as being attached to an event loop.
91
+ * Refed objects will not be garbage collected, even if
92
+ * all references are lost.
93
+ */
94
+ virtual void Ref() {
95
+ assert(!persistent().IsEmpty());
96
+ persistent().ClearWeak();
97
+ refs_++;
98
+ }
99
+
100
+ /* Unref() marks an object as detached from the event loop. This is its
101
+ * default state. When an object with a "weak" reference changes from
102
+ * attached to detached state it will be freed. Be careful not to access
103
+ * the object after making this call as it might be gone!
104
+ * (A "weak reference" means an object that only has a
105
+ * persistant handle.)
106
+ *
107
+ * DO NOT CALL THIS FROM DESTRUCTOR
108
+ */
109
+ virtual void Unref() {
110
+ assert(!persistent().IsEmpty());
111
+ assert(!persistent().IsWeak());
112
+ assert(refs_ > 0);
113
+ if (--refs_ == 0)
114
+ MakeWeak();
115
+ }
116
+
117
+ int refs_; // ro
118
+
119
+ private:
120
+ static void WeakCallback(
121
+ const v8::WeakCallbackData<v8::Object, ObjectWrap>& data) {
122
+ v8::Isolate* isolate = data.GetIsolate();
123
+ v8::HandleScope scope(isolate);
124
+ ObjectWrap* wrap = data.GetParameter();
125
+ assert(wrap->refs_ == 0);
126
+ assert(wrap->handle_.IsNearDeath());
127
+ assert(
128
+ data.GetValue() == v8::Local<v8::Object>::New(isolate, wrap->handle_));
129
+ wrap->handle_.Reset();
130
+ delete wrap;
131
+ }
132
+
133
+ v8::Persistent<v8::Object> handle_;
134
+ };
135
+
136
+ } // namespace node
137
+
138
+ #endif // SRC_NODE_OBJECT_WRAP_H_
@@ -0,0 +1,32 @@
1
+ #ifndef __ruby_gate_h
2
+ #define __ruby_gate_h
3
+
4
+ #include "h8.h"
5
+ #include "object_wrap.h"
6
+
7
+ namespace h8 {
8
+
9
+ class RubyWrap : public ObjectWrap {
10
+ public:
11
+
12
+ RubyWrap(H8* ctx) : context(ctx) {
13
+ ctx->registerWrap(this);
14
+ }
15
+
16
+ public void setRubyInstance(VALUE instance) {
17
+ this->instance = instance;
18
+ }
19
+
20
+ virtual ~RubyWrap() {
21
+ context->unregisterWrap(this);
22
+ }
23
+
24
+ private:
25
+ H8 *context;
26
+ VALUE instance = Qnil;
27
+
28
+ };
29
+ }
30
+
31
+
32
+ #endif
@@ -2,12 +2,14 @@
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'h8/version'
5
+ require "rake/extensiontask"
6
+ require 'rubygems/package_task'
5
7
 
6
- Gem::Specification.new do |spec|
8
+ spec = Gem::Specification.new do |spec|
7
9
  spec.name = "h8"
8
10
  spec.version = H8::VERSION
9
11
  spec.authors = ["sergeych"]
10
- spec.email = ["sergeych"]
12
+ spec.email = ["real.sergeych@gmail.com"]
11
13
  spec.summary = %q{Minimalistic and sane v8 bindings}
12
14
  spec.description = %q{Should be more or less replacement for broken therubyracer gem and riny 2.1+ }
13
15
  spec.homepage = ""
@@ -16,10 +18,27 @@ Gem::Specification.new do |spec|
16
18
  spec.files = `git ls-files -z`.split("\x0")
17
19
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
20
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
21
+ spec.require_paths = ['lib', 'ext']
22
+
23
+ spec.extensions = FileList["ext/**/extconf.rb"]
24
+
25
+ spec.platform = Gem::Platform::RUBY
20
26
 
21
27
  spec.add_development_dependency "bundler", "~> 1.6"
22
28
  spec.add_development_dependency "rake"
29
+ spec.add_development_dependency "rake-compiler"
30
+ spec.add_development_dependency "rspec", '>= 2.14.0'
31
+
32
+ # spec.add_dependency 'libv8'
33
+ end
23
34
 
24
- spec.add_dependency 'libv8'
35
+ Gem::PackageTask.new(spec) do |pkg|
25
36
  end
37
+
38
+ Rake::ExtensionTask.new "h8", spec do |ext|
39
+ ext.lib_dir = "lib/h8"
40
+ ext.source_pattern = "*.{c,cpp}"
41
+ ext.gem_spec = spec
42
+ end
43
+
44
+ spec
@@ -0,0 +1,9 @@
1
+ require 'h8/version'
2
+ require 'h8/context'
3
+ require 'h8/h8'
4
+ require 'h8/value'
5
+
6
+ module H8
7
+
8
+ # Your code goes here...
9
+ end
@@ -0,0 +1,21 @@
1
+ module H8
2
+ class Context
3
+ def initialize timout: nil, **kwargs
4
+ set **kwargs
5
+ end
6
+
7
+ def set **kwargs
8
+ kwargs.each { |name, value|
9
+ set_var(name.to_s, value)
10
+ }
11
+ end
12
+
13
+ def []= name, value
14
+ set name => value
15
+ end
16
+
17
+ def self.eval script
18
+ Context.new.eval script
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,77 @@
1
+ module H8
2
+
3
+ # Wrapper for javascript objects.
4
+ #
5
+ # Important: when accessin fields of the object, respond_to? will not work due to
6
+ # js notation, instead, check the returned value to be value.undefined?
7
+ class Value
8
+
9
+ include Comparable
10
+
11
+ def inspect
12
+ "<H8::Value #{to_s}>"
13
+ end
14
+
15
+ # Get js object attribute by its name or index (should be Fixnum instance). It always
16
+ # return H8::Value instance, check it to (not) be undefined? to see if there is such attribute
17
+ def [] name_index
18
+ name_index.is_a?(Fixnum) ? _get_index(name_index) : _get_attr(name_index)
19
+ end
20
+
21
+ # Optimized JS member access. Do not yet support calls!
22
+ # use only to get fields
23
+ def method_missing(method_sym, *arguments, &block)
24
+ name = method_sym.to_s
25
+ instance_eval <<-End
26
+ def #{name} *args, **kwargs
27
+ res = _get_attr('#{name}')
28
+ res.function? ? res.apply(res,*args) : res
29
+ end
30
+ End
31
+ send method_sym, *arguments
32
+ end
33
+
34
+ # def each_key
35
+ # p eval("Object.keys(this)");
36
+ # end
37
+ #
38
+ # def keys
39
+ # cxt = self._context
40
+ # cxt['__self'] =
41
+ # end
42
+
43
+ def <=> other
44
+ other = other.to_ruby if other.is_a?(H8::Value)
45
+ to_ruby <=> other
46
+ end
47
+
48
+ def call *args
49
+ _call args
50
+ end
51
+
52
+ def apply to, *args
53
+ _apply to, args
54
+ end
55
+
56
+ def to_ary
57
+ raise Error, 'Is not an array' unless array?
58
+ to_ruby
59
+ end
60
+
61
+ def to_ruby
62
+ case
63
+ when integer?
64
+ to_i
65
+ when string?
66
+ to_s
67
+ when float?
68
+ to_f
69
+ when array?
70
+ _get_attr('length').to_i.times.map { |i| _get_index(i).to_ruby }
71
+ else
72
+ raise Error, "Dont know how to convert H8::Value"
73
+ end
74
+ end
75
+ end
76
+
77
+ end