h8 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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