prism 0.14.0 → 0.15.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -1
- data/README.md +1 -1
- data/config.yml +86 -21
- data/ext/prism/api_node.c +213 -67
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +133 -83
- data/include/prism/diagnostic.h +1 -0
- data/include/prism/node.h +7 -0
- data/include/prism/util/pm_constant_pool.h +20 -6
- data/include/prism/version.h +3 -3
- data/include/prism.h +1 -1
- data/lib/prism/compiler.rb +9 -0
- data/lib/prism/debug.rb +30 -26
- data/lib/prism/dispatcher.rb +42 -0
- data/lib/prism/dsl.rb +23 -8
- data/lib/prism/ffi.rb +2 -2
- data/lib/prism/lex_compat.rb +9 -9
- data/lib/prism/mutation_compiler.rb +18 -3
- data/lib/prism/node.rb +580 -120
- data/lib/prism/serialize.rb +84 -78
- data/lib/prism/visitor.rb +9 -0
- data/prism.gemspec +1 -1
- data/src/diagnostic.c +1 -0
- data/src/node.c +99 -18
- data/src/prettyprint.c +102 -45
- data/src/prism.c +288 -88
- data/src/serialize.c +95 -57
- data/src/util/pm_constant_pool.c +25 -11
- metadata +2 -2
data/src/serialize.c
CHANGED
@@ -179,6 +179,7 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
179
179
|
break;
|
180
180
|
}
|
181
181
|
case PM_BACK_REFERENCE_READ_NODE: {
|
182
|
+
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_back_reference_read_node_t *)node)->name));
|
182
183
|
break;
|
183
184
|
}
|
184
185
|
case PM_BEGIN_NODE: {
|
@@ -312,23 +313,6 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
312
313
|
pm_buffer_append_u8(buffer, 1);
|
313
314
|
pm_serialize_location(parser, &((pm_call_and_write_node_t *)node)->message_loc, buffer);
|
314
315
|
}
|
315
|
-
if (((pm_call_and_write_node_t *)node)->opening_loc.start == NULL) {
|
316
|
-
pm_buffer_append_u8(buffer, 0);
|
317
|
-
} else {
|
318
|
-
pm_buffer_append_u8(buffer, 1);
|
319
|
-
pm_serialize_location(parser, &((pm_call_and_write_node_t *)node)->opening_loc, buffer);
|
320
|
-
}
|
321
|
-
if (((pm_call_and_write_node_t *)node)->arguments == NULL) {
|
322
|
-
pm_buffer_append_u8(buffer, 0);
|
323
|
-
} else {
|
324
|
-
pm_serialize_node(parser, (pm_node_t *)((pm_call_and_write_node_t *)node)->arguments, buffer);
|
325
|
-
}
|
326
|
-
if (((pm_call_and_write_node_t *)node)->closing_loc.start == NULL) {
|
327
|
-
pm_buffer_append_u8(buffer, 0);
|
328
|
-
} else {
|
329
|
-
pm_buffer_append_u8(buffer, 1);
|
330
|
-
pm_serialize_location(parser, &((pm_call_and_write_node_t *)node)->closing_loc, buffer);
|
331
|
-
}
|
332
316
|
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
333
317
|
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_call_and_write_node_t *)node)->read_name));
|
334
318
|
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_call_and_write_node_t *)node)->write_name));
|
@@ -398,23 +382,6 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
398
382
|
pm_buffer_append_u8(buffer, 1);
|
399
383
|
pm_serialize_location(parser, &((pm_call_operator_write_node_t *)node)->message_loc, buffer);
|
400
384
|
}
|
401
|
-
if (((pm_call_operator_write_node_t *)node)->opening_loc.start == NULL) {
|
402
|
-
pm_buffer_append_u8(buffer, 0);
|
403
|
-
} else {
|
404
|
-
pm_buffer_append_u8(buffer, 1);
|
405
|
-
pm_serialize_location(parser, &((pm_call_operator_write_node_t *)node)->opening_loc, buffer);
|
406
|
-
}
|
407
|
-
if (((pm_call_operator_write_node_t *)node)->arguments == NULL) {
|
408
|
-
pm_buffer_append_u8(buffer, 0);
|
409
|
-
} else {
|
410
|
-
pm_serialize_node(parser, (pm_node_t *)((pm_call_operator_write_node_t *)node)->arguments, buffer);
|
411
|
-
}
|
412
|
-
if (((pm_call_operator_write_node_t *)node)->closing_loc.start == NULL) {
|
413
|
-
pm_buffer_append_u8(buffer, 0);
|
414
|
-
} else {
|
415
|
-
pm_buffer_append_u8(buffer, 1);
|
416
|
-
pm_serialize_location(parser, &((pm_call_operator_write_node_t *)node)->closing_loc, buffer);
|
417
|
-
}
|
418
385
|
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
419
386
|
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_call_operator_write_node_t *)node)->read_name));
|
420
387
|
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_call_operator_write_node_t *)node)->write_name));
|
@@ -441,23 +408,6 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
441
408
|
pm_buffer_append_u8(buffer, 1);
|
442
409
|
pm_serialize_location(parser, &((pm_call_or_write_node_t *)node)->message_loc, buffer);
|
443
410
|
}
|
444
|
-
if (((pm_call_or_write_node_t *)node)->opening_loc.start == NULL) {
|
445
|
-
pm_buffer_append_u8(buffer, 0);
|
446
|
-
} else {
|
447
|
-
pm_buffer_append_u8(buffer, 1);
|
448
|
-
pm_serialize_location(parser, &((pm_call_or_write_node_t *)node)->opening_loc, buffer);
|
449
|
-
}
|
450
|
-
if (((pm_call_or_write_node_t *)node)->arguments == NULL) {
|
451
|
-
pm_buffer_append_u8(buffer, 0);
|
452
|
-
} else {
|
453
|
-
pm_serialize_node(parser, (pm_node_t *)((pm_call_or_write_node_t *)node)->arguments, buffer);
|
454
|
-
}
|
455
|
-
if (((pm_call_or_write_node_t *)node)->closing_loc.start == NULL) {
|
456
|
-
pm_buffer_append_u8(buffer, 0);
|
457
|
-
} else {
|
458
|
-
pm_buffer_append_u8(buffer, 1);
|
459
|
-
pm_serialize_location(parser, &((pm_call_or_write_node_t *)node)->closing_loc, buffer);
|
460
|
-
}
|
461
411
|
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
462
412
|
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_call_or_write_node_t *)node)->read_name));
|
463
413
|
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_call_or_write_node_t *)node)->write_name));
|
@@ -971,6 +921,94 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
971
921
|
}
|
972
922
|
break;
|
973
923
|
}
|
924
|
+
case PM_INDEX_AND_WRITE_NODE: {
|
925
|
+
if (((pm_index_and_write_node_t *)node)->receiver == NULL) {
|
926
|
+
pm_buffer_append_u8(buffer, 0);
|
927
|
+
} else {
|
928
|
+
pm_serialize_node(parser, (pm_node_t *)((pm_index_and_write_node_t *)node)->receiver, buffer);
|
929
|
+
}
|
930
|
+
if (((pm_index_and_write_node_t *)node)->call_operator_loc.start == NULL) {
|
931
|
+
pm_buffer_append_u8(buffer, 0);
|
932
|
+
} else {
|
933
|
+
pm_buffer_append_u8(buffer, 1);
|
934
|
+
pm_serialize_location(parser, &((pm_index_and_write_node_t *)node)->call_operator_loc, buffer);
|
935
|
+
}
|
936
|
+
pm_serialize_location(parser, &((pm_index_and_write_node_t *)node)->opening_loc, buffer);
|
937
|
+
if (((pm_index_and_write_node_t *)node)->arguments == NULL) {
|
938
|
+
pm_buffer_append_u8(buffer, 0);
|
939
|
+
} else {
|
940
|
+
pm_serialize_node(parser, (pm_node_t *)((pm_index_and_write_node_t *)node)->arguments, buffer);
|
941
|
+
}
|
942
|
+
pm_serialize_location(parser, &((pm_index_and_write_node_t *)node)->closing_loc, buffer);
|
943
|
+
if (((pm_index_and_write_node_t *)node)->block == NULL) {
|
944
|
+
pm_buffer_append_u8(buffer, 0);
|
945
|
+
} else {
|
946
|
+
pm_serialize_node(parser, (pm_node_t *)((pm_index_and_write_node_t *)node)->block, buffer);
|
947
|
+
}
|
948
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
949
|
+
pm_serialize_location(parser, &((pm_index_and_write_node_t *)node)->operator_loc, buffer);
|
950
|
+
pm_serialize_node(parser, (pm_node_t *)((pm_index_and_write_node_t *)node)->value, buffer);
|
951
|
+
break;
|
952
|
+
}
|
953
|
+
case PM_INDEX_OPERATOR_WRITE_NODE: {
|
954
|
+
if (((pm_index_operator_write_node_t *)node)->receiver == NULL) {
|
955
|
+
pm_buffer_append_u8(buffer, 0);
|
956
|
+
} else {
|
957
|
+
pm_serialize_node(parser, (pm_node_t *)((pm_index_operator_write_node_t *)node)->receiver, buffer);
|
958
|
+
}
|
959
|
+
if (((pm_index_operator_write_node_t *)node)->call_operator_loc.start == NULL) {
|
960
|
+
pm_buffer_append_u8(buffer, 0);
|
961
|
+
} else {
|
962
|
+
pm_buffer_append_u8(buffer, 1);
|
963
|
+
pm_serialize_location(parser, &((pm_index_operator_write_node_t *)node)->call_operator_loc, buffer);
|
964
|
+
}
|
965
|
+
pm_serialize_location(parser, &((pm_index_operator_write_node_t *)node)->opening_loc, buffer);
|
966
|
+
if (((pm_index_operator_write_node_t *)node)->arguments == NULL) {
|
967
|
+
pm_buffer_append_u8(buffer, 0);
|
968
|
+
} else {
|
969
|
+
pm_serialize_node(parser, (pm_node_t *)((pm_index_operator_write_node_t *)node)->arguments, buffer);
|
970
|
+
}
|
971
|
+
pm_serialize_location(parser, &((pm_index_operator_write_node_t *)node)->closing_loc, buffer);
|
972
|
+
if (((pm_index_operator_write_node_t *)node)->block == NULL) {
|
973
|
+
pm_buffer_append_u8(buffer, 0);
|
974
|
+
} else {
|
975
|
+
pm_serialize_node(parser, (pm_node_t *)((pm_index_operator_write_node_t *)node)->block, buffer);
|
976
|
+
}
|
977
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
978
|
+
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_index_operator_write_node_t *)node)->operator));
|
979
|
+
pm_serialize_location(parser, &((pm_index_operator_write_node_t *)node)->operator_loc, buffer);
|
980
|
+
pm_serialize_node(parser, (pm_node_t *)((pm_index_operator_write_node_t *)node)->value, buffer);
|
981
|
+
break;
|
982
|
+
}
|
983
|
+
case PM_INDEX_OR_WRITE_NODE: {
|
984
|
+
if (((pm_index_or_write_node_t *)node)->receiver == NULL) {
|
985
|
+
pm_buffer_append_u8(buffer, 0);
|
986
|
+
} else {
|
987
|
+
pm_serialize_node(parser, (pm_node_t *)((pm_index_or_write_node_t *)node)->receiver, buffer);
|
988
|
+
}
|
989
|
+
if (((pm_index_or_write_node_t *)node)->call_operator_loc.start == NULL) {
|
990
|
+
pm_buffer_append_u8(buffer, 0);
|
991
|
+
} else {
|
992
|
+
pm_buffer_append_u8(buffer, 1);
|
993
|
+
pm_serialize_location(parser, &((pm_index_or_write_node_t *)node)->call_operator_loc, buffer);
|
994
|
+
}
|
995
|
+
pm_serialize_location(parser, &((pm_index_or_write_node_t *)node)->opening_loc, buffer);
|
996
|
+
if (((pm_index_or_write_node_t *)node)->arguments == NULL) {
|
997
|
+
pm_buffer_append_u8(buffer, 0);
|
998
|
+
} else {
|
999
|
+
pm_serialize_node(parser, (pm_node_t *)((pm_index_or_write_node_t *)node)->arguments, buffer);
|
1000
|
+
}
|
1001
|
+
pm_serialize_location(parser, &((pm_index_or_write_node_t *)node)->closing_loc, buffer);
|
1002
|
+
if (((pm_index_or_write_node_t *)node)->block == NULL) {
|
1003
|
+
pm_buffer_append_u8(buffer, 0);
|
1004
|
+
} else {
|
1005
|
+
pm_serialize_node(parser, (pm_node_t *)((pm_index_or_write_node_t *)node)->block, buffer);
|
1006
|
+
}
|
1007
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
1008
|
+
pm_serialize_location(parser, &((pm_index_or_write_node_t *)node)->operator_loc, buffer);
|
1009
|
+
pm_serialize_node(parser, (pm_node_t *)((pm_index_or_write_node_t *)node)->value, buffer);
|
1010
|
+
break;
|
1011
|
+
}
|
974
1012
|
case PM_INSTANCE_VARIABLE_AND_WRITE_NODE: {
|
975
1013
|
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_instance_variable_and_write_node_t *)node)->name));
|
976
1014
|
pm_serialize_location(parser, &((pm_instance_variable_and_write_node_t *)node)->name_loc, buffer);
|
@@ -1834,12 +1872,12 @@ pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer)
|
|
1834
1872
|
pm_constant_t *constant = &parser->constant_pool.constants[bucket->id - 1];
|
1835
1873
|
size_t buffer_offset = offset + ((((size_t)bucket->id) - 1) * 8);
|
1836
1874
|
|
1837
|
-
if (bucket->
|
1838
|
-
// Since this is an owned constant, we are going to
|
1839
|
-
// contents into the buffer after the constant pool.
|
1840
|
-
// effectively in place of the source offset, we have a
|
1841
|
-
// offset. We will add a leading 1 to indicate that this
|
1842
|
-
// buffer offset.
|
1875
|
+
if (bucket->type == PM_CONSTANT_POOL_BUCKET_OWNED || bucket->type == PM_CONSTANT_POOL_BUCKET_CONSTANT) {
|
1876
|
+
// Since this is an owned or constant constant, we are going to
|
1877
|
+
// write its contents into the buffer after the constant pool.
|
1878
|
+
// So effectively in place of the source offset, we have a
|
1879
|
+
// buffer offset. We will add a leading 1 to indicate that this
|
1880
|
+
// is a buffer offset.
|
1843
1881
|
uint32_t content_offset = pm_sizet_to_u32(buffer->length);
|
1844
1882
|
uint32_t owned_mask = (uint32_t) (1 << 31);
|
1845
1883
|
|
data/src/util/pm_constant_pool.c
CHANGED
@@ -154,9 +154,16 @@ pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity) {
|
|
154
154
|
return true;
|
155
155
|
}
|
156
156
|
|
157
|
+
// Return a pointer to the constant indicated by the given constant id.
|
158
|
+
pm_constant_t *
|
159
|
+
pm_constant_pool_id_to_constant(pm_constant_pool_t *pool, pm_constant_id_t constant_id) {
|
160
|
+
assert(constant_id > 0 && constant_id <= pool->size);
|
161
|
+
return &pool->constants[constant_id - 1];
|
162
|
+
}
|
163
|
+
|
157
164
|
// Insert a constant into a constant pool and return its index in the pool.
|
158
165
|
static inline pm_constant_id_t
|
159
|
-
pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t length,
|
166
|
+
pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t length, pm_constant_pool_bucket_type_t type) {
|
160
167
|
if (pool->size >= (pool->capacity / 4 * 3)) {
|
161
168
|
if (!pm_constant_pool_resize(pool)) return 0;
|
162
169
|
}
|
@@ -178,19 +185,19 @@ pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t l
|
|
178
185
|
// Since we have found a match, we need to check if this is
|
179
186
|
// attempting to insert a shared or an owned constant. We want to
|
180
187
|
// prefer shared constants since they don't require allocations.
|
181
|
-
if (
|
188
|
+
if (type == PM_CONSTANT_POOL_BUCKET_OWNED) {
|
182
189
|
// If we're attempting to insert an owned constant and we have
|
183
190
|
// an existing constant, then either way we don't want the given
|
184
191
|
// memory. Either it's duplicated with the existing constant or
|
185
192
|
// it's not necessary because we have a shared version.
|
186
193
|
free((void *) start);
|
187
|
-
} else if (bucket->
|
194
|
+
} else if (bucket->type == PM_CONSTANT_POOL_BUCKET_OWNED) {
|
188
195
|
// If we're attempting to insert a shared constant and the
|
189
196
|
// existing constant is owned, then we can free the owned
|
190
197
|
// constant and replace it with the shared constant.
|
191
198
|
free((void *) constant->start);
|
192
199
|
constant->start = start;
|
193
|
-
bucket->
|
200
|
+
bucket->type = (unsigned int) (PM_CONSTANT_POOL_BUCKET_DEFAULT & 0x3);
|
194
201
|
}
|
195
202
|
|
196
203
|
return bucket->id;
|
@@ -202,15 +209,15 @@ pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t l
|
|
202
209
|
// IDs are allocated starting at 1, since the value 0 denotes a non-existant
|
203
210
|
// constant.
|
204
211
|
uint32_t id = ++pool->size;
|
205
|
-
assert(pool->size < ((uint32_t) (1 <<
|
212
|
+
assert(pool->size < ((uint32_t) (1 << 30)));
|
206
213
|
|
207
214
|
*bucket = (pm_constant_pool_bucket_t) {
|
208
|
-
.id = (unsigned int) (id &
|
209
|
-
.
|
215
|
+
.id = (unsigned int) (id & 0x3fffffff),
|
216
|
+
.type = (unsigned int) (type & 0x3),
|
210
217
|
.hash = hash
|
211
218
|
};
|
212
219
|
|
213
|
-
pool->constants[id - 1]
|
220
|
+
pool->constants[id - 1] = (pm_constant_t) {
|
214
221
|
.start = start,
|
215
222
|
.length = length,
|
216
223
|
};
|
@@ -222,7 +229,7 @@ pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t l
|
|
222
229
|
// if any potential calls to resize fail.
|
223
230
|
pm_constant_id_t
|
224
231
|
pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
|
225
|
-
return pm_constant_pool_insert(pool, start, length,
|
232
|
+
return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_DEFAULT);
|
226
233
|
}
|
227
234
|
|
228
235
|
// Insert a constant into a constant pool from memory that is now owned by the
|
@@ -230,7 +237,14 @@ pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, s
|
|
230
237
|
// resize fail.
|
231
238
|
pm_constant_id_t
|
232
239
|
pm_constant_pool_insert_owned(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
|
233
|
-
return pm_constant_pool_insert(pool, start, length,
|
240
|
+
return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_OWNED);
|
241
|
+
}
|
242
|
+
|
243
|
+
// Insert a constant into a constant pool from memory that is constant. Returns
|
244
|
+
// the id of the constant, or 0 if any potential calls to resize fail.
|
245
|
+
pm_constant_id_t
|
246
|
+
pm_constant_pool_insert_constant(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
|
247
|
+
return pm_constant_pool_insert(pool, start, length, PM_CONSTANT_POOL_BUCKET_CONSTANT);
|
234
248
|
}
|
235
249
|
|
236
250
|
// Free the memory associated with a constant pool.
|
@@ -242,7 +256,7 @@ pm_constant_pool_free(pm_constant_pool_t *pool) {
|
|
242
256
|
pm_constant_pool_bucket_t *bucket = &pool->buckets[index];
|
243
257
|
|
244
258
|
// If an id is set on this constant, then we know we have content here.
|
245
|
-
if (bucket->id != 0 && bucket->
|
259
|
+
if (bucket->id != 0 && bucket->type == PM_CONSTANT_POOL_BUCKET_OWNED) {
|
246
260
|
pm_constant_t *constant = &pool->constants[bucket->id - 1];
|
247
261
|
free((void *) constant->start);
|
248
262
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prism
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shopify
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-10-
|
11
|
+
date: 2023-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|