Skip to content

Commit

Permalink
[ruby/prism] Change pm_integer_t structure
Browse files Browse the repository at this point in the history
  • Loading branch information
tompng authored and kddnewton committed Mar 7, 2024
1 parent 5113d6b commit 81f02eb
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 206 deletions.
14 changes: 9 additions & 5 deletions prism/extension.c
Expand Up @@ -1047,12 +1047,16 @@ integer_parse(VALUE self, VALUE source) {
pm_integer_t integer = { 0 };
pm_integer_parse(&integer, PM_INTEGER_BASE_UNKNOWN, start, start + length);

VALUE number = UINT2NUM(integer.head.value);
size_t shift = 0;
VALUE number;

for (pm_integer_word_t *node = integer.head.next; node != NULL; node = node->next) {
VALUE receiver = rb_funcall(UINT2NUM(node->value), rb_intern("<<"), 1, ULONG2NUM(++shift * 32));
number = rb_funcall(receiver, rb_intern("|"), 1, number);
if (integer.values == NULL) {
number = UINT2NUM(integer.value);
} else {
number = UINT2NUM(0);
for (size_t i = 0; i < integer.length; i++) {
VALUE receiver = rb_funcall(UINT2NUM(integer.values[i]), rb_intern("<<"), 1, ULONG2NUM(i * 32));
number = rb_funcall(receiver, rb_intern("|"), 1, number);
}
}

if (integer.negative) number = rb_funcall(number, rb_intern("-@"), 0);
Expand Down
15 changes: 7 additions & 8 deletions prism/static_literals.c
Expand Up @@ -53,12 +53,11 @@ node_hash(const pm_parser_t *parser, const pm_node_t *node) {
case PM_INTEGER_NODE: {
// Integers hash their value.
const pm_integer_t *integer = &((const pm_integer_node_t *) node)->value;
const uint32_t *value = &integer->head.value;

uint32_t hash = murmur_hash((const uint8_t *) value, sizeof(uint32_t));
for (const pm_integer_word_t *word = integer->head.next; word != NULL; word = word->next) {
value = &word->value;
hash ^= murmur_hash((const uint8_t *) value, sizeof(uint32_t));
uint32_t hash;
if (integer->values) {
hash = murmur_hash((const uint8_t *) integer->values, sizeof(uint32_t) * integer->length);
} else {
hash = murmur_hash((const uint8_t *) &integer->value, sizeof(uint32_t));
}

if (integer->negative) {
Expand Down Expand Up @@ -204,9 +203,9 @@ pm_int64_value(const pm_parser_t *parser, const pm_node_t *node) {
switch (PM_NODE_TYPE(node)) {
case PM_INTEGER_NODE: {
const pm_integer_t *integer = &((const pm_integer_node_t *) node)->value;
if (integer->length > 0) return integer->negative ? INT64_MIN : INT64_MAX;
if (integer->values) return integer->negative ? INT64_MIN : INT64_MAX;

int64_t value = (int64_t) integer->head.value;
int64_t value = (int64_t) integer->value;
return integer->negative ? -value : value;
}
case PM_SOURCE_LINE_NODE:
Expand Down
14 changes: 7 additions & 7 deletions prism/templates/ext/prism/api_node.c.erb
Expand Up @@ -40,20 +40,20 @@ pm_string_new(const pm_string_t *string, rb_encoding *encoding) {
static VALUE
pm_integer_new(const pm_integer_t *integer) {
VALUE result;
if (integer->head.next) {
size_t length = integer->length + 1;
VALUE str = rb_str_new(NULL, length * 8);
if (integer->values) {
VALUE str = rb_str_new(NULL, integer->length * 8);
unsigned char *buf = (unsigned char *)RSTRING_PTR(str);
size_t offset = length * 8;
for (const pm_integer_word_t *node = &integer->head; node != NULL; node = node->next) {
size_t offset = integer->length * 8;
for (size_t i = 0; i < integer->length; i++) {
uint32_t value = integer->values[i];
for (int i = 0; i < 8; i++) {
int n = (node->value >> (4 * i)) & 0xf;
int n = (value >> (4 * i)) & 0xf;
buf[--offset] = n < 10 ? n + '0' : n - 10 + 'a';
}
}
result = rb_funcall(str, rb_intern("to_i"), 1, UINT2NUM(16));
} else {
result = UINT2NUM(integer->head.value);
result = UINT2NUM(integer->value);
}

if (integer->negative) {
Expand Down
12 changes: 8 additions & 4 deletions prism/templates/src/serialize.c.erb
Expand Up @@ -52,10 +52,14 @@ pm_serialize_string(const pm_parser_t *parser, const pm_string_t *string, pm_buf
static void
pm_serialize_integer(const pm_integer_t *integer, pm_buffer_t *buffer) {
pm_buffer_append_byte(buffer, integer->negative ? 1 : 0);
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(integer->length + 1));

for (const pm_integer_word_t *node = &integer->head; node != NULL; node = node->next) {
pm_buffer_append_varuint(buffer, node->value);
if (integer->values == NULL) {
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(1));
pm_buffer_append_varuint(buffer, integer->value);
} else {
pm_buffer_append_varuint(buffer, pm_sizet_to_u32(integer->length));
for (size_t i = 0; i < integer->length; i++) {
pm_buffer_append_varuint(buffer, integer->values[i]);
}
}
}

Expand Down

0 comments on commit 81f02eb

Please sign in to comment.