aboutsummaryrefslogtreecommitdiffstats
path: root/prism
diff options
context:
space:
mode:
authorKevin Newton <kddnewton@gmail.com>2023-10-17 15:10:49 -0400
committergit <svn-admin@ruby-lang.org>2023-10-18 16:08:31 +0000
commitf5f032295d49758032df4e4c257e423d3c96feb4 (patch)
treed0471ff22c81936f5c12bd0c3ffc0c5be3c8cc63 /prism
parent4f4016497e12af1b1a227bf0f7ff5e6b6e6f92ec (diff)
downloadruby-f5f032295d49758032df4e4c257e423d3c96feb4.tar.gz
[ruby/prism] Provide "constant" constants, embedded in the code
https://github.com/ruby/prism/commit/d469a56e7e
Diffstat (limited to 'prism')
-rw-r--r--prism/prism.c31
-rw-r--r--prism/templates/src/serialize.c.erb12
-rw-r--r--prism/util/pm_constant_pool.c27
-rw-r--r--prism/util/pm_constant_pool.h13
4 files changed, 46 insertions, 37 deletions
diff --git a/prism/prism.c b/prism/prism.c
index dc413965c5..bf79c21167 100644
--- a/prism/prism.c
+++ b/prism/prism.c
@@ -496,18 +496,8 @@ pm_parser_constant_id_owned(pm_parser_t *parser, const uint8_t *start, size_t le
// Retrieve the constant pool id for the given static literal C string.
static inline pm_constant_id_t
-pm_parser_constant_id_static(pm_parser_t *parser, const char *start, size_t length) {
- uint8_t *owned_copy;
- if (length > 0) {
- owned_copy = malloc(length);
- memcpy(owned_copy, start, length);
- } else {
- owned_copy = malloc(1);
- owned_copy[0] = '\0';
- }
- return pm_constant_pool_insert_owned(&parser->constant_pool, owned_copy, length);
- // Does not work because the static literal cannot be serialized as an offset of source
- // return pm_constant_pool_insert_shared(&parser->constant_pool, start, length);
+pm_parser_constant_id_constant(pm_parser_t *parser, const char *start, size_t length) {
+ return pm_constant_pool_insert_constant(&parser->constant_pool, (const uint8_t *) start, length);
}
// Retrieve the constant pool id for the given token.
@@ -1450,7 +1440,7 @@ pm_call_node_aref_create(pm_parser_t *parser, pm_node_t *receiver, pm_arguments_
node->closing_loc = arguments->closing_loc;
node->block = arguments->block;
- node->name = pm_parser_constant_id_static(parser, "[]", 2);
+ node->name = pm_parser_constant_id_constant(parser, "[]", 2);
return node;
}
@@ -1550,7 +1540,7 @@ pm_call_node_not_create(pm_parser_t *parser, pm_node_t *receiver, pm_token_t *me
node->arguments = arguments->arguments;
node->closing_loc = arguments->closing_loc;
- node->name = pm_parser_constant_id_static(parser, "!", 1);
+ node->name = pm_parser_constant_id_constant(parser, "!", 1);
return node;
}
@@ -1577,7 +1567,7 @@ pm_call_node_shorthand_create(pm_parser_t *parser, pm_node_t *receiver, pm_token
node->base.flags |= PM_CALL_NODE_FLAGS_SAFE_NAVIGATION;
}
- node->name = pm_parser_constant_id_static(parser, "call", 4);
+ node->name = pm_parser_constant_id_constant(parser, "call", 4);
return node;
}
@@ -1592,7 +1582,7 @@ pm_call_node_unary_create(pm_parser_t *parser, pm_token_t *operator, pm_node_t *
node->receiver = receiver;
node->message_loc = PM_OPTIONAL_LOCATION_TOKEN_VALUE(operator);
- node->name = pm_parser_constant_id_static(parser, name, strlen(name));
+ node->name = pm_parser_constant_id_constant(parser, name, strlen(name));
return node;
}
@@ -1646,7 +1636,8 @@ pm_call_node_writable_p(pm_call_node_t *node) {
static void
pm_call_write_read_name_init(pm_parser_t *parser, pm_constant_id_t *read_name, pm_constant_id_t *write_name) {
pm_constant_t *write_constant = pm_constant_pool_id_to_constant(&parser->constant_pool, *write_name);
- if (write_constant->length >= 1) {
+
+ if (write_constant->length > 0) {
size_t length = write_constant->length - 1;
void *memory = malloc(length);
@@ -1655,7 +1646,7 @@ pm_call_write_read_name_init(pm_parser_t *parser, pm_constant_id_t *read_name, p
*read_name = pm_constant_pool_insert_owned(&parser->constant_pool, (uint8_t *) memory, length);
} else {
// We can get here if the message was missing because of a syntax error.
- *read_name = pm_parser_constant_id_static(parser, "", 0);
+ *read_name = pm_parser_constant_id_constant(parser, "", 0);
}
}
@@ -9631,7 +9622,7 @@ parse_target(pm_parser_t *parser, pm_node_t *target) {
(call->block == NULL)
) {
// Replace the name with "[]=".
- call->name = pm_parser_constant_id_static(parser, "[]=", 3);
+ call->name = pm_parser_constant_id_constant(parser, "[]=", 3);
return target;
}
}
@@ -9798,7 +9789,7 @@ parse_write(pm_parser_t *parser, pm_node_t *target, pm_token_t *operator, pm_nod
target->location.end = value->location.end;
// Replace the name with "[]=".
- call->name = pm_parser_constant_id_static(parser, "[]=", 3);
+ call->name = pm_parser_constant_id_constant(parser, "[]=", 3);
return target;
}
diff --git a/prism/templates/src/serialize.c.erb b/prism/templates/src/serialize.c.erb
index 9ee179af7f..489765928b 100644
--- a/prism/templates/src/serialize.c.erb
+++ b/prism/templates/src/serialize.c.erb
@@ -234,12 +234,12 @@ pm_serialize_content(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer)
pm_constant_t *constant = &parser->constant_pool.constants[bucket->id - 1];
size_t buffer_offset = offset + ((((size_t)bucket->id) - 1) * 8);
- if (bucket->owned) {
- // Since this is an owned constant, we are going to write its
- // contents into the buffer after the constant pool. So
- // effectively in place of the source offset, we have a buffer
- // offset. We will add a leading 1 to indicate that this is a
- // buffer offset.
+ if (bucket->owned || bucket->constant) {
+ // Since this is an owned or constant constant, we are going to
+ // write its contents into the buffer after the constant pool.
+ // So effectively in place of the source offset, we have a
+ // buffer offset. We will add a leading 1 to indicate that this
+ // is a buffer offset.
uint32_t content_offset = pm_sizet_to_u32(buffer->length);
uint32_t owned_mask = (uint32_t) (1 << 31);
diff --git a/prism/util/pm_constant_pool.c b/prism/util/pm_constant_pool.c
index d2c4f1e16c..ee4add3ce1 100644
--- a/prism/util/pm_constant_pool.c
+++ b/prism/util/pm_constant_pool.c
@@ -154,9 +154,16 @@ pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity) {
return true;
}
+// Return a pointer to the constant indicated by the given constant id.
+pm_constant_t *
+pm_constant_pool_id_to_constant(pm_constant_pool_t *pool, pm_constant_id_t constant_id) {
+ assert(constant_id > 0 && constant_id <= pool->size);
+ return &pool->constants[constant_id - 1];
+}
+
// Insert a constant into a constant pool and return its index in the pool.
static inline pm_constant_id_t
-pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t length, bool owned) {
+pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t length, bool owned, bool constant) {
if (pool->size >= (pool->capacity / 4 * 3)) {
if (!pm_constant_pool_resize(pool)) return 0;
}
@@ -202,15 +209,16 @@ pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t l
// IDs are allocated starting at 1, since the value 0 denotes a non-existant
// constant.
uint32_t id = ++pool->size;
- assert(pool->size < ((uint32_t) (1 << 31)));
+ assert(pool->size < ((uint32_t) (1 << 30)));
*bucket = (pm_constant_pool_bucket_t) {
- .id = (unsigned int) (id & 0x7FFFFFFF),
+ .id = (unsigned int) (id & 0x3fffffff),
.owned = owned,
+ .constant = constant,
.hash = hash
};
- pool->constants[id - 1] = (pm_constant_t) {
+ pool->constants[id - 1] = (pm_constant_t) {
.start = start,
.length = length,
};
@@ -222,7 +230,7 @@ pm_constant_pool_insert(pm_constant_pool_t *pool, const uint8_t *start, size_t l
// if any potential calls to resize fail.
pm_constant_id_t
pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
- return pm_constant_pool_insert(pool, start, length, false);
+ return pm_constant_pool_insert(pool, start, length, false, false);
}
// Insert a constant into a constant pool from memory that is now owned by the
@@ -230,7 +238,14 @@ pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const uint8_t *start, s
// resize fail.
pm_constant_id_t
pm_constant_pool_insert_owned(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
- return pm_constant_pool_insert(pool, start, length, true);
+ return pm_constant_pool_insert(pool, start, length, true, false);
+}
+
+// Insert a constant into a constant pool from memory that is constant. Returns
+// the id of the constant, or 0 if any potential calls to resize fail.
+pm_constant_id_t
+pm_constant_pool_insert_constant(pm_constant_pool_t *pool, const uint8_t *start, size_t length) {
+ return pm_constant_pool_insert(pool, start, length, false, true);
}
// Free the memory associated with a constant pool.
diff --git a/prism/util/pm_constant_pool.h b/prism/util/pm_constant_pool.h
index 3ea335ac52..ec4ede0dc4 100644
--- a/prism/util/pm_constant_pool.h
+++ b/prism/util/pm_constant_pool.h
@@ -40,8 +40,9 @@ size_t pm_constant_id_list_memsize(pm_constant_id_list_t *list);
void pm_constant_id_list_free(pm_constant_id_list_t *list);
typedef struct {
- unsigned int id: 31;
+ unsigned int id: 30;
bool owned: 1;
+ bool constant: 1;
uint32_t hash;
} pm_constant_pool_bucket_t;
@@ -63,10 +64,8 @@ typedef struct {
// Initialize a new constant pool with a given capacity.
bool pm_constant_pool_init(pm_constant_pool_t *pool, uint32_t capacity);
-static inline pm_constant_t* pm_constant_pool_id_to_constant(pm_constant_pool_t *pool, pm_constant_id_t constant_id) {
- assert(constant_id > 0 && constant_id <= pool->size);
- return &pool->constants[constant_id - 1];
-}
+// Return a pointer to the constant indicated by the given constant id.
+pm_constant_t * pm_constant_pool_id_to_constant(pm_constant_pool_t *pool, pm_constant_id_t constant_id);
// Insert a constant into a constant pool that is a slice of a source string.
// Returns the id of the constant, or 0 if any potential calls to resize fail.
@@ -77,6 +76,10 @@ pm_constant_id_t pm_constant_pool_insert_shared(pm_constant_pool_t *pool, const
// resize fail.
pm_constant_id_t pm_constant_pool_insert_owned(pm_constant_pool_t *pool, const uint8_t *start, size_t length);
+// Insert a constant into a constant pool from memory that is constant. Returns
+// the id of the constant, or 0 if any potential calls to resize fail.
+pm_constant_id_t pm_constant_pool_insert_constant(pm_constant_pool_t *pool, const uint8_t *start, size_t length);
+
// Free the memory associated with a constant pool.
void pm_constant_pool_free(pm_constant_pool_t *pool);