ruby-changes:57665
From: Yusuke <ko1@a...>
Date: Sun, 8 Sep 2019 03:17:19 +0900 (JST)
Subject: [ruby-changes:57665] 46bfe907f1 (master): compile.c (compile_hash): rewrite keyword splat handling
https://git.ruby-lang.org/ruby.git/commit/?id=46bfe907f1 From 46bfe907f1d61217215bcd1a7da9dff258c63294 Mon Sep 17 00:00:00 2001 From: Yusuke Endoh <mame@r...> Date: Sun, 8 Sep 2019 03:06:38 +0900 Subject: compile.c (compile_hash): rewrite keyword splat handling and add some comments. (I confirm that `foo(**{})` allocates no hash object.) diff --git a/compile.c b/compile.c index 988493f..ade5806 100644 --- a/compile.c +++ b/compile.c @@ -4191,20 +4191,32 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popp https://github.com/ruby/ruby/blob/trunk/compile.c#L4191 int last_kw = !node->nd_next->nd_next; /* foo( ..., **kw) */ int only_kw = last_kw && first_kw; /* foo(1,2,3, **kw) */ - if (!empty_kw) { - ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); - if (!first_kw) ADD_INSN(ret, line, swap); - else ADD_INSN1(ret, line, newhash, INT2FIX(0)); + if (empty_kw) { + if (only_kw) { + /* **{} appears at the last, so it won't be modified. + * kw is a special NODE_LIT that contains a special empty hash, + * so this emits: putobject {} + */ + NO_CHECK(COMPILE(ret, "keyword splat", kw)); + } + else if (first_kw) { + /* **{} appears at the first, so it may be modified. + * We need to create a fresh hash object. + */ + ADD_INSN1(ret, line, newhash, INT2FIX(0)); + } } + else { + /* This is not empty hash: **{k:1}. + * We need to clone the hash (if first), or merge the hash to + * the accumulated hash (if not first). + */ + ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); + if (first_kw) ADD_INSN1(ret, line, newhash, INT2FIX(0)); + else ADD_INSN(ret, line, swap); - if (empty_kw && first_kw && !only_kw) { - ADD_INSN1(ret, line, newhash, INT2FIX(0)); - } - else if (!empty_kw || only_kw) { NO_CHECK(COMPILE(ret, "keyword splat", kw)); - } - if (!empty_kw) { ADD_SEND(ret, line, id_core_hash_merge_kwd, INT2FIX(2)); } -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/