Skip to content

Commit 39122d0

Browse files
committed
Remove act_like_pointer workaround and add spec
* Sulong no longer forces those pointers to native eagerly.
1 parent aa05ed6 commit 39122d0

File tree

4 files changed

+97
-28
lines changed

4 files changed

+97
-28
lines changed

lib/truffle/truffle/cext.rb

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ def address
102102
end
103103

104104
def cache_address
105-
name.act_like_pointer = true
106105
addr = name.address
107106
ENCODING_CACHE_MUTEX.synchronize do
108107
NATIVE_CACHE[addr] = self
@@ -138,21 +137,28 @@ def fd
138137

139138
class RStringPtr
140139
attr_reader :string
141-
attr_accessor :act_like_pointer
142140

143141
def initialize(string)
144142
@string = string
145-
@act_like_pointer = false
146143
end
147144

148145
def size
149146
Truffle::CExt.string_pointer_size(@string)
150147
end
151148

149+
def pointer?
150+
true
151+
end
152+
152153
def address
153154
@address ||= Truffle::CExt.string_pointer_to_native(@string)
154155
end
155156

157+
# Every IS_POINTER object should also have TO_NATIVE
158+
def to_native
159+
self
160+
end
161+
156162
def [](index)
157163
Truffle::CExt.string_pointer_read(@string, index)
158164
end
@@ -167,26 +173,32 @@ def native?
167173

168174
alias_method :to_str, :string
169175
alias_method :to_s, :string
170-
alias_method :pointer?, :act_like_pointer
171176
end
172177

173178
class RArrayPtr
174179
attr_reader :array
175-
attr_accessor :act_like_pointer
176180

177181
def initialize(array)
178182
@array = array
179-
@act_like_pointer = false
180183
end
181184

182185
def size
183186
@array.size
184187
end
185188

189+
def pointer?
190+
true
191+
end
192+
186193
def address
187194
raise RuntimeError, 'RARRAY_PTRs cannot be converted to native pointers yet'
188195
end
189196

197+
# Every IS_POINTER object should also have TO_NATIVE
198+
def to_native
199+
self
200+
end
201+
190202
def [](index)
191203
Truffle::CExt.rb_tr_wrap(array[index])
192204
end
@@ -198,27 +210,29 @@ def []=(index, value)
198210
def native?
199211
false
200212
end
201-
202-
alias_method :pointer?, :act_like_pointer
203213
end
204214

205215
class RStringEndPtr
206-
attr_accessor :act_like_pointer
207-
208216
def initialize(string)
209217
@string = string
210-
@act_like_pointer = false
211218
end
212219

213220
def size
214221
0
215222
end
216223

224+
def pointer?
225+
true
226+
end
227+
217228
def address
218229
@address ||= Truffle::CExt.string_pointer_to_native(@string) + @string.bytesize
219230
end
220231

221-
alias_method :pointer?, :act_like_pointer
232+
# Every IS_POINTER object should also have TO_NATIVE
233+
def to_native
234+
self
235+
end
222236
end
223237

224238
T_NONE = 0x00
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#include "ruby.h"
2+
#include "rubyspec.h"
3+
4+
#ifdef __cplusplus
5+
extern "C" {
6+
#endif
7+
8+
// Tests that Sulong does not force ptr to native
9+
char* function_returning_char_ptr(char* ptr) {
10+
return ptr;
11+
}
12+
13+
static VALUE string_ptr(VALUE self, VALUE str) {
14+
char* ptr = function_returning_char_ptr(RSTRING_PTR(str));
15+
char cstring[] = { ptr[0], 0 };
16+
return rb_str_new_cstr(cstring);
17+
}
18+
19+
static VALUE string_ptr_stored_in_native(VALUE self, VALUE str) {
20+
char* ptr = RSTRING_PTR(str);
21+
char** native = malloc(sizeof(char*));
22+
*native = ptr;
23+
free(native);
24+
return str;
25+
}
26+
27+
static VALUE string_ptr_return_address(VALUE self, VALUE str) {
28+
char* ptr = RSTRING_PTR(str);
29+
return LONG2NUM((long) ptr);
30+
}
31+
32+
void Init_truffleruby_string_spec(void) {
33+
VALUE cls;
34+
cls = rb_define_class("CApiTruffleStringSpecs", rb_cObject);
35+
rb_define_method(cls, "string_ptr", string_ptr, 1);
36+
rb_define_method(cls, "string_ptr_stored_in_native", string_ptr_stored_in_native, 1);
37+
rb_define_method(cls, "string_ptr_return_address", string_ptr_return_address, 1);
38+
}
39+
40+
#ifdef __cplusplus
41+
}
42+
#endif

spec/truffle/capi/string_spec.rb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
require_relative '../../ruby/optional/capi/spec_helper'
2+
3+
load_extension("truffleruby_string")
4+
5+
describe "TruffleRuby RSTRING_PTR" do
6+
before :each do
7+
@s = CApiTruffleStringSpecs.new
8+
end
9+
10+
it "does not store the String to native memory if not needed" do
11+
str = "foobar"
12+
@s.string_ptr(str).should == "f"
13+
Truffle::CExt.string_pointer_is_native?(str).should == false
14+
end
15+
16+
it "stores the String to native memory if stored in malloc'd memory" do
17+
str = "foobar"
18+
@s.string_ptr_stored_in_native(str)
19+
Truffle::CExt.string_pointer_is_native?(str).should == true
20+
end
21+
22+
it "stores the String to native memory if the address is returned" do
23+
str = "foobar"
24+
@s.string_ptr_return_address(str).should be_kind_of(Integer)
25+
Truffle::CExt.string_pointer_is_native?(str).should == true
26+
end
27+
end

src/main/c/cext/ruby.c

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -697,25 +697,11 @@ double rb_float_value(VALUE value) {
697697
// String
698698

699699
char *RSTRING_PTR_IMPL(VALUE string) {
700-
char* ret = RUBY_CEXT_INVOKE_NO_WRAP("RSTRING_PTR", string);
701-
702-
// We start off treating RStringPtr as if it weren't a pointer for interop purposes. This is so Sulong doesn't try
703-
// to convert it to an actual char* when returning from `polyglot_invoke`. Once we have a handle to the real RStringPtr
704-
// object, we can instruct it to start acting like a pointer, which is necessary for pointer address comparisons.
705-
polyglot_invoke(ret, "act_like_pointer=", rb_tr_unwrap(Qtrue));
706-
707-
return ret;
700+
return RUBY_CEXT_INVOKE_NO_WRAP("RSTRING_PTR", string);
708701
}
709702

710703
char *RSTRING_END(VALUE string) {
711-
char* ret = RUBY_CEXT_INVOKE_NO_WRAP("RSTRING_END", string);
712-
713-
// We start off treating RStringPtr as if it weren't a pointer for interop purposes. This is so Sulong doesn't try
714-
// to convert it to an actual char* when returning from `polyglot_invoke`. Once we have a handle to the real RStringPtr
715-
// object, we can instruct it to start acting like a pointer, which is necessary for pointer address comparisons.
716-
polyglot_invoke(ret, "act_like_pointer=", rb_tr_unwrap(Qtrue));
717-
718-
return ret;
704+
return RUBY_CEXT_INVOKE_NO_WRAP("RSTRING_END", string);
719705
}
720706

721707
int MBCLEN_NEEDMORE_P(int r) {

0 commit comments

Comments
 (0)