Skip to content

Commit 5749eb3

Browse files
committed
Imported Upstream version 2.4.2
1 parent a32e3ec commit 5749eb3

File tree

174 files changed

+3275
-906
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

174 files changed

+3275
-906
lines changed

array.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,8 +1775,8 @@ rb_ary_insert(int argc, VALUE *argv, VALUE ary)
17751775

17761776
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
17771777
rb_ary_modify_check(ary);
1778-
if (argc == 1) return ary;
17791778
pos = NUM2LONG(argv[0]);
1779+
if (argc == 1) return ary;
17801780
if (pos == -1) {
17811781
pos = RARRAY_LEN(ary);
17821782
}
@@ -5883,7 +5883,8 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary)
58835883
* This method is safe to use with mutable objects such as hashes, strings or
58845884
* other arrays:
58855885
*
5886-
* Array.new(4) { Hash.new } #=> [{}, {}, {}, {}]
5886+
* Array.new(4) { Hash.new } #=> [{}, {}, {}, {}]
5887+
* Array.new(4) {|i| i.to_s } #=> ["0", "1", "2", "3"]
58875888
*
58885889
* This is also a quick way to build up multi-dimensional arrays:
58895890
*

class.c

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -849,14 +849,23 @@ rb_include_class_new(VALUE module, VALUE super)
849849

850850
static int include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super);
851851

852+
static void
853+
ensure_includable(VALUE klass, VALUE module)
854+
{
855+
rb_frozen_class_p(klass);
856+
Check_Type(module, T_MODULE);
857+
if (!NIL_P(rb_refinement_module_get_refined_class(module))) {
858+
rb_raise(rb_eArgError, "refinement module is not allowed");
859+
}
860+
OBJ_INFECT(klass, module);
861+
}
862+
852863
void
853864
rb_include_module(VALUE klass, VALUE module)
854865
{
855866
int changed = 0;
856867

857-
rb_frozen_class_p(klass);
858-
Check_Type(module, T_MODULE);
859-
OBJ_INFECT(klass, module);
868+
ensure_includable(klass, module);
860869

861870
changed = include_modules_at(klass, RCLASS_ORIGIN(klass), module, TRUE);
862871
if (changed < 0)
@@ -966,9 +975,7 @@ rb_prepend_module(VALUE klass, VALUE module)
966975
VALUE origin;
967976
int changed = 0;
968977

969-
rb_frozen_class_p(klass);
970-
Check_Type(module, T_MODULE);
971-
OBJ_INFECT(klass, module);
978+
ensure_includable(klass, module);
972979

973980
origin = RCLASS_ORIGIN(klass);
974981
if (origin == klass) {
@@ -1917,8 +1924,8 @@ rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
19171924
va_list vargs;
19181925
int f_var = 0, f_hash = 0, f_block = 0;
19191926
int n_lead = 0, n_opt = 0, n_trail = 0, n_mand;
1920-
int argi = 0;
1921-
VALUE hash = Qnil;
1927+
int argi = 0, last_idx = -1;
1928+
VALUE hash = Qnil, last_hash = 0;
19221929

19231930
if (ISDIGIT(*p)) {
19241931
n_lead = *p - '0';
@@ -1969,22 +1976,23 @@ rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
19691976
hash = rb_check_hash_type(last);
19701977
if (!NIL_P(hash)) {
19711978
VALUE opts = rb_extract_keywords(&hash);
1972-
if (!hash) argc--;
1979+
if (!(last_hash = hash)) argc--;
1980+
else last_idx = argc - 1;
19731981
hash = opts ? opts : Qnil;
19741982
}
19751983
}
19761984
}
19771985
/* capture leading mandatory arguments */
19781986
for (i = n_lead; i-- > 0; ) {
19791987
var = va_arg(vargs, VALUE *);
1980-
if (var) *var = argv[argi];
1988+
if (var) *var = (argi == last_idx) ? last_hash : argv[argi];
19811989
argi++;
19821990
}
19831991
/* capture optional arguments */
19841992
for (i = n_opt; i-- > 0; ) {
19851993
var = va_arg(vargs, VALUE *);
19861994
if (argi < argc - n_trail) {
1987-
if (var) *var = argv[argi];
1995+
if (var) *var = (argi == last_idx) ? last_hash : argv[argi];
19881996
argi++;
19891997
}
19901998
else {
@@ -1997,7 +2005,11 @@ rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
19972005

19982006
var = va_arg(vargs, VALUE *);
19992007
if (0 < n_var) {
2000-
if (var) *var = rb_ary_new4(n_var, &argv[argi]);
2008+
if (var) {
2009+
int f_last = (last_idx + 1 == argc - n_trail);
2010+
*var = rb_ary_new4(n_var-f_last, &argv[argi]);
2011+
if (f_last) rb_ary_push(*var, last_hash);
2012+
}
20012013
argi += n_var;
20022014
}
20032015
else {
@@ -2007,7 +2019,7 @@ rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...)
20072019
/* capture trailing mandatory arguments */
20082020
for (i = n_trail; i-- > 0; ) {
20092021
var = va_arg(vargs, VALUE *);
2010-
if (var) *var = argv[argi];
2022+
if (var) *var = (argi == last_idx) ? last_hash : argv[argi];
20112023
argi++;
20122024
}
20132025
/* capture an option hash - phase 2: assignment */

compile.c

Lines changed: 56 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
#undef RUBY_UNTYPED_DATA_WARNING
3030
#define RUBY_UNTYPED_DATA_WARNING 0
3131

32+
#define ISEQ_TYPE_ONCE_GUARD ISEQ_TYPE_DEFINED_GUARD
33+
3234
#define FIXNUM_INC(n, i) ((n)+(INT2FIX(i)&~FIXNUM_FLAG))
3335
#define FIXNUM_OR(n, i) ((n)|INT2FIX(i))
3436

@@ -64,6 +66,7 @@ typedef struct iseq_label_data {
6466
int refcnt;
6567
unsigned int set: 1;
6668
unsigned int rescued: 2;
69+
unsigned int unremovable: 1;
6770
} LABEL;
6871

6972
typedef struct iseq_insn_data {
@@ -288,13 +291,15 @@ r_value(VALUE value)
288291
#define ADD_ADJUST_RESTORE(seq, label) \
289292
ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), -1))
290293

294+
#define LABEL_UNREMOVABLE(label) \
295+
((label) ? (LABEL_REF(label), (label)->unremovable=1) : 0)
291296
#define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc) do { \
292297
VALUE _e = rb_ary_new3(5, (type), \
293298
(VALUE)(ls) | 1, (VALUE)(le) | 1, \
294299
(VALUE)(iseqv), (VALUE)(lc) | 1); \
295-
if (ls) LABEL_REF(ls); \
296-
if (le) LABEL_REF(le); \
297-
if (lc) LABEL_REF(lc); \
300+
LABEL_UNREMOVABLE(ls); \
301+
LABEL_UNREMOVABLE(le); \
302+
LABEL_UNREMOVABLE(lc); \
298303
rb_ary_push(ISEQ_COMPILE_DATA(iseq)->catch_table_ary, freeze_hide_obj(_e)); \
299304
} while (0)
300305

