h8 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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