Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Note: We're only listing outstanding class updates.

* IO

* `IO.select` accepts +Float::INFINITY+ as a timeout argument.
* `IO.select` accepts `Float::INFINITY` as a timeout argument.
[[Feature #20610]]

* Math
Expand Down
2 changes: 1 addition & 1 deletion dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -1480,7 +1480,7 @@ rb_dir_getwd_ospath(void)
VALUE cwd;
VALUE path_guard;

path_guard = rb_imemo_tmpbuf_auto_free_pointer();
path_guard = rb_imemo_tmpbuf_new();
path = ruby_getcwd();
rb_imemo_tmpbuf_set_ptr(path_guard, path);
#ifdef __APPLE__
Expand Down
16 changes: 8 additions & 8 deletions imemo.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,23 @@ rb_imemo_new(enum imemo_type type, VALUE v0, size_t size)
return (VALUE)obj;
}

static rb_imemo_tmpbuf_t *
VALUE
rb_imemo_tmpbuf_new(void)
{
return IMEMO_NEW(rb_imemo_tmpbuf_t, imemo_tmpbuf, 0);
VALUE flags = T_IMEMO | (imemo_tmpbuf << FL_USHIFT);
NEWOBJ_OF(obj, rb_imemo_tmpbuf_t, 0, flags, sizeof(rb_imemo_tmpbuf_t), NULL);

return (VALUE)obj;
}

void *
rb_alloc_tmp_buffer_with_count(volatile VALUE *store, size_t size, size_t cnt)
{
void *ptr;
rb_imemo_tmpbuf_t *tmpbuf;

/* Keep the order; allocate an empty imemo first then xmalloc, to
* get rid of potential memory leak */
tmpbuf = rb_imemo_tmpbuf_new();
rb_imemo_tmpbuf_t *tmpbuf = (rb_imemo_tmpbuf_t *)rb_imemo_tmpbuf_new();
*store = (VALUE)tmpbuf;
ptr = ruby_xmalloc(size);
void *ptr = ruby_xmalloc(size);
tmpbuf->ptr = ptr;
tmpbuf->cnt = cnt;

Expand Down Expand Up @@ -97,7 +97,7 @@ rb_free_tmp_buffer(volatile VALUE *store)
rb_imemo_tmpbuf_t *
rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt)
{
rb_imemo_tmpbuf_t *tmpbuf = rb_imemo_tmpbuf_new();
rb_imemo_tmpbuf_t *tmpbuf = (rb_imemo_tmpbuf_t *)rb_imemo_tmpbuf_new();
tmpbuf->ptr = buf;
tmpbuf->next = old_heap;
tmpbuf->cnt = cnt;
Expand Down
13 changes: 3 additions & 10 deletions internal/imemo.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,15 @@ struct MEMO {
#ifndef RUBY_RUBYPARSER_H
typedef struct rb_imemo_tmpbuf_struct rb_imemo_tmpbuf_t;
#endif
VALUE rb_imemo_tmpbuf_new(void);
rb_imemo_tmpbuf_t *rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
struct vm_ifunc *rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc);
static inline enum imemo_type imemo_type(VALUE imemo);
static inline int imemo_type_p(VALUE imemo, enum imemo_type imemo_type);
static inline bool imemo_throw_data_p(VALUE imemo);
static inline struct vm_ifunc *rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data);
static inline VALUE rb_imemo_tmpbuf_auto_free_pointer(void);
static inline void *RB_IMEMO_TMPBUF_PTR(VALUE v);
static inline void *rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr);
static inline VALUE rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str);
static inline void MEMO_V1_SET(struct MEMO *m, VALUE v);
static inline void MEMO_V2_SET(struct MEMO *m, VALUE v);

Expand Down Expand Up @@ -200,12 +199,6 @@ rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data)
return rb_vm_ifunc_new(func, data, 0, UNLIMITED_ARGUMENTS);
}