@@ -1032,7 +1037,7 @@ new_adjust_body(rb_iseq_t *iseq, LABEL *label, int line)
10321037
adjust->link.next = 0;
10331038
adjust->label = label;
10341039
adjust->line_no = line;
1035-
if (label) LABEL_REF(label);
1040+
LABEL_UNREMOVABLE(label);
10361041
return adjust;
10371042
}
10381043

@@ -2013,8 +2018,29 @@ replace_destination(INSN *dobj, INSN *nobj)
20132018
static int
20142019
remove_unreachable_chunk(rb_iseq_t *iseq, LINK_ELEMENT *i)
20152020
{
2016-
int removed = 0;
2021+
LINK_ELEMENT *first = i, *end;
2022+
2023+
if (!i) return 0;
20172024
while (i) {
2025+
if (IS_INSN(i)) {
2026+
if (IS_INSN_ID(i, jump) || IS_INSN_ID(i, leave)) {
2027+
break;
2028+
}
2029+
}
2030+
else if (IS_LABEL(i)) {
2031+
if (((LABEL *)i)->unremovable) return 0;
2032+
if (((LABEL *)i)->refcnt > 0) {
2033+
if (i == first) return 0;
2034+
i = i->prev;
2035+
break;
2036+
}
2037+
}
2038+
else return 0;
2039+
i = i->next;
2040+
}
2041+
end = i;
2042+
i = first;
2043+
do {
20182044
if (IS_INSN(i)) {
20192045
struct rb_iseq_constant_body *body = iseq->body;
20202046
VALUE insn = INSN_OF(i);
@@ -2033,15 +2059,9 @@ remove_unreachable_chunk(rb_iseq_t *iseq, LINK_ELEMENT *i)
20332059
}
20342060
}
20352061
}
2036-
else if (IS_LABEL(i)) {
2037-
if (((LABEL *)i)->refcnt > 0) break;
2038-
}
2039-
else break;
20402062
REMOVE_ELEM(i);
2041-
removed = 1;
2042-
i = i->next;
2043-
}
2044-
return removed;
2063+
} while ((i != end) && (i = i->next) != 0);
2064+
return 1;
20452065
}
20462066

