1
1
/*
2
- * Copyright (c) 2018, 2023 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2018, 2024 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* The Universal Permissive License (UPL), Version 1.0
62
62
import com .oracle .truffle .api .interop .InteropLibrary ;
63
63
import com .oracle .truffle .api .interop .InvalidArrayIndexException ;
64
64
import com .oracle .truffle .api .interop .InvalidBufferOffsetException ;
65
+ import com .oracle .truffle .api .interop .UnsupportedMessageException ;
66
+ import com .oracle .truffle .api .library .CachedLibrary ;
65
67
import com .oracle .truffle .api .library .ExportLibrary ;
66
68
import com .oracle .truffle .api .library .ExportMessage ;
67
69
import com .oracle .truffle .api .nodes .Node ;
@@ -173,19 +175,24 @@ public void free() {
173
175
* wrapper let's a TruffleString look like a {@code char*}.
174
176
*/
175
177
@ ExportLibrary (InteropLibrary .class )
178
+ @ SuppressWarnings ("truffle-abstract-export" )
176
179
public static final class CStringWrapper extends CArrayWrapper {
177
180
178
181
public CStringWrapper (TruffleString delegate ) {
179
182
super (delegate );
180
183
}
181
184
182
185
public TruffleString getString () {
183
- return ((TruffleString ) getDelegate ());
186
+ TruffleString s = (TruffleString ) getDelegate ();
187
+ // TODO GR-37217: use sys.getdefaultencoding if the string contains non-latin1
188
+ // codepoints
189
+ assert s .getCodeRangeUncached (TS_ENCODING ) == TruffleString .CodeRange .ASCII ;
190
+ return s ;
184
191
}
185
192
186
193
@ ExportMessage
187
194
long getArraySize (
188
- @ Shared ( "cpLen" ) @ Cached TruffleString .CodePointLengthNode codePointLengthNode ) {
195
+ @ Shared @ Cached TruffleString .CodePointLengthNode codePointLengthNode ) {
189
196
return codePointLengthNode .execute (getString (), TS_ENCODING ) + 1 ;
190
197
}
191
198
@@ -196,15 +203,12 @@ boolean hasArrayElements() {
196
203
}
197
204
198
205
@ ExportMessage
199
- final byte readArrayElement (long index ,
200
- @ Shared ( "cpLen" ) @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
201
- @ Cached TruffleString .CodePointAtIndexNode codePointAtIndexNode ) throws InvalidArrayIndexException {
206
+ byte readArrayElement (long index ,
207
+ @ Shared @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
208
+ @ Shared @ Cached TruffleString .CodePointAtIndexNode codePointAtIndexNode ) throws InvalidArrayIndexException {
202
209
try {
203
210
int idx = PInt .intValueExact (index );
204
211
TruffleString s = getString ();
205
- // TODO GR-37217: use sys.getdefaultencoding if the string contains non-latin1
206
- // codepoints
207
- assert s .getCodeRangeUncached (TS_ENCODING ) == TruffleString .CodeRange .ASCII ;
208
212
int len = codePointLengthNode .execute (s , TS_ENCODING );
209
213
if (idx >= 0 && idx < len ) {
210
214
return (byte ) codePointAtIndexNode .execute (s , idx , TS_ENCODING );
@@ -219,8 +223,8 @@ final byte readArrayElement(long index,
219
223
}
220
224
221
225
@ ExportMessage
222
- final boolean isArrayElementReadable (long identifier ,
223
- @ Shared ( "cpLen" ) @ Cached TruffleString .CodePointLengthNode codePointLengthNode ) {
226
+ boolean isArrayElementReadable (long identifier ,
227
+ @ Shared @ Cached TruffleString .CodePointLengthNode codePointLengthNode ) {
224
228
return 0 <= identifier && identifier < getArraySize (codePointLengthNode );
225
229
}
226
230
@@ -236,6 +240,91 @@ void toNative(
236
240
setNativePointer (stringToNativeUtf8Bytes (getString (), switchEncodingNode , copyToByteArrayNode ));
237
241
}
238
242
}
243
+
244
+ @ ExportMessage
245
+ @ SuppressWarnings ("static-method" )
246
+ boolean hasBufferElements () {
247
+ return true ;
248
+ }
249
+
250
+ @ ExportMessage
251
+ long getBufferSize (
252
+ @ Shared @ Cached TruffleString .CodePointLengthNode codePointLengthNode ) {
253
+ return codePointLengthNode .execute (getString (), TS_ENCODING ) + 1 ;
254
+ }
255
+
256
+ @ ExportMessage
257
+ byte readBufferByte (long byteOffset ,
258
+ @ Shared @ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
259
+ @ Shared @ Cached TruffleString .CodePointAtIndexNode codePointAtIndexNode ) throws InvalidBufferOffsetException {
260
+ TruffleString s = getString ();
261
+ int len = codePointLengthNode .execute (s , TS_ENCODING );
262
+ if (byteOffset >= 0 && byteOffset < len ) {
263
+ return (byte ) codePointAtIndexNode .execute (s , (int ) byteOffset , TS_ENCODING );
264
+ } else if (byteOffset == len ) {
265
+ return 0 ;
266
+ } else {
267
+ throw InvalidBufferOffsetException .create (byteOffset , len );
268
+ }
269
+ }
270
+
271
+ @ ExportMessage
272
+ short readBufferShort (ByteOrder byteOrder , long byteOffset ,
273
+ @ CachedLibrary ("this" ) InteropLibrary thisLib ) throws UnsupportedMessageException , InvalidBufferOffsetException {
274
+ byte b1 = thisLib .readBufferByte (this , byteOffset );
275
+ byte b2 = thisLib .readBufferByte (this , byteOffset + 1 );
276
+ if (byteOrder == ByteOrder .LITTLE_ENDIAN ) {
277
+ return (short ) (((b2 & 0xFF ) << 8 ) | (b1 & 0xFF ));
278
+ } else {
279
+ return (short ) (((b1 & 0xFF ) << 8 ) | (b2 & 0xFF ));
280
+ }
281
+ }
282
+
283
+ @ ExportMessage
284
+ int readBufferInt (ByteOrder byteOrder , long byteOffset ,
285
+ @ CachedLibrary ("this" ) InteropLibrary thisLib ) throws UnsupportedMessageException , InvalidBufferOffsetException {
286
+ byte b1 = thisLib .readBufferByte (this , byteOffset );
287
+ byte b2 = thisLib .readBufferByte (this , byteOffset + 1 );
288
+ byte b3 = thisLib .readBufferByte (this , byteOffset + 2 );
289
+ byte b4 = thisLib .readBufferByte (this , byteOffset + 3 );
290
+ if (byteOrder == ByteOrder .LITTLE_ENDIAN ) {
291
+ return ((b4 & 0xFF ) << 8 * 3 ) | ((b3 & 0xFF ) << 8 * 2 ) | ((b2 & 0xFF ) << 8 ) | ((b1 & 0xFF ));
292
+ } else {
293
+ return ((b1 & 0xFF ) << 8 * 3 ) | ((b2 & 0xFF ) << 8 * 2 ) | ((b3 & 0xFF ) << 8 ) | ((b4 & 0xFF ));
294
+ }
295
+ }
296
+
297
+ @ ExportMessage
298
+ long readBufferLong (ByteOrder byteOrder , long byteOffset ,
299
+ @ CachedLibrary ("this" ) InteropLibrary thisLib ) throws UnsupportedMessageException , InvalidBufferOffsetException {
300
+ byte b1 = thisLib .readBufferByte (this , byteOffset );
301
+ byte b2 = thisLib .readBufferByte (this , byteOffset + 1 );
302
+ byte b3 = thisLib .readBufferByte (this , byteOffset + 2 );
303
+ byte b4 = thisLib .readBufferByte (this , byteOffset + 3 );
304
+ byte b5 = thisLib .readBufferByte (this , byteOffset + 4 );
305
+ byte b6 = thisLib .readBufferByte (this , byteOffset + 5 );
306
+ byte b7 = thisLib .readBufferByte (this , byteOffset + 6 );
307
+ byte b8 = thisLib .readBufferByte (this , byteOffset + 7 );
308
+ if (byteOrder == ByteOrder .LITTLE_ENDIAN ) {
309
+ return ((b8 & 0xFFL ) << (8 * 7 )) | ((b7 & 0xFFL ) << (8 * 6 )) | ((b6 & 0xFFL ) << (8 * 5 )) | ((b5 & 0xFFL ) << (8 * 4 )) |
310
+ ((b4 & 0xFFL ) << (8 * 3 )) | ((b3 & 0xFFL ) << (8 * 2 )) | ((b2 & 0xFFL ) << 8 ) | ((b1 & 0xFFL ));
311
+ } else {
312
+ return ((b1 & 0xFFL ) << (8 * 7 )) | ((b2 & 0xFFL ) << (8 * 6 )) | ((b3 & 0xFFL ) << (8 * 5 )) | ((b4 & 0xFFL ) << (8 * 4 )) |
313
+ ((b5 & 0xFFL ) << (8 * 3 )) | ((b6 & 0xFFL ) << (8 * 2 )) | ((b7 & 0xFFL ) << 8 ) | ((b8 & 0xFFL ));
314
+ }
315
+ }
316
+
317
+ @ ExportMessage
318
+ float readBufferFloat (ByteOrder byteOrder , long byteOffset ,
319
+ @ CachedLibrary ("this" ) InteropLibrary thisLib ) throws UnsupportedMessageException , InvalidBufferOffsetException {
320
+ return Float .intBitsToFloat (thisLib .readBufferInt (this , byteOrder , byteOffset ));
321
+ }
322
+
323
+ @ ExportMessage
324
+ double readBufferDouble (ByteOrder byteOrder , long byteOffset ,
325
+ @ CachedLibrary ("this" ) InteropLibrary thisLib ) throws UnsupportedMessageException , InvalidBufferOffsetException {
326
+ return Double .longBitsToDouble (thisLib .readBufferLong (this , byteOrder , byteOffset ));
327
+ }
239
328
}
240
329
241
330
/**
0 commit comments