summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortompng <tomoyapenguin@gmail.com>2024-02-25 00:35:06 +0900
committerKevin Newton <kddnewton@gmail.com>2024-03-07 18:02:33 -0500
commit05526a444c28c4efcf6d846d13da17d990848abd (patch)
treedbf387d984a699bc38a9a43c274f599ba3e92ae8
parent977012bae8100524a691f5850a462728b20e219d (diff)
[ruby/prism] Make pm_integer -> Integer faster
https://github.com/ruby/prism/commit/47601e7928
-rw-r--r--prism/templates/ext/prism/api_node.c.erb21
1 files changed, 15 insertions, 6 deletions
diff --git a/prism/templates/ext/prism/api_node.c.erb b/prism/templates/ext/prism/api_node.c.erb
index 301479b3c5..7b3e685a70 100644
--- a/prism/templates/ext/prism/api_node.c.erb
+++ b/prism/templates/ext/prism/api_node.c.erb
@@ -39,12 +39,21 @@ pm_string_new(const pm_string_t *string, rb_encoding *encoding) {
static VALUE
pm_integer_new(const pm_integer_t *integer) {
- VALUE result = UINT2NUM(integer->head.value);
- size_t shift = 0;
-
- for (const 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));
- result = rb_funcall(receiver, rb_intern("|"), 1, result);
+ VALUE result;
+ if (integer->head.next) {
+ size_t length = integer->length + 1;
+ VALUE str = rb_str_new(NULL, 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) {
+ for (int i = 0; i < 8; i++) {
+ int n = (node->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);
}
if (integer->negative) {