pyscriptc 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. pyscriptc/__init__.py +3 -0
  2. pyscriptc/__main__.py +3 -0
  3. pyscriptc/_posthog_token.py +1 -0
  4. pyscriptc/builtins.py +156 -0
  5. pyscriptc/canonical.py +167 -0
  6. pyscriptc/check.py +49 -0
  7. pyscriptc/cli.py +271 -0
  8. pyscriptc/coverage.py +388 -0
  9. pyscriptc/debug.py +120 -0
  10. pyscriptc/diagnostics.py +179 -0
  11. pyscriptc/errors.py +56 -0
  12. pyscriptc/ir.py +365 -0
  13. pyscriptc/llvm.py +2129 -0
  14. pyscriptc/log.py +127 -0
  15. pyscriptc/lower/__init__.py +1071 -0
  16. pyscriptc/lower/_calls.py +1499 -0
  17. pyscriptc/lower/_classes.py +969 -0
  18. pyscriptc/lower/_core.py +301 -0
  19. pyscriptc/lower/_expr.py +886 -0
  20. pyscriptc/lower/_stdlib.py +491 -0
  21. pyscriptc/lower/_stdlib_shared.py +93 -0
  22. pyscriptc/lower/_stmt.py +1173 -0
  23. pyscriptc/package.py +249 -0
  24. pyscriptc/restlower.py +1008 -0
  25. pyscriptc/runtime/ps_argv.c +28 -0
  26. pyscriptc/runtime/ps_b64.c +168 -0
  27. pyscriptc/runtime/ps_coll.c +133 -0
  28. pyscriptc/runtime/ps_dt.c +388 -0
  29. pyscriptc/runtime/ps_hash.c +411 -0
  30. pyscriptc/runtime/ps_help.c +219 -0
  31. pyscriptc/runtime/ps_hmac.c +120 -0
  32. pyscriptc/runtime/ps_io.c +198 -0
  33. pyscriptc/runtime/ps_island.c +272 -0
  34. pyscriptc/runtime/ps_json.c +402 -0
  35. pyscriptc/runtime/ps_mix.c +47 -0
  36. pyscriptc/runtime/ps_more.c +1089 -0
  37. pyscriptc/runtime/ps_osmore.c +447 -0
  38. pyscriptc/runtime/ps_path.c +547 -0
  39. pyscriptc/runtime/ps_re.c +1102 -0
  40. pyscriptc/runtime/ps_rt.c +1175 -0
  41. pyscriptc/runtime/ps_rt.h +189 -0
  42. pyscriptc/runtime/ps_struct.c +291 -0
  43. pyscriptc/runtime/ps_time.c +207 -0
  44. pyscriptc/runtime/ps_unicode.c +1521 -0
  45. pyscriptc/runtime/ps_url.c +327 -0
  46. pyscriptc/stdlib_queue.py +191 -0
  47. pyscriptc/stdmore.py +1596 -0
  48. pyscriptc/telemetry.py +219 -0
  49. pyscriptc-0.1.0.dist-info/METADATA +187 -0
  50. pyscriptc-0.1.0.dist-info/RECORD +54 -0
  51. pyscriptc-0.1.0.dist-info/WHEEL +5 -0
  52. pyscriptc-0.1.0.dist-info/entry_points.txt +2 -0
  53. pyscriptc-0.1.0.dist-info/licenses/LICENSE +201 -0
  54. pyscriptc-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,120 @@
