1
1
#include "types.h"
2
2
3
+ extern void wasm_engine_delete (TSWasmEngine * engine );
4
+ extern TSWasmEngine * wasmtime_engine_clone (TSWasmEngine * engine );
5
+
3
6
int language_init (Language * self , PyObject * args , PyObject * Py_UNUSED (kwargs )) {
4
7
PyObject * language ;
5
8
if (!PyArg_ParseTuple (args , "O:__init__" , & language )) {
@@ -25,10 +28,119 @@ int language_init(Language *self, PyObject *args, PyObject *Py_UNUSED(kwargs)) {
25
28
}
26
29
27
30
void language_dealloc (Language * self ) {
31
+ if (self -> wasm_engine != NULL ) {
32
+ wasm_engine_delete (self -> wasm_engine );
33
+ }
28
34
ts_language_delete (self -> language );
29
35
Py_TYPE (self )-> tp_free (self );
30
36
}
31
37
38
+ // ctypes.cast(managed_pointer.ptr(), ctypes.c_void_p).value
39
+ static void * get_managed_pointer (PyObject * cast , PyObject * c_void_p , PyObject * managed_pointer ) {
40
+ void * ptr = NULL ;
41
+ PyObject * ptr_method = NULL ;
42
+ PyObject * ptr_result = NULL ;
43
+ PyObject * cast_result = NULL ;
44
+ PyObject * value_attr = NULL ;
45
+
46
+ // Call .ptr() method on the managed pointer
47
+ ptr_method = PyObject_GetAttrString (managed_pointer , "ptr" );
48
+ if (ptr_method == NULL ) {
49
+ goto cleanup ;
50
+ }
51
+ ptr_result = PyObject_CallObject (ptr_method , NULL );
52
+ if (ptr_result == NULL ) {
53
+ goto cleanup ;
54
+ }
55
+
56
+ // Call cast function
57
+ cast_result = PyObject_CallFunctionObjArgs (cast , ptr_result , c_void_p , NULL );
58
+ if (cast_result == NULL ) {
59
+ goto cleanup ;
60
+ }
61
+
62
+ // Get the 'value' attribute from the cast result
63
+ value_attr = PyObject_GetAttrString (cast_result , "value" );
64
+ if (value_attr == NULL ) {
65
+ goto cleanup ;
66
+ }
67
+
68
+ // Convert the value attribute to a C void pointer
69
+ ptr = PyLong_AsVoidPtr (value_attr );
70
+
71
+ cleanup :
72
+ Py_XDECREF (value_attr );
73
+ Py_XDECREF (cast_result );
74
+ Py_XDECREF (ptr_result );
75
+ Py_XDECREF (ptr_method );
76
+
77
+ if (PyErr_Occurred ()) {
78
+ return NULL ;
79
+ }
80
+
81
+ return ptr ;
82
+ }
83
+
84
+ PyObject * language_from_wasm (PyTypeObject * cls , PyObject * args ) {
85
+ ModuleState * state = (ModuleState * )PyType_GetModuleState (cls );
86
+ TSWasmError error ;
87
+ TSWasmStore * wasm_store = NULL ;
88
+ TSLanguage * language = NULL ;
89
+ Language * self = NULL ;
90
+ char * name ;
91
+ PyObject * py_engine = NULL ;
92
+ char * wasm ;
93
+ Py_ssize_t wasm_length ;
94
+ if (state -> wasmtime_engine_type == NULL ) {
95
+ PyErr_SetString (PyExc_RuntimeError , "wasmtime module is not loaded" );
96
+ return NULL ;
97
+ }
98
+ if (!PyArg_ParseTuple (args , "sO!y#:from_wasm" , & name , state -> wasmtime_engine_type , & py_engine , & wasm , & wasm_length )) {
99
+ return NULL ;
100
+ }
101
+
102
+ TSWasmEngine * engine = (TSWasmEngine * )get_managed_pointer (state -> ctypes_cast , state -> c_void_p , py_engine );
103
+ if (engine == NULL ) {
104
+ goto fail ;
105
+ }
106
+ engine = wasmtime_engine_clone (engine );
107
+ if (engine == NULL ) {
108
+ goto fail ;
109
+ }
110
+
111
+ wasm_store = ts_wasm_store_new (engine , & error );
112
+ if (wasm_store == NULL ) {
113
+ PyErr_Format (PyExc_RuntimeError , "Failed to create TSWasmStore: %s" , error .message );
114
+ goto fail ;
115
+ }
116
+
117
+ language = (TSLanguage * )ts_wasm_store_load_language (wasm_store , name , wasm , wasm_length , & error );
118
+ if (language == NULL ) {
119
+ PyErr_Format (PyExc_RuntimeError , "Failed to load language: %s" , error .message );
120
+ goto fail ;
121
+ }
122
+
123
+ self = (Language * )cls -> tp_alloc (cls , 0 );
124
+ if (self == NULL ) {
125
+ goto fail ;
126
+ }
127
+
128
+ self -> language = language ;
129
+ self -> wasm_engine = engine ;
130
+ self -> version = ts_language_version (self -> language );
131
+ #if HAS_LANGUAGE_NAMES
132
+ self -> name = ts_language_name (self -> language );
133
+ #endif
134
+ return (PyObject * )self ;
135
+
136
+ fail :
137
+ if (engine != NULL ) {
138
+ wasm_engine_delete (engine );
139
+ }
140
+ ts_language_delete (language );
141
+ return NULL ;
142
+ }
143
+
32
144
PyObject * language_repr (Language * self ) {
33
145
#if HAS_LANGUAGE_NAMES
34
146
if (self -> name == NULL ) {
@@ -77,6 +189,10 @@ PyObject *language_get_field_count(Language *self, void *Py_UNUSED(payload)) {
77
189
return PyLong_FromUnsignedLong (ts_language_field_count (self -> language ));
78
190
}
79
191
192
+ PyObject * language_is_wasm (Language * self , void * Py_UNUSED (payload )) {
193
+ return PyBool_FromLong (ts_language_is_wasm (self -> language ));
194
+ }
195
+
80
196
PyObject * language_node_kind_for_id (Language * self , PyObject * args ) {
81
197
TSSymbol symbol ;
82
198
if (!PyArg_ParseTuple (args , "H:node_kind_for_id" , & symbol )) {
@@ -185,6 +301,9 @@ PyObject *language_query(Language *self, PyObject *args) {
185
301
return PyObject_CallFunction ((PyObject * )state -> query_type , "Os#" , self , source , length );
186
302
}
187
303
304
+ PyDoc_STRVAR (language_from_wasm_doc ,
305
+ "from_wasm(self, name, engine, wasm, /)\n--\n\n"
306
+ "Load a language compiled as wasm." );
188
307
PyDoc_STRVAR (language_node_kind_for_id_doc ,
189
308
"node_kind_for_id(self, id, /)\n--\n\n"
190
309
"Get the name of the node kind for the given numerical id." );
@@ -215,6 +334,12 @@ PyDoc_STRVAR(
215
334
"Create a new :class:`Query` from a string containing one or more S-expression patterns." );
216
335
217
336
static PyMethodDef language_methods [] = {
337
+ {
338
+ .ml_name = "from_wasm" ,
339
+ .ml_meth = (PyCFunction )language_from_wasm ,
340
+ .ml_flags = METH_CLASS | METH_VARARGS ,
341
+ .ml_doc = language_from_wasm_doc ,
342
+ },
218
343
{
219
344
.ml_name = "node_kind_for_id" ,
220
345
.ml_meth = (PyCFunction )language_node_kind_for_id ,
@@ -286,6 +411,8 @@ static PyGetSetDef language_accessors[] = {
286
411
PyDoc_STR ("The number of valid states in this language." ), NULL },
287
412
{"field_count" , (getter )language_get_field_count , NULL ,
288
413
PyDoc_STR ("The number of distinct field names in this language." ), NULL },
414
+ {"is_wasm" , (getter )language_is_wasm , NULL ,
415
+ PyDoc_STR ("Check if the language came from a wasm module." ), NULL },
289
416
{NULL },
290
417
};
291
418
0 commit comments