prism 0.14.0 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -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 +2 -2
- 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 +83 -77
- 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 = PM_CONSTANT_POOL_BUCKET_DEFAULT;
|
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.0
|
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:
|