diff options
| author | tompng <tomoyapenguin@gmail.com> | 2024-02-25 00:35:06 +0900 |
|---|---|---|
| committer | Kevin Newton <kddnewton@gmail.com> | 2024-03-07 18:02:33 -0500 |
| commit | 05526a444c28c4efcf6d846d13da17d990848abd (patch) | |
| tree | dbf387d984a699bc38a9a43c274f599ba3e92ae8 | |
| parent | 977012bae8100524a691f5850a462728b20e219d (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.erb | 21 |
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) { |