static inline VALUE
rb_imemo_tmpbuf_auto_free_pointer(void)
{
return rb_imemo_new(imemo_tmpbuf, 0, sizeof(rb_imemo_tmpbuf_t));
}

static inline void *
RB_IMEMO_TMPBUF_PTR(VALUE v)
{
Expand All @@ -220,7 +213,7 @@ rb_imemo_tmpbuf_set_ptr(VALUE v, void *ptr)
}

static inline VALUE
rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)
rb_imemo_tmpbuf_new_from_an_RString(VALUE str)
{
const void *src;
VALUE imemo;
Expand All @@ -230,7 +223,7 @@ rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)

StringValue(str);
/* create tmpbuf to keep the pointer before xmalloc */
imemo = rb_imemo_tmpbuf_auto_free_pointer();
imemo = rb_imemo_tmpbuf_new();
tmpbuf = (rb_imemo_tmpbuf_t *)imemo;
len = RSTRING_LEN(str);
src = RSTRING_PTR(str);
Expand Down
22 changes: 13 additions & 9 deletions lib/optparse.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1855,7 +1855,7 @@ def permute(*argv, **keywords)
#
def permute!(argv = default_argv, **keywords)
nonopts = []
order!(argv, **keywords, &nonopts.method(:<<))
order!(argv, **keywords) {|nonopt| nonopts << nonopt}
argv[0, 0] = nonopts
argv
end
Expand Down Expand Up @@ -1908,13 +1908,16 @@ def getopts(*args, symbolize_names: false, **keywords)
single_options, *long_options = *args

result = {}
setter = (symbolize_names ?
->(name, val) {result[name.to_sym] = val}
: ->(name, val) {result[name] = val})

single_options.scan(/(.)(:)?/) do |opt, val|
if val
result[opt] = nil
setter[opt, nil]
define("-#{opt} VAL")
else
result[opt] = false
setter[opt, false]
define("-#{opt}")
end
end if single_options
Expand All @@ -1923,16 +1926,16 @@ def getopts(*args, symbolize_names: false, **keywords)
arg, desc = arg.split(';', 2)
opt, val = arg.split(':', 2)
if val
result[opt] = val.empty? ? nil : val
setter[opt, (val unless val.empty?)]
define("--#{opt}=#{result[opt] || "VAL"}", *[desc].compact)
else
result[opt] = false
setter[opt, false]
define("--#{opt}", *[desc].compact)
end
end

parse_in_order(argv, result.method(:[]=), **keywords)
symbolize_names ? result.transform_keys(&:to_sym) : result
parse_in_order(argv, setter, **keywords)
result
end

#
Expand Down Expand Up @@ -1982,7 +1985,7 @@ def complete(typ, opt, icase = false, *pat) # :nodoc:
visit(:complete, typ, opt, icase, *pat) {|o, *sw| return sw}
}
exc = ambiguous ? AmbiguousOption : InvalidOption
raise exc.new(opt, additional: self.method(:additional_message).curry[typ])
raise exc.new(opt, additional: proc {|o| additional_message(typ, o)})
end
private :complete

Expand Down Expand Up @@ -2273,9 +2276,10 @@ def recover(argv)
argv
end

DIR = File.join(__dir__, '')
def self.filter_backtrace(array)
unless $DEBUG
array.delete_if(&%r"\A#{Regexp.quote(__FILE__)}:"o.method(:=~))
array.delete_if {|bt| bt.start_with?(DIR)}
end
array
end
Expand Down
2 changes: 1 addition & 1 deletion lib/prism/translation/ruby_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def visit_assoc_splat_node(node)
# ^^
# ```
def visit_back_reference_read_node(node)
s(node, :back_ref, node.name.name.delete_prefix("$").to_sym)
s(node, :back_ref, node.name.to_s.delete_prefix("$").to_sym)
end

