Skip to content

Commit f293a01

Browse files
committed
Intrinsify helper function PyTruffle_Unicode_FromFormat
1 parent ab30697 commit f293a01

File tree

8 files changed

+335
-143
lines changed

8 files changed

+335
-143
lines changed

graalpython/com.oracle.graal.python.cext/src/_warnings.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,15 @@ int PyErr_WarnEx(PyObject *category, const char *text, Py_ssize_t stack_level) {
7272
NO_INLINE int PyErr_WarnFormat(PyObject *category, Py_ssize_t stack_level, const char *format, ...) {
7373
va_list args;
7474
va_start(args, format);
75-
PyObject* result = PyTruffle_Unicode_FromFormat(format, args);
75+
PyObject* result = PyUnicode_FromFormatV(format, args);
7676
va_end(args);
7777
return warn_unicode(category, result, stack_level, Py_None);
7878
}
7979

8080
int PyErr_ResourceWarning(PyObject *source, Py_ssize_t stack_level, const char *format, ...) {
8181
va_list args;
8282
va_start(args, format);
83-
PyObject* result = PyTruffle_Unicode_FromFormat(format, args);
83+
PyObject* result = PyUnicode_FromFormatV(format, args);
8484
va_end(args);
8585
return warn_unicode(PyExc_ResourceWarning, result, stack_level, source);
8686
}

graalpython/com.oracle.graal.python.cext/src/capi.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -382,9 +382,6 @@ extern PyObject* wrapped_null;
382382

383383
/* internal functions to avoid unnecessary managed <-> native conversions */
384384

385-
/* STR */
386-
__attribute__((always_inline)) PyObject* PyTruffle_Unicode_FromFormat(const char *fmt, va_list va);
387-
388385
/* BYTES, BYTEARRAY */
389386
int bytes_buffer_getbuffer(PyBytesObject *self, Py_buffer *view, int flags);
390387
int bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags);

graalpython/com.oracle.graal.python.cext/src/errors.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ NO_INLINE
163163
PyObject* PyErr_Format(PyObject* exception, const char* fmt, ...) {
164164
va_list args;
165165
va_start(args, fmt);
166-
PyObject* formatted_msg = PyTruffle_Unicode_FromFormat(fmt, args);
166+
PyObject* formatted_msg = PyUnicode_FromFormatV(fmt, args);
167167
va_end(args);
168168
UPCALL_CEXT_VOID(_jls_PyErr_CreateAndSetException, native_to_java(exception), native_to_java(formatted_msg));
169169
return NULL;

graalpython/com.oracle.graal.python.cext/src/modsupport.c

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,24 @@ static void init_upcall_PyTruffle_Arg_ParseTupleAndKeyword(void) {
9696
}
9797

9898
/* just a renaming to avoid name clash with Java types */
99-
typedef char char_t;
100-
typedef float float_t;
101-
typedef double double_t;
102-
99+
typedef void* void_ptr_t;
100+
typedef char char_t;
101+
typedef float float_t;
102+
typedef double double_t;
103+
typedef int int_t;
104+
typedef unsigned int uint_t;
105+
typedef long long_t;
106+
typedef unsigned long ulong_t;
107+
typedef long long longlong_t;
108+
typedef unsigned long long ulonglong_t;
109+
110+
REGISTER_BASIC_TYPE(void_ptr_t);
111+
REGISTER_BASIC_TYPE(int_t);
112+
REGISTER_BASIC_TYPE(uint_t);
113+
REGISTER_BASIC_TYPE(long_t);
114+
REGISTER_BASIC_TYPE(ulong_t);
115+
REGISTER_BASIC_TYPE(longlong_t);
116+
REGISTER_BASIC_TYPE(ulonglong_t);
103117
REGISTER_BASIC_TYPE(int64_t);
104118
REGISTER_BASIC_TYPE(int32_t);
105119
REGISTER_BASIC_TYPE(int16_t);
@@ -114,6 +128,7 @@ REGISTER_BASIC_TYPE(PyObject);
114128
REGISTER_BASIC_TYPE(float_t);
115129
REGISTER_BASIC_TYPE(double_t);
116130
REGISTER_BASIC_TYPE(Py_ssize_t);
131+
REGISTER_BASIC_TYPE(size_t);
117132

118133
/* For pointers, make them look like an array of size 1 such that it is
119134
possible to dereference the pointer by accessing element 0. */

graalpython/com.oracle.graal.python.cext/src/unicodeobject.c

Lines changed: 4 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -230,146 +230,17 @@ PyObject * PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size) {
230230
return to_sulong(polyglot_from_string_n(u, size, SRC_CS));
231231
}
232232

