h8 0.0.2 → 0.0.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7353dcd3c307b93e4f7fd68ccbc7af260e51d09c
4
- data.tar.gz: 8603a9cfb342305c5dfcf156bf92d595bde23a34
3
+ metadata.gz: a72940e0db998af017aa93553d91b90eefe2662c
4
+ data.tar.gz: b2d87d6c19c23c983cdc00b60bf874d921133f29
5
5
  SHA512:
6
- metadata.gz: 94056bd7b5378d50ceefd3322479e38b3eb122ee019a0c4ce4a9531bb447fa062e26393c4a5738d97138eaf973a6627b55002126850133fe59c6a9b652028c96
7
- data.tar.gz: b1a98f23583bc8cb77ffd35bae2cb1f3d71ea6b9e6f6553149ee2162b468ff9474654d6069d5aa68bb8c0cd97713b26caa24b08604f4b52bbd8b8cca92cc5eb5
6
+ metadata.gz: 713eedbe21d86dcaeac35d3d3d052af41bb36fc9ff434c096fa1c15f95299194c1fce45945150ac8f8ad77fb8732fa2acbbe7e6c9a4d37aa6fca82e3cf075387
7
+ data.tar.gz: d0ff9c201ae06798b57d1c80bcb471f72a5bc29b8e4e3404b33df1ec689422472efc2e547836df50846f955d6aca441e2ab81488853d3e26af25f63ab85dec15
data/.gitignore CHANGED
@@ -20,3 +20,11 @@ tmp
20
20
  *.o
21
21
  *.a
22
22
  mkmf.log
23
+ .cproject
24
+ .project
25
+ .DS_Store
26
+ .idea
27
+ .ruby-version
28
+ .*swp
29
+ .*swo
30
+
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # Hybrid8, aka H8
2
2
 
3
- _Warning_ this gem has yet limited functionality and is under main development. Versions suitable
4
- for an open beta test will start from 0.1.*.
3
+ _Warning_ this gem functionality is almost complete but it lacks of testing and some features
4
+ (see below). This is a working (or better say, test passing) alpha. Beta suitable versions
5
+ will start from 0.1.*.
5
6
 
6
7
  Therubyracer gem alternative to effectively work with ruby 2.1+ in multithreaded environment in an
7
8
  effective and GC-safe way. Should be out of the box replacement for most scenarios.
@@ -16,6 +17,29 @@ javascript context
16
17
  while there are ruby objects referencing it. It also means that once created H8::Context will not
17
18
  be reclaimed as long as there is at least one active wrapped object returned from the script.
18
19
 
