rucy 0.3.11 → 0.3.12
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 +4 -4
- data/.doc/ext/rucy/value.cpp +28 -0
- data/.github/workflows/release-gem.yml +3 -0
- data/.github/workflows/utils.rb +88 -17
- data/ChangeLog.md +10 -0
- data/VERSION +1 -1
- data/ext/rucy/value.cpp +34 -2
- data/include/rucy/extension.h.erb +58 -37
- data/include/rucy/value.h.erb +2 -0
- data/include/rucy.h +2 -2
- data/lib/rucy/extension.rb +8 -2
- data/rucy.gemspec +2 -3
- data/src/rucy.cpp +15 -0
- data/src/value.cpp.erb +61 -24
- data/test/test_value.rb +24 -9
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b1729a91940f9162509a18696813859a374ccb82c4af989b4c782e6015e394fa
|
|
4
|
+
data.tar.gz: 645ee9505dc9178bd1aa77093f44566290e05dac58ca5d20d62193e0d7a5c0d3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2995825674988de7587c353785c032f15e974e5074412497b448fd6ac0450d0450dc4a0951b805e80ef58c66d47c92546e88da36127c4cbd0693c768b94e0b57
|
|
7
|
+
data.tar.gz: b7fbe367adbbcfd7de8dc7176f488a776451dbfb9658ac9c3f6a7b857aa3327cfcf5713f26b9bae709a4a3eb746c124917cb926da8df77ef728fe6701c9c1ba6
|
data/.doc/ext/rucy/value.cpp
CHANGED
|
@@ -28,6 +28,30 @@ VALUE value_to_ushort(VALUE self, VALUE num)
|
|
|
28
28
|
return value(to<unsigned short>(num));
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
static
|
|
32
|
+
VALUE value_to_int(VALUE self, VALUE num)
|
|
33
|
+
{
|
|
34
|
+
return value(to<int>(num));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static
|
|
38
|
+
VALUE value_to_uint(VALUE self, VALUE num)
|
|
39
|
+
{
|
|
40
|
+
return value(to<unsigned int>(num));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static
|
|
44
|
+
VALUE value_to_long(VALUE self, VALUE num)
|
|
45
|
+
{
|
|
46
|
+
return value(to<long>(num));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
static
|
|
50
|
+
VALUE value_to_ulong(VALUE self, VALUE num)
|
|
51
|
+
{
|
|
52
|
+
return value(to<unsigned long>(num));
|
|
53
|
+
}
|
|
54
|
+
|
|
31
55
|
static
|
|
32
56
|
VALUE true_to_value(VALUE self)
|
|
33
57
|
{
|
|
@@ -84,6 +108,10 @@ Init_value ()
|
|
|
84
108
|
rb_define_method(mTester, "value_to_uchar", RUBY_METHOD_FUNC(value_to_uchar), 1);
|
|
85
109
|
rb_define_method(mTester, "value_to_short", RUBY_METHOD_FUNC(value_to_short), 1);
|
|
86
110
|
rb_define_method(mTester, "value_to_ushort", RUBY_METHOD_FUNC(value_to_ushort), 1);
|
|
111
|
+
rb_define_method(mTester, "value_to_int", RUBY_METHOD_FUNC(value_to_int), 1);
|
|
112
|
+
rb_define_method(mTester, "value_to_uint", RUBY_METHOD_FUNC(value_to_uint), 1);
|
|
113
|
+
rb_define_method(mTester, "value_to_long", RUBY_METHOD_FUNC(value_to_long), 1);
|
|
114
|
+
rb_define_method(mTester, "value_to_ulong", RUBY_METHOD_FUNC(value_to_ulong), 1);
|
|
87
115
|
|
|
88
116
|
rb_define_method(mTester, "true_to_value", RUBY_METHOD_FUNC(true_to_value), -1);
|
|
89
117
|
rb_define_method(mTester, "false_to_value", RUBY_METHOD_FUNC(false_to_value), -1);
|
data/.github/workflows/utils.rb
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
require 'shellwords'
|
|
2
|
+
|
|
3
|
+
ALL_REPO = 'xord/all'
|
|
4
|
+
ALL_DIR = '../all'
|
|
5
|
+
ALL_FETCH_DEPTH = 100
|
|
6
|
+
|
|
1
7
|
RENAMES = {reflex: 'reflexion'}
|
|
2
8
|
|
|
3
9
|
def sh(cmd)
|
|
@@ -5,7 +11,7 @@ def sh(cmd)
|
|
|
5
11
|
system cmd
|
|
6
12
|
end
|
|
7
13
|
|
|
8
|
-
def setup_dependencies(
|
|
14
|
+
def setup_dependencies(only: nil)
|
|
9
15
|
gemspec_path = `git ls-files`.lines(chomp: true).find {|l| l =~ /\.gemspec$/}
|
|
10
16
|
return unless gemspec_path
|
|
11
17
|
|
|
@@ -13,44 +19,109 @@ def setup_dependencies(build: true, only: nil)
|
|
|
13
19
|
name = File.basename gemspec_path, '.gemspec'
|
|
14
20
|
|
|
15
21
|
exts = File.readlines('Rakefile')
|
|
16
|
-
.map {|l| l[%r|^\s*require\W+(\w+)/extension\W+$|, 1]}
|
|
22
|
+
.map {|l| l[%r|^\s*require\W+([\w\-\_]+)/extension\W+$|, 1]}
|
|
17
23
|
.compact
|
|
18
24
|
.reject {|ext| ext == name}
|
|
19
25
|
exts = exts & [only].flatten.map(&:to_s) if only
|
|
26
|
+
return if exts.empty?
|
|
27
|
+
|
|
28
|
+
unless setup_dependencies_via_monorepo(exts)
|
|
29
|
+
setup_dependencies_via_each_repo_by_version(gemspec, exts)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
exts.each {|ext| sh %( cd ../#{ext} && rake ext )}
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def setup_dependencies_via_monorepo(exts)
|
|
36
|
+
return false unless checkout_monorepo
|
|
37
|
+
exts.each {|ext| sh %( ln -snf all/#{ext} ../#{ext} )}
|
|
38
|
+
true
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def checkout_monorepo()
|
|
42
|
+
uuid = `git log -1 --format=%B`[/^\[\[([0-9a-fA-F-]+)\]\]$/, 1]
|
|
43
|
+
return false unless uuid
|
|
44
|
+
|
|
45
|
+
commit = setup_monorepo uuid
|
|
46
|
+
return false unless commit
|
|
47
|
+
|
|
48
|
+
Dir.chdir(ALL_DIR) {sh %( git checkout -q #{commit} )}
|
|
49
|
+
true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def setup_monorepo(uuid)
|
|
53
|
+
unless File.directory? ALL_DIR
|
|
54
|
+
url = "https://github.com/#{ALL_REPO}.git"
|
|
55
|
+
sh %( git clone --no-tags --depth #{ALL_FETCH_DEPTH} #{url} #{ALL_DIR} )
|
|
56
|
+
end
|
|
57
|
+
loop do
|
|
58
|
+
commit = find_monorepo_commit uuid
|
|
59
|
+
return commit if commit
|
|
60
|
+
|
|
61
|
+
deepened = Dir.chdir ALL_DIR do
|
|
62
|
+
before = `git rev-list --count HEAD`.to_i
|
|
63
|
+
sh %( git fetch --deepen #{ALL_FETCH_DEPTH} )
|
|
64
|
+
`git rev-list --count HEAD`.to_i > before
|
|
65
|
+
end
|
|
66
|
+
return nil unless deepened
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def find_monorepo_commit(uuid)
|
|
71
|
+
Dir.chdir ALL_DIR do
|
|
72
|
+
out = `git log origin/HEAD -F --grep="[[#{uuid}]]" --format=%H -1`.strip
|
|
73
|
+
out.empty? ? nil : out
|
|
74
|
+
end
|
|
75
|
+
end
|
|
20
76
|
|
|
77
|
+
def setup_dependencies_via_each_repo_by_version(gemspec, exts)
|
|
21
78
|
exts.each do |ext|
|
|
22
79
|
gem = RENAMES[ext.to_sym].then {|s| s || ext}
|
|
23
|
-
ver = gemspec[/add_dependency.*['"]#{gem}['"].*['"]\s
|
|
80
|
+
ver = gemspec[/add_dependency.*['"]#{gem}['"].*['"]\s*~>\s*([\d\.]+)\s*['"]/, 1]
|
|
24
81
|
opts = '-c advice.detachedHead=false --depth 1'
|
|
25
82
|
clone = "git clone #{opts} https://github.com/xord/#{ext}.git ../#{ext}"
|
|
26
83
|
|
|
27
84
|
# 'rake subtree:push' pushes all subrepos, so cloning by new tag
|
|
28
85
|
# often fails before tagging each new tag
|
|
29
86
|
sh %( #{clone} --branch v#{ver} || #{clone} )
|
|
30
|
-
sh %( cd ../#{ext} && rake ext )
|
|
31
87
|
end
|
|
32
88
|
end
|
|
33
89
|
|
|
34
90
|
def tag_versions()
|
|
35
|
-
|
|
36
|
-
|
|
91
|
+
changes = changelogs
|
|
92
|
+
tags = `git tag`.lines chomp: true
|
|
93
|
+
vers = `git log --oneline ./VERSION`
|
|
37
94
|
.lines(chomp: true)
|
|
38
95
|
.map {|line| line.split.first[/^\w+$/]}
|
|
39
|
-
.map {|
|
|
40
|
-
.select {|ver,
|
|
96
|
+
.map {|sha| [`git cat-file -p #{sha}:./VERSION 2>/dev/null`[/[\d\.]+/], sha]}
|
|
97
|
+
.select {|ver, sha| ver && sha}
|
|
41
98
|
.reverse
|
|
42
99
|
.to_h
|
|
43
100
|
|
|
44
|
-
|
|
45
|
-
.split(/^\s*##\s*\[\s*v([\d\.]+)\s*\].*$/)
|
|
46
|
-
.slice(1..-1)
|
|
47
|
-
.each_slice(2)
|
|
48
|
-
.to_h
|
|
49
|
-
.transform_values(&:strip!)
|
|
50
|
-
|
|
51
|
-
vers.to_a.reverse.each do |ver, hash|
|
|
101
|
+
vers.to_a.reverse.each do |ver, sha|
|
|
52
102
|
tag = "v#{ver}"
|
|
53
103
|
break if tags.include?(tag)
|
|
54
|
-
sh %( git tag -a -m \"#{changes[
|
|
104
|
+
sh %( git tag -a -m \"#{changes[tag]&.gsub '"', '\\"'}\" #{tag} #{sha} )
|
|
55
105
|
end
|
|
56
106
|
end
|
|
107
|
+
|
|
108
|
+
def release(*paths)
|
|
109
|
+
tag = ENV['GITHUB_REF']&.sub(%r|^refs/tags/|, '') || raise('GITHUB_REF tag not set')
|
|
110
|
+
notes = (changelogs[tag] || '').shellescape
|
|
111
|
+
paths = paths.flatten.join ' '
|
|
112
|
+
|
|
113
|
+
sh(%( gh release create #{tag} #{paths} --notes #{notes} )) ||
|
|
114
|
+
sh(%( gh release upload #{tag} #{paths} --clobber )) ||
|
|
115
|
+
raise('failed to upload to releases')
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def changelogs()
|
|
119
|
+
File.read('ChangeLog.md')
|
|
120
|
+
.split(/^\s*##\s*\[\s*(v[\d\.]+)\s*\].*$/)
|
|
121
|
+
.slice(1..)
|
|
122
|
+
.each_slice(2)
|
|
123
|
+
.to_h
|
|
124
|
+
.transform_values(&:strip!)
|
|
125
|
+
rescue Errno::ENOENT
|
|
126
|
+
raise 'failed to get changelogs'
|
|
127
|
+
end
|
data/ChangeLog.md
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
# rucy ChangeLog
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
## [v0.3.12] - 2026-05-10
|
|
5
|
+
|
|
6
|
+
- Migrate to TypedData API for Ruby 4.x compatibility
|
|
7
|
+
- Enable WB_PROTECTED for TypedData with no mark function
|
|
8
|
+
- Add range checks to integer value_to conversions
|
|
9
|
+
- Add Value::respond_to wrapping rb_respond_to
|
|
10
|
+
- Use hint_memory_usage callback for external memory GC integration
|
|
11
|
+
- Remove deprecated has_rdoc= from gemspecs
|
|
12
|
+
|
|
13
|
+
|
|
4
14
|
## [v0.3.11] - 2026-04-17
|
|
5
15
|
|
|
6
16
|
- Fix ANYARGS function pointer warnings in module bindings
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.3.
|
|
1
|
+
0.3.12
|
data/ext/rucy/value.cpp
CHANGED
|
@@ -32,6 +32,34 @@ RUCY_DEF1(value_to_ushort, num)
|
|
|
32
32
|
}
|
|
33
33
|
RUCY_END
|
|
34
34
|
|
|
35
|
+
static
|
|
36
|
+
RUCY_DEF1(value_to_int, num)
|
|
37
|
+
{
|
|
38
|
+
return value(to<int>(num));
|
|
39
|
+
}
|
|
40
|
+
RUCY_END
|
|
41
|
+
|
|
42
|
+
static
|
|
43
|
+
RUCY_DEF1(value_to_uint, num)
|
|
44
|
+
{
|
|
45
|
+
return value(to<unsigned int>(num));
|
|
46
|
+
}
|
|
47
|
+
RUCY_END
|
|
48
|
+
|
|
49
|
+
static
|
|
50
|
+
RUCY_DEF1(value_to_long, num)
|
|
51
|
+
{
|
|
52
|
+
return value(to<long>(num));
|
|
53
|
+
}
|
|
54
|
+
RUCY_END
|
|
55
|
+
|
|
56
|
+
static
|
|
57
|
+
RUCY_DEF1(value_to_ulong, num)
|
|
58
|
+
{
|
|
59
|
+
return value(to<unsigned long>(num));
|
|
60
|
+
}
|
|
61
|
+
RUCY_END
|
|
62
|
+
|
|
35
63
|
static
|
|
36
64
|
RUCY_DEFN(true_to_value)
|
|
37
65
|
{
|
|
@@ -89,10 +117,14 @@ Init_value ()
|
|
|
89
117
|
Module mRucy = define_module("Rucy");
|
|
90
118
|
Module mTester = mRucy.define_module("Tester");
|
|
91
119
|
|
|
92
|
-
mTester.define_method("value_to_char",
|
|
93
|
-
mTester.define_method("value_to_uchar",
|
|
120
|
+
mTester.define_method("value_to_char", value_to_char);
|
|
121
|
+
mTester.define_method("value_to_uchar", value_to_uchar);
|
|
94
122
|
mTester.define_method("value_to_short", value_to_short);
|
|
95
123
|
mTester.define_method("value_to_ushort", value_to_ushort);
|
|
124
|
+
mTester.define_method("value_to_int", value_to_int);
|
|
125
|
+
mTester.define_method("value_to_uint", value_to_uint);
|
|
126
|
+
mTester.define_method("value_to_long", value_to_long);
|
|
127
|
+
mTester.define_method("value_to_ulong", value_to_ulong);
|
|
96
128
|
|
|
97
129
|
mTester.define_method("true_to_value", true_to_value);
|
|
98
130
|
mTester.define_method("false_to_value", false_to_value);
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
#define __RUCY_EXTENSION_H__
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
#include <typeinfo>
|
|
7
8
|
#include <xot/ref.h>
|
|
8
9
|
#include <xot/string.h>
|
|
9
10
|
#include <rucy/defs.h>
|
|
@@ -384,81 +385,101 @@ namespace Rucy
|
|
|
384
385
|
};// ClassWrapper
|
|
385
386
|
|
|
386
387
|
|
|
387
|
-
template <typename T>
|
|
388
|
+
template <typename T>
|
|
389
|
+
inline void delete_type (void* p)
|
|
388
390
|
{
|
|
389
391
|
delete (T*) p;
|
|
390
392
|
}
|
|
391
393
|
|
|
392
|
-
template <typename T>
|
|
394
|
+
template <typename T>
|
|
395
|
+
inline void release_ref (void* p)
|
|
393
396
|
{
|
|
394
397
|
if (p) ((T*) p)->release();
|
|
395
398
|
}
|
|
396
399
|
|
|
397
|
-
template <typename T>
|
|
400
|
+
template <typename T>
|
|
401
|
+
inline void release_wrapper (void* p)
|
|
398
402
|
{
|
|
399
403
|
if (p) ((T*) p)->release(true);
|
|
400
404
|
}
|
|
401
405
|
|
|
402
406
|
|
|
403
|
-
template <typename T
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
+
template <typename T, RUBY_DATA_FUNC mark, RUBY_DATA_FUNC free>
|
|
408
|
+
inline const rb_data_type_t* get_data_type ()
|
|
409
|
+
{
|
|
410
|
+
static const rb_data_type_t data_type = {
|
|
411
|
+
typeid(T).name(),
|
|
412
|
+
{mark, free, NULL, NULL, {NULL}},
|
|
413
|
+
NULL, NULL,
|
|
414
|
+
RUBY_TYPED_FREE_IMMEDIATELY |
|
|
415
|
+
(mark == nullptr ? RUBY_TYPED_WB_PROTECTED : 0)
|
|
416
|
+
};
|
|
417
|
+
return &data_type;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
template <
|
|
422
|
+
typename T,
|
|
423
|
+
RUBY_DATA_FUNC mark = nullptr,
|
|
424
|
+
RUBY_DATA_FUNC free = delete_type<T>>
|
|
425
|
+
inline Value new_type (Value klass, T* ptr)
|
|
407
426
|
{
|
|
408
427
|
if (!ptr) return nil();
|
|
409
|
-
return
|
|
428
|
+
return rb_data_typed_object_wrap(klass, ptr, get_data_type<T, mark, free>());
|
|
410
429
|
}
|
|
411
430
|
|
|
412
|
-
template <
|
|
413
|
-
|
|
414
|
-
RUBY_DATA_FUNC mark =
|
|
415
|
-
RUBY_DATA_FUNC free = delete_type<T
|
|
431
|
+
template <
|
|
432
|
+
typename T,
|
|
433
|
+
RUBY_DATA_FUNC mark = nullptr,
|
|
434
|
+
RUBY_DATA_FUNC free = delete_type<T>>
|
|
435
|
+
inline Value new_type (Value klass)
|
|
416
436
|
{
|
|
417
|
-
return new_type(klass, new T
|
|
437
|
+
return new_type<T, mark, free>(klass, new T);
|
|
418
438
|
}
|
|
419
439
|
|
|
420
|
-
template <
|
|
421
|
-
|
|
422
|
-
RUBY_DATA_FUNC mark =
|
|
423
|
-
RUBY_DATA_FUNC free = release_ref<T
|
|
440
|
+
template <
|
|
441
|
+
typename T,
|
|
442
|
+
RUBY_DATA_FUNC mark = nullptr,
|
|
443
|
+
RUBY_DATA_FUNC free = release_ref<T>>
|
|
444
|
+
inline Value new_ref (Value klass, T* ptr)
|
|
424
445
|
{
|
|
425
446
|
if (ptr) ptr->retain();
|
|
426
|
-
return new_type
|
|
447
|
+
return new_type<T, mark, free>(klass, ptr);
|
|
427
448
|
}
|
|
428
449
|
|
|
429
|
-
template <
|
|
430
|
-
|
|
431
|
-
RUBY_DATA_FUNC mark =
|
|
432
|
-
RUBY_DATA_FUNC free = release_ref<T
|
|
450
|
+
template <
|
|
451
|
+
typename T,
|
|
452
|
+
RUBY_DATA_FUNC mark = nullptr,
|
|
453
|
+
RUBY_DATA_FUNC free = release_ref<T>>
|
|
454
|
+
inline Value new_ref (Value klass)
|
|
433
455
|
{
|
|
434
|
-
return new_ref(klass, new T
|
|
456
|
+
return new_ref<T, mark, free>(klass, new T);
|
|
435
457
|
}
|
|
436
458
|
|
|
437
|
-
template <
|
|
438
|
-
|
|
439
|
-
RUBY_DATA_FUNC mark =
|
|
440
|
-
RUBY_DATA_FUNC free = release_wrapper<T
|
|
459
|
+
template <
|
|
460
|
+
typename T,
|
|
461
|
+
RUBY_DATA_FUNC mark = nullptr,
|
|
462
|
+
RUBY_DATA_FUNC free = release_wrapper<T>>
|
|
463
|
+
inline Value new_wrapper (Value klass, T* ptr)
|
|
441
464
|
{
|
|
442
465
|
if (ptr) ptr->retain(true);
|
|
443
|
-
return new_type
|
|
466
|
+
return new_type<T, mark, free>(klass, ptr);
|
|
444
467
|
}
|
|
445
468
|
|
|
446
|
-
template <
|
|
447
|
-
|
|
448
|
-
RUBY_DATA_FUNC mark =
|
|
449
|
-
RUBY_DATA_FUNC free = release_wrapper<T
|
|
469
|
+
template <
|
|
470
|
+
typename T,
|
|
471
|
+
RUBY_DATA_FUNC mark = nullptr,
|
|
472
|
+
RUBY_DATA_FUNC free = release_wrapper<T>>
|
|
473
|
+
inline Value new_wrapper (Value klass)
|
|
450
474
|
{
|
|
451
|
-
return new_wrapper(klass, new T
|
|
475
|
+
return new_wrapper<T, mark, free>(klass, new T);
|
|
452
476
|
}
|
|
453
477
|
|
|
454
478
|
|
|
455
479
|
template <typename T> inline T* get_type_ptr (Value obj, Value klass = nil())
|
|
456
480
|
{
|
|
457
481
|
if (!klass.is_nil()) check_class(obj, klass);
|
|
458
|
-
|
|
459
|
-
T* p = NULL;
|
|
460
|
-
Data_Get_Struct(o, T, p);
|
|
461
|
-
return p;
|
|
482
|
+
return (T*) DATA_PTR(obj.value());
|
|
462
483
|
}
|
|
463
484
|
|
|
464
485
|
|
data/include/rucy/value.h.erb
CHANGED
data/include/rucy.h
CHANGED
data/lib/rucy/extension.rb
CHANGED
|
@@ -5,8 +5,10 @@ module Rucy
|
|
|
5
5
|
|
|
6
6
|
module_function
|
|
7
7
|
|
|
8
|
-
def name()
|
|
9
|
-
super.split('::')[-2]
|
|
8
|
+
def name(downcase = false)
|
|
9
|
+
super().split('::')[-2].then {|s|
|
|
10
|
+
downcase ? s.gsub(/([a-z])([A-Z])/) {"#{$1}-#{$2}"}.downcase : s
|
|
11
|
+
}
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
def version()
|
|
@@ -29,6 +31,10 @@ module Rucy
|
|
|
29
31
|
root_dir 'ext'
|
|
30
32
|
end
|
|
31
33
|
|
|
34
|
+
def lib_name()
|
|
35
|
+
name true
|
|
36
|
+
end
|
|
37
|
+
|
|
32
38
|
end# Extension
|
|
33
39
|
|
|
34
40
|
|
data/rucy.gemspec
CHANGED
|
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
ext = Rucy::Extension
|
|
13
|
-
name = ext.name
|
|
13
|
+
name = ext.name true
|
|
14
14
|
rdocs = glob.call *%w[README .doc/ext/**/*.cpp]
|
|
15
15
|
|
|
16
16
|
s.name = name
|
|
@@ -25,13 +25,12 @@ Gem::Specification.new do |s|
|
|
|
25
25
|
s.platform = Gem::Platform::RUBY
|
|
26
26
|
s.required_ruby_version = '>= 3.0.0'
|
|
27
27
|
|
|
28
|
-
s.add_dependency 'xot', '~> 0.3.
|
|
28
|
+
s.add_dependency 'xot', '~> 0.3.12'
|
|
29
29
|
|
|
30
30
|
s.files = `git ls-files`.split $/
|
|
31
31
|
s.executables = s.files.grep(%r{^bin/}) {|f| File.basename f}
|
|
32
32
|
s.test_files = s.files.grep %r{^(test|spec|features)/}
|
|
33
33
|
s.extra_rdoc_files = rdocs.to_a
|
|
34
|
-
s.has_rdoc = true
|
|
35
34
|
|
|
36
35
|
s.extensions << 'Rakefile'
|
|
37
36
|
end
|
data/src/rucy.cpp
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
#include "rucy/rucy.h"
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
#include <xot/util.h>
|
|
5
6
|
#include "rucy/exception.h"
|
|
6
7
|
|
|
7
8
|
|
|
@@ -9,6 +10,18 @@ namespace Rucy
|
|
|
9
10
|
{
|
|
10
11
|
|
|
11
12
|
|
|
13
|
+
static void
|
|
14
|
+
hint_memory_usage (ssize_t size)
|
|
15
|
+
{
|
|
16
|
+
rb_gc_adjust_memory_usage(size);
|
|
17
|
+
|
|
18
|
+
// rb_gc_adjust_memory_usage() uses MEMOP_TYPE_REALLOC internally,
|
|
19
|
+
// which increases malloc_increase but does not check the GC trigger.
|
|
20
|
+
// A tiny ruby_xmalloc() goes through MEMOP_TYPE_MALLOC and triggers
|
|
21
|
+
// GC when malloc_increase exceeds malloc_limit.
|
|
22
|
+
if (size > 0) ruby_xfree(ruby_xmalloc(1));
|
|
23
|
+
}
|
|
24
|
+
|
|
12
25
|
void
|
|
13
26
|
init ()
|
|
14
27
|
{
|
|
@@ -16,6 +29,8 @@ namespace Rucy
|
|
|
16
29
|
if (done) return;
|
|
17
30
|
done = true;
|
|
18
31
|
|
|
32
|
+
Xot::set_hint_memory_usage_fun(hint_memory_usage);
|
|
33
|
+
|
|
19
34
|
rucy_module();
|
|
20
35
|
native_error_class();
|
|
21
36
|
invalid_state_error_class();
|
data/src/value.cpp.erb
CHANGED
|
@@ -308,6 +308,12 @@ namespace Rucy
|
|
|
308
308
|
return rb_obj_is_kind_of(val, klass);
|
|
309
309
|
}
|
|
310
310
|
|
|
311
|
+
bool
|
|
312
|
+
Value::respond_to (Symbol name) const
|
|
313
|
+
{
|
|
314
|
+
return rb_respond_to(val, name.symbol());
|
|
315
|
+
}
|
|
316
|
+
|
|
311
317
|
Value
|
|
312
318
|
Value::inspect () const
|
|
313
319
|
{
|
|
@@ -646,29 +652,16 @@ namespace Rucy
|
|
|
646
652
|
return (bool) obj;
|
|
647
653
|
}
|
|
648
654
|
|
|
649
|
-
template <> int
|
|
650
|
-
value_to<int> (Value obj, bool convert)
|
|
651
|
-
{
|
|
652
|
-
if (convert) obj = obj.to_i();
|
|
653
|
-
return NUM2INT(obj.value());
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
template <> unsigned int
|
|
657
|
-
value_to<unsigned int> (Value obj, bool convert)
|
|
658
|
-
{
|
|
659
|
-
if (convert) obj = obj.to_i();
|
|
660
|
-
return NUM2UINT(obj.value());
|
|
661
|
-
}
|
|
662
|
-
|
|
663
655
|
template <> char
|
|
664
656
|
value_to<char> (Value obj, bool convert)
|
|
665
657
|
{
|
|
666
|
-
|
|
658
|
+
if (convert) obj = obj.to_i();
|
|
659
|
+
int n = NUM2INT(obj.value());
|
|
667
660
|
if (
|
|
668
661
|
n < std::numeric_limits<char>::min() ||
|
|
669
662
|
n > std::numeric_limits<char>::max())
|
|
670
663
|
{
|
|
671
|
-
range_error(__FILE__, __LINE__, "cannot cast '%d' to char");
|
|
664
|
+
range_error(__FILE__, __LINE__, "cannot cast '%d' to char", n);
|
|
672
665
|
}
|
|
673
666
|
return (char) n;
|
|
674
667
|
}
|
|
@@ -676,12 +669,13 @@ namespace Rucy
|
|
|
676
669
|
template <> unsigned char
|
|
677
670
|
value_to<unsigned char> (Value obj, bool convert)
|
|
678
671
|
{
|
|
679
|
-
|
|
672
|
+
if (convert) obj = obj.to_i();
|
|
673
|
+
int n = NUM2INT(obj.value());
|
|
680
674
|
if (
|
|
681
675
|
n < std::numeric_limits<unsigned char>::min() ||
|
|
682
676
|
n > std::numeric_limits<unsigned char>::max())
|
|
683
677
|
{
|
|
684
|
-
range_error(__FILE__, __LINE__, "cannot cast '%d' to unsigned char");
|
|
678
|
+
range_error(__FILE__, __LINE__, "cannot cast '%d' to unsigned char", n);
|
|
685
679
|
}
|
|
686
680
|
return (unsigned char) n;
|
|
687
681
|
}
|
|
@@ -689,12 +683,13 @@ namespace Rucy
|
|
|
689
683
|
template <> short
|
|
690
684
|
value_to<short> (Value obj, bool convert)
|
|
691
685
|
{
|
|
692
|
-
|
|
686
|
+
if (convert) obj = obj.to_i();
|
|
687
|
+
int n = NUM2INT(obj.value());
|
|
693
688
|
if (
|
|
694
689
|
n < std::numeric_limits<short>::min() ||
|
|
695
690
|
n > std::numeric_limits<short>::max())
|
|
696
691
|
{
|
|
697
|
-
range_error(__FILE__, __LINE__, "cannot cast '%d' to short");
|
|
692
|
+
range_error(__FILE__, __LINE__, "cannot cast '%d' to short", n);
|
|
698
693
|
}
|
|
699
694
|
return (short) n;
|
|
700
695
|
}
|
|
@@ -702,28 +697,67 @@ namespace Rucy
|
|
|
702
697
|
template <> unsigned short
|
|
703
698
|
value_to<unsigned short> (Value obj, bool convert)
|
|
704
699
|
{
|
|
705
|
-
|
|
700
|
+
if (convert) obj = obj.to_i();
|
|
701
|
+
int n = NUM2INT(obj.value());
|
|
706
702
|
if (
|
|
707
703
|
n < std::numeric_limits<unsigned short>::min() ||
|
|
708
704
|
n > std::numeric_limits<unsigned short>::max())
|
|
709
705
|
{
|
|
710
|
-
range_error(__FILE__, __LINE__, "cannot cast '%d' to unsigned short");
|
|
706
|
+
range_error(__FILE__, __LINE__, "cannot cast '%d' to unsigned short", n);
|
|
711
707
|
}
|
|
712
708
|
return (unsigned short) n;
|
|
713
709
|
}
|
|
714
710
|
|
|
711
|
+
template <> int
|
|
712
|
+
value_to<int> (Value obj, bool convert)
|
|
713
|
+
{
|
|
714
|
+
if (convert) obj = obj.to_i();
|
|
715
|
+
long long n = NUM2LL(obj.value());
|
|
716
|
+
if (
|
|
717
|
+
n < std::numeric_limits<int>::min() ||
|
|
718
|
+
n > std::numeric_limits<int>::max())
|
|
719
|
+
{
|
|
720
|
+
range_error(__FILE__, __LINE__, "cannot cast '%lld' to int", n);
|
|
721
|
+
}
|
|
722
|
+
return (int) n;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
template <> unsigned int
|
|
726
|
+
value_to<unsigned int> (Value obj, bool convert)
|
|
727
|
+
{
|
|
728
|
+
if (convert) obj = obj.to_i();
|
|
729
|
+
long long n = NUM2LL(obj.value());
|
|
730
|
+
if (
|
|
731
|
+
n < std::numeric_limits<unsigned int>::min() ||
|
|
732
|
+
n > std::numeric_limits<unsigned int>::max())
|
|
733
|
+
{
|
|
734
|
+
range_error(__FILE__, __LINE__, "cannot cast '%lld' to unsigned int", n);
|
|
735
|
+
}
|
|
736
|
+
return (unsigned int) n;
|
|
737
|
+
}
|
|
738
|
+
|
|
715
739
|
template <> long
|
|
716
740
|
value_to<long> (Value obj, bool convert)
|
|
717
741
|
{
|
|
718
742
|
if (convert) obj = obj.to_i();
|
|
719
|
-
|
|
743
|
+
long long n = NUM2LL(obj.value());
|
|
744
|
+
if (
|
|
745
|
+
n < std::numeric_limits<long>::min() ||
|
|
746
|
+
n > std::numeric_limits<long>::max())
|
|
747
|
+
{
|
|
748
|
+
range_error(__FILE__, __LINE__, "cannot cast '%lld' to long", n);
|
|
749
|
+
}
|
|
750
|
+
return (long) n;
|
|
720
751
|
}
|
|
721
752
|
|
|
722
753
|
template <> unsigned long
|
|
723
754
|
value_to<unsigned long> (Value obj, bool convert)
|
|
724
755
|
{
|
|
725
756
|
if (convert) obj = obj.to_i();
|
|
726
|
-
|
|
757
|
+
long long n = NUM2LL(obj.value());
|
|
758
|
+
if (n < 0)
|
|
759
|
+
range_error(__FILE__, __LINE__, "cannot cast '%lld' to unsigned long", n);
|
|
760
|
+
return (unsigned long) n;
|
|
727
761
|
}
|
|
728
762
|
|
|
729
763
|
template <> long long
|
|
@@ -737,6 +771,9 @@ namespace Rucy
|
|
|
737
771
|
value_to<unsigned long long> (Value obj, bool convert)
|
|
738
772
|
{
|
|
739
773
|
if (convert) obj = obj.to_i();
|
|
774
|
+
long long n = NUM2LL(obj.value());
|
|
775
|
+
if (n < 0)
|
|
776
|
+
range_error(__FILE__, __LINE__, "cannot cast '%lld' to unsigned long long", n);
|
|
740
777
|
return NUM2ULL(obj.value());
|
|
741
778
|
}
|
|
742
779
|
|
data/test/test_value.rb
CHANGED
|
@@ -8,31 +8,46 @@ class TestFunction < Test::Unit::TestCase
|
|
|
8
8
|
def test_value_to_char()
|
|
9
9
|
assert_equal 0, value_to_char( 0)
|
|
10
10
|
assert_equal 127, value_to_char( 127)
|
|
11
|
-
assert_equal -128, value_to_char(-128)
|
|
12
11
|
assert_raise(RangeError) {value_to_char 128}
|
|
13
|
-
|
|
12
|
+
assert_equal(-128, value_to_char(-128))
|
|
13
|
+
assert_raise(RangeError) {value_to_char(-129)}
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def test_value_to_uchar()
|
|
17
|
-
assert_equal 0, value_to_uchar( 0)
|
|
18
17
|
assert_equal 255, value_to_uchar(255)
|
|
19
18
|
assert_raise(RangeError) {value_to_uchar 256}
|
|
20
|
-
|
|
19
|
+
assert_equal 0, value_to_uchar( 0)
|
|
20
|
+
assert_raise(RangeError) {value_to_uchar( -1)}
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
def test_value_to_short()
|
|
24
|
-
assert_equal 0,
|
|
24
|
+
assert_equal 0, value_to_short( 0)
|
|
25
25
|
assert_equal 32767, value_to_short( 32767)
|
|
26
|
-
assert_equal -32768, value_to_short(-32768)
|
|
27
26
|
assert_raise(RangeError) {value_to_short 32768}
|
|
28
|
-
|
|
27
|
+
assert_equal(-32768, value_to_short(-32768))
|
|
28
|
+
assert_raise(RangeError) {value_to_short(-32769)}
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def test_value_to_ushort()
|
|
32
|
-
assert_equal 0, value_to_ushort( 0)
|
|
33
32
|
assert_equal 65535, value_to_ushort(65535)
|
|
34
33
|
assert_raise(RangeError) {value_to_ushort 65536}
|
|
35
|
-
|
|
34
|
+
assert_equal 0, value_to_ushort( 0)
|
|
35
|
+
assert_raise(RangeError) {value_to_ushort( -1)}
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_value_to_int()
|
|
39
|
+
assert_equal 0, value_to_int( 0)
|
|
40
|
+
assert_equal 2147483647, value_to_int( 2147483647)
|
|
41
|
+
assert_raise(RangeError) {value_to_int 2147483648}
|
|
42
|
+
assert_equal(-2147483648, value_to_int(-2147483648))
|
|
43
|
+
assert_raise(RangeError) {value_to_int(-2147483649)}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_value_to_uint()
|
|
47
|
+
assert_equal 4294967295, value_to_uint(4294967295)
|
|
48
|
+
assert_raise(RangeError) {value_to_uint 4294967296}
|
|
49
|
+
assert_equal 0, value_to_uint( 0)
|
|
50
|
+
assert_raise(RangeError) {value_to_uint( -1)}
|
|
36
51
|
end
|
|
37
52
|
|
|
38
53
|
def test_to_value()
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rucy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.12
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- xordog
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-05-09 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: xot
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.3.
|
|
19
|
+
version: 0.3.12
|
|
20
20
|
type: :runtime
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.3.
|
|
26
|
+
version: 0.3.12
|
|
27
27
|
description: This library helps you to develop Ruby Extension by C++.
|
|
28
28
|
email: xordog@gmail.com
|
|
29
29
|
executables:
|