2012-12-21 11:38:03 +04:00
|
|
|
# -*- mode: ruby; coding: us-ascii -*-
|
|
|
|
firstline, predefined = __LINE__+1, %[\
|
2016-03-17 15:47:31 +03:00
|
|
|
max
|
|
|
|
min
|
Emit special instruction for array literal + .(hash|min|max)
This commit introduces a new instruction `opt_newarray_send` which is
used when there is an array literal followed by either the `hash`,
`min`, or `max` method.
```
[a, b, c].hash
```
Will emit an `opt_newarray_send` instruction. This instruction falls
back to a method call if the "interested" method has been monkey
patched.
Here are some examples of the instructions generated:
```
$ ./miniruby --dump=insns -e '[@a, @b].max'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE)
0000 getinstancevariable :@a, <is:0> ( 1)[Li]
0003 getinstancevariable :@b, <is:1>
0006 opt_newarray_send 2, :max
0009 leave
$ ./miniruby --dump=insns -e '[@a, @b].min'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE)
0000 getinstancevariable :@a, <is:0> ( 1)[Li]
0003 getinstancevariable :@b, <is:1>
0006 opt_newarray_send 2, :min
0009 leave
$ ./miniruby --dump=insns -e '[@a, @b].hash'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,13)> (catch: FALSE)
0000 getinstancevariable :@a, <is:0> ( 1)[Li]
0003 getinstancevariable :@b, <is:1>
0006 opt_newarray_send 2, :hash
0009 leave
```
[Feature #18897] [ruby-core:109147]
Co-authored-by: John Hawthorn <jhawthorn@github.com>
2022-06-07 03:27:56 +03:00
|
|
|
hash
|
2013-11-10 01:17:06 +04:00
|
|
|
freeze
|
2019-08-02 17:25:38 +03:00
|
|
|
nil?
|
2013-05-02 11:54:17 +04:00
|
|
|
inspect
|
2012-12-04 21:36:19 +04:00
|
|
|
intern
|
2013-05-02 11:54:17 +04:00
|
|
|
object_id
|
2021-05-22 13:04:01 +03:00
|
|
|
const_added
|
2013-05-02 11:54:17 +04:00
|
|
|
const_missing
|
2012-12-04 21:36:19 +04:00
|
|
|
method_missing MethodMissing
|
2013-05-02 11:54:17 +04:00
|
|
|
method_added
|
|
|
|
singleton_method_added
|
|
|
|
method_removed
|
|
|
|
singleton_method_removed
|
|
|
|
method_undefined
|
|
|
|
singleton_method_undefined
|
2012-12-04 21:36:19 +04:00
|
|
|
length
|
|
|
|
size
|
|
|
|
gets
|
|
|
|
succ
|
|
|
|
each
|
2013-05-01 06:38:44 +04:00
|
|
|
proc
|
2012-12-04 21:36:19 +04:00
|
|
|
lambda
|
|
|
|
send
|
|
|
|
__send__
|
2021-07-27 03:28:48 +03:00
|
|
|
__recursive_key__
|
2012-12-04 21:36:19 +04:00
|
|
|
initialize
|
|
|
|
initialize_copy
|
|
|
|
initialize_clone
|
|
|
|
initialize_dup
|
2014-05-20 10:28:52 +04:00
|
|
|
to_int
|
|
|
|
to_ary
|
|
|
|
to_str
|
|
|
|
to_sym
|
|
|
|
to_hash
|
|
|
|
to_proc
|
|
|
|
to_io
|
|
|
|
to_a
|
|
|
|
to_s
|
2014-05-20 12:28:33 +04:00
|
|
|
to_i
|
2018-02-27 11:15:27 +03:00
|
|
|
to_f
|
2017-04-14 08:19:12 +03:00
|
|
|
to_r
|
2014-06-28 08:58:25 +04:00
|
|
|
bt
|
|
|
|
bt_locations
|
parse.y: optimize IDs in ripper
* parse.y: optimize ripper_intern calls, ::, **, -@, +@, <=>, >=,
<=, ==, ===, !=, =~, !~, <<, >>, and call.
* parse.y: use initialized IDs, warn and warning.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48153 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-10-27 09:23:09 +03:00
|
|
|
call
|
2014-11-16 11:33:35 +03:00
|
|
|
mesg
|
|
|
|
exception
|
2019-07-20 04:42:10 +03:00
|
|
|
locals
|
2017-02-12 07:20:35 +03:00
|
|
|
not NOT
|
2017-02-12 11:33:33 +03:00
|
|
|
and AND
|
|
|
|
or OR
|
2019-08-03 02:37:08 +03:00
|
|
|
div
|
|
|
|
divmod
|
|
|
|
fdiv
|
|
|
|
quo
|
|
|
|
name
|
2019-09-01 07:37:28 +03:00
|
|
|
nil
|
2022-12-08 08:19:53 +03:00
|
|
|
path
|
2014-05-20 10:28:52 +04:00
|
|
|
|
2012-12-04 21:36:19 +04:00
|
|
|
_ UScore
|
2019-08-29 16:07:45 +03:00
|
|
|
|
|
|
|
# MUST be successive
|
|
|
|
_1 NUMPARAM_1
|
|
|
|
_2 NUMPARAM_2
|
|
|
|
_3 NUMPARAM_3
|
|
|
|
_4 NUMPARAM_4
|
|
|
|
_5 NUMPARAM_5
|
|
|
|
_6 NUMPARAM_6
|
|
|
|
_7 NUMPARAM_7
|
|
|
|
_8 NUMPARAM_8
|
|
|
|
_9 NUMPARAM_9
|
|
|
|
|
2012-12-04 21:36:19 +04:00
|
|
|
"/*NULL*/" NULL
|
|
|
|
empty?
|
2013-05-02 11:54:17 +04:00
|
|
|
eql?
|
2022-12-15 21:46:24 +03:00
|
|
|
default
|
2012-12-04 21:36:19 +04:00
|
|
|
respond_to? Respond_to
|
|
|
|
respond_to_missing? Respond_to_missing
|
|
|
|
<IFUNC>
|
|
|
|
<CFUNC>
|
|
|
|
core#set_method_alias
|
|
|
|
core#set_variable_alias
|
|
|
|
core#undef_method
|
|
|
|
core#define_method
|
|
|
|
core#define_singleton_method
|
|
|
|
core#set_postexe
|
|
|
|
core#hash_merge_ptr
|
|
|
|
core#hash_merge_kwd
|
2019-04-17 09:48:03 +03:00
|
|
|
core#raise
|
2021-08-15 03:38:24 +03:00
|
|
|
core#sprintf
|
2015-10-27 11:06:58 +03:00
|
|
|
|
2015-11-21 02:49:31 +03:00
|
|
|
- debug#created_info
|
2016-02-17 15:42:00 +03:00
|
|
|
|
|
|
|
$_ LASTLINE
|
|
|
|
$~ BACKREF
|
2019-04-10 15:43:34 +03:00
|
|
|
$! ERROR_INFO
|
2012-12-04 21:36:19 +04:00
|
|
|
]
|
|
|
|
|
2015-11-05 07:04:00 +03:00
|
|
|
# VM ID OP Parser Token
|
|
|
|
token_ops = %[\
|
|
|
|
Dot2 .. DOT2
|
|
|
|
Dot3 ... DOT3
|
2019-04-03 11:11:41 +03:00
|
|
|
BDot2 .. BDOT2
|
|
|
|
BDot3 ... BDOT3
|
2015-11-05 07:04:00 +03:00
|
|
|
UPlus +@ UPLUS
|
|
|
|
UMinus -@ UMINUS
|
|
|
|
Pow ** POW
|
|
|
|
Cmp <=> CMP
|
|
|
|
PLUS +
|
|
|
|
MINUS -
|
|
|
|
MULT *
|
|
|
|
DIV /
|
|
|
|
MOD %
|
|
|
|
LTLT << LSHFT
|
|
|
|
GTGT >> RSHFT
|
|
|
|
LT <
|
|
|
|
LE <= LEQ
|
|
|
|
GT >
|
|
|
|
GE >= GEQ
|
|
|
|
Eq == EQ
|
|
|
|
Eqq === EQQ
|
|
|
|
Neq != NEQ
|
|
|
|
Not !
|
2018-09-26 05:38:45 +03:00
|
|
|
And &
|
|
|
|
Or |
|
2015-11-05 07:04:00 +03:00
|
|
|
Backquote `
|
|
|
|
EqTilde =~ MATCH
|
|
|
|
NeqTilde !~ NMATCH
|
|
|
|
AREF []
|
|
|
|
ASET []=
|
|
|
|
COLON2 ::
|
|
|
|
ANDOP &&
|
|
|
|
OROP ||
|
2015-11-10 12:42:27 +03:00
|
|
|
ANDDOT &.
|
2015-11-05 07:04:00 +03:00
|
|
|
]
|
|
|
|
|
2012-12-21 11:38:07 +04:00
|
|
|
class KeywordError < RuntimeError
|
|
|
|
def self.raise(mesg, line)
|
|
|
|
super(self, mesg, ["#{__FILE__}:#{line}", *caller])
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-07-27 03:11:23 +03:00
|
|
|
def id2varname(token, prefix = nil)
|
|
|
|
if /#/ =~ token
|
|
|
|
token = "_#{token.gsub(/\W+/, '_')}"
|
|
|
|
else
|
|
|
|
token = token.sub(/\?/, 'P')
|
|
|
|
token = prefix + token if prefix
|
|
|
|
token.sub!(/\A[a-z]/) {$&.upcase}
|
|
|
|
token.sub!(/\A\$/, "_G_")
|
|
|
|
token.sub!(/\A@@/, "_C_")
|
|
|
|
token.sub!(/\A@/, "_I_")
|
|
|
|
token.gsub!(/\W+/, "")
|
|
|
|
end
|
|
|
|
token
|
|
|
|
end
|
|
|
|
|
2012-12-04 21:36:19 +04:00
|
|
|
predefined_ids = {}
|
|
|
|
preserved_ids = []
|
2012-12-21 11:38:03 +04:00
|
|
|
local_ids = []
|
|
|
|
instance_ids = []
|
|
|
|
global_ids = []
|
|
|
|
const_ids = []
|
|
|
|
class_ids = []
|
2014-11-14 09:55:05 +03:00
|
|
|
attrset_ids = []
|
2015-11-05 07:04:00 +03:00
|
|
|
token_op_ids = []
|
2012-12-21 11:38:03 +04:00
|
|
|
names = {}
|
2012-12-28 02:08:41 +04:00
|
|
|
predefined.split(/^/).each_with_index do |line, num|
|
2013-05-01 06:38:44 +04:00
|
|
|
next if /^#/ =~ line
|
|
|
|
line.sub!(/\s+#.*/, '')
|
|
|
|
name, token = line.split
|
|
|
|
next unless name
|
2021-07-27 03:11:23 +03:00
|
|
|
token = id2varname(token || name)
|
2015-10-27 17:14:18 +03:00
|
|
|
if name == '-'
|
|
|
|
preserved_ids << token
|
|
|
|
next
|
|
|
|
end
|
2012-12-21 11:38:07 +04:00
|
|
|
if prev = names[name]
|
|
|
|
KeywordError.raise("#{name} is already registered at line #{prev+firstline}", firstline+num)
|
|
|
|
end
|
|
|
|
if prev = predefined_ids[token]
|
|
|
|
KeywordError.raise("#{token} is already used for #{prev} at line #{names[prev]+firstline}", firstline+num)
|
|
|
|
end
|
|
|
|
names[name] = num
|
2012-12-21 11:38:03 +04:00
|
|
|
case name
|
|
|
|
when /\A[A-Z]\w*\z/; const_ids
|
|
|
|
when /\A(?!\d)\w+\z/; local_ids
|
2016-02-17 15:42:00 +03:00
|
|
|
when /\A\$(?:\d+|(?!\d)\w+|\W)\z/; global_ids
|
2012-12-21 11:38:03 +04:00
|
|
|
when /\A@@(?!\d)\w+\z/; class_ids
|
|
|
|
when /\A@(?!\d)\w+\z/; instance_ids
|
2014-11-14 09:55:05 +03:00
|
|
|
when /\A((?!\d)\w+)=\z/; attrset_ids
|
2012-12-21 11:38:03 +04:00
|
|
|
else preserved_ids
|
|
|
|
end << token
|
2012-12-04 21:36:19 +04:00
|
|
|
predefined_ids[token] = name
|
|
|
|
end
|
2022-09-08 09:25:05 +03:00
|
|
|
index = 127
|
2015-11-05 07:04:00 +03:00
|
|
|
token_ops.split(/^/).each do |line|
|
|
|
|
next if /^#/ =~ line
|
|
|
|
line.sub!(/\s+#.*/, '')
|
|
|
|
id, op, token = line.split
|
|
|
|
next unless id and op
|
|
|
|
token ||= (id unless /\A\W\z/ =~ op)
|
2022-09-08 09:25:05 +03:00
|
|
|
token_op_ids << [id, op, token, (index += 1 if token)]
|
2015-11-05 07:04:00 +03:00
|
|
|
end
|
2012-12-21 11:38:03 +04:00
|
|
|
{
|
|
|
|
"LOCAL" => local_ids,
|
|
|
|
"INSTANCE" => instance_ids,
|
|
|
|
"GLOBAL" => global_ids,
|
|
|
|
"CONST" => const_ids,
|
|
|
|
"CLASS" => class_ids,
|
2014-11-14 09:55:05 +03:00
|
|
|
"ATTRSET" => attrset_ids,
|
2012-12-21 11:38:03 +04:00
|
|
|
:preserved => preserved_ids,
|
|
|
|
:predefined => predefined_ids,
|
2015-11-05 07:04:00 +03:00
|
|
|
:token_op => token_op_ids,
|
2022-09-08 09:25:05 +03:00
|
|
|
:last_token => index,
|
2012-12-21 11:38:03 +04:00
|
|
|
}
|