1
+ /* HMAC-MD5, SHA-1, SHA-256, SHA-384, and SHA-512.
2
+
3
+ One call hashes the token. The block transform is the same code hashlib
4
+ already uses. compare_digest is constant time when the lengths match.
5
+ */
6
+
7
+ #include "ps_rt.h"
8
+
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+
12
+ extern PsBuf *ps_hash_md5(int64_t n, char *p);
13
+ extern PsBuf *ps_hash_sha1(int64_t n, char *p);
14
+ extern PsBuf *ps_hash_sha256(int64_t n, char *p);
15
+ extern PsBuf *ps_hash_sha384(int64_t n, char *p);
16
+ extern PsBuf *ps_hash_sha512(int64_t n, char *p);
17
+
18
+ typedef struct PsHmac {
19
+ PsBuf key;
20
+ PsBuf msg;
21
+ int64_t alg;
22
+ } PsHmac;
23
+
24
+ static PsBuf *(*ps_hmac_hash(int64_t alg))(int64_t, char *) {
25
+ if (alg == 1) {
26
+ return ps_hash_md5;
27
+ }
28
+ if (alg == 2) {
29
+ return ps_hash_sha1;
30
+ }
31
+ if (alg == 3) {
32
+ return ps_hash_sha256;
33
+ }
34
+ if (alg == 4) {
35
+ return ps_hash_sha384;
36
+ }
37
+ if (alg == 5) {
38
+ return ps_hash_sha512;
39
+ }
40
+ ps_raise_cstr(PS_VALUE, "hmac algorithm is md5, sha1, sha256, sha384, or sha512");
41
+ }
42
+
43
+ static int ps_hmac_block(int64_t alg) {
44
+ if (alg == 4 || alg == 5) {
45
+ return 128;
46
+ }
47
+ return 64;
48
+ }
49
+
50
+ static void ps_hmac_mac(int64_t alg, const char *key, int64_t kn, const char *msg, int64_t mn, PsBuf *out) {
51
+ PsBuf *(*hash)(int64_t, char *) = ps_hmac_hash(alg);
52
+ int block = ps_hmac_block(alg);
53
+ uint8_t *pad;
54
+ uint8_t *inner;
55
+ uint8_t *keyed;
56
+ PsBuf *core;
57
+ PsBuf *digest;
58
+ int i;
59
+ if (kn > block) {
60
+ core = hash(kn, (char *)key);
61
+ kn = core->len;
62
+ key = core->data;
63
+ }
64
+ keyed = malloc((size_t)block);
65
+ inner = malloc((size_t)block + (size_t)mn);
66
+ if (keyed == NULL || inner == NULL) {
67
+ abort();
68
+ }
69
+ memset(keyed, 0, (size_t)block);
70
+ if (kn > 0) {
71
+ memcpy(keyed, key, (size_t)kn);
72
+ }
73
+ for (i = 0; i < block; i++) {
74
+ inner[i] = (uint8_t)(keyed[i] ^ 0x36);
75
+ }
76
+ if (mn > 0) {
77
+ memcpy(inner + block, msg, (size_t)mn);
78
+ }
79
+ core = hash((int64_t)block + mn, (char *)inner);
80
+ pad = malloc((size_t)block + (size_t)core->len);
81
+ if (pad == NULL) {
82
+ abort();
83
+ }
84
+ for (i = 0; i < block; i++) {
85
+ pad[i] = (uint8_t)(keyed[i] ^ 0x5c);
86
+ }
87
+ memcpy(pad + block, core->data, (size_t)core->len);
88
+ digest = hash((int64_t)block + core->len, (char *)pad);
89
+ ps_buf_copy(out, digest->data, digest->len);
90
+ free(keyed);
91
+ free(inner);
92
+ free(pad);
93
+ }
94
+
95
+ void ps_hmac_digest(int64_t kn, const char *key, int64_t mn, const char *msg, int64_t alg, PsBuf *out) {
96
+ ps_hmac_mac(alg, key, kn, msg, mn, out);
97
+ }
98
+
99
+ void ps_hmac_new(int64_t kn, const char *key, int64_t mn, const char *msg, int64_t alg, PsHmac *out) {
100
+ ps_hmac_hash(alg);
101
+ ps_buf_copy(&out->key, key, kn);
102
+ ps_buf_copy(&out->msg, msg, mn);
103
+ out->alg = alg;
104
+ }
105
+
106
+ void ps_hmac_finish(PsHmac *box, PsBuf *out) {
107
+ ps_hmac_mac(box->alg, box->key.data, box->key.len, box->msg.data, box->msg.len, out);
108
+ }
109
+
110
+ int32_t ps_hmac_compare(int64_t an, const char *a, int64_t bn, const char *b) {
111
+ unsigned char diff = 0;
112
+ int64_t i;
113
+ if (an != bn) {
114
+ return 0;
115
+ }
116
+ for (i = 0; i < an; i++) {
117
+ diff = (unsigned char)(diff | ((unsigned char)a[i] ^ (unsigned char)b[i]));
118
+ }
119
+ return diff == 0;
120
+ }
@@ -0,0 +1,198 @@
1
+ /* io.StringIO, io.BytesIO, and builtin open.
2
+
3
+ Memory buffers start at position 0, so read() returns the initial value.
4
+ File writes are flushed so a later open sees them. OS errors are RuntimeError.
5
+ */
6
+
7
+ #include "ps_rt.h"
8
+
9
+ #include <stdio.h>
10
+ #include <stdlib.h>
11
+ #include <string.h>
12
+
13
+ typedef struct PsIO {
14
+ int32_t kind;
15
+ int32_t closed;
16
+ PsGrow mem;
17
+ int64_t pos;
18
+ FILE *fp;
19
+ } PsIO;
20
+
21
+ static PsIO *ps_blank(int kind) {
22
+ PsIO *io = calloc(1, sizeof(PsIO));
23
+ if (io == NULL) {
24
+ abort();
25
+ }
26
+ io->kind = kind;
27
+ ps_grow_init(&io->mem);
28
+ return io;
29
+ }
30
+
31
+ static void ps_open_check(PsIO *io) {
32
+ if (io == NULL || io->closed) {
33
+ ps_raise_cstr(PS_VALUE, "I/O operation on closed file");
34
+ }
35
+ }
36
+
37
+ PsIO *ps_io_string(int64_t n, const char *s) {
38
+ PsIO *io = ps_blank(1);
39
+ if (n > 0) {
40
+ ps_grow_add(&io->mem, s, n);
41
+ }
42
+ return io;
43
+ }
44
+
45
+ PsIO *ps_io_bytes(int64_t n, const char *s) {
46
+ PsIO *io = ps_blank(2);
47
+ if (n > 0) {
48
+ ps_grow_add(&io->mem, s, n);
49
+ }
50
+ return io;
51
+ }
52
+
53
+ PsIO *ps_io_open(int64_t n, const char *path, int64_t mode) {
54
+ const char *how = NULL;
55
+ int kind = 3;
56
+ char *text;
57
+ FILE *fp;
58
+ PsIO *io;
59
+ if (mode == 1) {
60
+ how = "r";
61
+ } else if (mode == 2) {
62
+ how = "w";
63
+ } else if (mode == 3) {
64
+ how = "rb";
65
+ kind = 4;
66
+ } else if (mode == 4) {
67
+ how = "wb";
68
+ kind = 4;
69
+ } else if (mode == 5) {
70
+ how = "a";
71
+ } else if (mode == 6) {
72
+ how = "ab";
73
+ kind = 4;
74
+ } else {
75
+ ps_raise_cstr(PS_VALUE, "open mode is not lowered");
76
+ }
77
+ text = malloc((size_t)n + 1);
78
+ if (text == NULL) {
79
+ abort();
80
+ }
81
+ if (n > 0) {
82
+ memcpy(text, path, (size_t)n);
83
+ }
84
+ text[n] = '\0';
85
+ fp = fopen(text, how);
86
+ free(text);
87
+ if (fp == NULL) {
88
+ ps_raise_cstr(PS_RUNTIME, "open failed");
89
+ }
90
+ io = ps_blank(kind);
91
+ io->fp = fp;
92
+ return io;
93
+ }
94
+
95
+ static int ps_can_read(PsIO *io) {
96
+ if (io->kind == 1 || io->kind == 2) {
97
+ return 1;
98
+ }
99
+ return io->fp != NULL;
100
+ }
101
+
102
+ void ps_io_read(PsIO *io, PsBuf *out) {
103
+ ps_open_check(io);
104
+ if (!ps_can_read(io)) {
105
+ ps_raise_cstr(PS_VALUE, "read failed");
106
+ }
107
+ if (io->fp != NULL) {
108
+ long size;
109
+ char *buf;
110
+ if (fseek(io->fp, 0, SEEK_END) != 0) {
111
+ ps_raise_cstr(PS_RUNTIME, "read failed");
112
+ }
113
+ size = ftell(io->fp);
114
+ if (size < 0 || fseek(io->fp, 0, SEEK_SET) != 0) {
115
+ ps_raise_cstr(PS_RUNTIME, "read failed");
116
+ }
117
+ buf = malloc((size_t)size + 1);
118
+ if (buf == NULL) {
119
+ abort();
120
+ }
121
+ if (size > 0 && fread(buf, 1, (size_t)size, io->fp) != (size_t)size) {
122
+ free(buf);
123
+ ps_raise_cstr(PS_RUNTIME, "read failed");
124
+ }
125
+ buf[size] = '\0';
126
+ out->len = size;
127
+ out->data = buf;
128
+ return;
129
+ }
130
+ if (io->pos > io->mem.len) {
131
+ io->pos = io->mem.len;
132
+ }
133
+ ps_buf_copy(out, io->mem.data == NULL ? "" : io->mem.data + io->pos, io->mem.len - io->pos);
134
+ io->pos = io->mem.len;
135
+ }
136
+
137
+ int64_t ps_io_write(PsIO *io, int64_t n, const char *s) {
138
+ ps_open_check(io);
139
+ if (n < 0) {
140
+ ps_raise_code(PS_VALUE);
141
+ }
142
+ if (io->fp != NULL) {
143
+ if (n > 0 && fwrite(s, 1, (size_t)n, io->fp) != (size_t)n) {
144
+ ps_raise_cstr(PS_RUNTIME, "write failed");
145
+ }
146
+ if (fflush(io->fp) != 0) {
147
+ ps_raise_cstr(PS_RUNTIME, "write failed");
148
+ }
149
+ return n;
150
+ }
151
+ if (io->pos > io->mem.len) {
152
+ while (io->mem.len < io->pos) {
153
+ ps_grow_byte(&io->mem, '\0');
154
+ }
155
+ }
156
+ if (io->pos == io->mem.len) {
157
+ ps_grow_add(&io->mem, s, n);
158
+ io->pos = io->mem.len;
159
+ return n;
160
+ }
161
+ if (io->mem.cap < io->pos + n + 1) {
162
+ ps_grow_add(&io->mem, "", 0);
163
+ while (io->mem.cap < io->pos + n + 1) {
164
+ ps_grow_byte(&io->mem, '\0');
165
+ io->mem.len -= 1;
166
+ }
167
+ }
168
+ if (n > 0) {
169
+ memcpy(io->mem.data + io->pos, s, (size_t)n);
170
+ }
171
+ if (io->pos + n > io->mem.len) {
172
+ io->mem.len = io->pos + n;
173
+ io->mem.data[io->mem.len] = '\0';
174
+ }
175
+ io->pos += n;
176
+ return n;
177
+ }
178
+
179
+ void ps_io_close(PsIO *io) {
180
+ if (io->closed) {
181
+ return;
182
+ }
183
+ if (io->fp != NULL && fclose(io->fp) != 0) {
184
+ io->fp = NULL;
185
+ io->closed = 1;
186
+ ps_raise_cstr(PS_RUNTIME, "close failed");
187
+ }
188
+ io->fp = NULL;
189
+ io->closed = 1;
190
+ }
191
+
192
+ void ps_io_value(PsIO *io, PsBuf *out) {
193
+ ps_open_check(io);
194
+ if (io->fp != NULL) {
195
+ ps_raise_cstr(PS_VALUE, "getvalue is lowered for StringIO and BytesIO");
196
+ }
197
+ ps_buf_copy(out, io->mem.data == NULL ? "" : io->mem.data, io->mem.len);
198
+ }
@@ -0,0 +1,272 @@
1
+ /* Embedded CPython for the island modules.
2
+
3
+ Linked only when the LLVM text calls one of these symbols. Py_InitializeEx
4
+ runs on the first call, not at process start. Arguments and results stay in
5
+ the scalar, str, bytes, and list set the rest of the runtime already uses.
6
+ */
7
+
8
+ #define PY_SSIZE_T_CLEAN
9
+ #include <Python.h>
10
+
11
+ #include "ps_rt.h"
12
+
13
+ #include <stdlib.h>
14
+ #include <string.h>
15
+
16
+ static void ps_island_fail(void) {
17
+ PyObject *typ = NULL;
18
+ PyObject *val = NULL;
19
+ PyObject *tb = NULL;
20
+ PyObject *text = NULL;
21
+ const char *msg = "island call failed";
22
+ PyErr_Fetch(&typ, &val, &tb);
23
+ PyErr_NormalizeException(&typ, &val, &tb);
24
+ if (val != NULL) {
25
+ text = PyObject_Str(val);
26
+ if (text != NULL) {
27
+ const char *got = PyUnicode_AsUTF8(text);
28
+ if (got != NULL) {
29
+ msg = got;
30
+ }
31
+ }
32
+ }
33
+ ps_raise_cstr(PS_RUNTIME, msg);
34
+ }
35
+
36
+ static void ps_island_ensure(void) {
37
+ if (Py_IsInitialized()) {
38
+ return;
39
+ }
40
+ Py_InitializeEx(0);
41
+ if (!Py_IsInitialized()) {
42
+ ps_raise_cstr(PS_RUNTIME, "CPython island failed to initialize");
43
+ }
44
+ }
45
+
46
+ static PyObject *ps_import(const char *name) {
47
+ PyObject *mod = PyImport_ImportModule(name);
48
+ if (mod == NULL) {
49
+ ps_island_fail();
50
+ }
51
+ return mod;
52
+ }
53
+
54
+ static void ps_take_unicode(PyObject *obj, PsBuf *out) {
55
+ Py_ssize_t n = 0;
56
+ const char *s = PyUnicode_AsUTF8AndSize(obj, &n);
57
+ if (s == NULL) {
58
+ ps_island_fail();
59
+ }
60
+ ps_buf_copy(out, s, (int64_t)n);
61
+ }
62
+
63
+ static void ps_take_bytes(PyObject *obj, PsBuf *out) {
64
+ char *s = NULL;
65
+ Py_ssize_t n = 0;
66
+ if (PyBytes_AsStringAndSize(obj, &s, &n) < 0) {
67
+ ps_island_fail();
68
+ }
69
+ ps_buf_copy(out, s, (int64_t)n);
70
+ }
71
+
72
+ void ps_island_check_output(PsSeq *args, PsBuf *out) {
73
+ PyObject *mod;
74
+ PyObject *fn;
75
+ PyObject *list;
76
+ PyObject *result;
77
+ int64_t i;
78
+ ps_island_ensure();
79
+ list = PyList_New((Py_ssize_t)args->len);
80
+ if (list == NULL) {
81
+ ps_island_fail();
82
+ }
83
+ for (i = 0; i < args->len; i++) {
84
+ PsBuf item;
85
+ PyObject *text;
86
+ memcpy(&item, (char *)args->data + (size_t)i * (size_t)args->elem, sizeof item);
87
+ text = PyUnicode_FromStringAndSize(item.data, (Py_ssize_t)item.len);
88
+ if (text == NULL || PyList_SetItem(list, (Py_ssize_t)i, text) < 0) {
89
+ ps_island_fail();
90
+ }
91
+ }
92
+ mod = ps_import("subprocess");
93
+ fn = PyObject_GetAttrString(mod, "check_output");
94
+ Py_DECREF(mod);
95
+ if (fn == NULL) {
96
+ Py_DECREF(list);
97
+ ps_island_fail();
98
+ }
99
+ result = PyObject_CallFunctionObjArgs(fn, list, NULL);
100
+ Py_DECREF(fn);
101
+ Py_DECREF(list);
102
+ if (result == NULL) {
103
+ ps_island_fail();
104
+ }
105
+ ps_take_bytes(result, out);
106
+ Py_DECREF(result);
107
+ }
108
+
109
+ void ps_island_hostname(PsBuf *out) {
110
+ PyObject *mod;
111
+ PyObject *result;
112
+ ps_island_ensure();
113
+ mod = ps_import("socket");
114
+ result = PyObject_CallMethod(mod, "gethostname", NULL);
115
+ Py_DECREF(mod);
116
+ if (result == NULL) {
117
+ ps_island_fail();
118
+ }
119
+ ps_take_unicode(result, out);
120
+ Py_DECREF(result);
121
+ }
122
+
123
+ int64_t ps_island_threads(void) {
124
+ PyObject *mod;
125
+ PyObject *result;
126
+ long value;
127
+ ps_island_ensure();
128
+ mod = ps_import("threading");
129
+ result = PyObject_CallMethod(mod, "active_count", NULL);
130
+ Py_DECREF(mod);
131
+ if (result == NULL) {
132
+ ps_island_fail();
133
+ }
134
+ value = PyLong_AsLong(result);
135
+ Py_DECREF(result);
136
+ if (value == -1 && PyErr_Occurred()) {
137
+ ps_island_fail();
138
+ }
139
+ return (int64_t)value;
140
+ }
141
+
142
+ void ps_island_thread_name(PsBuf *out) {
143
+ PyObject *mod;
144
+ PyObject *thread;
145
+ PyObject *name;
146
+ ps_island_ensure();
147
+ mod = ps_import("threading");
148
+ thread = PyObject_CallMethod(mod, "current_thread", NULL);
149
+ Py_DECREF(mod);
150
+ if (thread == NULL) {
151
+ ps_island_fail();
152
+ }
153
+ name = PyObject_GetAttrString(thread, "name");
154
+ Py_DECREF(thread);
155
+ if (name == NULL) {
156
+ ps_island_fail();
157
+ }
158
+ ps_take_unicode(name, out);
159
+ Py_DECREF(name);
160
+ }
161
+
162
+ void ps_island_cleandoc(int64_t n, const char *s, PsBuf *out) {
163
+ PyObject *mod;
164
+ PyObject *fn;
165
+ PyObject *text;
166
+ PyObject *result;
167
+ ps_island_ensure();
168
+ mod = ps_import("inspect");
169
+ fn = PyObject_GetAttrString(mod, "cleandoc");
170
+ Py_DECREF(mod);
171
+ if (fn == NULL) {
172
+ ps_island_fail();
173
+ }
174
+ text = PyUnicode_FromStringAndSize(s, (Py_ssize_t)n);
175
+ if (text == NULL) {
176
+ Py_DECREF(fn);
177
+ ps_island_fail();
178
+ }
179
+ result = PyObject_CallFunctionObjArgs(fn, text, NULL);
180
+ Py_DECREF(fn);
181
+ Py_DECREF(text);
182
+ if (result == NULL) {
183
+ ps_island_fail();
184
+ }
185
+ ps_take_unicode(result, out);
186
+ Py_DECREF(result);
187
+ }
188
+
189
+ static void ps_island_log(const char *level, int64_t n, const char *s) {
190
+ PyObject *mod;
191
+ PyObject *fn;
192
+ PyObject *text;
193
+ PyObject *result;
194
+ ps_island_ensure();
195
+ mod = ps_import("logging");
196
+ fn = PyObject_GetAttrString(mod, level);
197
+ Py_DECREF(mod);
198
+ if (fn == NULL) {
199
+ ps_island_fail();
200
+ }
201
+ text = PyUnicode_FromStringAndSize(s, (Py_ssize_t)n);
202
+ if (text == NULL) {
203
+ Py_DECREF(fn);
204
+ ps_island_fail();
205
+ }
206
+ result = PyObject_CallFunctionObjArgs(fn, text, NULL);
207
+ Py_DECREF(fn);
208
+ Py_DECREF(text);
209
+ Py_XDECREF(result);
210
+ if (result == NULL) {
211
+ ps_island_fail();
212
+ }
213
+ }
214
+
215
+ void ps_island_log_info(int64_t n, const char *s) { ps_island_log("info", n, s); }
216
+
217
+ void ps_island_log_warning(int64_t n, const char *s) { ps_island_log("warning", n, s); }
218
+
219
+ /* nativeprobe is a PyInit_* extension over libmix. Embedded CPython loads
220
+ it the same way a normal interpreter does. The direct path is ps_mix.c. */
221
+
222
+ static int64_t ps_island_mix_call(const char *name, int64_t n, const char *data, int64_t times, int with_times) {
223
+ PyObject *mod;
224
+ PyObject *fn;
225
+ PyObject *buf;
226
+ PyObject *result;
227
+ PyObject *count;
228
+ int64_t value;
229
+ ps_island_ensure();
230
+ mod = ps_import("nativeprobe");
231
+ fn = PyObject_GetAttrString(mod, name);
232
+ Py_DECREF(mod);
233
+ if (fn == NULL) {
234
+ ps_island_fail();
235
+ }
236
+ buf = PyBytes_FromStringAndSize(data, (Py_ssize_t)n);
237
+ if (buf == NULL) {
238
+ Py_DECREF(fn);
239
+ ps_island_fail();
240
+ }
241
+ if (with_times) {
242
+ count = PyLong_FromLongLong(times);
243
+ if (count == NULL) {
244
+ Py_DECREF(fn);
245
+ Py_DECREF(buf);
246
+ ps_island_fail();
247
+ }
248
+ result = PyObject_CallFunctionObjArgs(fn, buf, count, NULL);
249
+ Py_DECREF(count);
250
+ } else {
251
+ result = PyObject_CallFunctionObjArgs(fn, buf, NULL);
252
+ }
253
+ Py_DECREF(fn);
254
+ Py_DECREF(buf);
255
+ if (result == NULL) {
256
+ ps_island_fail();
257
+ }
258
+ value = PyLong_AsLongLong(result);
259
+ Py_DECREF(result);
260
+ if (value == -1 && PyErr_Occurred()) {
261
+ ps_island_fail();
262
+ }
263
+ return value;
264
+ }
265
+
266
+ int64_t ps_island_mix_crc32(int64_t n, const char *data) {
267
+ return ps_island_mix_call("crc32", n, data, 0, 0);
268
+ }
269
+
270
+ int64_t ps_island_mix_crc32_n(int64_t n, const char *data, int64_t times) {
271
+ return ps_island_mix_call("crc32_n", n, data, times, 1);
272
+ }