20472067
static int
@@ -2216,7 +2236,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
22162236
OPERAND_AT(pobj, 0) == Qfalse :
22172237
FALSE);
22182238
}
2219-
else if (IS_INSN_ID(pobj, putstring)) {
2239+
else if (IS_INSN_ID(pobj, putstring) || IS_INSN_ID(pobj, duparray)) {
22202240
cond = IS_INSN_ID(iobj, branchif);
22212241
}
22222242
else if (IS_INSN_ID(pobj, putnil)) {
@@ -2874,18 +2894,8 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *cond,
28742894
case NODE_LIT: /* NODE_LIT is always not true */
28752895
case NODE_TRUE:
28762896
case NODE_STR:
2877-
case NODE_DSTR:
2878-
case NODE_XSTR:
2879-
case NODE_DXSTR:
2880-
case NODE_DREGX:
2881-
case NODE_DREGX_ONCE:
2882-
case NODE_DSYM:
2883-
case NODE_ARRAY:
28842897
case NODE_ZARRAY:
2885-
case NODE_HASH:
28862898
case NODE_LAMBDA:
2887-
case NODE_DEFN:
2888-
case NODE_DEFS:
28892899
/* printf("useless condition eliminate (%s)\n", ruby_node_name(nd_type(cond))); */
28902900
ADD_INSNL(ret, nd_line(cond), jump, then_label);
28912901
break;
@@ -4655,22 +4665,23 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int poppe
46554665
CHECK(COMPILE_POPPED(ensr, "ensure ensr", node->nd_ensr));
46564666
last = ensr->last;
46574667
last_leave = last && IS_INSN(last) && IS_INSN_ID(last, leave);
4658-
if (!popped && last_leave)
4659-
popped = 1;
46604668

46614669
er.begin = lstart;
46624670
er.end = lend;
46634671
er.next = 0;
46644672
push_ensure_entry(iseq, &enl, &er, node->nd_ensr);
46654673

46664674
ADD_LABEL(ret, lstart);
4667-
CHECK(COMPILE_(ret, "ensure head", node->nd_head, popped));
4675+
CHECK(COMPILE_(ret, "ensure head", node->nd_head, (popped | last_leave)));
46684676
ADD_LABEL(ret, lend);
46694677
if (ensr->anchor.next == 0) {
46704678
ADD_INSN(ret, line, nop);
46714679
}
46724680
else {
46734681
ADD_SEQ(ret, ensr);
4682+
if (!popped && last_leave) {
4683+
ADD_INSN(ret, line, putnil);
4684+
}
46744685
}
46754686
ADD_LABEL(ret, lcont);
46764687
if (last_leave) ADD_INSN(ret, line, pop);
@@ -5484,13 +5495,25 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int poppe
54845495
if (is) {
54855496
enum iseq_type type = is->body->type;
54865497
const rb_iseq_t *parent_iseq = is->body->parent_iseq;
5487-
enum iseq_type parent_type = parent_iseq ? parent_iseq->body->type : type;
5498+
enum iseq_type parent_type;
54885499

5489-
if (type == ISEQ_TYPE_TOP || type == ISEQ_TYPE_MAIN ||
5490-
((type == ISEQ_TYPE_RESCUE || type == ISEQ_TYPE_ENSURE) &&
5491-
(parent_type == ISEQ_TYPE_TOP || parent_type == ISEQ_TYPE_MAIN))) {
5500+
if (type == ISEQ_TYPE_TOP) {
5501+
LABEL *splabel = NEW_LABEL(line);
5502+
ADD_LABEL(ret, splabel);
5503+
ADD_ADJUST(ret, line, 0);
54925504
ADD_INSN(ret, line, putnil);
54935505
ADD_INSN(ret, line, leave);
5506+
ADD_ADJUST_RESTORE(ret, splabel);
5507+
}
5508+
else if ((type == ISEQ_TYPE_RESCUE || type == ISEQ_TYPE_ENSURE || type == ISEQ_TYPE_MAIN) &&
5509+
parent_iseq &&
5510+
((parent_type = parent_iseq->body->type) == ISEQ_TYPE_TOP ||
5511+
parent_type == ISEQ_TYPE_MAIN)) {
5512+
ADD_INSN(ret, line, putnil);
5513+
ADD_INSN1(ret, line, throw, INT2FIX(TAG_RETURN));
5514+
if (popped) {
5515+
ADD_INSN(ret, line, pop);
5516+
}
54945517
}
54955518
else {
54965519
LABEL *splabel = 0;
@@ -5782,7 +5805,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int poppe
57825805
int ic_index = iseq->body->is_size++;
57835806
NODE *dregx_node = NEW_NODE(NODE_DREGX, node->u1.value, node->u2.value, node->u3.value);
57845807
NODE *block_node = NEW_NODE(NODE_SCOPE, 0, dregx_node, 0);
5785-
const rb_iseq_t * block_iseq = NEW_CHILD_ISEQ(block_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
5808+
const rb_iseq_t *block_iseq = NEW_CHILD_ISEQ(block_node, make_name_for_block(iseq),
5809+
ISEQ_TYPE_ONCE_GUARD, line);
57865810

57875811
ADD_INSN2(ret, line, once, block_iseq, INT2FIX(ic_index));
57885812

0 commit comments

Comments
 (0)