233-
MUST_INLINE PyObject* PyTruffle_Unicode_FromFormat(const char *fmt, va_list va) {
234-
va_list vacpy;
235-
size_t fmt_size = strlen(fmt) + 1;
236-
char* fmtcpy = strdup(fmt);
237-
char* c = fmtcpy;
238-
239-
int remaining_space = 2047;
240-
char* buffer = (char*)calloc(sizeof(char), remaining_space + 1);
241-
char* full_buffer = buffer;
242-
243-
void *variable = NULL;
244-
PyObject *tmp = NULL;
245-
char *allocated = NULL; // points to the same as variable, if it has to be free'd
246-
247-
va_copy(vacpy, va);
248-
249-
while (c[0]) {
250-
if (c[0] == '%') {
251-
// we've reached the next directive, write until here
252-
c[0] = '\0';
253-
int bytes_written;
254-
if (variable != NULL) {
255-
bytes_written = snprintf(buffer, remaining_space, fmtcpy, variable);
256-
if (allocated != NULL) {
257-
free(allocated);
258-
allocated = NULL;
259-
}
260-
variable = NULL;
261-
} else {
262-
bytes_written = vsnprintf(buffer, remaining_space, fmtcpy, vacpy);
263-
}
264-
remaining_space -= bytes_written;
265-
buffer += bytes_written;
266-
fmtcpy = c;
267-
c[0] = '%';
268-
269-
// now decide if we need to do something special with this directive
270-
PyObject* (*converter)(PyObject*) = NULL;
271-
switch (c[1]) {
272-
case 'A':
273-
// The conversion cases, these all use a function to convert the
274-
// PyObject* to a char* and they fall through
275-
converter = PyObject_ASCII;
276-
case 'U':
277-
if (converter == NULL) converter = PyObject_Str;
278-
case 'S':
279-
if (converter == NULL) converter = PyObject_Str;
280-
case 'R':
281-
if (converter == NULL) converter = PyObject_Repr;
282-
c[1] = 's';
283-
tmp = va_arg(va, PyObject*);
284-
// just advance cursor on 'vacpy'
285-
va_arg(vacpy, PyObject*);
286-
allocated = variable = as_char_pointer(converter(tmp));
287-
break;
288-
case 'c':
289-
// This case should just treat it's argument as an integer
290-
c[1] = 'd';
291-
// intentionally fall-through
292-
case 'd':
293-
case 'i':
294-
case 'x':
295-
// just advance cursor on 'va'
296-
va_arg(va, int);
297-
break;
298-
case 'u':
299-
// just advance cursor on 'va'
300-
va_arg(va, unsigned int);
301-
break;
302-
case 'l':
303-
// 'c[2]' is guaranteed to be a correct memory access since
304-
// it will in the worst case be '\0'.
305-
switch (c[2]) {
306-
// %ld, %li
307-
case 'd':
308-
case 'i':
309-
// just advance cursor on 'va'
310-
va_arg(va, long);
311-
break;
312-
// %lu
313-
case 'u':
314-
// just advance cursor on 'va'
315-
va_arg(va, unsigned long);
316-
// %ll?
317-
case 'l':
318-
// just advance cursor on 'va'
319-
va_arg(va, long long);
320-
}
321-
break;
322-
case 'z':
323-
// just advance cursor on 'va'
324-
va_arg(va, Py_ssize_t);
325-
break;
326-
case 's':
327-
// just advance cursor on 'va'
328-
va_arg(va, char*);
329-
break;
330-
case 'p':
331-
// just advance cursor on 'va'
332-
va_arg(va, void*);
333-
break;
334-
case '%':
335-
// literal %
336-
break;
337-
default:
338-
variable = va_arg(va, PyObject*);
339-
// just advance cursor on 'vacpy'
340-
va_arg(vacpy, PyObject*);
341-
}
342-
// skip over next char, we checked it
343-
c += 1;
344-
}
345-
c += 1;
346-
}
347-
348-
// write the remaining buffer
349-
if (variable != NULL) {
350-
snprintf(buffer, remaining_space, fmtcpy, variable);
351-
if (allocated) {
352-
free(allocated);
353-
}
354-
} else {
355-
vsnprintf(buffer, remaining_space, fmtcpy, vacpy);
356-
}
357-
358-
PyObject* result = PyUnicode_FromString(full_buffer);
359-
free(full_buffer);
360-
va_end(vacpy);
361-
return result;
362-
}
363-
233+
typedef PyObject* (*unicode_fromformat_fun_t)(void* jstr, va_list va);
234+
UPCALL_TYPED_ID(PyTruffle_Unicode_FromFormat, unicode_fromformat_fun_t);
364235
PyObject* PyUnicode_FromFormatV(const char* format, va_list va) {
365-
return PyTruffle_Unicode_FromFormat(format, va);
236+
return _jls_PyTruffle_Unicode_FromFormat(polyglot_from_string(format, "ascii"), va);
366237
}
367238

