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,26 @@
1
+ #include "rr.h"
2
+
3
+ namespace rr {
4
+
5
+ void Array::Init() {
6
+ ClassBuilder("Array", Object::Class).
7
+ defineSingletonMethod("New", &New).
8
+ defineMethod("Length", &Length).
9
+ defineMethod("CloneElementAt", &CloneElementAt).
10
+ store(&Class);
11
+ }
12
+
13
+ VALUE Array::New(int argc, VALUE argv[], VALUE self) {
14
+ VALUE length; rb_scan_args(argc, argv, "01", &length);
15
+ return Array(v8::Array::New(RTEST(length) ? NUM2INT(length) : 0));
16
+ }
17
+
18
+ VALUE Array::Length(VALUE self) {
19
+ return UInt32(Array(self)->Length());
20
+ }
21
+
22
+ VALUE Array::CloneElementAt(VALUE self, VALUE index) {
23
+ return Object(Array(self)->CloneElementAt(UInt32(index)));
24
+ }
25
+
26
+ }
@@ -0,0 +1,54 @@
1
+ #include "rr.h"
2
+
3
+ namespace rr {
4
+
5
+ VALUE Backref::Storage;
6
+ ID Backref::_new;
7
+ ID Backref::object;
8
+
9
+ void Backref::Init() {
10
+ Storage = rb_eval_string("Ref::WeakReference");
11
+ rb_gc_register_address(&Storage);
12
+ _new = rb_intern("new");
13
+ object = rb_intern("object");
14
+ }
15
+
16
+ Backref::Backref(VALUE initial) {
17
+ allocate(initial);
18
+ }
19
+
20
+ Backref::~Backref() {
21
+ deallocate();
22
+ }
23
+
24
+ void Backref::allocate(VALUE data) {
25
+ this->storage = rb_funcall(Storage, _new, 1, data);
26
+ rb_gc_register_address(&storage);
27
+ }
28
+
29
+ void Backref::deallocate() {
30
+ rb_gc_unregister_address(&storage);
31
+ }
32
+
33
+ VALUE Backref::get() {
34
+ return rb_funcall(storage, object, 0);
35
+ }
36
+
37
+ VALUE Backref::set(VALUE data) {
38
+ deallocate();
39
+ allocate(data);
40
+ return data;
41
+ }
42
+
43
+ v8::Handle<v8::Value> Backref::toExternal() {
44
+ v8::Local<v8::Value> wrapper = v8::External::Wrap(this);
45
+ v8::Persistent<v8::Value>::New(wrapper).MakeWeak(this, &release);
46
+ return wrapper;
47
+ }
48
+
49
+ void Backref::release(v8::Persistent<v8::Value> handle, void* data) {
50
+ handle.Dispose();
51
+ Backref* backref = (Backref*)data;
52
+ delete backref;
53
+ }
54
+ }
@@ -0,0 +1,53 @@
1
+ require File.expand_path('../../../lib/v8/helper', __FILE__)
2
+
3
+ LIBV8_COMPATIBILITY = '~> 3.11.8'
4
+
5
+ def have_rubygem_libv8?
6
+ require 'rubygems'
7
+ gem 'libv8-st', LIBV8_COMPATIBILITY
8
+ require 'libv8'
9
+ return true
10
+ rescue Gem::LoadError
11
+ return false
12
+ rescue LoadError
13
+ return false
14
+ end
15
+
16
+ def build_with_system_libv8
17
+ dir_config('v8')
18
+ find_header('v8.h') or begin
19
+ puts <<-EOS
20
+ The Ruby Racer requires libv8 #{LIBV8_COMPATIBILITY}
21
+ to be present on your system in order to compile
22
+ and link, but it could not be found.
23
+
24
+ In order to resolve this, you will either need to manually
25
+ install an appropriate libv8 and make sure that this
26
+ build process can find it. If you install it into the
27
+ standard system path, then it should just be picked up
28
+ automatically. Otherwise, you'll have to pass some extra
29
+ flags to the build process as a hint.
30
+
31
+ If you don't want to bother with all that, there is a
32
+ rubygem that will do all this for you. You can add
33
+ following line to your Gemfile:
34
+ gem 'libv8', '#{LIBV8_COMPATIBILITY}'
35
+
36
+ We hope that helps, and we apologize, but now we have
37
+ to push the eject button on this install.
38
+
39
+ thanks,
40
+ The Mgmt.
41
+
42
+ EOS
43
+ raise "unable to locate libv8. Please see output for details"
44
+ end
45
+ $LDFLAGS << " -lv8 "
46
+ end
47
+
48
+ def build_with_rubygem_libv8
49
+ require 'libv8'
50
+ include Libv8
51
+ $INCFLAGS.insert 0, "#{libv8_include_flags} "
52
+ $LDFLAGS.insert 0, libv8_objects.join(' ') + " "
53
+ end
@@ -0,0 +1,34 @@
1
+ #include "rr.h"
2
+
3
+ namespace rr {
4
+ VALUE Constants::_Undefined;
5
+ VALUE Constants::_Null;
6
+ VALUE Constants::_True;
7
+ VALUE Constants::_False;
8
+ void Constants::Init() {
9
+ ModuleBuilder("V8::C").
10
+ defineSingletonMethod("Undefined", &Undefined).
11
+ defineSingletonMethod("Null", &Null).
12
+ defineSingletonMethod("True", &True).
13
+ defineSingletonMethod("False", &False);
14
+
15
+ _Undefined = _Null = _True = _False = Qnil;
16
+ rb_gc_register_address(&_Undefined);
17
+ rb_gc_register_address(&_Null);
18
+ rb_gc_register_address(&_True);
19
+ rb_gc_register_address(&_False);
20
+ }
21
+
22
+ VALUE Constants::Undefined(VALUE self) {
23
+ return cached<Primitive, v8::Primitive>(&_Undefined, v8::Undefined());
24
+ }
25
+ VALUE Constants::Null(VALUE self) {
26
+ return cached<Primitive, v8::Primitive>(&_Null, v8::Null());
27
+ }
28
+ VALUE Constants::True(VALUE self) {
29
+ return cached<Bool, v8::Boolean>(&_True, v8::True());
30
+ }
31
+ VALUE Constants::False(VALUE self) {
32
+ return cached<Bool, v8::Boolean>(&_False, v8::False());
33
+ }
34
+ }
@@ -0,0 +1,52 @@
1
+ #include "rr.h"
2
+
3
+ namespace rr {
4
+ void ResourceConstraints::Init() {
5
+ ClassBuilder("ResourceConstraints").
6
+ defineSingletonMethod("new", &initialize).
7
+ defineMethod("max_young_space_size", &max_young_space_size).
8
+ defineMethod("set_max_young_space_size", &set_max_young_space_size).
9
+ defineMethod("max_old_space_size", &max_old_space_size).
10
+ defineMethod("set_max_old_space_size", &set_max_old_space_size).
11
+ defineMethod("max_executable_size", &set_max_executable_size).
12
+ defineMethod("set_max_executable_size", &set_max_executable_size).
13
+ store(&Class);
14
+ ModuleBuilder("V8::C").
15
+ defineSingletonMethod("SetResourceConstraints", &SetResourceConstraints);
16
+ }
17
+
18
+ VALUE ResourceConstraints::SetResourceConstraints(VALUE self, VALUE constraints) {
19
+ Void(v8::SetResourceConstraints(ResourceConstraints(constraints)));
20
+ }
21
+
22
+ VALUE ResourceConstraints::initialize(VALUE self) {
23
+ return ResourceConstraints(new v8::ResourceConstraints());
24
+ }
25
+ VALUE ResourceConstraints::max_young_space_size(VALUE self) {
26
+ return INT2FIX(ResourceConstraints(self)->max_young_space_size());
27
+ }
28
+ VALUE ResourceConstraints::set_max_young_space_size(VALUE self, VALUE value) {
29
+ Void(ResourceConstraints(self)->set_max_young_space_size(NUM2INT(value)));
30
+ }
31
+ VALUE ResourceConstraints::max_old_space_size(VALUE self) {
32
+ return INT2FIX(ResourceConstraints(self)->max_old_space_size());
33
+ }
34
+ VALUE ResourceConstraints::set_max_old_space_size(VALUE self, VALUE value) {
35
+ Void(ResourceConstraints(self)->set_max_old_space_size(NUM2INT(value)));
36
+ }
37
+ VALUE ResourceConstraints::max_executable_size(VALUE self) {
38
+ return INT2FIX(ResourceConstraints(self)->max_executable_size());
39
+ }
40
+ VALUE ResourceConstraints::set_max_executable_size(VALUE self, VALUE value) {
41
+ Void(ResourceConstraints(self)->set_max_executable_size(NUM2INT(value)));
42
+ }
43
+
44
+ // What do these even mean?
45
+ // uint32_t* stack_limit() const { return stack_limit_; }
46
+ // // Sets an address beyond which the VM's stack may not grow.
47
+ // void set_stack_limit(uint32_t* value) { stack_limit_ = value; }
48
+
49
+ template <> void Pointer<v8::ResourceConstraints>::unwrap(VALUE value) {
50
+ Data_Get_Struct(value, class v8::ResourceConstraints, pointer);
51
+ }
52
+ }
@@ -0,0 +1,130 @@
1
+ #include "rr.h"
2
+
3
+ namespace rr {
4
+
5
+ void Context::Init() {
6
+ ClassBuilder("Context").
7
+ defineSingletonMethod("New", &New).
8
+ defineSingletonMethod("GetCurrent", &GetCurrent).
9
+ defineSingletonMethod("GetEntered", &GetEntered).
10
+ defineSingletonMethod("GetCalling", &GetCalling).
11
+ defineSingletonMethod("InContext", &InContext).
12
+ defineMethod("Dispose", &Dispose).
13
+ defineMethod("Global", &Global).
14
+ defineMethod("DetachGlobal", &Global).
15
+ defineMethod("ReattachGlobal", &ReattachGlobal).
16
+ defineMethod("SetSecurityToken", &SetSecurityToken).
17
+ defineMethod("UseDefaultSecurityToken", &UseDefaultSecurityToken).
18
+ defineMethod("GetSecurityToken", &GetSecurityToken).
19
+ defineMethod("HasOutOfMemoryException", &HasOutOfMemoryException).
20
+ defineMethod("SetData", &SetData).
21
+ defineMethod("GetData", &GetData).
22
+ defineMethod("AllowCodeGenerationFromStrings", &AllowCodeGenerationFromStrings).
23
+ defineMethod("IsCodeGenerationFromStringsAllowed", &IsCodeGenerationFromStringsAllowed).
24
+ defineMethod("Enter", &Enter).
25
+ defineMethod("Exit", &Exit).
26
+ store(&Class);
27
+ ClassBuilder("ExtensionConfiguration").
28
+ defineSingletonMethod("new", &ExtensionConfiguration::initialize).
29
+ store(&ExtensionConfiguration::Class);
30
+ }
31
+
32
+ VALUE Context::Dispose(VALUE self) {
33
+ Void(Context(self).dispose())
34
+ }
35
+
36
+ VALUE Context::Global(VALUE self) {
37
+ return Object(Context(self)->Global());
38
+ }
39
+
40
+ VALUE Context::DetachGlobal(VALUE self) {
41
+ Void(Context(self)->DetachGlobal());
42
+ }
43
+
44
+ VALUE Context::ReattachGlobal(VALUE self, VALUE global) {
45
+ Void(Context(self)->ReattachGlobal(Object(global)));
46
+ }
47
+
48
+ VALUE Context::GetEntered(VALUE self) {
49
+ return Context(v8::Context::GetEntered());
50
+ }
51
+
52
+ VALUE Context::GetCurrent(VALUE self) {
53
+ return Context(v8::Context::GetCurrent());
54
+ }
55
+
56
+ VALUE Context::GetCalling(VALUE self) {
57
+ return Context(v8::Context::GetCalling());
58
+ }
59
+
60
+ VALUE Context::SetSecurityToken(VALUE self, VALUE token) {
61
+ Void(Context(self)->SetSecurityToken(Value(token)));
62
+ }
63
+
64
+ VALUE Context::UseDefaultSecurityToken(VALUE self) {
65
+ Void(Context(self)->UseDefaultSecurityToken());
66
+ }
67
+
68
+ VALUE Context::GetSecurityToken(VALUE self) {
69
+ return Value(Context(self)->GetSecurityToken());
70
+ }
71
+
72
+ VALUE Context::HasOutOfMemoryException(VALUE self) {
73
+ return Bool(Context(self)->HasOutOfMemoryException());
74
+ }
75
+
76
+ VALUE Context::InContext(VALUE self) {
77
+ return Bool(v8::Context::InContext());
78
+ }
79
+
80
+ VALUE Context::SetData(VALUE self, VALUE data) {
81
+ Void(Context(self)->SetData(String(data)));
82
+ }
83
+
84
+ VALUE Context::GetData(VALUE self) {
85
+ return Value(Context(self)->GetData());
86
+ }
87
+
88
+ VALUE Context::AllowCodeGenerationFromStrings(VALUE self, VALUE allow) {
89
+ Void(Context(self)->AllowCodeGenerationFromStrings(RTEST(allow)));
90
+ }
91
+
92
+ VALUE Context::IsCodeGenerationFromStringsAllowed(VALUE self) {
93
+ return Bool(Context(self)->IsCodeGenerationFromStringsAllowed());
94
+ }
95
+
96
+ VALUE ExtensionConfiguration::initialize(VALUE self, VALUE names) {
97
+ int length = RARRAY_LENINT(names);
98
+ const char* array[length];
99
+ for (int i = 0; i < length; i++) {
100
+ array[i] = RSTRING_PTR(rb_ary_entry(names, i));
101
+ }
102
+ return ExtensionConfiguration(new v8::ExtensionConfiguration(length, array));
103
+ }
104
+
105
+ VALUE Context::New(int argc, VALUE argv[], VALUE self) {
106
+ VALUE extension_configuration; VALUE global_template; VALUE global_object;
107
+ rb_scan_args(argc, argv, "03", &extension_configuration, &global_template, &global_object);
108
+ v8::Persistent<v8::Context> context(v8::Context::New(
109
+ ExtensionConfiguration(extension_configuration),
110
+ *ObjectTemplate(global_template),
111
+ *Object(global_object)
112
+ ));
113
+ Context reference(context);
114
+ context.Dispose();
115
+ return reference;
116
+ }
117
+
118
+ VALUE Context::Enter(VALUE self) {
119
+ Void(Context(self)->Enter());
120
+ }
121
+
122
+ VALUE Context::Exit(VALUE self) {
123
+ Void(Context(self)->Exit());
124
+ }
125
+
126
+ template <> void Pointer<v8::ExtensionConfiguration>::unwrap(VALUE value) {
127
+ Data_Get_Struct(value, class v8::ExtensionConfiguration, pointer);
128
+ }
129
+
130
+ }
@@ -0,0 +1,18 @@
1
+ #include "rr.h"
2
+
3
+ namespace rr {
4
+
5
+ void Date::Init() {
6
+ ClassBuilder("Date", Value::Class).
7
+ defineSingletonMethod("New", &New).
8
+ defineMethod("NumberValue", &NumberValue).
9
+ store(&Class);
10
+ }
11
+
12
+ VALUE Date::New(VALUE self, VALUE time) {
13
+ return Value(v8::Date::New(NUM2DBL(time)));
14
+ }
15
+ VALUE Date::NumberValue(VALUE self) {
16
+ return rb_float_new(Date(self)->NumberValue());
17
+ }
18
+ }
@@ -0,0 +1,38 @@
1
+ #include "rr.h"
2
+
3
+ namespace rr {
4
+ void Exception::Init() {
5
+ ModuleBuilder("V8::C").
6
+ defineSingletonMethod("ThrowException", &ThrowException);
7
+ ClassBuilder("Exception").
8
+ defineSingletonMethod("RangeError", &RangeError).
9
+ defineSingletonMethod("ReferenceError", &ReferenceError).
10
+ defineSingletonMethod("SyntaxError", &SyntaxError).
11
+ defineSingletonMethod("TypeError", &TypeError).
12
+ defineSingletonMethod("Error", &Error);
13
+ }
14
+
15
+ VALUE Exception::ThrowException(VALUE self, VALUE exception) {
16
+ return Value(v8::ThrowException(Value(exception)));
17
+ }
18
+
19
+ VALUE Exception::RangeError(VALUE self, VALUE message) {
20
+ return Value(v8::Exception::RangeError(String(message)));
21
+ }
22
+
23
+ VALUE Exception::ReferenceError(VALUE self, VALUE message) {
24
+ return Value(v8::Exception::ReferenceError(String(message)));
25
+ }
26
+
27
+ VALUE Exception::SyntaxError(VALUE self, VALUE message) {
28
+ return Value(v8::Exception::SyntaxError(String(message)));
29
+ }
30
+
31
+ VALUE Exception::TypeError(VALUE self, VALUE message) {
32
+ return Value(v8::Exception::TypeError(String(message)));
33
+ }
34
+
35
+ VALUE Exception::Error(VALUE self, VALUE message) {
36
+ return Value(v8::Exception::Error(String(message)));
37
+ }
38
+ }
@@ -0,0 +1,23 @@
1
+ require 'mkmf'
2
+ require File.expand_path '../build', __FILE__
3
+
4
+ have_library('pthread')
5
+ have_library('objc') if V8::darwin?
6
+ $CPPFLAGS += " -Wall" unless $CPPFLAGS.split.include? "-Wall"
7
+ $CPPFLAGS += " -g" unless $CPPFLAGS.split.include? "-g"
8
+ $CPPFLAGS += " -rdynamic" unless $CPPFLAGS.split.include? "-rdynamic" or V8::mingw?
9
+ $CPPFLAGS += " -fPIC" unless $CPPFLAGS.split.include? "-rdynamic" or V8::darwin? or V8::mingw?
10
+
11
+ CONFIG['LDSHARED'] = '$(CXX) -shared' unless V8::darwin? or V8::mingw?
12
+ if CONFIG['warnflags']
13
+ CONFIG['warnflags'].gsub!('-Wdeclaration-after-statement', '')
14
+ CONFIG['warnflags'].gsub!('-Wimplicit-function-declaration', '')
15
+ end
16
+
17
+ if have_rubygem_libv8?
18
+ build_with_rubygem_libv8
19
+ else
20
+ build_with_system_libv8
21
+ end
22
+
23
+ create_makefile('v8/init')
@@ -0,0 +1,43 @@
1
+ #include "rr.h"
2
+
3
+ namespace rr {
4
+
5
+ void External::Init() {
6
+ ClassBuilder("External", "Value").
7
+ defineSingletonMethod("New", &New).
8
+ defineMethod("Value", &Value).
9
+ store(&Class);
10
+ }
11
+ VALUE External::New(VALUE self, VALUE data) {
12
+ return External(wrap(data));
13
+ }
14
+
15
+ v8::Handle<v8::External> External::wrap(VALUE data) {
16
+ Data* holder = new Data(data);
17
+ v8::Local<v8::External> ext = v8::External::New(holder);
18
+ v8::Persistent<v8::External>::New(ext).MakeWeak(holder, &release);
19
+ return ext;
20
+ }
21
+
22
+ VALUE External::unwrap(v8::Handle<v8::External> external) {
23
+ Data* data = (Data*)(external->Value());
24
+ return data->value;
25
+ }
26
+
27
+ VALUE External::Value(VALUE self) {
28
+ return unwrap(External(self));
29
+ }
30
+
31
+ void External::release(v8::Persistent<v8::Value> handle, void* parameter) {
32
+ handle.Dispose();
33
+ Data* data = (Data*)parameter;
34
+ delete data;
35
+ }
36
+ External::Data::Data(VALUE data) {
37
+ this->value = data;
38
+ rb_gc_register_address(&value);
39
+ }
40
+ External::Data::~Data() {
41
+ rb_gc_unregister_address(&value);
42
+ }
43
+ }