# ```
Expand Down
2 changes: 1 addition & 1 deletion numeric.c
Original file line number Diff line number Diff line change
Expand Up @@ -6455,7 +6455,7 @@ Init_Numeric(void)
*
* If the platform supports denormalized numbers,
* there are numbers between zero and Float::MIN.
* 0.0.next_float returns the smallest positive floating point number
* +0.0.next_float+ returns the smallest positive floating point number
* including denormalized numbers.
*/
rb_define_const(rb_cFloat, "MIN", DBL2NUM(DBL_MIN));
Expand Down
30 changes: 19 additions & 11 deletions prism/prism.c
Original file line number Diff line number Diff line change
Expand Up @@ -18491,20 +18491,28 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
return (pm_node_t *) node;
}
case PM_TOKEN_CHARACTER_LITERAL: {
parser_lex(parser);

pm_token_t opening = parser->previous;
opening.type = PM_TOKEN_STRING_BEGIN;
opening.end = opening.start + 1;

pm_token_t content = parser->previous;
content.type = PM_TOKEN_STRING_CONTENT;
content.start = content.start + 1;

pm_token_t closing = not_provided(parser);
pm_node_t *node = (pm_node_t *) pm_string_node_create_current_string(parser, &opening, &content, &closing);
pm_node_t *node = (pm_node_t *) pm_string_node_create_current_string(
parser,
&(pm_token_t) {
.type = PM_TOKEN_STRING_BEGIN,
.start = parser->current.start,
.end = parser->current.start + 1
},
&(pm_token_t) {
.type = PM_TOKEN_STRING_CONTENT,
.start = parser->current.start + 1,
.end = parser->current.end
},
&closing
);

pm_node_flag_set(node, parse_unescaped_encoding(parser));

// Skip past the character literal here, since now we have handled
// parser->explicit_encoding correctly.
parser_lex(parser);

// Characters can be followed by strings in which case they are
// automatically concatenated.
if (match1(parser, PM_TOKEN_STRING_BEGIN)) {
Expand Down
6 changes: 3 additions & 3 deletions process.c
Original file line number Diff line number Diff line change
Expand Up @@ -2635,7 +2635,7 @@ rb_exec_fillarg(VALUE prog, int argc, VALUE *argv, VALUE env, VALUE opthash, VAL
}
rb_str_buf_cat(argv_str, (char *)&null, sizeof(null)); /* terminator for execve. */
eargp->invoke.cmd.argv_str =
rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(argv_str);
rb_imemo_tmpbuf_new_from_an_RString(argv_str);
}
RB_GC_GUARD(execarg_obj);
}
Expand Down Expand Up @@ -2726,7 +2726,7 @@ open_func(void *ptr)
static void
rb_execarg_allocate_dup2_tmpbuf(struct rb_execarg *eargp, long len)
{
VALUE tmpbuf = rb_imemo_tmpbuf_auto_free_pointer();
VALUE tmpbuf = rb_imemo_tmpbuf_new();
rb_imemo_tmpbuf_set_ptr(tmpbuf, ruby_xmalloc(run_exec_dup2_tmpbuf_size(len)));
eargp->dup2_tmpbuf = tmpbuf;
}
Expand Down Expand Up @@ -2830,7 +2830,7 @@ rb_execarg_parent_start1(VALUE execarg_obj)
p = NULL;
rb_str_buf_cat(envp_str, (char *)&p, sizeof(p));
eargp->envp_str =
rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(envp_str);
rb_imemo_tmpbuf_new_from_an_RString(envp_str);
eargp->envp_buf = envp_buf;