368239
NO_INLINE
369240
PyObject* PyUnicode_FromFormat(const char* format, ...) {
370241
va_list args;
371242
va_start(args, format);
372-
PyObject* result = PyTruffle_Unicode_FromFormat(format, args);
243+
PyObject* result = _jls_PyTruffle_Unicode_FromFormat(polyglot_from_string(format, "ascii"), args);
373244
va_end(args);
374245
return result;
375246
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PythonCextBuiltins.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.ToJavaNode;
133133
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.ToNewRefNode;
134134
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.TransformExceptionToNativeNode;
135+
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.UnicodeFromFormatNode;
135136
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.VoidPtrToJavaNode;
136137
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.CastToNativeLongNodeGen;
137138
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodesFactory.PRaiseNativeNodeGen;
@@ -3808,4 +3809,23 @@ static PBuiltinFunction asBuiltinFunction(Object methObj, AsPythonObjectNode asP
38083809
return null;
38093810
}
38103811
}
3812+
3813+
// directly called without landing function
3814+
@Builtin(name = "PyTruffle_Unicode_FromFormat", minNumOfPositionalArgs = 2)
3815+
@GenerateNodeFactory
3816+
abstract static class PyTruffleUnicodeFromFromat extends PythonBuiltinNode {
3817+
@Specialization
3818+
static Object doGeneric(VirtualFrame frame, String format, Object vaList,
3819+
@Cached UnicodeFromFormatNode unicodeFromFormatNode,
3820+
@Cached CExtNodes.ToSulongNode toSulongNode,
3821+
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode,
3822+
@Cached GetNativeNullNode getNativeNullNode) {
3823+
try {
3824+
return toSulongNode.execute(unicodeFromFormatNode.execute(format, vaList));
3825+
} catch (PException e) {
3826+
transformExceptionToNativeNode.execute(frame, e);
3827+
return getNativeNullNode.execute();
3828+
}
3829+
}
3830+
}
38113831
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,8 @@ public long getId() {
732732
* 'capi.c'.
733733
*/
734734
public enum LLVMType {
735+
int_t,
736+
uint_t,
735737
int8_t,
736738
int16_t,
737739
int32_t,
@@ -740,12 +742,18 @@ public enum LLVMType {
740742
uint16_t,
741743
uint32_t,
742744
uint64_t,
745+
long_t,
746+
ulong_t,
747+
longlong_t,
748+
ulonglong_t,
743749
float_t,
744750
double_t,
751+
size_t,
745752
Py_ssize_t,
746753
Py_complex,
747754
PyObject_ptr_t,
748755
char_ptr_t,
756+
void_ptr_t,
749757
int8_ptr_t,
750758
int16_ptr_t,
751759
int32_ptr_t,

0 commit comments

Comments
 (0)