20
+ - you can pass ruby objects from ruby code called from javascript back to the ruby code intact.
21
+ Ruby objects are automatically wrapped in js code and unwrapped in ruby code (you might need to
22
+ call #to_ruby)
23
+
24
+ - Uncaught ruby exceptions are thrown as javascript exceptions in javascript code. The same,
25
+ uncaught javascript exceptions raise ruby error in ruby code.
26
+
27
+ ## Main difference from therubyracer/features not ready
28
+
29
+ *This version is not (yet?) thread safe*. For the sake of effectiveness, do not access same
30
+ H8::Context and its returned values from concurrent threads. Use Mutexes!
31
+
32
+ - correct and accurate object tracking in both JS and Ruby VMs, GC aware.
33
+
34
+ - passed thru objects and exceptions in js -> ruby -> js -> ruby chains are usually kept unchanged,
35
+ e.g. wrapped in one language then unwrapped when passed to the original language
36
+
37
+ - Not Yet: source information in uncaught exception in js
38
+
39
+ - Script is executed in the calling ruby thread without unblocking it (for the sake of
40
+ effectiveness). If we would release GIL and reacquire it, it would take more time. And there is no
41
+ multithreading support yet (this one might be added soon).
42
+
19
43
  ## Installation
20
44
 
21
45
  ### Prerequisites
@@ -23,6 +47,33 @@ be reclaimed as long as there is at least one active wrapped object returned fro
23
47
  You should have installed libv8, use latest version with v8::Isolate and v8::Locker. This version
24
48
  may not find you installation, contact me if you have problems, I'll tune it up.
25
49
 
50
+ #### Macos (10.9 maybe+)
51
+
52
+ The working process:
53
+
54
+ install v8 from sources 3.31.77 (or try newer), then execute:
55
+
56
+ gclient update
57
+ export CXXFLAGS='-std=c++11 -stdlib=libc++ -mmacosx-version-min=10.9'
58
+ export LDFLAGS=-lc++
59
+ make native
60
+ exportexport V8_3_31_ROOT=`pwd` # or somehow else set it
61
+
62
+ Note that exporting symbols is a hack that may not be in need anymore. After that the gem should
63
+ install normally.
64
+
65
+ #### Debian and like
66
+
67
+ Install first a valid v8 version. We provide a ready package!
68
+
69
+ sudo apt-get install libv8-3.31-dev
70
+
71
+ It should install prerequisites, if not, manually install
72
+
73
+ sudo apt-get install libicu-dev
74
+
75
+ You might also need to install GMP.
76
+
26
77
  ### Setting up
27
78
 
28
79
  Add this line to your application's Gemfile:
@@ -93,3 +144,5 @@ wheel.
93
144
  3. Commit your changes (`git commit -am 'Add some feature'`)
94
145
  4. Push to the branch (`git push origin my-new-feature`)
95
146
  5. Create a new Pull Request
147
+
148
+
@@ -0,0 +1,24 @@
1
+ /*
2
+ * JsCatcher.cpp
3
+ *
4
+ * Created on: Dec 23, 2014
5
+ * Author: sergeych
6
+ */
7
+
8
+ #include "JsCatcher.h"
9
+
10
+ namespace h8 {
11
+
12
+
13
+ JsCatcher::JsCatcher(H8* h8) : h8(h8), v8::TryCatch(h8->getIsolate()) {}
14
+
15
+ void JsCatcher::throwIfCaught() {
16
+ if( HasCaught() ) {
17
+ if( !CanContinue() && HasTerminated() ) {
18
+ throw JsTimeoutError(h8);
19
+ }
20
+ throw JsError(h8, Message(), Exception());
21
+ }
22
+ }
23
+
24
+ } /* namespace h8 */
@@ -0,0 +1,29 @@
1
+ /*
2
+ * JsCatcher.h
3
+ *
4
+ * Created on: Dec 23, 2014
5
+ * Author: sergeych
6
+ */
7
+
8
+ #ifndef JSCATCHER_H_
9
+ #define JSCATCHER_H_
10
+
11
+ #include <include/v8.h>
12
+ #include "h8.h"
13
+
14
+ namespace h8 {
15
+
16
+ class H8;
17
+
18
+ class JsCatcher : public v8::TryCatch {
19
+ public:
20
+ JsCatcher(H8* h8);
21
+
22
+ void throwIfCaught();
23
+ private:
24
+ H8* h8;
25
+ };
26
+
27
+ } /* namespace h8 */
28
+
29
+ #endif /* JSCATCHER_H_ */
@@ -0,0 +1,37 @@
1
+ #ifndef __allocated_resource
2
+ #define __allocated_resource
3
+
4
+ #include "chain.h"
5
+
6
+ namespace h8 {
7
+
8
+ /**
9
+ * Resource that allocates anything that is tied to Isolate and should be
10
+ * freed _before_ isolate is destroyed.
11
+ *
12
+ * (1) derive any of such your resources from it
13
+ * (2) register them in the parent H8 (h8->add_resource())
14
+ * (3) free() resource in free(), then call unlink()/super
15
+ * (4) free all resources in the destructor if any.
16
+ */
17
+ class AllocatedResource : public chain::link {
18
+ public:
19
+ /**
20
+ * If your resource references any ruby object, be sure to mark them
21
+ * all overriding this method!
22
+ */
23
+ virtual void rb_mark_gc() {};
24
+
25
+ virtual void free() {
26
+ unlink();
27
+ };
28
+
29
+ /* Default implementation does nothing but call unlink throgh parent
30
+ * destructor
31
+ */
32
+ virtual ~AllocatedResource() {};
33
+ };
34
+
35
+ }
36
+
37
+ #endif
@@ -0,0 +1,191 @@
1
+ #ifndef __chain_h
2
+ #define __chain_h
3
+
4
+ #include <assert.h>
5
+
6
+ /**
7
+ * Copyright (C) by Sergey S. Chernov, iCodici S.n.C
8
+ *
9
+ * Free software under MIT license.
10
+ *
11
+ * Extremely fast minimalistic double linked list.
12
+ *
13
+ * List item derives from chain::link. List item can not be inserted in
14
+ * more than one list. Linking chain::link into other list removes it
15
+ * from any other list. Unlinked chain::link links to self.
16
+ *
17
+ * Not thread safe! Inserting and removing in any position of the list
18
+ * is O(1) operation, iterating is O(N) operation.
19
+ *
20
+ * Typical usages:
21
+ *
22
+ * minimal:
23
+ * Use any chain::link instance as a root of you list. You can do
24
+ * everything with it without creating chain instance
25
+ *
26
+ * typical:
27
+ * create chain instance and feed it with chain::instance derivatives.
28
+ * does the same as above but provide more commonly used unterface
29
+ * (actually it is a wrapped chain::link item)
30
+ */
31
+ class chain {
32
+ public:
33
+ class link;
34
+
35
+ /**
36
+ * Iterator that can iterate over either chain or even chain::link
37
+ * item (in which case it iterates from a given link and traverses
38
+ * all the list
39
+ */
40
+ class iterator {
41
+ public:
42
+ iterator(link *start) :
43
+ current(start) {
44
+ }
45
+
46
+ bool operator !=(const iterator& other) const {
47
+ return current != other.current;
48
+ }
49
+
50
+ const iterator& operator++() {
51
+ current = current->next;
52
+ return *this;
53
+ }
54
+
55
+ link* operator*() const {
56
+ return current;
57
+ }
58
+
59
+ private:
60
+ link *current;
61
+ };
62
+
63
+ /**
64
+ * chain list item. Can be used as a list itself: can be iterated, can insert items,
65
+ * can provide head and tail items and any of its linked items can be easily removed
66
+ */
67
+ class link {
68
+ public:
69
+ /// Create empty list item (which is locked to itself)
70
+ link() {
71
+ next = prev = this;
72
+ }
73
+
74
+ /// Leave whatever chain it is in (or do nothing)
75
+ void unlink() {
76
+ next->prev = prev;
77
+ prev->next = next;
78
+ next = prev = this;
79
+ }
80
+
81
+ // Insert in the chain after the specified item
82
+ void link_after(link *left) {
83
+ unlink();
84
+ next = left->next;
85
+ left->next = this;
86
+ prev = left;
87
+ next->prev = this;
88
+ }
89
+
90
+ /**
91
+ * @return true if this is the only item in the list (this is not connected
92
+ * to any other item)
93
+ */
94
+ bool is_disconnected() const {
95
+ return next == prev && next == this;
96
+ }
97
+
98
+ /**
99
+ * Get the next item in the list.
100
+ *
101
+ * @return this if the list is empty
102
+ */
103
+ template<class T>
104
+ T* get_next() {
105
+ return (T*) (next);
106
+ }
107
+
108
+ /**
109
+ * Get the previous item in the list.
110
+ *
111
+ * @return this if the list is empty
112
+ */
113
+ template<class T>
114
+ T* get_prev() {
115
+ return (T*) (prev);
116
+ }
117
+
118
+ ~link() {
119
+ unlink();
120
+ }
121
+
122
+ chain::iterator begin() const {
123
+ return iterator(next);
124
+ }
125
+
126
+ chain::iterator end() const {
127
+ return iterator(const_cast<link*>(this));
128
+ }
129
+
130
+ private:
131
+ link *next, *prev;
132
+ friend class chain;
133
+ };
134
+
135
+ iterator begin() const {
136
+ return root.begin();
137
+ }
138
+
139
+ iterator end() const {
140
+ return root.end();
141
+ }
142
+
143
+ /**
144
+ * Add item to the tail of the list
145
+ */
146
+ void push(link* item) {
147
+ item->link_after(root.prev);
148
+ }
149
+
150
+ void push_first(link* item) {
151
+ item->link_after(&root);
152
+ }
153
+
154
+ template<class T>
155
+ T* peek_first() {
156
+ return (T*) root.next;
157
+ }
158
+
159
+ template<class T>
160
+ T* peek_last() {
161
+ return (T*) root.prev;
162
+ }
163
+
164
+ /**
165
+ * Convenience method: removes head item (if any) and returns it.
166
+ * Actually, you can get any item from the list (using peek_head(), peek_tail() or iterating
167
+ * the list) and then remove it from the list (@see chain::link#unlink()) - it is effective and
168
+ * simple way.
169
+ *
170
+ * @return detached head item or NULL
171
+ */
172
+ template<class T>
173
+ T* pop() {
174
+ if (root.is_disconnected())
175
+ return 0;
176
+ link *first = root.next;
177
+ first->unlink();
178
+ return (T*) first;
179
+ }
180
+
181
+ bool is_empty() const {
182
+ return root.is_disconnected();
183
+ }
184
+
185
+ private:
186
+ // Root item default constructor is enough
187
+ link root;
188
+
189
+ };
190
+
191
+ #endif
@@ -16,44 +16,63 @@
16
16
 
17
17
  require "mkmf"
18
18
 
19
+ cxx11flag = " --std=c++11"
20
+
21
+ $CXXFLAGS = CONFIG["CXXFLAGS"] unless defined?($CXXFLAGS)
22
+ $CXXFLAGS += cxx11flag unless $CXXFLAGS.include?(cxx11flag)
19
23
 
20
24
  abort 'missing malloc()' unless have_func 'malloc'
21
25
  abort 'missing free()' unless have_func 'free'
22
26
 
23
- # Give it a name
24
- extension_name = 'h8'
25
-
26
- dir_config('v8', '/Users/sergeych/dev/v8', '/Users/sergeych/dev/v8/lib')
27
-
28
- dir_config(extension_name)
29
- ok = true
30
-
31
- unless have_header('include/v8.h')
32
- $stderr.puts "can't find v8.h, install libv8 3.25.30+ first"
33
- ok = false
34
- end
35
-
36
- unless have_library('v8_base') && have_library('v8_snapshot') && have_library('v8_libplatform') \
37
- && have_library('v8_libbase') && have_library('icuuc') && have_library('icudata')
38
- $stderr.puts "can't find libv8"
39
- ok = false
40
- end
41
-
27
+ begin
28
+
29
+ # Give it a name
30
+ extension_name = 'h8'
31
+
32
+ chk_headers = ['include/v8.h']
33
+ chk_libs = %w(v8_base v8_libbase v8_libplatform v8_snapshot icudata icui18n icuuc)
34
+
35
+ case RbConfig::CONFIG['target_os']
36
+ when /darwin/
37
+ v8_path = ENV['V8_3_31_ROOT'] or raise "Please give me export V8_3_31_ROOT=..."
38
+ # dir_config('v8', '/Users/sergeych/dev/v8', '/Users/sergeych/dev/v8/out/native')
39
+ dir_config('v8', v8_path, v8_path+'/out/native')
40
+ CONFIG['CXXFLAGS'] += ' --std=c++11'
41
+ else
42
+ # example linux package https://github.com/porzione/v8-git-debian
43
+ dir_config('v8', '/usr/include/libv8-3.31', '/usr/lib/libv8-3.31')
44
+ # force static, but system icu
45
+ $LOCAL_LIBS = chk_libs.reject { |l| l.match /^icu/ }.map { |l| "-l#{l}" }.join(" ")
46
+ end
47
+
48
+ dir_config(extension_name)
49
+
50
+ chk_headers.each do |h|
51
+ unless have_header(h)
52
+ raise "can't find v8 header '#{h}', install libv8 3.31+ first"
53
+ end
54
+ end
55
+
56
+ chk_libs.each do |lib|
57
+ unless have_library(lib)
58
+ raise "can't find v8 lib '#{lib}'"
59
+ end
60
+ end
42
61
 
43
62
  # This test is actually due to a Clang 3.3 shortcoming, included in OS X 10.9,
44
63
  # fixed in Clang 3.4:
45
64
  # http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html#new-compiler-flags
46
- if try_compile('', '-O6')
47
- $CFLAGS += ' -Wall -W -O6 -g'
48
- else
49
- $CFLAGS += ' -Wall -W -O3 -g'
50
- end
51
-
52
- CONFIG['CXXFLAGS'] += " --std=c++11"
65
+ # if try_compile('', '-O6')
66
+ # $CFLAGS += ' -Wall -W -O6 -g'
67
+ # else
68
+ # $CFLAGS += ' -Wall -W -O3 -g'
69
+ # end
53
70
 
54
- if ok
71
+ # create_makefile('h8/h8')
55
72
  create_makefile(extension_name)
56
- else
73
+ rescue
74
+ $stderr.puts "*********************************************************************"
75
+ $stderr.puts "\n#{$!}\n\n"
57
76
  $stderr.puts "*********************************************************************"
58
77
  $stderr.puts "Your compiler was unable to link to all necessary libraries"
59
78
  $stderr.puts "Please install all prerequisites first"
@@ -62,7 +81,7 @@ else
62
81
  raise "Unable to build, correct above errors and rerun"
63
82
  end
64
83
 
65
- # LIBV8_COMPATIBILITY = '~> 3.30'
84
+ # LIBV8_COMPATIBILITY = '~> 3.31'
66
85
  #
67
86
  # begin
68
87
  # require 'rubygems'
@@ -77,5 +96,4 @@ end
77
96
  #
78
97
  # Libv8.configure_makefile
79
98
 
80
- create_makefile('h8/h8')
81
99