/*
Expand Down
79 changes: 69 additions & 10 deletions string.c
Original file line number Diff line number Diff line change
Expand Up @@ -10744,20 +10744,79 @@ rb_str_hex(VALUE str)
* call-seq:
* oct -> integer
*
* Interprets the leading substring of +self+ as a string of octal digits
* (with an optional sign) and returns the corresponding number;
* returns zero if there is no such leading substring:
* Interprets the leading substring of +self+ as octal, binary, decimal, or hexadecimal, possibly signed;
* returns their value as an integer.
*
* '123'.oct # => 83
* '-377'.oct # => -255
* '0377non-numeric'.oct # => 255
* 'non-numeric'.oct # => 0
* In brief:
*
* If +self+ starts with <tt>0</tt>, radix indicators are honored;
* see Kernel#Integer.
* # Interpreted as octal.
* '777'.oct # => 511
* '777x'.oct # => 511
* '0777'.oct # => 511
* '0o777'.oct # => 511
* '-777'.oct # => -511
* # Not interpreted as octal.
* '0b111'.oct # => 7 # Interpreted as binary.
* '0d999'.oct # => 999 # Interpreted as decimal.
* '0xfff'.oct # => 4095 # Interpreted as hexadecimal.
*
* Related: String#hex.
* The leading substring is interpreted as octal when it begins with:
*
* - One or more character representing octal digits
* (each in the range <tt>'0'..'7'</tt>);
* the string to be interpreted ends at the first character that does not represent an octal digit:
*
* '7'.oct @ => 7
* '11'.oct # => 9
* '777'.oct # => 511
* '0777'.oct # => 511
* '7778'.oct # => 511
* '777x'.oct # => 511
*
* - <tt>'0o'</tt>, followed by one or more octal digits:
*
* '0o777'.oct # => 511
* '0o7778'.oct # => 511
*
* The leading substring is _not_ interpreted as octal when it begins with:
*
* - <tt>'0b'</tt>, followed by one or more characters representing binary digits
* (each in the range <tt>'0'..'1'</tt>);
* the string to be interpreted ends at the first character that does not represent a binary digit.
* the string is interpreted as binary digits (base 2):
*
* '0b111'.oct # => 7
* '0b1112'.oct # => 7
*
* - <tt>'0d'</tt>, followed by one or more characters representing decimal digits
* (each in the range <tt>'0'..'9'</tt>);
* the string to be interpreted ends at the first character that does not represent a decimal digit.
* the string is interpreted as decimal digits (base 10):
*
* '0d999'.oct # => 999
* '0d999x'.oct # => 999
*
* - <tt>'0x'</tt>, followed by one or more characters representing hexadecimal digits
* (each in one of the ranges <tt>'0'..'9'</tt>, <tt>'a'..'f'</tt>, or <tt>'A'..'F'</tt>);
* the string to be interpreted ends at the first character that does not represent a hexadecimal digit.
* the string is interpreted as hexadecimal digits (base 16):
*
* '0xfff'.oct # => 4095
* '0xfffg'.oct # => 4095
*
* Any of the above may prefixed with <tt>'-'</tt>, which negates the interpreted value:
*
* '-777'.oct # => -511
* '-0777'.oct # => -511
* '-0b111'.oct # => -7
* '-0xfff'.oct # => -4095
*
* For any substring not described above, returns zero:
*
* 'foo'.oct # => 0
* ''.oct # => 0
*
* Related: see {Converting to Non-String}[rdoc-ref:String@Converting+to+Non--5CString].
*/

static VALUE
Expand Down
2 changes: 2 additions & 0 deletions test/prism/fixtures/character_literal.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# encoding: Windows-31J
p ?\u3042""
1 change: 1 addition & 0 deletions test/prism/ruby/ruby_parser_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
module Prism
class RubyParserTest < TestCase
todos = [
"character_literal.txt",
"encoding_euc_jp.txt",
"regex_char_width.txt",
"seattlerb/masgn_colon3.txt",
Expand Down
2 changes: 1 addition & 1 deletion util.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ ruby_strdup(const char *str)
char *
ruby_getcwd(void)
{
VALUE guard = rb_imemo_tmpbuf_auto_free_pointer();
VALUE guard = rb_imemo_tmpbuf_new();
int size = 200;
char *buf = xmalloc(size);

Expand Down