prism 0.13.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 +37 -1
- data/README.md +4 -1
- data/config.yml +96 -35
- data/docs/fuzzing.md +5 -10
- data/docs/prism.png +0 -0
- data/docs/serialization.md +10 -0
- data/ext/prism/api_node.c +239 -86
- data/ext/prism/extension.c +35 -48
- data/ext/prism/extension.h +1 -1
- data/include/prism/ast.h +170 -118
- data/include/prism/diagnostic.h +1 -0
- data/include/prism/node.h +8 -0
- data/include/prism/parser.h +26 -0
- data/include/prism/util/pm_buffer.h +3 -0
- data/include/prism/util/pm_constant_pool.h +21 -2
- data/include/prism/util/pm_string.h +2 -1
- data/include/prism/version.h +2 -2
- data/include/prism.h +1 -2
- data/lib/prism/compiler.rb +150 -141
- 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 +4 -4
- data/lib/prism/lex_compat.rb +42 -8
- data/lib/prism/mutation_compiler.rb +18 -3
- data/lib/prism/node.rb +2061 -191
- data/lib/prism/node_ext.rb +44 -0
- data/lib/prism/parse_result.rb +32 -5
- data/lib/prism/pattern.rb +1 -1
- data/lib/prism/serialize.rb +95 -87
- data/lib/prism/visitor.rb +9 -0
- data/prism.gemspec +2 -3
- data/src/diagnostic.c +2 -1
- data/src/node.c +99 -32
- data/src/prettyprint.c +137 -80
- data/src/prism.c +1960 -843
- data/src/serialize.c +140 -79
- data/src/util/pm_buffer.c +9 -7
- data/src/util/pm_constant_pool.c +25 -11
- metadata +3 -4
- data/include/prism/unescape.h +0 -48
- data/src/unescape.c +0 -637
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,26 +313,9 @@ 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
|
-
|
316
|
-
|
317
|
-
|
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
|
-
pm_buffer_append_u32(buffer, node->flags >> 2);
|
333
|
-
pm_serialize_string(parser, &((pm_call_and_write_node_t *)node)->read_name, buffer);
|
334
|
-
pm_serialize_string(parser, &((pm_call_and_write_node_t *)node)->write_name, buffer);
|
316
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
317
|
+
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_call_and_write_node_t *)node)->read_name));
|
318
|
+
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_call_and_write_node_t *)node)->write_name));
|
335
319
|
pm_serialize_location(parser, &((pm_call_and_write_node_t *)node)->operator_loc, buffer);
|
336
320
|
pm_serialize_node(parser, (pm_node_t *)((pm_call_and_write_node_t *)node)->value, buffer);
|
337
321
|
break;
|
@@ -376,8 +360,8 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
376
360
|
} else {
|
377
361
|
pm_serialize_node(parser, (pm_node_t *)((pm_call_node_t *)node)->block, buffer);
|
378
362
|
}
|
379
|
-
pm_buffer_append_u32(buffer, node->flags
|
380
|
-
|
363
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
364
|
+
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_call_node_t *)node)->name));
|
381
365
|
break;
|
382
366
|
}
|
383
367
|
case PM_CALL_OPERATOR_WRITE_NODE: {
|
@@ -398,26 +382,9 @@ 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
|
-
|
402
|
-
|
403
|
-
|
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
|
-
pm_buffer_append_u32(buffer, node->flags >> 2);
|
419
|
-
pm_serialize_string(parser, &((pm_call_operator_write_node_t *)node)->read_name, buffer);
|
420
|
-
pm_serialize_string(parser, &((pm_call_operator_write_node_t *)node)->write_name, buffer);
|
385
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
386
|
+
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_call_operator_write_node_t *)node)->read_name));
|
387
|
+
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_call_operator_write_node_t *)node)->write_name));
|
421
388
|
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_call_operator_write_node_t *)node)->operator));
|
422
389
|
pm_serialize_location(parser, &((pm_call_operator_write_node_t *)node)->operator_loc, buffer);
|
423
390
|
pm_serialize_node(parser, (pm_node_t *)((pm_call_operator_write_node_t *)node)->value, buffer);
|
@@ -441,26 +408,9 @@ 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
|
-
|
445
|
-
|
446
|
-
|
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
|
-
pm_buffer_append_u32(buffer, node->flags >> 2);
|
462
|
-
pm_serialize_string(parser, &((pm_call_or_write_node_t *)node)->read_name, buffer);
|
463
|
-
pm_serialize_string(parser, &((pm_call_or_write_node_t *)node)->write_name, buffer);
|
411
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
412
|
+
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_call_or_write_node_t *)node)->read_name));
|
413
|
+
pm_buffer_append_u32(buffer, pm_sizet_to_u32(((pm_call_or_write_node_t *)node)->write_name));
|
464
414
|
pm_serialize_location(parser, &((pm_call_or_write_node_t *)node)->operator_loc, buffer);
|
465
415
|
pm_serialize_node(parser, (pm_node_t *)((pm_call_or_write_node_t *)node)->value, buffer);
|
466
416
|
break;
|
@@ -805,7 +755,7 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
805
755
|
pm_serialize_node(parser, (pm_node_t *)((pm_flip_flop_node_t *)node)->right, buffer);
|
806
756
|
}
|
807
757
|
pm_serialize_location(parser, &((pm_flip_flop_node_t *)node)->operator_loc, buffer);
|
808
|
-
pm_buffer_append_u32(buffer, node->flags
|
758
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
809
759
|
break;
|
810
760
|
}
|
811
761
|
case PM_FLOAT_NODE: {
|
@@ -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);
|
@@ -1009,7 +1047,7 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
1009
1047
|
break;
|
1010
1048
|
}
|
1011
1049
|
case PM_INTEGER_NODE: {
|
1012
|
-
pm_buffer_append_u32(buffer, node->flags
|
1050
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
1013
1051
|
break;
|
1014
1052
|
}
|
1015
1053
|
case PM_INTERPOLATED_MATCH_LAST_LINE_NODE: {
|
@@ -1020,7 +1058,7 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
1020
1058
|
pm_serialize_node(parser, (pm_node_t *) ((pm_interpolated_match_last_line_node_t *)node)->parts.nodes[index], buffer);
|
1021
1059
|
}
|
1022
1060
|
pm_serialize_location(parser, &((pm_interpolated_match_last_line_node_t *)node)->closing_loc, buffer);
|
1023
|
-
pm_buffer_append_u32(buffer, node->flags
|
1061
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
1024
1062
|
break;
|
1025
1063
|
}
|
1026
1064
|
case PM_INTERPOLATED_REGULAR_EXPRESSION_NODE: {
|
@@ -1031,7 +1069,7 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
1031
1069
|
pm_serialize_node(parser, (pm_node_t *) ((pm_interpolated_regular_expression_node_t *)node)->parts.nodes[index], buffer);
|
1032
1070
|
}
|
1033
1071
|
pm_serialize_location(parser, &((pm_interpolated_regular_expression_node_t *)node)->closing_loc, buffer);
|
1034
|
-
pm_buffer_append_u32(buffer, node->flags
|
1072
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
1035
1073
|
break;
|
1036
1074
|
}
|
1037
1075
|
case PM_INTERPOLATED_STRING_NODE: {
|
@@ -1182,7 +1220,7 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
1182
1220
|
pm_serialize_location(parser, &((pm_match_last_line_node_t *)node)->content_loc, buffer);
|
1183
1221
|
pm_serialize_location(parser, &((pm_match_last_line_node_t *)node)->closing_loc, buffer);
|
1184
1222
|
pm_serialize_string(parser, &((pm_match_last_line_node_t *)node)->unescaped, buffer);
|
1185
|
-
pm_buffer_append_u32(buffer, node->flags
|
1223
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
1186
1224
|
break;
|
1187
1225
|
}
|
1188
1226
|
case PM_MATCH_PREDICATE_NODE: {
|
@@ -1405,7 +1443,7 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
1405
1443
|
pm_serialize_node(parser, (pm_node_t *)((pm_range_node_t *)node)->right, buffer);
|
1406
1444
|
}
|
1407
1445
|
pm_serialize_location(parser, &((pm_range_node_t *)node)->operator_loc, buffer);
|
1408
|
-
pm_buffer_append_u32(buffer, node->flags
|
1446
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
1409
1447
|
break;
|
1410
1448
|
}
|
1411
1449
|
case PM_RATIONAL_NODE: {
|
@@ -1420,7 +1458,7 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
1420
1458
|
pm_serialize_location(parser, &((pm_regular_expression_node_t *)node)->content_loc, buffer);
|
1421
1459
|
pm_serialize_location(parser, &((pm_regular_expression_node_t *)node)->closing_loc, buffer);
|
1422
1460
|
pm_serialize_string(parser, &((pm_regular_expression_node_t *)node)->unescaped, buffer);
|
1423
|
-
pm_buffer_append_u32(buffer, node->flags
|
1461
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
1424
1462
|
break;
|
1425
1463
|
}
|
1426
1464
|
case PM_REQUIRED_DESTRUCTURED_PARAMETER_NODE: {
|
@@ -1549,7 +1587,7 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
1549
1587
|
break;
|
1550
1588
|
}
|
1551
1589
|
case PM_STRING_NODE: {
|
1552
|
-
pm_buffer_append_u32(buffer, node->flags
|
1590
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
1553
1591
|
if (((pm_string_node_t *)node)->opening_loc.start == NULL) {
|
1554
1592
|
pm_buffer_append_u8(buffer, 0);
|
1555
1593
|
} else {
|
@@ -1661,7 +1699,7 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
1661
1699
|
} else {
|
1662
1700
|
pm_serialize_node(parser, (pm_node_t *)((pm_until_node_t *)node)->statements, buffer);
|
1663
1701
|
}
|
1664
|
-
pm_buffer_append_u32(buffer, node->flags
|
1702
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
1665
1703
|
break;
|
1666
1704
|
}
|
1667
1705
|
case PM_WHEN_NODE: {
|
@@ -1692,7 +1730,7 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
|
1692
1730
|
} else {
|
1693
1731
|
pm_serialize_node(parser, (pm_node_t *)((pm_while_node_t *)node)->statements, buffer);
|
1694
1732
|
}
|
1695
|
-
pm_buffer_append_u32(buffer, node->flags
|
1733
|
+
pm_buffer_append_u32(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
|
1696
1734
|
break;
|
1697
1735
|
}
|
1698
1736
|
case PM_X_STRING_NODE: {
|
@@ -1746,6 +1784,27 @@ pm_serialize_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buf
|
|
1746
1784
|
}
|
1747
1785
|
}
|
1748
1786
|
|
1787
|
+
static void
|
1788
|
+
pm_serialize_magic_comment(pm_parser_t *parser, pm_magic_comment_t *magic_comment, pm_buffer_t *buffer) {
|
1789
|
+
// serialize key location
|
1790
|
+
pm_buffer_append_u32(buffer, pm_ptrdifft_to_u32(magic_comment->key_start - parser->start));
|
1791
|
+
pm_buffer_append_u32(buffer, pm_ptrdifft_to_u32(magic_comment->key_length));
|
1792
|
+
|
1793
|
+
// serialize value location
|
1794
|
+
pm_buffer_append_u32(buffer, pm_ptrdifft_to_u32(magic_comment->value_start - parser->start));
|
1795
|
+
pm_buffer_append_u32(buffer, pm_ptrdifft_to_u32(magic_comment->value_length));
|
1796
|
+
}
|
1797
|
+
|
1798
|
+
static void
|
1799
|
+
pm_serialize_magic_comment_list(pm_parser_t *parser, pm_list_t *list, pm_buffer_t *buffer) {
|
1800
|
+
pm_buffer_append_u32(buffer, pm_sizet_to_u32(pm_list_size(list)));
|
1801
|
+
|
1802
|
+
pm_magic_comment_t *magic_comment;
|
1803
|
+
for (magic_comment = (pm_magic_comment_t *) list->head; magic_comment != NULL; magic_comment = (pm_magic_comment_t *) magic_comment->node.next) {
|
1804
|
+
pm_serialize_magic_comment(parser, magic_comment, buffer);
|
1805
|
+
}
|
1806
|
+
}
|
1807
|
+
|
1749
1808
|
static void
|
1750
1809
|
pm_serialize_diagnostic(pm_parser_t *parser, pm_diagnostic_t *diagnostic, pm_buffer_t *buffer) {
|
1751
1810
|
// serialize message
|
@@ -1775,11 +1834,12 @@ pm_serialize_encoding(pm_encoding_t *encoding, pm_buffer_t *buffer) {
|
|
1775
1834
|
pm_buffer_append_str(buffer, encoding->name, encoding_length);
|
1776
1835
|
}
|
1777
1836
|
|
1778
|
-
#line
|
1837
|
+
#line 200 "serialize.c.erb"
|
1779
1838
|
void
|
1780
1839
|
pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
|
1781
1840
|
pm_serialize_encoding(&parser->encoding, buffer);
|
1782
1841
|
pm_serialize_comment_list(parser, &parser->comment_list, buffer);
|
1842
|
+
pm_serialize_magic_comment_list(parser, &parser->magic_comment_list, buffer);
|
1783
1843
|
pm_serialize_diagnostic_list(parser, &parser->error_list, buffer);
|
1784
1844
|
pm_serialize_diagnostic_list(parser, &parser->warning_list, buffer);
|
1785
1845
|
|
@@ -1812,12 +1872,12 @@ pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer)
|
|
1812
1872
|
pm_constant_t *constant = &parser->constant_pool.constants[bucket->id - 1];
|
1813
1873
|
size_t buffer_offset = offset + ((((size_t)bucket->id) - 1) * 8);
|
1814
1874
|
|
1815
|
-
if (bucket->
|
1816
|
-
// Since this is an owned constant, we are going to
|
1817
|
-
// contents into the buffer after the constant pool.
|
1818
|
-
// effectively in place of the source offset, we have a
|
1819
|
-
// offset. We will add a leading 1 to indicate that this
|
1820
|
-
// 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.
|
1821
1881
|
uint32_t content_offset = pm_sizet_to_u32(buffer->length);
|
1822
1882
|
uint32_t owned_mask = (uint32_t) (1 << 31);
|
1823
1883
|
|
@@ -1868,6 +1928,7 @@ pm_lex_serialize(const uint8_t *source, size_t size, const char *filepath, pm_bu
|
|
1868
1928
|
|
1869
1929
|
pm_serialize_encoding(&parser.encoding, buffer);
|
1870
1930
|
pm_serialize_comment_list(&parser, &parser.comment_list, buffer);
|
1931
|
+
pm_serialize_magic_comment_list(&parser, &parser.magic_comment_list, buffer);
|
1871
1932
|
pm_serialize_diagnostic_list(&parser, &parser.error_list, buffer);
|
1872
1933
|
pm_serialize_diagnostic_list(&parser, &parser.warning_list, buffer);
|
1873
1934
|
|
data/src/util/pm_buffer.c
CHANGED
@@ -1,24 +1,26 @@
|
|
1
1
|
#include "prism/util/pm_buffer.h"
|
2
2
|
|
3
|
-
#define PRISM_BUFFER_INITIAL_SIZE 1024
|
4
|
-
|
5
3
|
// Return the size of the pm_buffer_t struct.
|
6
4
|
size_t
|
7
5
|
pm_buffer_sizeof(void) {
|
8
6
|
return sizeof(pm_buffer_t);
|
9
7
|
}
|
10
8
|
|
11
|
-
// Initialize a pm_buffer_t with
|
9
|
+
// Initialize a pm_buffer_t with the given capacity.
|
12
10
|
bool
|
13
|
-
|
11
|
+
pm_buffer_init_capacity(pm_buffer_t *buffer, size_t capacity) {
|
14
12
|
buffer->length = 0;
|
15
|
-
buffer->capacity =
|
13
|
+
buffer->capacity = capacity;
|
16
14
|
|
17
|
-
buffer->value = (char *) malloc(
|
15
|
+
buffer->value = (char *) malloc(capacity);
|
18
16
|
return buffer->value != NULL;
|
19
17
|
}
|
20
18
|
|
21
|
-
|
19
|
+
// Initialize a pm_buffer_t with its default values.
|
20
|
+
bool
|
21
|
+
pm_buffer_init(pm_buffer_t *buffer) {
|
22
|
+
return pm_buffer_init_capacity(buffer, 1024);
|
23
|
+
}
|
22
24
|
|
23
25
|
// Return the value of the buffer.
|
24
26
|
char *
|
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-
|
11
|
+
date: 2023-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -33,6 +33,7 @@ files:
|
|
33
33
|
- docs/fuzzing.md
|
34
34
|
- docs/heredocs.md
|
35
35
|
- docs/mapping.md
|
36
|
+
- docs/prism.png
|
36
37
|
- docs/ripper.md
|
37
38
|
- docs/ruby_api.md
|
38
39
|
- docs/serialization.md
|
@@ -51,7 +52,6 @@ files:
|
|
51
52
|
- include/prism/pack.h
|
52
53
|
- include/prism/parser.h
|
53
54
|
- include/prism/regexp.h
|
54
|
-
- include/prism/unescape.h
|
55
55
|
- include/prism/util/pm_buffer.h
|
56
56
|
- include/prism/util/pm_char.h
|
57
57
|
- include/prism/util/pm_constant_pool.h
|
@@ -99,7 +99,6 @@ files:
|
|
99
99
|
- src/regexp.c
|
100
100
|
- src/serialize.c
|
101
101
|
- src/token_type.c
|
102
|
-
- src/unescape.c
|
103
102
|
- src/util/pm_buffer.c
|
104
103
|
- src/util/pm_char.c
|
105
104
|
- src/util/pm_constant_pool.c
|
data/include/prism/unescape.h
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
#ifndef PRISM_UNESCAPE_H
|
2
|
-
#define PRISM_UNESCAPE_H
|
3
|
-
|
4
|
-
#include "prism/defines.h"
|
5
|
-
#include "prism/diagnostic.h"
|
6
|
-
#include "prism/parser.h"
|
7
|
-
#include "prism/util/pm_char.h"
|
8
|
-
#include "prism/util/pm_list.h"
|
9
|
-
#include "prism/util/pm_memchr.h"
|
10
|
-
#include "prism/util/pm_string.h"
|
11
|
-
|
12
|
-
#include <assert.h>
|
13
|
-
#include <stdbool.h>
|
14
|
-
#include <stdint.h>
|
15
|
-
#include <string.h>
|
16
|
-
|
17
|
-
// The type of unescape we are performing.
|
18
|
-
typedef enum {
|
19
|
-
// When we're creating a string inside of a list literal like %w, we
|
20
|
-
// shouldn't escape anything.
|
21
|
-
PM_UNESCAPE_NONE,
|
22
|
-
|
23
|
-
// When we're unescaping a single-quoted string, we only need to unescape
|
24
|
-
// single quotes and backslashes.
|
25
|
-
PM_UNESCAPE_MINIMAL,
|
26
|
-
|
27
|
-
// When we're unescaping a string list, in addition to MINIMAL, we need to
|
28
|
-
// unescape whitespace.
|
29
|
-
PM_UNESCAPE_WHITESPACE,
|
30
|
-
|
31
|
-
// When we're unescaping a double-quoted string, we need to unescape all
|
32
|
-
// escapes.
|
33
|
-
PM_UNESCAPE_ALL,
|
34
|
-
} pm_unescape_type_t;
|
35
|
-
|
36
|
-
// Unescape the contents of the given token into the given string using the given unescape mode.
|
37
|
-
PRISM_EXPORTED_FUNCTION void pm_unescape_manipulate_string(pm_parser_t *parser, pm_string_t *string, pm_unescape_type_t unescape_type);
|
38
|
-
void pm_unescape_manipulate_char_literal(pm_parser_t *parser, pm_string_t *string, pm_unescape_type_t unescape_type);
|
39
|
-
|
40
|
-
// Accepts a source string and a type of unescaping and returns the unescaped version.
|
41
|
-
// The caller must pm_string_free(result); after calling this function.
|
42
|
-
PRISM_EXPORTED_FUNCTION bool pm_unescape_string(const uint8_t *start, size_t length, pm_unescape_type_t unescape_type, pm_string_t *result);
|
43
|
-
|
44
|
-
// Returns the number of bytes that encompass the first escape sequence in the
|
45
|
-
// given string.
|
46
|
-
size_t pm_unescape_calculate_difference(pm_parser_t *parser, const uint8_t *value, pm_unescape_type_t unescape_type, bool expect_single_codepoint);
|
47
|
-
|
48
|
-
#endif
|