therubyracer-st 0.11.0beta5-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/.gitignore +23 -0
  2. data/.travis.yml +10 -0
  3. data/Changelog.md +242 -0
  4. data/Gemfile +15 -0
  5. data/README.md +185 -0
  6. data/Rakefile +58 -0
  7. data/benchmarks.rb +217 -0
  8. data/ext/v8/accessor.cc +181 -0
  9. data/ext/v8/array.cc +26 -0
  10. data/ext/v8/backref.cc +54 -0
  11. data/ext/v8/build.rb +53 -0
  12. data/ext/v8/constants.cc +34 -0
  13. data/ext/v8/constraints.cc +52 -0
  14. data/ext/v8/context.cc +130 -0
  15. data/ext/v8/date.cc +18 -0
  16. data/ext/v8/exception.cc +38 -0
  17. data/ext/v8/extconf.rb +23 -0
  18. data/ext/v8/external.cc +43 -0
  19. data/ext/v8/function.cc +58 -0
  20. data/ext/v8/gc.cc +43 -0
  21. data/ext/v8/handles.cc +34 -0
  22. data/ext/v8/heap.cc +31 -0
  23. data/ext/v8/init.cc +39 -0
  24. data/ext/v8/invocation.cc +86 -0
  25. data/ext/v8/locker.cc +77 -0
  26. data/ext/v8/message.cc +51 -0
  27. data/ext/v8/object.cc +334 -0
  28. data/ext/v8/primitive.cc +8 -0
  29. data/ext/v8/rr.cc +83 -0
  30. data/ext/v8/rr.h +883 -0
  31. data/ext/v8/script.cc +80 -0
  32. data/ext/v8/signature.cc +18 -0
  33. data/ext/v8/stack.cc +75 -0
  34. data/ext/v8/string.cc +47 -0
  35. data/ext/v8/template.cc +175 -0
  36. data/ext/v8/trycatch.cc +86 -0
  37. data/ext/v8/v8.cc +87 -0
  38. data/ext/v8/value.cc +239 -0
  39. data/lib/v8.rb +36 -0
  40. data/lib/v8/access.rb +5 -0
  41. data/lib/v8/access/indices.rb +40 -0
  42. data/lib/v8/access/invocation.rb +47 -0
  43. data/lib/v8/access/names.rb +65 -0
  44. data/lib/v8/array.rb +26 -0
  45. data/lib/v8/context.rb +243 -0
  46. data/lib/v8/conversion.rb +35 -0
  47. data/lib/v8/conversion/array.rb +11 -0
  48. data/lib/v8/conversion/class.rb +120 -0
  49. data/lib/v8/conversion/code.rb +38 -0
  50. data/lib/v8/conversion/fundamental.rb +11 -0
  51. data/lib/v8/conversion/hash.rb +11 -0
  52. data/lib/v8/conversion/indentity.rb +31 -0
  53. data/lib/v8/conversion/method.rb +26 -0
  54. data/lib/v8/conversion/object.rb +28 -0
  55. data/lib/v8/conversion/primitive.rb +7 -0
  56. data/lib/v8/conversion/proc.rb +5 -0
  57. data/lib/v8/conversion/reference.rb +16 -0
  58. data/lib/v8/conversion/string.rb +12 -0
  59. data/lib/v8/conversion/symbol.rb +7 -0
  60. data/lib/v8/conversion/time.rb +13 -0
  61. data/lib/v8/error.rb +25 -0
  62. data/lib/v8/error/protect.rb +20 -0
  63. data/lib/v8/error/try.rb +15 -0
  64. data/lib/v8/function.rb +28 -0
  65. data/lib/v8/helper.rb +30 -0
  66. data/lib/v8/object.rb +79 -0
  67. data/lib/v8/util/weakcell.rb +29 -0
  68. data/lib/v8/version.rb +3 -0
  69. data/spec/c/array_spec.rb +17 -0
  70. data/spec/c/constants_spec.rb +20 -0
  71. data/spec/c/exception_spec.rb +26 -0
  72. data/spec/c/external_spec.rb +9 -0
  73. data/spec/c/function_spec.rb +46 -0
  74. data/spec/c/handles_spec.rb +35 -0
  75. data/spec/c/locker_spec.rb +38 -0
  76. data/spec/c/object_spec.rb +46 -0
  77. data/spec/c/script_spec.rb +28 -0
  78. data/spec/c/string_spec.rb +16 -0
  79. data/spec/c/template_spec.rb +30 -0
  80. data/spec/c/trycatch_spec.rb +51 -0
  81. data/spec/mem/blunt_spec.rb +42 -0
  82. data/spec/redjs_spec.rb +10 -0
  83. data/spec/spec_helper.rb +45 -0
  84. data/spec/threading_spec.rb +52 -0
  85. data/spec/v8/context_spec.rb +19 -0
  86. data/spec/v8/conversion_spec.rb +9 -0
  87. data/spec/v8/error_spec.rb +21 -0
  88. data/spec/v8/function_spec.rb +9 -0
  89. data/spec/v8/object_spec.rb +15 -0
  90. data/thefrontside.png +0 -0
  91. data/therubyracer.gemspec +20 -0
  92. data/vendor/v8.dll +0 -0
  93. metadata +161 -0
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env rake
2
+ require 'bundler/setup'
3
+ require "bundler/gem_tasks"
4
+
5
+ task :clean do
6
+ sh "rm -rf lib/v8/init.bundle lib/v8/init.so"
7
+ sh "rm -rf pkg"
8
+ end
9
+
10
+ GEMSPEC = eval(File.read("therubyracer.gemspec"))
11
+
12
+ require File.expand_path('../lib/v8/helper', __FILE__)
13
+ if V8::mingw?
14
+ GEMSPEC.files += ["vendor/v8.dll"]
15
+ end
16
+
17
+ require "rake/extensiontask"
18
+ Rake::ExtensionTask.new("init", GEMSPEC) do |ext|
19
+ ext.ext_dir = "ext/v8"
20
+ ext.lib_dir = "lib/v8"
21
+ ext.source_pattern = "*.{cc,h}"
22
+ end
23
+
24
+ if V8::mingw?
25
+ task "v8:copy" do
26
+ abort "unable to find v8.dll" unless V8::v8_path
27
+ rm_rf "vendor"
28
+ mkdir "vendor"
29
+ cp File.join(V8::v8_path, "v8.dll"), "vendor"
30
+ end
31
+ [:compile, :native].each do |task|
32
+ Rake::Task[task].prerequisites.unshift "v8:copy"
33
+ end
34
+ end
35
+
36
+ require 'rspec/core/rake_task'
37
+ RSpec::Core::RakeTask.new(:spec) do |task|
38
+ task.rspec_opts = '--tag ~memory --tag ~threads'
39
+ end
40
+
41
+ task :sanity => [:clean, :compile] do
42
+ sh %q{ruby -Ilib -e "require 'v8'"}
43
+ end
44
+
45
+ NativeGem = "therubyracer-#{V8::VERSION}-#{Gem::Platform.new(RUBY_PLATFORM)}.gem"
46
+
47
+ task :gem # dummy task
48
+
49
+ desc "Build #{NativeGem} into the pkg directory"
50
+ task "build:native" => [:native, :gem]
51
+
52
+ desc "Build and install #{NativeGem} into system gems"
53
+ task "install:native" => "build:native" do
54
+ sh "gem install pkg/#{NativeGem}"
55
+ end
56
+
57
+ task :default => :spec
58
+
@@ -0,0 +1,217 @@
1
+ require 'bundler/setup'
2
+ require 'v8'
3
+ require 'benchmark'
4
+ require 'optparse'
5
+
6
+ OPTIONS = {
7
+ :times => 5,
8
+ :mode => :object,
9
+ :objects => 500
10
+ }
11
+
12
+ parser = OptionParser.new do |opts|
13
+ opts.on("-t", "--times [T]", Integer, "run benchmark N times") do |t|
14
+ OPTIONS[:times] = t
15
+ end
16
+
17
+ opts.on("-m", "--mode [MODE]", [:object, :function, :eval], "select the type of object access to stress test") do |mode|
18
+ mode = mode.to_sym
19
+ raise "unsupported mode #{mode}" unless [:object,:function,:eval].include?(mode)
20
+ OPTIONS[:mode] = mode
21
+ end
22
+
23
+ opts.on("-o", "--objects [N]", Integer, "create N objects for each iteration") do |n|
24
+ OPTIONS[:objects] = n
25
+ end
26
+ opts
27
+ end
28
+
29
+ parser.parse! ARGV
30
+
31
+ MODE = OPTIONS[:mode]
32
+ TIMES = OPTIONS[:times]
33
+ OBJECTS = OPTIONS[:objects]
34
+
35
+ puts "using #{OPTIONS[:mode]}"
36
+ if MODE==:object
37
+ def get(i)
38
+ @cxt["test"]["objects"][i]
39
+ end
40
+ elsif MODE==:function
41
+ def get(i)
42
+ @cxt["test"].getObject(i)
43
+ end
44
+ elsif MODE==:eval
45
+ def get(i)
46
+ @cxt.eval "test.getObject(#{i})"
47
+ end
48
+ end
49
+
50
+ js= <<JS
51
+
52
+ function createTest()
53
+ {
54
+ var test = {};
55
+ test.objects = [];
56
+ test.seed = 49734321;
57
+ test.summ;
58
+
59
+ test.random = function()
60
+ {
61
+ // Robert Jenkins' 32 bit integer hash function.
62
+ test.seed = ((test.seed + 0x7ed55d16) + (test.seed << 12)) & 0xffffffff;
63
+ test.seed = ((test.seed ^ 0xc761c23c) ^ (test.seed >>> 19)) & 0xffffffff;
64
+ test.seed = ((test.seed + 0x165667b1) + (test.seed << 5)) & 0xffffffff;
65
+ test.seed = ((test.seed + 0xd3a2646c) ^ (test.seed << 9)) & 0xffffffff;
66
+ test.seed = ((test.seed + 0xfd7046c5) + (test.seed << 3)) & 0xffffffff;
67
+ test.seed = ((test.seed ^ 0xb55a4f09) ^ (test.seed >>> 16)) & 0xffffffff;
68
+ return (test.seed & 0xfffffff) / 0x10000000;
69
+ };
70
+
71
+ test.init = function()
72
+ {
73
+ test.objects = [];
74
+ for(var i=0; i<#{OBJECTS}; i++)
75
+ {
76
+ var hash = {};
77
+ for(var j=0; j<10; j++)
78
+ {
79
+ var isString = test.random();
80
+ var key = "str" + test.random();
81
+ var value;
82
+ if(isString < 0.5)
83
+ value = "str" + test.random();
84
+ else
85
+ value = test.random();
86
+ hash[key] = value;
87
+ }
88
+ test.objects[i] = hash;
89
+ }
90
+ return test.objects.length;
91
+ }
92
+
93
+ test.findSum = function()
94
+ {
95
+ test.summ = 0;
96
+ var length = test.objects.length;
97
+ for(var i=0; i<length; i++)
98
+ {
99
+ var hash = test.objects[i];
100
+ for (var k in hash)
101
+ {
102
+ if (hash.hasOwnProperty(k) && (typeof(hash[k]) == "number"))
103
+ {
104
+ test.summ += hash[k];
105
+ }
106
+ }
107
+ }
108
+ return test.summ;
109
+ };
110
+
111
+ test.finalCheck = function()
112
+ {
113
+ var summ = 0;
114
+ var length = test.objects.length;
115
+ for(var i=0; i<length; i++)
116
+ {
117
+ var hash = test.objects[i];
118
+ for (var k in hash)
119
+ {
120
+ if (hash.hasOwnProperty(k) && (typeof(hash[k]) == "number"))
121
+ {
122
+ summ += hash[k];
123
+ }
124
+ }
125
+ }
126
+ return summ ;
127
+ };
128
+
129
+ test.getObject = function(index)
130
+ {
131
+ if(!test.objects[index]) return {};
132
+ return test.objects[index];
133
+ }
134
+
135
+ test.setObject = function(index, object)
136
+ {
137
+ test.objects[index] = object;
138
+ }
139
+
140
+ return test;
141
+ }
142
+
143
+ JS
144
+
145
+
146
+
147
+
148
+
149
+ def profile
150
+ Benchmark.realtime do
151
+ yield
152
+ end
153
+ end
154
+
155
+ def get_res result
156
+ result.to_f
157
+ end
158
+
159
+
160
+
161
+
162
+
163
+ puts "init js context..."
164
+ cxt = V8::Context.new
165
+ @cxt=cxt
166
+ cxt.eval(js)
167
+
168
+ cxt.eval('var test = createTest()')
169
+
170
+ puts "run init test"
171
+ result =profile do
172
+ TIMES.times do
173
+ cxt['test'].init()
174
+ end
175
+ end
176
+
177
+ puts "init time: #{get_res(result) / TIMES} sec."
178
+ sum1=sum2=0
179
+ puts "run findSum test"
180
+
181
+ result =profile do
182
+ TIMES.times do
183
+ sum1= cxt['test'].findSum
184
+ end
185
+ end
186
+
187
+ puts "findSum time: #{get_res(result) / TIMES} sec."
188
+
189
+
190
+ puts "run Objects inversion in ruby test"
191
+ result =profile do
192
+ TIMES.times do |j|
193
+ puts j
194
+ for i in 0..(OBJECTS-1) do
195
+ obj = get(i)
196
+ obj.each do |key, value|
197
+ if value.instance_of? Float
198
+ obj[key] = value * (-1)
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
204
+
205
+ puts "Objects time: #{get_res(result) / TIMES} sec."
206
+
207
+ puts "run finalCheck test"
208
+
209
+
210
+ result =profile do
211
+ TIMES.times do
212
+ sum2= cxt['test'].findSum
213
+ end
214
+ end
215
+
216
+ puts "final check time: #{get_res(result) / TIMES} sec."
217
+ puts "#{sum1==sum2*(TIMES%2==0?1:-1) ? 'TEST PASS': 'TEST FAIL'}: Sum before inversions: #{sum1} / Sum after inversions: #{sum2}"
@@ -0,0 +1,181 @@
1
+ #include "rr.h"
2
+
3
+ namespace rr {
4
+
5
+ VALUE Accessor::Info::Class;
6
+
7
+ void Accessor::Init() {
8
+ ClassBuilder("AccessorInfo").
9
+ defineMethod("This", &Info::This).
10
+ defineMethod("Holder", &Info::Holder).
11
+ defineMethod("Data", &Info::Data).
12
+ store(&Info::Class);
13
+ }
14
+
15
+ Accessor::Accessor(VALUE getter, VALUE setter, VALUE data_) : get(getter), set(setter), data(data_) {}
16
+
17
+ Accessor::Accessor(VALUE get, VALUE set, VALUE query, VALUE deleter, VALUE enumerator, VALUE data) {
18
+ this->get = get;
19
+ this->set = set;
20
+ this->query = query;
21
+ this->deleter = deleter;
22
+ this->enumerator = enumerator;
23
+ this->data = data;
24
+ }
25
+
26
+ Accessor::Accessor(v8::Handle<v8::Value> value) {
27
+ v8::Local<v8::Object> wrapper = value->ToObject();
28
+ this->get = unwrap(wrapper, 0);
29
+ this->set = unwrap(wrapper, 1);
30
+ this->query = unwrap(wrapper, 2);
31
+ this->deleter = unwrap(wrapper, 3);
32
+ this->enumerator = unwrap(wrapper, 4);
33
+ v8::Handle<v8::Value> data = wrapper->Get(5);
34
+ if (!data.IsEmpty()) {
35
+ this->data = Value(data);
36
+ }
37
+ }
38
+
39
+ Accessor::operator v8::Handle<v8::Value>() {
40
+ v8::Local<v8::Object> wrapper = v8::Object::New();
41
+ wrap(wrapper, 0, this->get);
42
+ wrap(wrapper, 1, this->set);
43
+ wrap(wrapper, 2, this->query);
44
+ wrap(wrapper, 3, this->deleter);
45
+ wrap(wrapper, 4, this->enumerator);
46
+ if (RTEST(this->data)) {
47
+ wrapper->Set(5, Value(this->data));
48
+ }
49
+ return wrapper;
50
+ }
51
+
52
+ void Accessor::wrap(v8::Handle<v8::Object> wrapper, int index, VALUE value) {
53
+ if (RTEST(value)) {
54
+ wrapper->Set(index, External::wrap(value));
55
+ }
56
+ }
57
+
58
+ VALUE Accessor::unwrap(v8::Handle<v8::Object> wrapper, int index) {
59
+ v8::Handle<v8::Value> value = wrapper->Get(index);
60
+ if (value.IsEmpty()) {
61
+ return Qnil;
62
+ } else {
63
+ v8::Handle<v8::External> external(v8::External::Cast(*value));
64
+ return External::unwrap(external);
65
+ }
66
+ }
67
+
68
+
69
+ VALUE Accessor::Info::This(VALUE self) {
70
+ return Object(Info(self)->This());
71
+ }
72
+
73
+ VALUE Accessor::Info::Holder(VALUE self) {
74
+ return Object(Info(self)->Holder());
75
+ }
76
+
77
+ VALUE Accessor::Info::Data(VALUE self) {
78
+ return Accessor(Info(self)->Data()).data;
79
+ }
80
+
81
+ v8::Handle<v8::Value> Accessor::AccessorGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
82
+ return Info(info).get(property);
83
+ }
84
+
85
+ void Accessor::AccessorSetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
86
+ Info(info).set(property, value);
87
+ }
88
+ v8::Handle<v8::Value> Accessor::NamedPropertyGetter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
89
+ return Info(info).get(property);
90
+ }
91
+ v8::Handle<v8::Value> Accessor::NamedPropertySetter(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
92
+ return Info(info).set(property, value);
93
+ }
94
+ v8::Handle<v8::Integer> Accessor::NamedPropertyQuery(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
95
+ return Info(info).query(property);
96
+ }
97
+ v8::Handle<v8::Boolean> Accessor::NamedPropertyDeleter(v8::Local<v8::String> property, const v8::AccessorInfo& info) {
98
+ return Info(info).remove(property);
99
+ }
100
+ v8::Handle<v8::Array> Accessor::NamedPropertyEnumerator(const v8::AccessorInfo& info) {
101
+ return Info(info).enumerateNames();
102
+ }
103
+
104
+ v8::Handle<v8::Value> Accessor::IndexedPropertyGetter(uint32_t index, const v8::AccessorInfo& info) {
105
+ return Info(info).get(index);
106
+ }
107
+ v8::Handle<v8::Value> Accessor::IndexedPropertySetter(uint32_t index, v8::Local<v8::Value> value, const v8::AccessorInfo& info) {
108
+ return Info(info).set(index, value);
109
+ }
110
+ v8::Handle<v8::Integer> Accessor::IndexedPropertyQuery(uint32_t index, const v8::AccessorInfo& info) {
111
+ return Info(info).query(index);
112
+ }
113
+ v8::Handle<v8::Boolean> Accessor::IndexedPropertyDeleter(uint32_t index, const v8::AccessorInfo& info) {
114
+ return Info(info).remove(index);
115
+ }
116
+ v8::Handle<v8::Array> Accessor::IndexedPropertyEnumerator(const v8::AccessorInfo& info) {
117
+ return Info(info).enumerateIndices();
118
+ }
119
+
120
+ Accessor::Info::Info(const v8::AccessorInfo& info) {
121
+ this->info = &info;
122
+ }
123
+
124
+ Accessor::Info::Info(VALUE value) {
125
+ Data_Get_Struct(value, class v8::AccessorInfo, info);
126
+ }
127
+
128
+ v8::Handle<v8::Value> Accessor::Info::get(v8::Local<v8::String> property) {
129
+ Accessor accessor(info->Data());
130
+ return Value(rb_funcall(accessor.get, rb_intern("call"), 2, (VALUE)String(property), (VALUE)*this));
131
+ }
132
+
133
+ v8::Handle<v8::Value> Accessor::Info::set(v8::Local<v8::String> property, v8::Local<v8::Value> value) {
134
+ Accessor accessor(info->Data());
135
+ return Value(rb_funcall(accessor.set, rb_intern("call"), 3, (VALUE)String(property), (VALUE)Value(value), (VALUE)*this));
136
+ }
137
+
138
+ v8::Handle<v8::Integer> Accessor::Info::query(v8::Local<v8::String> property) {
139
+ Accessor accessor(info->Data());
140
+ return v8::Integer::New(NUM2INT(rb_funcall(accessor.query, rb_intern("call"), 2, (VALUE)String(property), (VALUE)*this)));
141
+ }
142
+
143
+ v8::Handle<v8::Boolean> Accessor::Info::remove(v8::Local<v8::String> property) {
144
+ Accessor accessor(info->Data());
145
+ return v8::Boolean::New(Bool(rb_funcall(accessor.deleter, rb_intern("call"), 2, (VALUE)String(property), (VALUE)*this)));
146
+ }
147
+
148
+ v8::Handle<v8::Array> Accessor::Info::enumerateNames() {
149
+ Accessor accessor(info->Data());
150
+ return Array(rb_funcall(accessor.enumerator, rb_intern("call"), 1, (VALUE)*this));
151
+ }
152
+
153
+ v8::Handle<v8::Value> Accessor::Info::get(uint32_t index) {
154
+ Accessor accessor(info->Data());
155
+ return Value(rb_funcall(accessor.get, rb_intern("call"), 2, UINT2NUM(index), (VALUE)*this));
156
+ }
157
+
158
+ v8::Handle<v8::Value> Accessor::Info::set(uint32_t index, v8::Local<v8::Value> value) {
159
+ Accessor accessor(info->Data());
160
+ return Value(rb_funcall(accessor.set, rb_intern("call"), 3, UINT2NUM(index), (VALUE)Value(value), (VALUE)*this));
161
+ }
162
+
163
+ v8::Handle<v8::Integer> Accessor::Info::query(uint32_t index) {
164
+ Accessor accessor(info->Data());
165
+ return v8::Integer::New(NUM2INT(rb_funcall(accessor.query, rb_intern("call"), 2, UINT2NUM(index), (VALUE)*this)));
166
+ }
167
+
168
+ v8::Handle<v8::Boolean> Accessor::Info::remove(uint32_t index) {
169
+ Accessor accessor(info->Data());
170
+ return v8::Boolean::New(Bool(rb_funcall(accessor.deleter, rb_intern("call"), 2, UINT2NUM(index), (VALUE)*this)));
171
+ }
172
+
173
+ v8::Handle<v8::Array> Accessor::Info::enumerateIndices() {
174
+ Accessor accessor(info->Data());
175
+ return Array(rb_funcall(accessor.enumerator, rb_intern("call"), 1, (VALUE)*this));
176
+ }
177
+
178
+ Accessor::Info::operator VALUE() {
179
+ return Data_Wrap_Struct(Class, 0, 0, (void*)this->info);
180
+ }
181
+ }