Created
July 24, 2021 09:52
-
-
Save wanabe/2c7c0606f3bd45e06adbe87bd31f311b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/compile.c b/compile.c | |
index 1cabb8cccd..9e3a1111dc 100644 | |
--- a/compile.c | |
+++ b/compile.c | |
@@ -6562,7 +6562,7 @@ iseq_compile_array_deconstruct(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NO | |
ADD_INSNL(ret, line, branchunless, match_failed); | |
- ADD_SEND(ret, line, rb_intern("deconstruct"), INT2FIX(0)); | |
+ ADD_INSN(ret, line, deconstruct); | |
// Cache the result (if it's cacheable - currently, only top-level array patterns) | |
if (deconstructed_pos) { | |
diff --git a/defs/id.def b/defs/id.def | |
index fc7a04ffbc..41cc51adb7 100644 | |
--- a/defs/id.def | |
+++ b/defs/id.def | |
@@ -56,6 +56,7 @@ firstline, predefined = __LINE__+1, %[\ | |
quo | |
name | |
nil | |
+ deconstruct | |
_ UScore | |
diff --git a/insns.def b/insns.def | |
index 8d609927b5..e42048dd2a 100644 | |
--- a/insns.def | |
+++ b/insns.def | |
@@ -1422,6 +1422,16 @@ opt_regexpmatch2 | |
} | |
} | |
+/* deconstruct */ | |
+DEFINE_INSN | |
+deconstruct | |
+() | |
+(VALUE recv) | |
+(VALUE val) | |
+{ | |
+ val = vm_deconstruct(recv); | |
+} | |
+ | |
/* call native compiled method */ | |
DEFINE_INSN_IF(SUPPORT_CALL_C_FUNCTION) | |
opt_call_c_function | |
diff --git a/vm.c b/vm.c | |
index 8c62d7dd91..5a7144ee69 100644 | |
--- a/vm.c | |
+++ b/vm.c | |
@@ -1927,6 +1927,7 @@ vm_init_redefined_flag(void) | |
OP(And, AND), (C(Integer)); | |
OP(Or, OR), (C(Integer)); | |
OP(NilP, NIL_P), (C(NilClass)); | |
+ OP(Deconstruct, DECONSTRUCT), (C(Array)); | |
#undef C | |
#undef OP | |
} | |
diff --git a/vm_core.h b/vm_core.h | |
index f21d85032c..c051fa7e5c 100644 | |
--- a/vm_core.h | |
+++ b/vm_core.h | |
@@ -538,6 +538,7 @@ enum ruby_basic_operators { | |
BOP_CALL, | |
BOP_AND, | |
BOP_OR, | |
+ BOP_DECONSTRUCT, | |
BOP_LAST_ | |
}; | |
diff --git a/vm_insnhelper.c b/vm_insnhelper.c | |
index 840bd490b6..08000bf7ff 100644 | |
--- a/vm_insnhelper.c | |
+++ b/vm_insnhelper.c | |
@@ -5250,6 +5250,14 @@ vm_opt_regexpmatch2(VALUE recv, VALUE obj) | |
} | |
} | |
+static VALUE | |
+vm_deconstruct(VALUE recv) { | |
+ if (RBASIC_CLASS(recv) == rb_cArray && BASIC_OP_UNREDEFINED_P(BOP_DECONSTRUCT, ARRAY_REDEFINED_OP_FLAG)) { | |
+ return recv; | |
+ } | |
+ return rb_funcall(recv, rb_intern("deconstruct"), 0); | |
+} | |
+ | |
rb_event_flag_t rb_iseq_event_flags(const rb_iseq_t *iseq, size_t pos); | |
NOINLINE(static void vm_trace(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/compile.c b/compile.c | |
index 1cabb8cccd..38bc3fb2a9 100644 | |
--- a/compile.c | |
+++ b/compile.c | |
@@ -6304,14 +6304,10 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c | |
ADD_SEND(ret, line, idRespond_to, INT2FIX(1)); | |
ADD_INSNL(ret, line, branchunless, match_failed); | |
- if (NIL_P(keys)) { | |
- ADD_INSN(ret, line, putnil); | |
- } | |
- else { | |
- ADD_INSN1(ret, line, duparray, keys); | |
+ if (!NIL_P(keys)) { | |
RB_OBJ_WRITTEN(iseq, Qundef, rb_obj_hide(keys)); | |
} | |
- ADD_SEND(ret, line, rb_intern("deconstruct_keys"), INT2FIX(1)); | |
+ ADD_INSN1(ret, line, deconstruct_keys, keys); | |
ADD_INSN(ret, line, dup); | |
ADD_INSN1(ret, line, checktype, INT2FIX(T_HASH)); | |
diff --git a/defs/id.def b/defs/id.def | |
index fc7a04ffbc..83fd2f316e 100644 | |
--- a/defs/id.def | |
+++ b/defs/id.def | |
@@ -56,6 +56,7 @@ firstline, predefined = __LINE__+1, %[\ | |
quo | |
name | |
nil | |
+ deconstruct_keys | |
_ UScore | |
diff --git a/insns.def b/insns.def | |
index 8d609927b5..ab4d5aeb98 100644 | |
--- a/insns.def | |
+++ b/insns.def | |
@@ -1422,6 +1422,16 @@ opt_regexpmatch2 | |
} | |
} | |
+/* deconstruct_keys */ | |
+DEFINE_INSN | |
+deconstruct_keys | |
+(VALUE keys) | |
+(VALUE recv) | |
+(VALUE val) | |
+{ | |
+ val = vm_deconstruct_keys(recv, keys); | |
+} | |
+ | |
/* call native compiled method */ | |
DEFINE_INSN_IF(SUPPORT_CALL_C_FUNCTION) | |
opt_call_c_function | |
diff --git a/vm.c b/vm.c | |
index 8c62d7dd91..517b4e55ef 100644 | |
--- a/vm.c | |
+++ b/vm.c | |
@@ -1927,6 +1927,7 @@ vm_init_redefined_flag(void) | |
OP(And, AND), (C(Integer)); | |
OP(Or, OR), (C(Integer)); | |
OP(NilP, NIL_P), (C(NilClass)); | |
+ OP(Deconstruct_keys, DECONSTRUCT_KEYS), (C(Hash)); | |
#undef C | |
#undef OP | |
} | |
diff --git a/vm_core.h b/vm_core.h | |
index f21d85032c..471d6581ed 100644 | |
--- a/vm_core.h | |
+++ b/vm_core.h | |
@@ -538,6 +538,7 @@ enum ruby_basic_operators { | |
BOP_CALL, | |
BOP_AND, | |
BOP_OR, | |
+ BOP_DECONSTRUCT_KEYS, | |
BOP_LAST_ | |
}; | |
diff --git a/vm_insnhelper.c b/vm_insnhelper.c | |
index 840bd490b6..d24386dd27 100644 | |
--- a/vm_insnhelper.c | |
+++ b/vm_insnhelper.c | |
@@ -5250,6 +5250,17 @@ vm_opt_regexpmatch2(VALUE recv, VALUE obj) | |
} | |
} | |
+static VALUE | |
+vm_deconstruct_keys(VALUE recv, VALUE keys) { | |
+ if (RBASIC_CLASS(recv) == rb_cHash && BASIC_OP_UNREDEFINED_P(BOP_DECONSTRUCT_KEYS, HASH_REDEFINED_OP_FLAG)) { | |
+ return recv; | |
+ } | |
+ if (RB_BUILTIN_TYPE(keys) == T_ARRAY) { | |
+ keys = rb_ary_resurrect(keys); | |
+ } | |
+ return rb_funcallv(recv, rb_intern("deconstruct_keys"), 1, &keys); | |
+} | |
+ | |
rb_event_flag_t rb_iseq_event_flags(const rb_iseq_t *iseq, size_t pos); | |
NOINLINE(static void vm_trace(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment