Skip to content

Commit e415105

Browse files
committed
[GR-18163] Fix rb_integer_pack() for values between 2**62 and 2**63
PullRequest: truffleruby/4089
2 parents 5a2ad5d + e4592d9 commit e415105

File tree

11 files changed

+70
-12
lines changed

11 files changed

+70
-12
lines changed

Diff for: CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Bug fixes:
1010
* Fix `IO.copy_stream` with a `Tempfile` destination (#3280, @eregon).
1111
* Fix `Regexp.union` negotiating the wrong result encoding (#3287, @nirvdrum, @simonlevasseur).
1212
* Fix `Proc#parameters` and return all the numbered parameters lower than the used explicitly ones (@andrykonchin).
13+
* Fix some C API functions which were failing when called with Ruby values represented as Java primitives (#3352, @eregon).
1314

1415
Compatibility:
1516

Diff for: lib/cext/ABI_check.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
6
1+
7

Diff for: lib/truffle/truffle/cext.rb

+40
Original file line numberDiff line numberDiff line change
@@ -424,16 +424,44 @@ def RB_OBJ_TAINTABLE(object)
424424
end
425425
end
426426

427+
def rb_obj_clone(object)
428+
object.clone
429+
end
430+
431+
def rb_obj_dup(object)
432+
object.dup
433+
end
434+
435+
def rb_obj_encoding(object)
436+
object.encoding
437+
end
438+
427439
FREEZE_METHOD = Kernel.instance_method :freeze
428440

429441
def rb_obj_freeze(obj)
430442
FREEZE_METHOD.bind(obj).call
431443
end
432444

445+
def rb_obj_frozen_p(object)
446+
object.frozen?
447+
end
448+
449+
def rb_obj_id(object)
450+
object.object_id
451+
end
452+
433453
def rb_float_new(value)
434454
value.to_f
435455
end
436456

457+
def rb_flt_rationalize(value)
458+
value.rationalize
459+
end
460+
461+
def rb_flt_rationalize_with_prec(value, prec)
462+
value.rationalize(prec)
463+
end
464+
437465
def rb_absint_singlebit_p(val)
438466
Primitive.rb_int_singlebit_p(val.abs)
439467
end
@@ -556,6 +584,10 @@ def rb_class_of(object)
556584
Primitive.metaclass(object)
557585
end
558586

587+
def rb_singleton_class(object)
588+
object.singleton_class
589+
end
590+
559591
def rb_class_real(ruby_class)
560592
while ruby_class.singleton_class?
561593
ruby_class = ruby_class.superclass
@@ -844,6 +876,10 @@ def rb_intern(str)
844876
Primitive.string_to_symbol(str, true)
845877
end
846878

879+
def rb_int_cmp(a, b)
880+
a <=> b
881+
end
882+
847883
def rb_int_positive_pow(a, b)
848884
a ** b
849885
end
@@ -1379,6 +1415,10 @@ def rb_equal(a, b)
13791415
Primitive.same_or_equal?(a, b)
13801416
end
13811417

1418+
def rb_tr_obj_equal(a, b)
1419+
Primitive.equal?(a, b)
1420+
end
1421+
13821422
def rb_obj_call_init(obj, args, block)
13831423
obj.__send__ :initialize, *args, &block
13841424
end

Diff for: spec/ruby/optional/capi/integer_spec.rb

+17
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,23 @@
140140
result.should == -1
141141
@words.should == "\x11\x32\x54\x76\x98\xBA\xDC\xFE"
142142
end
143+
144+
it "converts numbers near the fixnum limit successfully" do
145+
result = @s.rb_integer_pack(0x7123_4567_89ab_cdef, @words, 1, 8, 0,
146+
CApiIntegerSpecs::NATIVE|CApiIntegerSpecs::PACK_2COMP)
147+
result.should == 1
148+
@words.should == "\xEF\xCD\xAB\x89\x67\x45\x23\x71"
149+
150+
result = @s.rb_integer_pack(2**62-1, @words, 1, 8, 0,
151+
CApiIntegerSpecs::NATIVE|CApiIntegerSpecs::PACK_2COMP)
152+
result.should == 1
153+
@words.should == "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x3F"
154+
155+
result = @s.rb_integer_pack(2**63-1, @words, 1, 8, 0,
156+
CApiIntegerSpecs::NATIVE|CApiIntegerSpecs::PACK_2COMP)
157+
result.should == 1
158+
@words.should == "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F"
159+
end
143160
end
144161
end
145162
end

Diff for: src/main/c/cext/class.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ VALUE rb_class_of(VALUE object) {
4848
}
4949

5050
VALUE rb_singleton_class(VALUE object) {
51-
return RUBY_INVOKE(object, "singleton_class");
51+
return RUBY_CEXT_INVOKE("rb_singleton_class", object);
5252
}
5353

5454
VALUE rb_obj_alloc(VALUE ruby_class) {

Diff for: src/main/c/cext/define.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ void rb_define_global_function(const char *name, VALUE (*function)(ANYARGS), int
7474

7575
#undef rb_define_singleton_method
7676
void rb_define_singleton_method(VALUE object, const char *name, VALUE (*function)(ANYARGS), int argc) {
77-
rb_define_method(RUBY_INVOKE(object, "singleton_class"), name, function, argc);
77+
rb_define_method(rb_singleton_class(object), name, function, argc);
7878
}
7979

8080
void rb_define_alias(VALUE module, const char *new_name, const char *old_name) {

Diff for: src/main/c/cext/encoding.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ int rb_enc_to_index(rb_encoding *enc) {
219219
}
220220

221221
VALUE rb_obj_encoding(VALUE obj) {
222-
return RUBY_INVOKE(obj, "encoding");
222+
return RUBY_CEXT_INVOKE("rb_obj_encoding", obj);
223223
}
224224

225225
int rb_to_encoding_index(VALUE enc) {

Diff for: src/main/c/cext/integer.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ int rb_integer_pack(VALUE value, void *words, size_t numwords, size_t wordsize,
101101
long l = NUM2LONG(value);
102102
sign = (l > 0) - (l < 0);
103103
} else {
104-
sign = polyglot_as_i32(polyglot_invoke(rb_tr_unwrap(value), "<=>", 0));
104+
sign = polyglot_as_i32(RUBY_CEXT_INVOKE_NO_WRAP("rb_int_cmp", value, INT2FIX(0)));
105105
}
106106
int bytes_needed = size / 8 + (size % 8 == 0 ? 0 : 1);
107107
int words_needed = bytes_needed / wordsize + (bytes_needed % wordsize == 0 ? 0 : 1);

Diff for: src/main/c/cext/object.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,15 @@ VALUE rb_obj_reveal(VALUE obj, VALUE klass) {
115115
}
116116

117117
VALUE rb_obj_clone(VALUE obj) {
118-
return RUBY_INVOKE(obj, "clone");
118+
return RUBY_CEXT_INVOKE("rb_obj_clone", obj);
119119
}
120120

121121
VALUE rb_obj_dup(VALUE object) {
122-
return RUBY_INVOKE(object, "dup");
122+
return RUBY_CEXT_INVOKE("rb_obj_dup", object);
123123
}
124124

125125
VALUE rb_obj_id(VALUE object) {
126-
return RUBY_INVOKE(object, "object_id");
126+
return RUBY_CEXT_INVOKE("rb_obj_id", object);
127127
}
128128

129129
// The semantics of SameOrEqualNode: a.equal?(b) || a == b
@@ -138,7 +138,7 @@ void rb_obj_call_init(VALUE object, int argc, const VALUE *argv) {
138138
// frozen status
139139

140140
VALUE rb_obj_frozen_p(VALUE object) {
141-
return RUBY_INVOKE(object, "frozen?");
141+
return RUBY_CEXT_INVOKE("rb_obj_frozen_p", object);
142142
}
143143

144144
VALUE rb_obj_freeze(VALUE object) {

Diff for: src/main/c/cext/rational.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ VALUE rb_rational_den(VALUE rat) {
3333
}
3434

3535
VALUE rb_flt_rationalize_with_prec(VALUE value, VALUE precision) {
36-
return RUBY_INVOKE(value, "rationalize", precision);
36+
return RUBY_CEXT_INVOKE("rb_flt_rationalize_with_prec", value, precision);
3737
}
3838

3939
VALUE rb_flt_rationalize(VALUE value) {
40-
return RUBY_INVOKE(value, "rationalize");
40+
return RUBY_CEXT_INVOKE("rb_flt_rationalize", value);
4141
}

Diff for: src/main/c/cext/truffleruby.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ VALUE rb_java_to_string(VALUE obj) {
3131

3232
// BasicObject#equal?
3333
int rb_tr_obj_equal(VALUE first, VALUE second) {
34-
return RTEST(RUBY_INVOKE(first, "equal?", second));
34+
return RTEST(RUBY_CEXT_INVOKE("rb_tr_obj_equal", first, second));
3535
}
3636

3737
void rb_tr_warn_va_list(const char *fmt, va_list args) {

0 commit comments

Comments
 (0)