2000-05-01 13:42:38 +04:00
|
|
|
/**********************************************************************
|
1998-01-16 15:13:05 +03:00
|
|
|
|
|
|
|
object.c -
|
|
|
|
|
|
|
|
$Author$
|
|
|
|
created at: Thu Jul 15 12:01:24 JST 1993
|
|
|
|
|
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing.
* parse.y (pragma_encoding): encoding specification pragma.
* parse.y (rb_intern3): encoding specified symbols.
* string.c (rb_str_length): length based on characters.
for older behavior, bytesize method added.
* string.c (rb_str_index_m): index based on characters. rindex as
well.
* string.c (succ_char): encoding aware succeeding string.
* string.c (rb_str_reverse): reverse based on characters.
* string.c (rb_str_inspect): encoding aware string description.
* string.c (rb_str_upcase_bang): encoding aware case conversion.
downcase, capitalize, swapcase as well.
* string.c (rb_str_tr_bang): tr based on characters. delete,
squeeze, tr_s, count as well.
* string.c (rb_str_split_m): split based on characters.
* string.c (rb_str_each_line): encoding aware each_line.
* string.c (rb_str_each_char): added. iteration based on
characters.
* string.c (rb_str_strip_bang): encoding aware whitespace
stripping. lstrip, rstrip as well.
* string.c (rb_str_justify): encoding aware justifying (ljust,
rjust, center).
* string.c (str_encoding): get encoding attribute from a string.
* re.c (rb_reg_initialize): encoding aware regular expression
* sprintf.c (rb_str_format): formatting (i.e. length count) based
on characters.
* io.c (rb_io_getc): getc to return one-character string.
for older behavior, getbyte method added.
* ext/stringio/stringio.c (strio_getc): ditto.
* io.c (rb_io_ungetc): allow pushing arbitrary string at the
current reading point.
* ext/stringio/stringio.c (strio_ungetc): ditto.
* ext/strscan/strscan.c: encoding support.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-25 07:29:39 +04:00
|
|
|
Copyright (C) 1993-2007 Yukihiro Matsumoto
|
2000-05-01 13:42:38 +04:00
|
|
|
Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
|
2000-05-09 08:53:16 +04:00
|
|
|
Copyright (C) 2000 Information-technology Promotion Agency, Japan
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2000-05-01 13:42:38 +04:00
|
|
|
**********************************************************************/
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2020-05-08 12:31:09 +03:00
|
|
|
#include "ruby/internal/config.h"
|
2019-12-04 11:16:30 +03:00
|
|
|
|
2001-05-16 13:05:54 +04:00
|
|
|
#include <ctype.h>
|
2019-12-04 11:16:30 +03:00
|
|
|
#include <errno.h>
|
2008-01-16 09:26:33 +03:00
|
|
|
#include <float.h>
|
2019-12-04 11:16:30 +03:00
|
|
|
#include <math.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
2010-10-26 21:27:32 +04:00
|
|
|
#include "constant.h"
|
2013-05-02 11:54:17 +04:00
|
|
|
#include "id.h"
|
2019-12-04 11:16:30 +03:00
|
|
|
#include "internal.h"
|
|
|
|
#include "internal/array.h"
|
|
|
|
#include "internal/class.h"
|
|
|
|
#include "internal/error.h"
|
|
|
|
#include "internal/eval.h"
|
|
|
|
#include "internal/inits.h"
|
|
|
|
#include "internal/numeric.h"
|
|
|
|
#include "internal/object.h"
|
|
|
|
#include "internal/struct.h"
|
2021-06-27 11:11:24 +03:00
|
|
|
#include "internal/string.h"
|
2019-12-04 11:16:30 +03:00
|
|
|
#include "internal/symbol.h"
|
|
|
|
#include "internal/variable.h"
|
2022-11-08 23:35:31 +03:00
|
|
|
#include "variable.h"
|
* probes.d: add DTrace probe declarations. [ruby-core:27448]
* array.c (empty_ary_alloc, ary_new): added array create DTrace probe.
* compile.c (rb_insns_name): allowing DTrace probes to access
instruction sequence name.
* Makefile.in: translate probes.d file to appropriate header file.
* common.mk: declare dependencies on the DTrace header.
* configure.in: add a test for existence of DTrace.
* eval.c (setup_exception): add a probe for when an exception is
raised.
* gc.c: Add DTrace probes for mark begin and end, and sweep begin and
end.
* hash.c (empty_hash_alloc): Add a probe for hash allocation.
* insns.def: Add probes for function entry and return.
* internal.h: function declaration for compile.c change.
* load.c (rb_f_load): add probes for `load` entry and exit, require
entry and exit, and wrapping search_required for load path search.
* object.c (rb_obj_alloc): added a probe for general object creation.
* parse.y (yycompile0): added a probe around parse and compile phase.
* string.c (empty_str_alloc, str_new): DTrace probes for string
allocation.
* test/dtrace/*: tests for DTrace probes.
* vm.c (vm_invoke_proc): add probes for function return on exception
raise, hash create, and instruction sequence execution.
* vm_core.h: add probe declarations for function entry and exit.
* vm_dump.c: add probes header file.
* vm_eval.c (vm_call0_cfunc, vm_call0_cfunc_with_frame): add probe on
function entry and return.
* vm_exec.c: expose instruction number to instruction name function.
* vm_insnshelper.c: add function entry and exit probes for cfunc
methods.
* vm_insnhelper.h: vm usage information is always collected, so
uncomment the functions.
12 19:14:50 2012 Akinori MUSHA <knu@iDaemons.org>
* configure.in (isinf, isnan): isinf() and isnan() are macros on
DragonFly which cannot be found by AC_REPLACE_FUNCS(). This
workaround enforces the fact that they exist on DragonFly.
12 15:59:38 2012 Shugo Maeda <shugo@ruby-lang.org>
* vm_core.h (rb_call_info_t::refinements), compile.c (new_callinfo),
vm_insnhelper.c (vm_search_method): revert r37616 because it's too
slow. [ruby-dev:46477]
* test/ruby/test_refinement.rb (test_inline_method_cache): skip
the test until the bug is fixed efficiently.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37631 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-11-13 01:52:12 +04:00
|
|
|
#include "probes.h"
|
2019-12-04 11:16:30 +03:00
|
|
|
#include "ruby/encoding.h"
|
|
|
|
#include "ruby/st.h"
|
|
|
|
#include "ruby/util.h"
|
2020-10-28 00:10:39 +03:00
|
|
|
#include "ruby/assert.h"
|
2020-03-17 13:37:07 +03:00
|
|
|
#include "builtin.h"
|
2022-10-03 18:14:32 +03:00
|
|
|
#include "shape.h"
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*!
|
2020-12-22 10:39:42 +03:00
|
|
|
* \addtogroup object
|
2017-07-22 09:30:53 +03:00
|
|
|
* \{
|
|
|
|
*/
|
|
|
|
|
2020-12-22 10:39:42 +03:00
|
|
|
VALUE rb_cBasicObject;
|
|
|
|
VALUE rb_mKernel;
|
|
|
|
VALUE rb_cObject;
|
|
|
|
VALUE rb_cModule;
|
|
|
|
VALUE rb_cClass;
|
2021-10-21 10:21:08 +03:00
|
|
|
VALUE rb_cRefinement;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2020-12-22 10:39:42 +03:00
|
|
|
VALUE rb_cNilClass;
|
|
|
|
VALUE rb_cTrueClass;
|
|
|
|
VALUE rb_cFalseClass;
|
2017-07-22 09:30:53 +03:00
|
|
|
|
2019-09-26 18:27:47 +03:00
|
|
|
static VALUE rb_cNilClass_to_s;
|
|
|
|
static VALUE rb_cTrueClass_to_s;
|
|
|
|
static VALUE rb_cFalseClass_to_s;
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \cond INTERNAL_MACRO */
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2013-05-02 11:54:17 +04:00
|
|
|
#define id_eq idEq
|
|
|
|
#define id_eql idEqlP
|
|
|
|
#define id_match idEqTilde
|
|
|
|
#define id_inspect idInspect
|
|
|
|
#define id_init_copy idInitialize_copy
|
|
|
|
#define id_init_clone idInitialize_clone
|
|
|
|
#define id_init_dup idInitialize_dup
|
|
|
|
#define id_const_missing idConst_missing
|
2018-02-27 11:15:27 +03:00
|
|
|
#define id_to_f idTo_f
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2013-01-15 18:07:24 +04:00
|
|
|
#define CLASS_OR_MODULE_P(obj) \
|
|
|
|
(!SPECIAL_CONST_P(obj) && \
|
|
|
|
(BUILTIN_TYPE(obj) == T_CLASS || BUILTIN_TYPE(obj) == T_MODULE))
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \endcond */
|
|
|
|
|
2013-04-03 11:35:35 +04:00
|
|
|
VALUE
|
|
|
|
rb_obj_hide(VALUE obj)
|
|
|
|
{
|
|
|
|
if (!SPECIAL_CONST_P(obj)) {
|
* include/ruby/ruby.h: constify RBasic::klass and add
RBASIC_CLASS(obj) macro which returns a class of `obj'.
This change is a part of RGENGC branch [ruby-trunk - Feature #8339].
* object.c: add new function rb_obj_reveal().
This function reveal interal (hidden) object by rb_obj_hide().
Note that do not change class before and after hiding.
Only permitted example is:
klass = RBASIC_CLASS(obj);
rb_obj_hide(obj);
....
rb_obj_reveal(obj, klass);
TODO: API design. rb_obj_reveal() should be replaced with others.
TODO: modify constified variables using cast may be harmful for
compiler's analysis and optimizaton.
Any idea to prohibt inserting RBasic::klass directly?
If rename RBasic::klass and force to use RBASIC_CLASS(obj),
then all codes such as `RBASIC(obj)->klass' will be
compilation error. Is it acceptable? (We have similar
experience at Ruby 1.9,
for example "RARRAY(ary)->ptr" to "RARRAY_PTR(ary)".
* internal.h: add some macros.
* RBASIC_CLEAR_CLASS(obj) clear RBasic::klass to make it internal
object.
* RBASIC_SET_CLASS(obj, cls) set RBasic::klass.
* RBASIC_SET_CLASS_RAW(obj, cls) same as RBASIC_SET_CLASS
without write barrier (planned).
* RCLASS_SET_SUPER(a, b) set super class of a.
* array.c, class.c, compile.c, encoding.c, enum.c, error.c, eval.c,
file.c, gc.c, hash.c, io.c, iseq.c, marshal.c, object.c,
parse.y, proc.c, process.c, random.c, ruby.c, sprintf.c,
string.c, thread.c, transcode.c, vm.c, vm_eval.c, win32/file.c:
Use above macros and functions to access RBasic::klass.
* ext/coverage/coverage.c, ext/readline/readline.c,
ext/socket/ancdata.c, ext/socket/init.c,
* ext/zlib/zlib.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40691 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-05-13 14:49:11 +04:00
|
|
|
RBASIC_CLEAR_CLASS(obj);
|
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_obj_reveal(VALUE obj, VALUE klass)
|
|
|
|
{
|
|
|
|
if (!SPECIAL_CONST_P(obj)) {
|
|
|
|
RBASIC_SET_CLASS(obj, klass);
|
2013-04-03 11:35:35 +04:00
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2013-05-13 10:33:48 +04:00
|
|
|
VALUE
|
|
|
|
rb_obj_setup(VALUE obj, VALUE klass, VALUE type)
|
|
|
|
{
|
|
|
|
RBASIC(obj)->flags = type;
|
* include/ruby/ruby.h: constify RBasic::klass and add
RBASIC_CLASS(obj) macro which returns a class of `obj'.
This change is a part of RGENGC branch [ruby-trunk - Feature #8339].
* object.c: add new function rb_obj_reveal().
This function reveal interal (hidden) object by rb_obj_hide().
Note that do not change class before and after hiding.
Only permitted example is:
klass = RBASIC_CLASS(obj);
rb_obj_hide(obj);
....
rb_obj_reveal(obj, klass);
TODO: API design. rb_obj_reveal() should be replaced with others.
TODO: modify constified variables using cast may be harmful for
compiler's analysis and optimizaton.
Any idea to prohibt inserting RBasic::klass directly?
If rename RBasic::klass and force to use RBASIC_CLASS(obj),
then all codes such as `RBASIC(obj)->klass' will be
compilation error. Is it acceptable? (We have similar
experience at Ruby 1.9,
for example "RARRAY(ary)->ptr" to "RARRAY_PTR(ary)".
* internal.h: add some macros.
* RBASIC_CLEAR_CLASS(obj) clear RBasic::klass to make it internal
object.
* RBASIC_SET_CLASS(obj, cls) set RBasic::klass.
* RBASIC_SET_CLASS_RAW(obj, cls) same as RBASIC_SET_CLASS
without write barrier (planned).
* RCLASS_SET_SUPER(a, b) set super class of a.
* array.c, class.c, compile.c, encoding.c, enum.c, error.c, eval.c,
file.c, gc.c, hash.c, io.c, iseq.c, marshal.c, object.c,
parse.y, proc.c, process.c, random.c, ruby.c, sprintf.c,
string.c, thread.c, transcode.c, vm.c, vm_eval.c, win32/file.c:
Use above macros and functions to access RBasic::klass.
* ext/coverage/coverage.c, ext/readline/readline.c,
ext/socket/ancdata.c, ext/socket/init.c,
* ext/zlib/zlib.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40691 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-05-13 14:49:11 +04:00
|
|
|
RBASIC_SET_CLASS(obj, klass);
|
2013-05-13 10:33:48 +04:00
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/**
|
2003-12-28 09:33:07 +03:00
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj === other -> true or false
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2012-06-01 01:30:18 +04:00
|
|
|
* Case Equality -- For class Object, effectively the same as calling
|
|
|
|
* <code>#==</code>, but typically overridden by descendants to provide
|
|
|
|
* meaningful semantics in +case+ statements.
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
2020-05-06 03:43:49 +03:00
|
|
|
#define case_equal rb_equal
|
2020-05-06 01:11:42 +03:00
|
|
|
/* The default implementation of #=== is
|
|
|
|
* to call #== with the rb_equal() optimization. */
|
2003-12-28 09:33:07 +03:00
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_equal(VALUE obj1, VALUE obj2)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
|
|
|
VALUE result;
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
if (obj1 == obj2) return Qtrue;
|
Improve performance of rb_equal()
* object.c (rb_equal): add optimized path to compare the objects using
rb_equal_opt(). Previously, if not same objects were given, rb_equal() would
call `==' method via rb_funcall() which took a long time.
rb_equal_opt() has provided faster comparing for Fixnum/Float/String objects.
Now, Time#eql? uses rb_equal() to compare with argument object and it will
be faster around 40% on 64-bit environment.
* array.c (rb_ary_index): remove redundant rb_equal_opt() calling.
Now, rb_equal() was optimized using rb_equal_opt().
If rb_equal_opt() returns Qundef, it will invoke rb_equal() -> rb_equal_opt(),
and it will cause the performance regression.
So, this patch will remove first redundant rb_equal_opt() calling.
* array.c (rb_ary_rindex): ditto.
* array.c (rb_ary_includes): ditto.
[ruby-core:80360] [Bug #13365] [Fix GH-#1552]
### Before
Time#eql? with other 7.309M (± 1.4%) i/s - 36.647M in 5.014964s
Array#index(val) 1.433M (± 1.2%) i/s - 7.207M in 5.030942s
Array#rindex(val) 1.418M (± 1.6%) i/s - 7.103M in 5.009164s
Array#include?(val) 1.451M (± 0.9%) i/s - 7.295M in 5.026392s
### After
Time#eql? with other 10.321M (± 1.9%) i/s - 51.684M in 5.009203s
Array#index(val) 1.474M (± 0.9%) i/s - 7.433M in 5.044384s
Array#rindex(val) 1.449M (± 1.7%) i/s - 7.292M in 5.034436s
Array#include?(val) 1.466M (± 1.7%) i/s - 7.373M in 5.030047s
### Test code
require 'benchmark/ips'
Benchmark.ips do |x|
t1 = Time.now
t2 = Time.now
x.report "Time#eql? with other" do |i|
i.times { t1.eql?(t2) }
end
# Benchmarks to check whether it didn't introduce the regression
obj = Object.new
x.report "Array#index(val)" do |i|
ary = [1, 2, true, false, obj]
i.times { ary.index(obj) }
end
x.report "Array#rindex(val)" do |i|
ary = [1, 2, true, false, obj].reverse
i.times { ary.rindex(obj) }
end
x.report "Array#include?(val)" do |i|
ary = [1, 2, true, false, obj]
i.times { ary.include?(obj) }
end
end
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58880 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-05-25 07:25:37 +03:00
|
|
|
result = rb_equal_opt(obj1, obj2);
|
2022-11-15 07:24:08 +03:00
|
|
|
if (UNDEF_P(result)) {
|
Improve performance of rb_equal()
* object.c (rb_equal): add optimized path to compare the objects using
rb_equal_opt(). Previously, if not same objects were given, rb_equal() would
call `==' method via rb_funcall() which took a long time.
rb_equal_opt() has provided faster comparing for Fixnum/Float/String objects.
Now, Time#eql? uses rb_equal() to compare with argument object and it will
be faster around 40% on 64-bit environment.
* array.c (rb_ary_index): remove redundant rb_equal_opt() calling.
Now, rb_equal() was optimized using rb_equal_opt().
If rb_equal_opt() returns Qundef, it will invoke rb_equal() -> rb_equal_opt(),
and it will cause the performance regression.
So, this patch will remove first redundant rb_equal_opt() calling.
* array.c (rb_ary_rindex): ditto.
* array.c (rb_ary_includes): ditto.
[ruby-core:80360] [Bug #13365] [Fix GH-#1552]
### Before
Time#eql? with other 7.309M (± 1.4%) i/s - 36.647M in 5.014964s
Array#index(val) 1.433M (± 1.2%) i/s - 7.207M in 5.030942s
Array#rindex(val) 1.418M (± 1.6%) i/s - 7.103M in 5.009164s
Array#include?(val) 1.451M (± 0.9%) i/s - 7.295M in 5.026392s
### After
Time#eql? with other 10.321M (± 1.9%) i/s - 51.684M in 5.009203s
Array#index(val) 1.474M (± 0.9%) i/s - 7.433M in 5.044384s
Array#rindex(val) 1.449M (± 1.7%) i/s - 7.292M in 5.034436s
Array#include?(val) 1.466M (± 1.7%) i/s - 7.373M in 5.030047s
### Test code
require 'benchmark/ips'
Benchmark.ips do |x|
t1 = Time.now
t2 = Time.now
x.report "Time#eql? with other" do |i|
i.times { t1.eql?(t2) }
end
# Benchmarks to check whether it didn't introduce the regression
obj = Object.new
x.report "Array#index(val)" do |i|
ary = [1, 2, true, false, obj]
i.times { ary.index(obj) }
end
x.report "Array#rindex(val)" do |i|
ary = [1, 2, true, false, obj].reverse
i.times { ary.rindex(obj) }
end
x.report "Array#include?(val)" do |i|
ary = [1, 2, true, false, obj]
i.times { ary.include?(obj) }
end
end
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58880 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-05-25 07:25:37 +03:00
|
|
|
result = rb_funcall(obj1, id_eq, 1, obj2);
|
|
|
|
}
|
2021-08-02 06:06:44 +03:00
|
|
|
return RBOOL(RTEST(result));
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_eql(VALUE obj1, VALUE obj2)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2017-05-25 07:25:39 +03:00
|
|
|
VALUE result;
|
|
|
|
|
2022-10-07 15:44:13 +03:00
|
|
|
if (obj1 == obj2) return TRUE;
|
2017-05-25 07:25:39 +03:00
|
|
|
result = rb_eql_opt(obj1, obj2);
|
2022-11-15 07:24:08 +03:00
|
|
|
if (UNDEF_P(result)) {
|
2017-05-25 07:25:39 +03:00
|
|
|
result = rb_funcall(obj1, id_eql, 1, obj2);
|
|
|
|
}
|
2022-10-07 15:44:13 +03:00
|
|
|
return RTEST(result);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/**
|
2003-12-28 09:33:07 +03:00
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj == other -> true or false
|
|
|
|
* obj.equal?(other) -> true or false
|
|
|
|
* obj.eql?(other) -> true or false
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2019-03-22 14:04:59 +03:00
|
|
|
* Equality --- At the Object level, #== returns <code>true</code>
|
|
|
|
* only if +obj+ and +other+ are the same object. Typically, this
|
|
|
|
* method is overridden in descendant classes to provide
|
2012-02-24 02:36:40 +04:00
|
|
|
* class-specific meaning.
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
2019-03-22 14:04:59 +03:00
|
|
|
* Unlike #==, the #equal? method should never be overridden by
|
|
|
|
* subclasses as it is used to determine object identity (that is,
|
|
|
|
* <code>a.equal?(b)</code> if and only if <code>a</code> is the same
|
|
|
|
* object as <code>b</code>):
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
2012-02-24 02:36:40 +04:00
|
|
|
* obj = "a"
|
|
|
|
* other = obj.dup
|
|
|
|
*
|
2013-07-04 17:31:11 +04:00
|
|
|
* obj == other #=> true
|
|
|
|
* obj.equal? other #=> false
|
|
|
|
* obj.equal? obj #=> true
|
2012-02-24 02:36:40 +04:00
|
|
|
*
|
2019-03-22 14:04:59 +03:00
|
|
|
* The #eql? method returns <code>true</code> if +obj+ and +other+
|
|
|
|
* refer to the same hash key. This is used by Hash to test members
|
2019-07-27 03:04:13 +03:00
|
|
|
* for equality. For any pair of objects where #eql? returns +true+,
|
|
|
|
* the #hash value of both objects must be equal. So any subclass
|
|
|
|
* that overrides #eql? should also override #hash appropriately.
|
|
|
|
*
|
|
|
|
* For objects of class Object, #eql? is synonymous
|
2019-03-22 14:04:59 +03:00
|
|
|
* with #==. Subclasses normally continue this tradition by aliasing
|
|
|
|
* #eql? to their overridden #== method, but there are exceptions.
|
|
|
|
* Numeric types, for example, perform type conversion across #==,
|
|
|
|
* but not across #eql?, so:
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* 1 == 1.0 #=> true
|
|
|
|
* 1.eql? 1.0 #=> false
|
2017-07-22 09:30:53 +03:00
|
|
|
*--
|
|
|
|
* \private
|
|
|
|
*++
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
mjit_compile.c: merge initial JIT compiler
which has been developed by Takashi Kokubun <takashikkbn@gmail> as
YARV-MJIT. Many of its bugs are fixed by wanabe <s.wanabe@gmail.com>.
This JIT compiler is designed to be a safe migration path to introduce
JIT compiler to MRI. So this commit does not include any bytecode
changes or dynamic instruction modifications, which are done in original
MJIT.
This commit even strips off some aggressive optimizations from
YARV-MJIT, and thus it's slower than YARV-MJIT too. But it's still
fairly faster than Ruby 2.5 in some benchmarks (attached below).
Note that this JIT compiler passes `make test`, `make test-all`, `make
test-spec` without JIT, and even with JIT. Not only it's perfectly safe
with JIT disabled because it does not replace VM instructions unlike
MJIT, but also with JIT enabled it stably runs Ruby applications
including Rails applications.
I'm expecting this version as just "initial" JIT compiler. I have many
optimization ideas which are skipped for initial merging, and you may
easily replace this JIT compiler with a faster one by just replacing
mjit_compile.c. `mjit_compile` interface is designed for the purpose.
common.mk: update dependencies for mjit_compile.c.
internal.h: declare `rb_vm_insn_addr2insn` for MJIT.
vm.c: exclude some definitions if `-DMJIT_HEADER` is provided to
compiler. This avoids to include some functions which take a long time
to compile, e.g. vm_exec_core. Some of the purpose is achieved in
transform_mjit_header.rb (see `IGNORED_FUNCTIONS`) but others are
manually resolved for now. Load mjit_helper.h for MJIT header.
mjit_helper.h: New. This is a file used only by JIT-ed code. I'll
refactor `mjit_call_cfunc` later.
vm_eval.c: add some #ifdef switches to skip compiling some functions
like Init_vm_eval.
win32/mkexports.rb: export thread/ec functions, which are used by MJIT.
include/ruby/defines.h: add MJIT_FUNC_EXPORTED macro alis to clarify
that a function is exported only for MJIT.
array.c: export a function used by MJIT.
bignum.c: ditto.
class.c: ditto.
compile.c: ditto.
error.c: ditto.
gc.c: ditto.
hash.c: ditto.
iseq.c: ditto.
numeric.c: ditto.
object.c: ditto.
proc.c: ditto.
re.c: ditto.
st.c: ditto.
string.c: ditto.
thread.c: ditto.
variable.c: ditto.
vm_backtrace.c: ditto.
vm_insnhelper.c: ditto.
vm_method.c: ditto.
I would like to improve maintainability of function exports, but I
believe this way is acceptable as initial merging if we clarify the
new exports are for MJIT (so that we can use them as TODO list to fix)
and add unit tests to detect unresolved symbols.
I'll add unit tests of JIT compilations in succeeding commits.
Author: Takashi Kokubun <takashikkbn@gmail.com>
Contributor: wanabe <s.wanabe@gmail.com>
Part of [Feature #14235]
---
* Known issues
* Code generated by gcc is faster than clang. The benchmark may be worse
in macOS. Following benchmark result is provided by gcc w/ Linux.
* Performance is decreased when Google Chrome is running
* JIT can work on MinGW, but it doesn't improve performance at least
in short running benchmark.
* Currently it doesn't perform well with Rails. We'll try to fix this
before release.
---
* Benchmark reslts
Benchmarked with:
Intel 4.0GHz i7-4790K with 16GB memory under x86-64 Ubuntu 8 Cores
- 2.0.0-p0: Ruby 2.0.0-p0
- r62186: Ruby trunk (early 2.6.0), before MJIT changes
- JIT off: On this commit, but without `--jit` option
- JIT on: On this commit, and with `--jit` option
** Optcarrot fps
Benchmark: https://github.com/mame/optcarrot
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:--------|:--------|:--------|:--------|:--------|
|fps |37.32 |51.46 |51.31 |58.88 |
|vs 2.0.0 |1.00x |1.38x |1.37x |1.58x |
** MJIT benchmarks
Benchmark: https://github.com/benchmark-driver/mjit-benchmarks
(Original: https://github.com/vnmakarov/ruby/tree/rtl_mjit_branch/MJIT-benchmarks)
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:----------|:--------|:--------|:--------|:--------|
|aread |1.00 |1.09 |1.07 |2.19 |
|aref |1.00 |1.13 |1.11 |2.22 |
|aset |1.00 |1.50 |1.45 |2.64 |
|awrite |1.00 |1.17 |1.13 |2.20 |
|call |1.00 |1.29 |1.26 |2.02 |
|const2 |1.00 |1.10 |1.10 |2.19 |
|const |1.00 |1.11 |1.10 |2.19 |
|fannk |1.00 |1.04 |1.02 |1.00 |
|fib |1.00 |1.32 |1.31 |1.84 |
|ivread |1.00 |1.13 |1.12 |2.43 |
|ivwrite |1.00 |1.23 |1.21 |2.40 |
|mandelbrot |1.00 |1.13 |1.16 |1.28 |
|meteor |1.00 |2.97 |2.92 |3.17 |
|nbody |1.00 |1.17 |1.15 |1.49 |
|nest-ntimes|1.00 |1.22 |1.20 |1.39 |
|nest-while |1.00 |1.10 |1.10 |1.37 |
|norm |1.00 |1.18 |1.16 |1.24 |
|nsvb |1.00 |1.16 |1.16 |1.17 |
|red-black |1.00 |1.02 |0.99 |1.12 |
|sieve |1.00 |1.30 |1.28 |1.62 |
|trees |1.00 |1.14 |1.13 |1.19 |
|while |1.00 |1.12 |1.11 |2.41 |
** Discourse's script/bench.rb
Benchmark: https://github.com/discourse/discourse/blob/v1.8.7/script/bench.rb
NOTE: Rails performance was somehow a little degraded with JIT for now.
We should fix this.
(At least I know opt_aref is performing badly in JIT and I have an idea
to fix it. Please wait for the fix.)
*** JIT off
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 17
75: 18
90: 22
99: 29
home_admin:
50: 21
75: 21
90: 27
99: 40
topic_admin:
50: 17
75: 18
90: 22
99: 32
categories:
50: 35
75: 41
90: 43
99: 77
home:
50: 39
75: 46
90: 49
99: 95
topic:
50: 46
75: 52
90: 56
99: 101
*** JIT on
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 19
75: 21
90: 25
99: 33
home_admin:
50: 24
75: 26
90: 30
99: 35
topic_admin:
50: 19
75: 20
90: 25
99: 30
categories:
50: 40
75: 44
90: 48
99: 76
home:
50: 42
75: 48
90: 51
99: 89
topic:
50: 49
75: 55
90: 58
99: 99
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62197 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 14:22:28 +03:00
|
|
|
MJIT_FUNC_EXPORTED VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_obj_equal(VALUE obj1, VALUE obj2)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2021-08-02 06:06:44 +03:00
|
|
|
return RBOOL(obj1 == obj2);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2015-07-29 11:25:49 +03:00
|
|
|
VALUE rb_obj_hash(VALUE obj);
|
* string.c (rb_hash_uint32, rb_hash_uint, rb_hash_start, rb_hash_end),
include/ruby/intern.h: add Murmurhash API. [ruby-dev:37784]
* complex.c (nucomp_hash), array.c (rb_ary_hash), time.c (time_hash),
string.c (rb_str_hsah), object.c (rb_obj_hash), range.c
(range_hash), struct.c (rb_struct_hash), hash.c (rb_any_hash),
rational.c (nurat_hash): use Murmurhash. [ruby-dev:37784]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22317 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2009-02-14 22:55:34 +03:00
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/**
|
2007-12-09 19:39:49 +03:00
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* !obj -> true or false
|
2007-12-09 19:39:49 +03:00
|
|
|
*
|
|
|
|
* Boolean negate.
|
2017-07-22 09:30:53 +03:00
|
|
|
*--
|
|
|
|
* \private
|
|
|
|
*++
|
2007-12-09 19:39:49 +03:00
|
|
|
*/
|
|
|
|
|
mjit_compile.c: merge initial JIT compiler
which has been developed by Takashi Kokubun <takashikkbn@gmail> as
YARV-MJIT. Many of its bugs are fixed by wanabe <s.wanabe@gmail.com>.
This JIT compiler is designed to be a safe migration path to introduce
JIT compiler to MRI. So this commit does not include any bytecode
changes or dynamic instruction modifications, which are done in original
MJIT.
This commit even strips off some aggressive optimizations from
YARV-MJIT, and thus it's slower than YARV-MJIT too. But it's still
fairly faster than Ruby 2.5 in some benchmarks (attached below).
Note that this JIT compiler passes `make test`, `make test-all`, `make
test-spec` without JIT, and even with JIT. Not only it's perfectly safe
with JIT disabled because it does not replace VM instructions unlike
MJIT, but also with JIT enabled it stably runs Ruby applications
including Rails applications.
I'm expecting this version as just "initial" JIT compiler. I have many
optimization ideas which are skipped for initial merging, and you may
easily replace this JIT compiler with a faster one by just replacing
mjit_compile.c. `mjit_compile` interface is designed for the purpose.
common.mk: update dependencies for mjit_compile.c.
internal.h: declare `rb_vm_insn_addr2insn` for MJIT.
vm.c: exclude some definitions if `-DMJIT_HEADER` is provided to
compiler. This avoids to include some functions which take a long time
to compile, e.g. vm_exec_core. Some of the purpose is achieved in
transform_mjit_header.rb (see `IGNORED_FUNCTIONS`) but others are
manually resolved for now. Load mjit_helper.h for MJIT header.
mjit_helper.h: New. This is a file used only by JIT-ed code. I'll
refactor `mjit_call_cfunc` later.
vm_eval.c: add some #ifdef switches to skip compiling some functions
like Init_vm_eval.
win32/mkexports.rb: export thread/ec functions, which are used by MJIT.
include/ruby/defines.h: add MJIT_FUNC_EXPORTED macro alis to clarify
that a function is exported only for MJIT.
array.c: export a function used by MJIT.
bignum.c: ditto.
class.c: ditto.
compile.c: ditto.
error.c: ditto.
gc.c: ditto.
hash.c: ditto.
iseq.c: ditto.
numeric.c: ditto.
object.c: ditto.
proc.c: ditto.
re.c: ditto.
st.c: ditto.
string.c: ditto.
thread.c: ditto.
variable.c: ditto.
vm_backtrace.c: ditto.
vm_insnhelper.c: ditto.
vm_method.c: ditto.
I would like to improve maintainability of function exports, but I
believe this way is acceptable as initial merging if we clarify the
new exports are for MJIT (so that we can use them as TODO list to fix)
and add unit tests to detect unresolved symbols.
I'll add unit tests of JIT compilations in succeeding commits.
Author: Takashi Kokubun <takashikkbn@gmail.com>
Contributor: wanabe <s.wanabe@gmail.com>
Part of [Feature #14235]
---
* Known issues
* Code generated by gcc is faster than clang. The benchmark may be worse
in macOS. Following benchmark result is provided by gcc w/ Linux.
* Performance is decreased when Google Chrome is running
* JIT can work on MinGW, but it doesn't improve performance at least
in short running benchmark.
* Currently it doesn't perform well with Rails. We'll try to fix this
before release.
---
* Benchmark reslts
Benchmarked with:
Intel 4.0GHz i7-4790K with 16GB memory under x86-64 Ubuntu 8 Cores
- 2.0.0-p0: Ruby 2.0.0-p0
- r62186: Ruby trunk (early 2.6.0), before MJIT changes
- JIT off: On this commit, but without `--jit` option
- JIT on: On this commit, and with `--jit` option
** Optcarrot fps
Benchmark: https://github.com/mame/optcarrot
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:--------|:--------|:--------|:--------|:--------|
|fps |37.32 |51.46 |51.31 |58.88 |
|vs 2.0.0 |1.00x |1.38x |1.37x |1.58x |
** MJIT benchmarks
Benchmark: https://github.com/benchmark-driver/mjit-benchmarks
(Original: https://github.com/vnmakarov/ruby/tree/rtl_mjit_branch/MJIT-benchmarks)
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:----------|:--------|:--------|:--------|:--------|
|aread |1.00 |1.09 |1.07 |2.19 |
|aref |1.00 |1.13 |1.11 |2.22 |
|aset |1.00 |1.50 |1.45 |2.64 |
|awrite |1.00 |1.17 |1.13 |2.20 |
|call |1.00 |1.29 |1.26 |2.02 |
|const2 |1.00 |1.10 |1.10 |2.19 |
|const |1.00 |1.11 |1.10 |2.19 |
|fannk |1.00 |1.04 |1.02 |1.00 |
|fib |1.00 |1.32 |1.31 |1.84 |
|ivread |1.00 |1.13 |1.12 |2.43 |
|ivwrite |1.00 |1.23 |1.21 |2.40 |
|mandelbrot |1.00 |1.13 |1.16 |1.28 |
|meteor |1.00 |2.97 |2.92 |3.17 |
|nbody |1.00 |1.17 |1.15 |1.49 |
|nest-ntimes|1.00 |1.22 |1.20 |1.39 |
|nest-while |1.00 |1.10 |1.10 |1.37 |
|norm |1.00 |1.18 |1.16 |1.24 |
|nsvb |1.00 |1.16 |1.16 |1.17 |
|red-black |1.00 |1.02 |0.99 |1.12 |
|sieve |1.00 |1.30 |1.28 |1.62 |
|trees |1.00 |1.14 |1.13 |1.19 |
|while |1.00 |1.12 |1.11 |2.41 |
** Discourse's script/bench.rb
Benchmark: https://github.com/discourse/discourse/blob/v1.8.7/script/bench.rb
NOTE: Rails performance was somehow a little degraded with JIT for now.
We should fix this.
(At least I know opt_aref is performing badly in JIT and I have an idea
to fix it. Please wait for the fix.)
*** JIT off
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 17
75: 18
90: 22
99: 29
home_admin:
50: 21
75: 21
90: 27
99: 40
topic_admin:
50: 17
75: 18
90: 22
99: 32
categories:
50: 35
75: 41
90: 43
99: 77
home:
50: 39
75: 46
90: 49
99: 95
topic:
50: 46
75: 52
90: 56
99: 101
*** JIT on
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 19
75: 21
90: 25
99: 33
home_admin:
50: 24
75: 26
90: 30
99: 35
topic_admin:
50: 19
75: 20
90: 25
99: 30
categories:
50: 40
75: 44
90: 48
99: 76
home:
50: 42
75: 48
90: 51
99: 89
topic:
50: 49
75: 55
90: 58
99: 99
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62197 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 14:22:28 +03:00
|
|
|
MJIT_FUNC_EXPORTED VALUE
|
2007-12-09 19:39:49 +03:00
|
|
|
rb_obj_not(VALUE obj)
|
|
|
|
{
|
2022-01-01 09:41:00 +03:00
|
|
|
return RBOOL(!RTEST(obj));
|
2007-12-09 19:39:49 +03:00
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/**
|
2007-12-09 19:39:49 +03:00
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj != other -> true or false
|
2007-12-09 19:39:49 +03:00
|
|
|
*
|
|
|
|
* Returns true if two objects are not-equal, otherwise false.
|
2017-07-22 09:30:53 +03:00
|
|
|
*--
|
|
|
|
* \private
|
|
|
|
*++
|
2007-12-09 19:39:49 +03:00
|
|
|
*/
|
|
|
|
|
mjit_compile.c: merge initial JIT compiler
which has been developed by Takashi Kokubun <takashikkbn@gmail> as
YARV-MJIT. Many of its bugs are fixed by wanabe <s.wanabe@gmail.com>.
This JIT compiler is designed to be a safe migration path to introduce
JIT compiler to MRI. So this commit does not include any bytecode
changes or dynamic instruction modifications, which are done in original
MJIT.
This commit even strips off some aggressive optimizations from
YARV-MJIT, and thus it's slower than YARV-MJIT too. But it's still
fairly faster than Ruby 2.5 in some benchmarks (attached below).
Note that this JIT compiler passes `make test`, `make test-all`, `make
test-spec` without JIT, and even with JIT. Not only it's perfectly safe
with JIT disabled because it does not replace VM instructions unlike
MJIT, but also with JIT enabled it stably runs Ruby applications
including Rails applications.
I'm expecting this version as just "initial" JIT compiler. I have many
optimization ideas which are skipped for initial merging, and you may
easily replace this JIT compiler with a faster one by just replacing
mjit_compile.c. `mjit_compile` interface is designed for the purpose.
common.mk: update dependencies for mjit_compile.c.
internal.h: declare `rb_vm_insn_addr2insn` for MJIT.
vm.c: exclude some definitions if `-DMJIT_HEADER` is provided to
compiler. This avoids to include some functions which take a long time
to compile, e.g. vm_exec_core. Some of the purpose is achieved in
transform_mjit_header.rb (see `IGNORED_FUNCTIONS`) but others are
manually resolved for now. Load mjit_helper.h for MJIT header.
mjit_helper.h: New. This is a file used only by JIT-ed code. I'll
refactor `mjit_call_cfunc` later.
vm_eval.c: add some #ifdef switches to skip compiling some functions
like Init_vm_eval.
win32/mkexports.rb: export thread/ec functions, which are used by MJIT.
include/ruby/defines.h: add MJIT_FUNC_EXPORTED macro alis to clarify
that a function is exported only for MJIT.
array.c: export a function used by MJIT.
bignum.c: ditto.
class.c: ditto.
compile.c: ditto.
error.c: ditto.
gc.c: ditto.
hash.c: ditto.
iseq.c: ditto.
numeric.c: ditto.
object.c: ditto.
proc.c: ditto.
re.c: ditto.
st.c: ditto.
string.c: ditto.
thread.c: ditto.
variable.c: ditto.
vm_backtrace.c: ditto.
vm_insnhelper.c: ditto.
vm_method.c: ditto.
I would like to improve maintainability of function exports, but I
believe this way is acceptable as initial merging if we clarify the
new exports are for MJIT (so that we can use them as TODO list to fix)
and add unit tests to detect unresolved symbols.
I'll add unit tests of JIT compilations in succeeding commits.
Author: Takashi Kokubun <takashikkbn@gmail.com>
Contributor: wanabe <s.wanabe@gmail.com>
Part of [Feature #14235]
---
* Known issues
* Code generated by gcc is faster than clang. The benchmark may be worse
in macOS. Following benchmark result is provided by gcc w/ Linux.
* Performance is decreased when Google Chrome is running
* JIT can work on MinGW, but it doesn't improve performance at least
in short running benchmark.
* Currently it doesn't perform well with Rails. We'll try to fix this
before release.
---
* Benchmark reslts
Benchmarked with:
Intel 4.0GHz i7-4790K with 16GB memory under x86-64 Ubuntu 8 Cores
- 2.0.0-p0: Ruby 2.0.0-p0
- r62186: Ruby trunk (early 2.6.0), before MJIT changes
- JIT off: On this commit, but without `--jit` option
- JIT on: On this commit, and with `--jit` option
** Optcarrot fps
Benchmark: https://github.com/mame/optcarrot
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:--------|:--------|:--------|:--------|:--------|
|fps |37.32 |51.46 |51.31 |58.88 |
|vs 2.0.0 |1.00x |1.38x |1.37x |1.58x |
** MJIT benchmarks
Benchmark: https://github.com/benchmark-driver/mjit-benchmarks
(Original: https://github.com/vnmakarov/ruby/tree/rtl_mjit_branch/MJIT-benchmarks)
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:----------|:--------|:--------|:--------|:--------|
|aread |1.00 |1.09 |1.07 |2.19 |
|aref |1.00 |1.13 |1.11 |2.22 |
|aset |1.00 |1.50 |1.45 |2.64 |
|awrite |1.00 |1.17 |1.13 |2.20 |
|call |1.00 |1.29 |1.26 |2.02 |
|const2 |1.00 |1.10 |1.10 |2.19 |
|const |1.00 |1.11 |1.10 |2.19 |
|fannk |1.00 |1.04 |1.02 |1.00 |
|fib |1.00 |1.32 |1.31 |1.84 |
|ivread |1.00 |1.13 |1.12 |2.43 |
|ivwrite |1.00 |1.23 |1.21 |2.40 |
|mandelbrot |1.00 |1.13 |1.16 |1.28 |
|meteor |1.00 |2.97 |2.92 |3.17 |
|nbody |1.00 |1.17 |1.15 |1.49 |
|nest-ntimes|1.00 |1.22 |1.20 |1.39 |
|nest-while |1.00 |1.10 |1.10 |1.37 |
|norm |1.00 |1.18 |1.16 |1.24 |
|nsvb |1.00 |1.16 |1.16 |1.17 |
|red-black |1.00 |1.02 |0.99 |1.12 |
|sieve |1.00 |1.30 |1.28 |1.62 |
|trees |1.00 |1.14 |1.13 |1.19 |
|while |1.00 |1.12 |1.11 |2.41 |
** Discourse's script/bench.rb
Benchmark: https://github.com/discourse/discourse/blob/v1.8.7/script/bench.rb
NOTE: Rails performance was somehow a little degraded with JIT for now.
We should fix this.
(At least I know opt_aref is performing badly in JIT and I have an idea
to fix it. Please wait for the fix.)
*** JIT off
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 17
75: 18
90: 22
99: 29
home_admin:
50: 21
75: 21
90: 27
99: 40
topic_admin:
50: 17
75: 18
90: 22
99: 32
categories:
50: 35
75: 41
90: 43
99: 77
home:
50: 39
75: 46
90: 49
99: 95
topic:
50: 46
75: 52
90: 56
99: 101
*** JIT on
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 19
75: 21
90: 25
99: 33
home_admin:
50: 24
75: 26
90: 30
99: 35
topic_admin:
50: 19
75: 20
90: 25
99: 30
categories:
50: 40
75: 44
90: 48
99: 76
home:
50: 42
75: 48
90: 51
99: 89
topic:
50: 49
75: 55
90: 58
99: 99
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62197 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 14:22:28 +03:00
|
|
|
MJIT_FUNC_EXPORTED VALUE
|
2007-12-09 19:39:49 +03:00
|
|
|
rb_obj_not_equal(VALUE obj1, VALUE obj2)
|
|
|
|
{
|
|
|
|
VALUE result = rb_funcall(obj1, id_eq, 1, obj2);
|
2022-01-01 09:41:00 +03:00
|
|
|
return rb_obj_not(result);
|
2007-12-09 19:39:49 +03:00
|
|
|
}
|
|
|
|
|
2001-07-14 19:17:19 +04:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_class_real(VALUE cl)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2014-09-26 00:29:15 +04:00
|
|
|
while (cl &&
|
|
|
|
((RBASIC(cl)->flags & FL_SINGLETON) || BUILTIN_TYPE(cl) == T_ICLASS)) {
|
2007-09-28 10:21:46 +04:00
|
|
|
cl = RCLASS_SUPER(cl);
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
return cl;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2001-07-14 19:17:19 +04:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_obj_class(VALUE obj)
|
2001-07-14 19:17:19 +04:00
|
|
|
{
|
|
|
|
return rb_class_real(CLASS_OF(obj));
|
|
|
|
}
|
|
|
|
|
2010-03-23 12:38:54 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj.singleton_class -> class
|
2010-03-23 12:38:54 +03:00
|
|
|
*
|
|
|
|
* Returns the singleton class of <i>obj</i>. This method creates
|
2014-12-09 12:20:05 +03:00
|
|
|
* a new singleton class if <i>obj</i> does not have one.
|
2010-03-23 12:38:54 +03:00
|
|
|
*
|
|
|
|
* If <i>obj</i> is <code>nil</code>, <code>true</code>, or
|
|
|
|
* <code>false</code>, it returns NilClass, TrueClass, or FalseClass,
|
|
|
|
* respectively.
|
2016-10-26 09:11:23 +03:00
|
|
|
* If <i>obj</i> is an Integer, a Float or a Symbol, it raises a TypeError.
|
2010-03-23 12:38:54 +03:00
|
|
|
*
|
|
|
|
* Object.new.singleton_class #=> #<Class:#<Object:0xb7ce1e24>>
|
|
|
|
* String.singleton_class #=> #<Class:String>
|
|
|
|
* nil.singleton_class #=> NilClass
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_obj_singleton_class(VALUE obj)
|
|
|
|
{
|
|
|
|
return rb_singleton_class(obj);
|
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \private */
|
mjit_compile.c: merge initial JIT compiler
which has been developed by Takashi Kokubun <takashikkbn@gmail> as
YARV-MJIT. Many of its bugs are fixed by wanabe <s.wanabe@gmail.com>.
This JIT compiler is designed to be a safe migration path to introduce
JIT compiler to MRI. So this commit does not include any bytecode
changes or dynamic instruction modifications, which are done in original
MJIT.
This commit even strips off some aggressive optimizations from
YARV-MJIT, and thus it's slower than YARV-MJIT too. But it's still
fairly faster than Ruby 2.5 in some benchmarks (attached below).
Note that this JIT compiler passes `make test`, `make test-all`, `make
test-spec` without JIT, and even with JIT. Not only it's perfectly safe
with JIT disabled because it does not replace VM instructions unlike
MJIT, but also with JIT enabled it stably runs Ruby applications
including Rails applications.
I'm expecting this version as just "initial" JIT compiler. I have many
optimization ideas which are skipped for initial merging, and you may
easily replace this JIT compiler with a faster one by just replacing
mjit_compile.c. `mjit_compile` interface is designed for the purpose.
common.mk: update dependencies for mjit_compile.c.
internal.h: declare `rb_vm_insn_addr2insn` for MJIT.
vm.c: exclude some definitions if `-DMJIT_HEADER` is provided to
compiler. This avoids to include some functions which take a long time
to compile, e.g. vm_exec_core. Some of the purpose is achieved in
transform_mjit_header.rb (see `IGNORED_FUNCTIONS`) but others are
manually resolved for now. Load mjit_helper.h for MJIT header.
mjit_helper.h: New. This is a file used only by JIT-ed code. I'll
refactor `mjit_call_cfunc` later.
vm_eval.c: add some #ifdef switches to skip compiling some functions
like Init_vm_eval.
win32/mkexports.rb: export thread/ec functions, which are used by MJIT.
include/ruby/defines.h: add MJIT_FUNC_EXPORTED macro alis to clarify
that a function is exported only for MJIT.
array.c: export a function used by MJIT.
bignum.c: ditto.
class.c: ditto.
compile.c: ditto.
error.c: ditto.
gc.c: ditto.
hash.c: ditto.
iseq.c: ditto.
numeric.c: ditto.
object.c: ditto.
proc.c: ditto.
re.c: ditto.
st.c: ditto.
string.c: ditto.
thread.c: ditto.
variable.c: ditto.
vm_backtrace.c: ditto.
vm_insnhelper.c: ditto.
vm_method.c: ditto.
I would like to improve maintainability of function exports, but I
believe this way is acceptable as initial merging if we clarify the
new exports are for MJIT (so that we can use them as TODO list to fix)
and add unit tests to detect unresolved symbols.
I'll add unit tests of JIT compilations in succeeding commits.
Author: Takashi Kokubun <takashikkbn@gmail.com>
Contributor: wanabe <s.wanabe@gmail.com>
Part of [Feature #14235]
---
* Known issues
* Code generated by gcc is faster than clang. The benchmark may be worse
in macOS. Following benchmark result is provided by gcc w/ Linux.
* Performance is decreased when Google Chrome is running
* JIT can work on MinGW, but it doesn't improve performance at least
in short running benchmark.
* Currently it doesn't perform well with Rails. We'll try to fix this
before release.
---
* Benchmark reslts
Benchmarked with:
Intel 4.0GHz i7-4790K with 16GB memory under x86-64 Ubuntu 8 Cores
- 2.0.0-p0: Ruby 2.0.0-p0
- r62186: Ruby trunk (early 2.6.0), before MJIT changes
- JIT off: On this commit, but without `--jit` option
- JIT on: On this commit, and with `--jit` option
** Optcarrot fps
Benchmark: https://github.com/mame/optcarrot
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:--------|:--------|:--------|:--------|:--------|
|fps |37.32 |51.46 |51.31 |58.88 |
|vs 2.0.0 |1.00x |1.38x |1.37x |1.58x |
** MJIT benchmarks
Benchmark: https://github.com/benchmark-driver/mjit-benchmarks
(Original: https://github.com/vnmakarov/ruby/tree/rtl_mjit_branch/MJIT-benchmarks)
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:----------|:--------|:--------|:--------|:--------|
|aread |1.00 |1.09 |1.07 |2.19 |
|aref |1.00 |1.13 |1.11 |2.22 |
|aset |1.00 |1.50 |1.45 |2.64 |
|awrite |1.00 |1.17 |1.13 |2.20 |
|call |1.00 |1.29 |1.26 |2.02 |
|const2 |1.00 |1.10 |1.10 |2.19 |
|const |1.00 |1.11 |1.10 |2.19 |
|fannk |1.00 |1.04 |1.02 |1.00 |
|fib |1.00 |1.32 |1.31 |1.84 |
|ivread |1.00 |1.13 |1.12 |2.43 |
|ivwrite |1.00 |1.23 |1.21 |2.40 |
|mandelbrot |1.00 |1.13 |1.16 |1.28 |
|meteor |1.00 |2.97 |2.92 |3.17 |
|nbody |1.00 |1.17 |1.15 |1.49 |
|nest-ntimes|1.00 |1.22 |1.20 |1.39 |
|nest-while |1.00 |1.10 |1.10 |1.37 |
|norm |1.00 |1.18 |1.16 |1.24 |
|nsvb |1.00 |1.16 |1.16 |1.17 |
|red-black |1.00 |1.02 |0.99 |1.12 |
|sieve |1.00 |1.30 |1.28 |1.62 |
|trees |1.00 |1.14 |1.13 |1.19 |
|while |1.00 |1.12 |1.11 |2.41 |
** Discourse's script/bench.rb
Benchmark: https://github.com/discourse/discourse/blob/v1.8.7/script/bench.rb
NOTE: Rails performance was somehow a little degraded with JIT for now.
We should fix this.
(At least I know opt_aref is performing badly in JIT and I have an idea
to fix it. Please wait for the fix.)
*** JIT off
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 17
75: 18
90: 22
99: 29
home_admin:
50: 21
75: 21
90: 27
99: 40
topic_admin:
50: 17
75: 18
90: 22
99: 32
categories:
50: 35
75: 41
90: 43
99: 77
home:
50: 39
75: 46
90: 49
99: 95
topic:
50: 46
75: 52
90: 56
99: 101
*** JIT on
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 19
75: 21
90: 25
99: 33
home_admin:
50: 24
75: 26
90: 30
99: 35
topic_admin:
50: 19
75: 20
90: 25
99: 30
categories:
50: 40
75: 44
90: 48
99: 76
home:
50: 42
75: 48
90: 51
99: 89
topic:
50: 49
75: 55
90: 58
99: 99
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62197 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 14:22:28 +03:00
|
|
|
MJIT_FUNC_EXPORTED void
|
2014-06-23 06:33:15 +04:00
|
|
|
rb_obj_copy_ivar(VALUE dest, VALUE obj)
|
|
|
|
{
|
2022-11-08 23:35:31 +03:00
|
|
|
RUBY_ASSERT(!RB_TYPE_P(obj, T_CLASS) && !RB_TYPE_P(obj, T_MODULE));
|
2021-02-23 03:18:10 +03:00
|
|
|
|
2022-11-08 23:35:31 +03:00
|
|
|
RUBY_ASSERT(BUILTIN_TYPE(dest) == BUILTIN_TYPE(obj));
|
|
|
|
uint32_t src_num_ivs = RBASIC_IV_COUNT(obj);
|
|
|
|
rb_shape_t * src_shape = rb_shape_get_shape(obj);
|
|
|
|
rb_shape_t * shape_to_set_on_dest = src_shape;
|
|
|
|
VALUE * src_buf;
|
|
|
|
VALUE * dest_buf;
|
|
|
|
|
|
|
|
if (!src_num_ivs) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The copy should be mutable, so we don't want the frozen shape
|
|
|
|
if (rb_shape_frozen_shape_p(src_shape)) {
|
2022-11-10 19:36:24 +03:00
|
|
|
shape_to_set_on_dest = rb_shape_get_parent(src_shape);
|
2022-10-03 18:14:32 +03:00
|
|
|
}
|
2022-11-08 23:35:31 +03:00
|
|
|
|
|
|
|
src_buf = ROBJECT_IVPTR(obj);
|
|
|
|
dest_buf = ROBJECT_IVPTR(dest);
|
|
|
|
|
|
|
|
rb_shape_t * initial_shape = rb_shape_get_shape(dest);
|
|
|
|
|
|
|
|
if (initial_shape->size_pool_index != src_shape->size_pool_index) {
|
2022-11-18 02:57:11 +03:00
|
|
|
RUBY_ASSERT(initial_shape->type == SHAPE_T_OBJECT);
|
2022-11-08 23:35:31 +03:00
|
|
|
|
|
|
|
shape_to_set_on_dest = rb_shape_rebuild_shape(initial_shape, src_shape);
|
|
|
|
}
|
|
|
|
|
|
|
|
RUBY_ASSERT(src_num_ivs <= shape_to_set_on_dest->capacity);
|
|
|
|
if (initial_shape->capacity < shape_to_set_on_dest->capacity) {
|
|
|
|
rb_ensure_iv_list_size(dest, initial_shape->capacity, shape_to_set_on_dest->capacity);
|
|
|
|
dest_buf = ROBJECT_IVPTR(dest);
|
2022-10-03 18:14:32 +03:00
|
|
|
}
|
|
|
|
|
2022-11-08 23:35:31 +03:00
|
|
|
MEMCPY(dest_buf, src_buf, VALUE, src_num_ivs);
|
|
|
|
|
|
|
|
// Fire write barriers
|
|
|
|
for (uint32_t i = 0; i < src_num_ivs; i++) {
|
|
|
|
RB_OBJ_WRITTEN(dest, Qundef, dest_buf[i]);
|
|
|
|
}
|
2022-10-17 21:31:24 +03:00
|
|
|
|
2022-11-08 23:35:31 +03:00
|
|
|
rb_shape_set_shape(dest, shape_to_set_on_dest);
|
2014-06-23 06:33:15 +04:00
|
|
|
}
|
|
|
|
|
2002-09-03 09:20:14 +04:00
|
|
|
static void
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
init_copy(VALUE dest, VALUE obj)
|
2002-09-03 09:20:14 +04:00
|
|
|
{
|
2002-09-04 10:37:39 +04:00
|
|
|
if (OBJ_FROZEN(dest)) {
|
2003-01-31 07:00:17 +03:00
|
|
|
rb_raise(rb_eTypeError, "[bug] frozen object (%s) allocated", rb_obj_classname(dest));
|
2002-09-04 10:37:39 +04:00
|
|
|
}
|
|
|
|
RBASIC(dest)->flags &= ~(T_MASK|FL_EXIVAR);
|
2022-10-03 18:14:32 +03:00
|
|
|
// Copies the shape id from obj to dest
|
2019-09-25 06:59:12 +03:00
|
|
|
RBASIC(dest)->flags |= RBASIC(obj)->flags & (T_MASK|FL_EXIVAR);
|
2014-09-08 08:11:00 +04:00
|
|
|
rb_copy_wb_protected_attribute(dest, obj);
|
2004-05-14 20:39:15 +04:00
|
|
|
rb_copy_generic_ivar(dest, obj);
|
2002-12-04 10:39:32 +03:00
|
|
|
rb_gc_copy_finalizer(dest, obj);
|
2022-10-03 18:14:32 +03:00
|
|
|
|
2022-11-01 22:31:24 +03:00
|
|
|
if (RB_TYPE_P(obj, T_OBJECT)) {
|
|
|
|
rb_obj_copy_ivar(dest, obj);
|
|
|
|
}
|
2002-09-03 09:20:14 +04:00
|
|
|
}
|
|
|
|
|
2019-09-24 02:03:15 +03:00
|
|
|
static VALUE immutable_obj_clone(VALUE obj, VALUE kwfreeze);
|
|
|
|
static VALUE mutable_obj_clone(VALUE obj, VALUE kwfreeze);
|
2017-07-22 09:30:53 +03:00
|
|
|
PUREFUNC(static inline int special_object_p(VALUE obj)); /*!< \private */
|
2016-11-29 18:34:31 +03:00
|
|
|
static inline int
|
|
|
|
special_object_p(VALUE obj)
|
|
|
|
{
|
|
|
|
if (SPECIAL_CONST_P(obj)) return TRUE;
|
|
|
|
switch (BUILTIN_TYPE(obj)) {
|
|
|
|
case T_BIGNUM:
|
|
|
|
case T_FLOAT:
|
2017-01-23 09:16:04 +03:00
|
|
|
case T_SYMBOL:
|
2017-02-22 05:02:11 +03:00
|
|
|
case T_RATIONAL:
|
|
|
|
case T_COMPLEX:
|
|
|
|
/* not a comprehensive list */
|
2016-11-29 18:34:31 +03:00
|
|
|
return TRUE;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-24 02:03:15 +03:00
|
|
|
static VALUE
|
2020-03-17 13:37:07 +03:00
|
|
|
obj_freeze_opt(VALUE freeze)
|
|
|
|
{
|
2021-06-16 16:07:05 +03:00
|
|
|
switch (freeze) {
|
2019-09-24 02:03:15 +03:00
|
|
|
case Qfalse:
|
|
|
|
case Qtrue:
|
|
|
|
case Qnil:
|
|
|
|
break;
|
|
|
|
default:
|
2020-03-17 13:37:07 +03:00
|
|
|
rb_raise(rb_eArgError, "unexpected value for freeze: %"PRIsVALUE, rb_obj_class(freeze));
|
2019-09-24 02:03:15 +03:00
|
|
|
}
|
2020-03-17 13:37:07 +03:00
|
|
|
|
2019-09-24 02:03:15 +03:00
|
|
|
return freeze;
|
2020-03-17 13:37:07 +03:00
|
|
|
}
|
2003-12-28 09:33:07 +03:00
|
|
|
|
2016-08-01 08:55:35 +03:00
|
|
|
static VALUE
|
2020-03-17 13:37:07 +03:00
|
|
|
rb_obj_clone2(rb_execution_context_t *ec, VALUE obj, VALUE freeze)
|
2017-02-22 04:55:10 +03:00
|
|
|
{
|
2019-09-24 02:03:15 +03:00
|
|
|
VALUE kwfreeze = obj_freeze_opt(freeze);
|
2017-02-22 04:55:10 +03:00
|
|
|
if (!special_object_p(obj))
|
|
|
|
return mutable_obj_clone(obj, kwfreeze);
|
|
|
|
return immutable_obj_clone(obj, kwfreeze);
|
2017-02-22 05:02:11 +03:00
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \private */
|
2017-02-22 05:02:11 +03:00
|
|
|
VALUE
|
|
|
|
rb_immutable_obj_clone(int argc, VALUE *argv, VALUE obj)
|
|
|
|
{
|
2021-06-28 04:51:42 +03:00
|
|
|
VALUE kwfreeze = rb_get_freeze_opt(argc, argv);
|
2017-02-22 05:02:11 +03:00
|
|
|
return immutable_obj_clone(obj, kwfreeze);
|
2017-02-22 04:55:10 +03:00
|
|
|
}
|
|
|
|
|
2021-06-28 04:51:42 +03:00
|
|
|
VALUE
|
|
|
|
rb_get_freeze_opt(int argc, VALUE *argv)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2016-08-01 08:55:35 +03:00
|
|
|
static ID keyword_ids[1];
|
|
|
|
VALUE opt;
|
2019-09-24 02:03:15 +03:00
|
|
|
VALUE kwfreeze = Qnil;
|
2016-08-01 08:55:35 +03:00
|
|
|
|
|
|
|
if (!keyword_ids[0]) {
|
|
|
|
CONST_ID(keyword_ids[0], "freeze");
|
|
|
|
}
|
2016-08-03 09:03:50 +03:00
|
|
|
rb_scan_args(argc, argv, "0:", &opt);
|
2016-08-01 08:55:35 +03:00
|
|
|
if (!NIL_P(opt)) {
|
2017-02-22 04:55:10 +03:00
|
|
|
rb_get_kwargs(opt, keyword_ids, 0, 1, &kwfreeze);
|
2022-11-15 07:24:08 +03:00
|
|
|
if (!UNDEF_P(kwfreeze))
|
2019-09-24 02:03:15 +03:00
|
|
|
kwfreeze = obj_freeze_opt(kwfreeze);
|
2016-08-01 08:55:35 +03:00
|
|
|
}
|
2019-09-24 02:03:15 +03:00
|
|
|
return kwfreeze;
|
2017-02-22 04:55:10 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
2019-09-24 02:03:15 +03:00
|
|
|
immutable_obj_clone(VALUE obj, VALUE kwfreeze)
|
2017-02-22 04:55:10 +03:00
|
|
|
{
|
2019-09-24 02:03:15 +03:00
|
|
|
if (kwfreeze == Qfalse)
|
2017-02-22 04:55:10 +03:00
|
|
|
rb_raise(rb_eArgError, "can't unfreeze %"PRIsVALUE,
|
|
|
|
rb_obj_class(obj));
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
2019-09-24 02:03:15 +03:00
|
|
|
mutable_obj_clone(VALUE obj, VALUE kwfreeze)
|
2017-02-22 04:55:10 +03:00
|
|
|
{
|
|
|
|
VALUE clone, singleton;
|
2019-09-24 02:03:15 +03:00
|
|
|
VALUE argv[2];
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2002-09-03 09:20:14 +04:00
|
|
|
clone = rb_obj_alloc(rb_obj_class(obj));
|
2013-05-23 22:01:46 +04:00
|
|
|
|
2012-12-29 06:37:47 +04:00
|
|
|
singleton = rb_singleton_class_clone_and_attach(obj, clone);
|
* include/ruby/ruby.h: constify RBasic::klass and add
RBASIC_CLASS(obj) macro which returns a class of `obj'.
This change is a part of RGENGC branch [ruby-trunk - Feature #8339].
* object.c: add new function rb_obj_reveal().
This function reveal interal (hidden) object by rb_obj_hide().
Note that do not change class before and after hiding.
Only permitted example is:
klass = RBASIC_CLASS(obj);
rb_obj_hide(obj);
....
rb_obj_reveal(obj, klass);
TODO: API design. rb_obj_reveal() should be replaced with others.
TODO: modify constified variables using cast may be harmful for
compiler's analysis and optimizaton.
Any idea to prohibt inserting RBasic::klass directly?
If rename RBasic::klass and force to use RBASIC_CLASS(obj),
then all codes such as `RBASIC(obj)->klass' will be
compilation error. Is it acceptable? (We have similar
experience at Ruby 1.9,
for example "RARRAY(ary)->ptr" to "RARRAY_PTR(ary)".
* internal.h: add some macros.
* RBASIC_CLEAR_CLASS(obj) clear RBasic::klass to make it internal
object.
* RBASIC_SET_CLASS(obj, cls) set RBasic::klass.
* RBASIC_SET_CLASS_RAW(obj, cls) same as RBASIC_SET_CLASS
without write barrier (planned).
* RCLASS_SET_SUPER(a, b) set super class of a.
* array.c, class.c, compile.c, encoding.c, enum.c, error.c, eval.c,
file.c, gc.c, hash.c, io.c, iseq.c, marshal.c, object.c,
parse.y, proc.c, process.c, random.c, ruby.c, sprintf.c,
string.c, thread.c, transcode.c, vm.c, vm_eval.c, win32/file.c:
Use above macros and functions to access RBasic::klass.
* ext/coverage/coverage.c, ext/readline/readline.c,
ext/socket/ancdata.c, ext/socket/init.c,
* ext/zlib/zlib.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40691 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-05-13 14:49:11 +04:00
|
|
|
RBASIC_SET_CLASS(clone, singleton);
|
2011-09-19 02:54:25 +04:00
|
|
|
if (FL_TEST(singleton, FL_SINGLETON)) {
|
|
|
|
rb_singleton_class_attached(singleton, clone);
|
|
|
|
}
|
2013-05-23 22:01:46 +04:00
|
|
|
|
2003-05-20 12:40:50 +04:00
|
|
|
init_copy(clone, obj);
|
2016-08-01 08:55:35 +03:00
|
|
|
|
2019-09-24 02:03:15 +03:00
|
|
|
switch (kwfreeze) {
|
|
|
|
case Qnil:
|
2019-08-26 07:11:46 +03:00
|
|
|
rb_funcall(clone, id_init_clone, 1, obj);
|
2016-08-01 08:55:35 +03:00
|
|
|
RBASIC(clone)->flags |= RBASIC(obj)->flags & FL_FREEZE;
|
2022-10-03 18:14:32 +03:00
|
|
|
if (RB_OBJ_FROZEN(obj)) {
|
|
|
|
rb_shape_transition_shape_frozen(clone);
|
|
|
|
}
|
2019-09-24 02:03:15 +03:00
|
|
|
break;
|
|
|
|
case Qtrue:
|
|
|
|
{
|
|
|
|
static VALUE freeze_true_hash;
|
|
|
|
if (!freeze_true_hash) {
|
|
|
|
freeze_true_hash = rb_hash_new();
|
|
|
|
rb_gc_register_mark_object(freeze_true_hash);
|
2021-07-27 03:20:24 +03:00
|
|
|
rb_hash_aset(freeze_true_hash, ID2SYM(idFreeze), Qtrue);
|
2019-09-24 02:03:15 +03:00
|
|
|
rb_obj_freeze(freeze_true_hash);
|
|
|
|
}
|
|
|
|
|
|
|
|
argv[0] = obj;
|
|
|
|
argv[1] = freeze_true_hash;
|
|
|
|
rb_funcallv_kw(clone, id_init_clone, 2, argv, RB_PASS_KEYWORDS);
|
|
|
|
RBASIC(clone)->flags |= FL_FREEZE;
|
2022-10-03 18:14:32 +03:00
|
|
|
rb_shape_transition_shape_frozen(clone);
|
2019-09-24 02:03:15 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case Qfalse:
|
|
|
|
{
|
2019-08-26 07:11:46 +03:00
|
|
|
static VALUE freeze_false_hash;
|
|
|
|
if (!freeze_false_hash) {
|
|
|
|
freeze_false_hash = rb_hash_new();
|
2019-09-24 02:03:15 +03:00
|
|
|
rb_gc_register_mark_object(freeze_false_hash);
|
2021-07-27 03:20:24 +03:00
|
|
|
rb_hash_aset(freeze_false_hash, ID2SYM(idFreeze), Qfalse);
|
2019-08-26 07:11:46 +03:00
|
|
|
rb_obj_freeze(freeze_false_hash);
|
|
|
|
}
|
|
|
|
|
|
|
|
argv[0] = obj;
|
|
|
|
argv[1] = freeze_false_hash;
|
2020-03-12 11:09:43 +03:00
|
|
|
rb_funcallv_kw(clone, id_init_clone, 2, argv, RB_PASS_KEYWORDS);
|
2019-09-24 02:03:15 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
rb_bug("invalid kwfreeze passed to mutable_obj_clone");
|
2019-08-26 07:11:46 +03:00
|
|
|
}
|
1998-01-16 15:13:05 +03:00
|
|
|
|
|
|
|
return clone;
|
|
|
|
}
|
|
|
|
|
2016-08-01 08:55:35 +03:00
|
|
|
VALUE
|
|
|
|
rb_obj_clone(VALUE obj)
|
|
|
|
{
|
2017-02-22 04:55:10 +03:00
|
|
|
if (special_object_p(obj)) return obj;
|
2019-09-24 02:03:15 +03:00
|
|
|
return mutable_obj_clone(obj, Qnil);
|
2016-08-01 08:55:35 +03:00
|
|
|
}
|
|
|
|
|
2021-03-11 10:34:49 +03:00
|
|
|
/*
|
2003-12-28 09:33:07 +03:00
|
|
|
* call-seq:
|
|
|
|
* obj.dup -> an_object
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Produces a shallow copy of <i>obj</i>---the instance variables of
|
2014-12-09 12:20:05 +03:00
|
|
|
* <i>obj</i> are copied, but not the objects they reference.
|
2004-02-10 11:12:04 +03:00
|
|
|
*
|
|
|
|
* This method may have class-specific behavior. If so, that
|
|
|
|
* behavior will be documented under the #+initialize_copy+ method of
|
|
|
|
* the class.
|
2013-11-21 09:19:32 +04:00
|
|
|
*
|
|
|
|
* === on dup vs clone
|
|
|
|
*
|
2019-03-22 14:04:59 +03:00
|
|
|
* In general, #clone and #dup may have different semantics in
|
|
|
|
* descendant classes. While #clone is used to duplicate an object,
|
|
|
|
* including its internal state, #dup typically uses the class of the
|
|
|
|
* descendant object to create the new instance.
|
2013-11-21 09:19:32 +04:00
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* When using #dup, any modules that the object has been extended with will not
|
2013-11-21 09:19:32 +04:00
|
|
|
* be copied.
|
|
|
|
*
|
|
|
|
* class Klass
|
|
|
|
* attr_accessor :str
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* module Foo
|
|
|
|
* def foo; 'foo'; end
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* s1 = Klass.new #=> #<Klass:0x401b3a38>
|
|
|
|
* s1.extend(Foo) #=> #<Klass:0x401b3a38>
|
|
|
|
* s1.foo #=> "foo"
|
|
|
|
*
|
2020-06-07 11:01:37 +03:00
|
|
|
* s2 = s1.clone #=> #<Klass:0x401be280>
|
2013-11-21 09:19:32 +04:00
|
|
|
* s2.foo #=> "foo"
|
|
|
|
*
|
2020-06-07 11:01:37 +03:00
|
|
|
* s3 = s1.dup #=> #<Klass:0x401c1084>
|
|
|
|
* s3.foo #=> NoMethodError: undefined method `foo' for #<Klass:0x401c1084>
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
2000-07-17 13:38:10 +04:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_obj_dup(VALUE obj)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2000-07-17 13:38:10 +04:00
|
|
|
VALUE dup;
|
2000-06-22 12:29:58 +04:00
|
|
|
|
2016-11-29 18:34:31 +03:00
|
|
|
if (special_object_p(obj)) {
|
2016-11-27 14:07:27 +03:00
|
|
|
return obj;
|
2002-02-01 09:03:03 +03:00
|
|
|
}
|
2002-09-03 09:20:14 +04:00
|
|
|
dup = rb_obj_alloc(rb_obj_class(obj));
|
2003-05-19 09:41:08 +04:00
|
|
|
init_copy(dup, obj);
|
2010-02-08 10:43:54 +03:00
|
|
|
rb_funcall(dup, id_init_dup, 1, obj);
|
2002-08-27 12:31:08 +04:00
|
|
|
|
|
|
|
return dup;
|
|
|
|
}
|
|
|
|
|
2014-08-02 05:26:58 +04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2017-05-30 21:17:55 +03:00
|
|
|
* obj.itself -> obj
|
2014-08-02 05:26:58 +04:00
|
|
|
*
|
2017-05-30 21:17:55 +03:00
|
|
|
* Returns the receiver.
|
2014-08-02 05:26:58 +04:00
|
|
|
*
|
2017-05-30 21:17:55 +03:00
|
|
|
* string = "my string"
|
|
|
|
* string.itself.object_id == string.object_id #=> true
|
2014-08-02 05:26:58 +04:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_obj_itself(VALUE obj)
|
|
|
|
{
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2020-07-10 05:49:50 +03:00
|
|
|
VALUE
|
2017-05-14 14:45:00 +03:00
|
|
|
rb_obj_size(VALUE self, VALUE args, VALUE obj)
|
|
|
|
{
|
|
|
|
return LONG2FIX(1);
|
|
|
|
}
|
|
|
|
|
2017-05-01 10:50:53 +03:00
|
|
|
static VALUE
|
2020-07-04 04:02:43 +03:00
|
|
|
block_given_p(rb_execution_context_t *ec, VALUE self)
|
2017-05-01 10:50:53 +03:00
|
|
|
{
|
2021-08-02 06:06:44 +03:00
|
|
|
return RBOOL(rb_block_given_p());
|
2017-05-01 10:50:53 +03:00
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/**
|
|
|
|
* :nodoc:
|
|
|
|
*--
|
2017-07-22 11:07:56 +03:00
|
|
|
* Default implementation of \c #initialize_copy
|
2017-07-22 09:30:53 +03:00
|
|
|
* \param[in,out] obj the receiver being initialized
|
|
|
|
* \param[in] orig the object to be copied from.
|
|
|
|
*++
|
|
|
|
*/
|
2002-08-27 12:31:08 +04:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_obj_init_copy(VALUE obj, VALUE orig)
|
2002-08-27 12:31:08 +04:00
|
|
|
{
|
2002-09-03 09:20:14 +04:00
|
|
|
if (obj == orig) return obj;
|
|
|
|
rb_check_frozen(obj);
|
|
|
|
if (TYPE(obj) != TYPE(orig) || rb_obj_class(obj) != rb_obj_class(orig)) {
|
2003-05-19 09:41:08 +04:00
|
|
|
rb_raise(rb_eTypeError, "initialize_copy should take same class object");
|
2000-07-17 13:38:10 +04:00
|
|
|
}
|
2002-08-27 12:31:08 +04:00
|
|
|
return obj;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*!
|
|
|
|
* :nodoc:
|
|
|
|
*--
|
2019-08-26 07:11:46 +03:00
|
|
|
* Default implementation of \c #initialize_dup
|
2017-07-22 09:30:53 +03:00
|
|
|
*
|
|
|
|
* \param[in,out] obj the receiver being initialized
|
2019-08-26 07:11:46 +03:00
|
|
|
* \param[in] orig the object to be dup from.
|
2017-07-22 09:30:53 +03:00
|
|
|
*++
|
|
|
|
**/
|
2010-02-08 10:43:54 +03:00
|
|
|
VALUE
|
|
|
|
rb_obj_init_dup_clone(VALUE obj, VALUE orig)
|
|
|
|
{
|
|
|
|
rb_funcall(obj, id_init_copy, 1, orig);
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2019-08-26 07:11:46 +03:00
|
|
|
/*!
|
|
|
|
* :nodoc:
|
|
|
|
*--
|
|
|
|
* Default implementation of \c #initialize_clone
|
|
|
|
*
|
|
|
|
* \param[in] The number of arguments
|
|
|
|
* \param[in] The array of arguments
|
|
|
|
* \param[in] obj the receiver being initialized
|
|
|
|
*++
|
|
|
|
**/
|
|
|
|
static VALUE
|
|
|
|
rb_obj_init_clone(int argc, VALUE *argv, VALUE obj)
|
|
|
|
{
|
|
|
|
VALUE orig, opts;
|
2021-06-28 04:51:42 +03:00
|
|
|
if (rb_scan_args(argc, argv, "1:", &orig, &opts) < argc) {
|
|
|
|
/* Ignore a freeze keyword */
|
|
|
|
rb_get_freeze_opt(1, &opts);
|
|
|
|
}
|
2019-08-26 07:11:46 +03:00
|
|
|
rb_funcall(obj, id_init_copy, 1, orig);
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2021-03-11 10:34:49 +03:00
|
|
|
/*
|
2003-12-28 09:33:07 +03:00
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj.to_s -> string
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2019-03-22 14:04:59 +03:00
|
|
|
* Returns a string representing <i>obj</i>. The default #to_s prints
|
|
|
|
* the object's class and an encoding of the object id. As a special
|
|
|
|
* case, the top-level object that is the initial execution context
|
|
|
|
* of Ruby programs returns ``main''.
|
2017-07-22 09:30:53 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
1998-01-16 15:13:05 +03:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_any_to_s(VALUE obj)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
1999-01-20 07:59:39 +03:00
|
|
|
VALUE str;
|
2012-08-17 18:29:00 +04:00
|
|
|
VALUE cname = rb_class_name(CLASS_OF(obj));
|
1999-01-20 07:59:39 +03:00
|
|
|
|
2012-08-17 18:29:00 +04:00
|
|
|
str = rb_sprintf("#<%"PRIsVALUE":%p>", cname, (void*)obj);
|
1998-01-16 15:13:05 +03:00
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
return str;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_inspect(VALUE obj)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2015-02-16 07:08:52 +03:00
|
|
|
VALUE str = rb_obj_as_string(rb_funcallv(obj, id_inspect, 0, 0));
|
2017-07-22 09:30:53 +03:00
|
|
|
|
2015-12-13 05:48:34 +03:00
|
|
|
rb_encoding *enc = rb_default_internal_encoding();
|
|
|
|
if (enc == NULL) enc = rb_default_external_encoding();
|
|
|
|
if (!rb_enc_asciicompat(enc)) {
|
2012-01-15 11:28:50 +04:00
|
|
|
if (!rb_enc_str_asciionly_p(str))
|
2015-12-10 21:57:08 +03:00
|
|
|
return rb_str_escape(str);
|
2012-01-15 11:28:50 +04:00
|
|
|
return str;
|
|
|
|
}
|
2015-12-13 05:48:34 +03:00
|
|
|
if (rb_enc_get(str) != enc && !rb_enc_str_asciionly_p(str))
|
2015-12-10 21:57:08 +03:00
|
|
|
return rb_str_escape(str);
|
2012-01-15 11:28:50 +04:00
|
|
|
return str;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2012-03-31 02:40:54 +04:00
|
|
|
inspect_i(st_data_t k, st_data_t v, st_data_t a)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2012-03-31 02:40:54 +04:00
|
|
|
ID id = (ID)k;
|
|
|
|
VALUE value = (VALUE)v;
|
|
|
|
VALUE str = (VALUE)a;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
|
|
|
/* need not to show internal data */
|
|
|
|
if (CLASS_OF(value) == 0) return ST_CONTINUE;
|
1999-01-20 07:59:39 +03:00
|
|
|
if (!rb_is_instance_id(id)) return ST_CONTINUE;
|
2006-08-31 14:47:44 +04:00
|
|
|
if (RSTRING_PTR(str)[0] == '-') { /* first element */
|
|
|
|
RSTRING_PTR(str)[0] = '#';
|
2001-01-15 10:01:00 +03:00
|
|
|
rb_str_cat2(str, " ");
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
else {
|
2000-04-10 09:48:43 +04:00
|
|
|
rb_str_cat2(str, ", ");
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2014-11-25 21:44:16 +03:00
|
|
|
rb_str_catf(str, "%"PRIsVALUE"=%+"PRIsVALUE,
|
|
|
|
rb_id2str(id), value);
|
1998-01-16 15:13:05 +03:00
|
|
|
|
|
|
|
return ST_CONTINUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
inspect_obj(VALUE obj, VALUE str, int recur)
|
1999-01-20 07:59:39 +03:00
|
|
|
{
|
* array.c: replace rb_protect_inspect() and rb_inspecting_p() by
rb_exec_recursive() in eval.c.
* eval.c (rb_exec_recursive): new function.
* array.c (rb_ary_join): use rb_exec_recursive().
* array.c (rb_ary_inspect, rb_ary_hash): ditto.
* file.c (rb_file_join): ditto.
* hash.c (rb_hash_inspect, rb_hash_to_s, rb_hash_hash): ditto.
* io.c (rb_io_puts): ditto.
* object.c (rb_obj_inspect): ditto
* struct.c (rb_struct_inspect): ditto.
* lib/set.rb (SortedSet::setup): a hack to shut up warning.
[ruby-talk:132866]
* lib/time.rb (Time::strptime): add new function. inspired by
[ruby-talk:132815].
* lib/parsedate.rb (ParseDate::strptime): ditto.
* regparse.c: move st_*_strend() functions from st.c. fixed some
potential memory leaks.
* exception error messages updated. [ruby-core:04497]
* ext/socket/socket.c (Init_socket): add bunch of Socket
constants. Patch from Sam Roberts <sroberts@uniserve.com>.
[ruby-core:04409]
* array.c (rb_ary_s_create): no need for negative argc check.
[ruby-core:04463]
* array.c (rb_ary_unshift_m): ditto.
* lib/xmlrpc/parser.rb (XMLRPC::FaultException): make it subclass
of StandardError class, not Exception class. [ruby-core:04429]
* parse.y (fcall_gen): lvar(arg) will be evaluated as
lvar.call(arg) when lvar is a defined local variable. [new]
* object.c (rb_class_initialize): call inherited method before
calling initializing block.
* eval.c (rb_thread_start_1): initialize newly pushed frame.
* lib/open3.rb (Open3::popen3): $? should not be EXIT_FAILURE.
fixed: [ruby-core:04444]
* eval.c (is_defined): NODE_IASGN is an assignment.
* ext/readline/readline.c (Readline.readline): use rl_outstream
and rl_instream. [ruby-dev:25699]
* ext/etc/etc.c (Init_etc): sGroup needs HAVE_ST_GR_PASSWD check
[ruby-dev:25675]
* misc/ruby-mode.el: [ruby-core:04415]
* lib/rdoc/generators/html_generator.rb: [ruby-core:04412]
* lib/rdoc/generators/ri_generator.rb: ditto.
* struct.c (make_struct): fixed: [ruby-core:04402]
* ext/curses/curses.c (window_color_set): [ruby-core:04393]
* ext/socket/socket.c (Init_socket): SO_REUSEPORT added.
[ruby-talk:130092]
* object.c: [ruby-doc:818]
* parse.y (open_args): fix too verbose warnings for the space
before argument parentheses. [ruby-dev:25492]
* parse.y (parser_yylex): ditto.
* parse.y (parser_yylex): the first expression in the parentheses
should not be a command. [ruby-dev:25492]
* lib/irb/context.rb (IRB::Context::initialize): [ruby-core:04330]
* object.c (Init_Object): remove Object#type. [ruby-core:04335]
* st.c (st_foreach): report success/failure by return value.
[ruby-Bugs-1396]
* parse.y: forgot to initialize parser struct. [ruby-dev:25492]
* parse.y (parser_yylex): no tLABEL on EXPR_BEG.
[ruby-talk:127711]
* document updates - [ruby-core:04296], [ruby-core:04301],
[ruby-core:04302], [ruby-core:04307]
* dir.c (rb_push_glob): should work for NUL delimited patterns.
* dir.c (rb_glob2): should aware of offset in the pattern.
* string.c (rb_str_new4): should propagate taintedness.
* env.h: rename member names in struct FRAME; last_func -> callee,
orig_func -> this_func, last_class -> this_class.
* struct.c (rb_struct_set): use original method name, not callee
name, to retrieve member slot. [ruby-core:04268]
* time.c (time_strftime): protect from format modification from GC
finalizers.
* object.c (Init_Object): remove rb_obj_id_obsolete()
* eval.c (rb_mod_define_method): incomplete subclass check.
[ruby-dev:25464]
* gc.c (rb_data_object_alloc): klass may be NULL.
[ruby-list:40498]
* bignum.c (rb_big_rand): should return positive random number.
[ruby-dev:25401]
* bignum.c (rb_big_rand): do not use rb_big_modulo to generate
random bignums. [ruby-dev:25396]
* variable.c (rb_autoload): [ruby-dev:25373]
* eval.c (svalue_to_avalue): [ruby-dev:25366]
* string.c (rb_str_justify): [ruby-dev:25367]
* io.c (rb_f_select): [ruby-dev:25312]
* ext/socket/socket.c (sock_s_getservbyport): [ruby-talk:124072]
* struct.c (make_struct): [ruby-dev:25249]
* dir.c (dir_open_dir): new function. [ruby-dev:25242]
* io.c (rb_f_open): add type check for return value from to_open.
* lib/pstore.rb (PStore#transaction): Use the empty content when a
file is not found. [ruby-dev:24561]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8068 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-03-04 09:47:45 +03:00
|
|
|
if (recur) {
|
2005-03-07 05:05:08 +03:00
|
|
|
rb_str_cat2(str, " ...");
|
* array.c: replace rb_protect_inspect() and rb_inspecting_p() by
rb_exec_recursive() in eval.c.
* eval.c (rb_exec_recursive): new function.
* array.c (rb_ary_join): use rb_exec_recursive().
* array.c (rb_ary_inspect, rb_ary_hash): ditto.
* file.c (rb_file_join): ditto.
* hash.c (rb_hash_inspect, rb_hash_to_s, rb_hash_hash): ditto.
* io.c (rb_io_puts): ditto.
* object.c (rb_obj_inspect): ditto
* struct.c (rb_struct_inspect): ditto.
* lib/set.rb (SortedSet::setup): a hack to shut up warning.
[ruby-talk:132866]
* lib/time.rb (Time::strptime): add new function. inspired by
[ruby-talk:132815].
* lib/parsedate.rb (ParseDate::strptime): ditto.
* regparse.c: move st_*_strend() functions from st.c. fixed some
potential memory leaks.
* exception error messages updated. [ruby-core:04497]
* ext/socket/socket.c (Init_socket): add bunch of Socket
constants. Patch from Sam Roberts <sroberts@uniserve.com>.
[ruby-core:04409]
* array.c (rb_ary_s_create): no need for negative argc check.
[ruby-core:04463]
* array.c (rb_ary_unshift_m): ditto.
* lib/xmlrpc/parser.rb (XMLRPC::FaultException): make it subclass
of StandardError class, not Exception class. [ruby-core:04429]
* parse.y (fcall_gen): lvar(arg) will be evaluated as
lvar.call(arg) when lvar is a defined local variable. [new]
* object.c (rb_class_initialize): call inherited method before
calling initializing block.
* eval.c (rb_thread_start_1): initialize newly pushed frame.
* lib/open3.rb (Open3::popen3): $? should not be EXIT_FAILURE.
fixed: [ruby-core:04444]
* eval.c (is_defined): NODE_IASGN is an assignment.
* ext/readline/readline.c (Readline.readline): use rl_outstream
and rl_instream. [ruby-dev:25699]
* ext/etc/etc.c (Init_etc): sGroup needs HAVE_ST_GR_PASSWD check
[ruby-dev:25675]
* misc/ruby-mode.el: [ruby-core:04415]
* lib/rdoc/generators/html_generator.rb: [ruby-core:04412]
* lib/rdoc/generators/ri_generator.rb: ditto.
* struct.c (make_struct): fixed: [ruby-core:04402]
* ext/curses/curses.c (window_color_set): [ruby-core:04393]
* ext/socket/socket.c (Init_socket): SO_REUSEPORT added.
[ruby-talk:130092]
* object.c: [ruby-doc:818]
* parse.y (open_args): fix too verbose warnings for the space
before argument parentheses. [ruby-dev:25492]
* parse.y (parser_yylex): ditto.
* parse.y (parser_yylex): the first expression in the parentheses
should not be a command. [ruby-dev:25492]
* lib/irb/context.rb (IRB::Context::initialize): [ruby-core:04330]
* object.c (Init_Object): remove Object#type. [ruby-core:04335]
* st.c (st_foreach): report success/failure by return value.
[ruby-Bugs-1396]
* parse.y: forgot to initialize parser struct. [ruby-dev:25492]
* parse.y (parser_yylex): no tLABEL on EXPR_BEG.
[ruby-talk:127711]
* document updates - [ruby-core:04296], [ruby-core:04301],
[ruby-core:04302], [ruby-core:04307]
* dir.c (rb_push_glob): should work for NUL delimited patterns.
* dir.c (rb_glob2): should aware of offset in the pattern.
* string.c (rb_str_new4): should propagate taintedness.
* env.h: rename member names in struct FRAME; last_func -> callee,
orig_func -> this_func, last_class -> this_class.
* struct.c (rb_struct_set): use original method name, not callee
name, to retrieve member slot. [ruby-core:04268]
* time.c (time_strftime): protect from format modification from GC
finalizers.
* object.c (Init_Object): remove rb_obj_id_obsolete()
* eval.c (rb_mod_define_method): incomplete subclass check.
[ruby-dev:25464]
* gc.c (rb_data_object_alloc): klass may be NULL.
[ruby-list:40498]
* bignum.c (rb_big_rand): should return positive random number.
[ruby-dev:25401]
* bignum.c (rb_big_rand): do not use rb_big_modulo to generate
random bignums. [ruby-dev:25396]
* variable.c (rb_autoload): [ruby-dev:25373]
* eval.c (svalue_to_avalue): [ruby-dev:25366]
* string.c (rb_str_justify): [ruby-dev:25367]
* io.c (rb_f_select): [ruby-dev:25312]
* ext/socket/socket.c (sock_s_getservbyport): [ruby-talk:124072]
* struct.c (make_struct): [ruby-dev:25249]
* dir.c (dir_open_dir): new function. [ruby-dev:25242]
* io.c (rb_f_open): add type check for return value from to_open.
* lib/pstore.rb (PStore#transaction): Use the empty content when a
file is not found. [ruby-dev:24561]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8068 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-03-04 09:47:45 +03:00
|
|
|
}
|
|
|
|
else {
|
2007-09-28 10:21:46 +04:00
|
|
|
rb_ivar_foreach(obj, inspect_i, str);
|
* array.c: replace rb_protect_inspect() and rb_inspecting_p() by
rb_exec_recursive() in eval.c.
* eval.c (rb_exec_recursive): new function.
* array.c (rb_ary_join): use rb_exec_recursive().
* array.c (rb_ary_inspect, rb_ary_hash): ditto.
* file.c (rb_file_join): ditto.
* hash.c (rb_hash_inspect, rb_hash_to_s, rb_hash_hash): ditto.
* io.c (rb_io_puts): ditto.
* object.c (rb_obj_inspect): ditto
* struct.c (rb_struct_inspect): ditto.
* lib/set.rb (SortedSet::setup): a hack to shut up warning.
[ruby-talk:132866]
* lib/time.rb (Time::strptime): add new function. inspired by
[ruby-talk:132815].
* lib/parsedate.rb (ParseDate::strptime): ditto.
* regparse.c: move st_*_strend() functions from st.c. fixed some
potential memory leaks.
* exception error messages updated. [ruby-core:04497]
* ext/socket/socket.c (Init_socket): add bunch of Socket
constants. Patch from Sam Roberts <sroberts@uniserve.com>.
[ruby-core:04409]
* array.c (rb_ary_s_create): no need for negative argc check.
[ruby-core:04463]
* array.c (rb_ary_unshift_m): ditto.
* lib/xmlrpc/parser.rb (XMLRPC::FaultException): make it subclass
of StandardError class, not Exception class. [ruby-core:04429]
* parse.y (fcall_gen): lvar(arg) will be evaluated as
lvar.call(arg) when lvar is a defined local variable. [new]
* object.c (rb_class_initialize): call inherited method before
calling initializing block.
* eval.c (rb_thread_start_1): initialize newly pushed frame.
* lib/open3.rb (Open3::popen3): $? should not be EXIT_FAILURE.
fixed: [ruby-core:04444]
* eval.c (is_defined): NODE_IASGN is an assignment.
* ext/readline/readline.c (Readline.readline): use rl_outstream
and rl_instream. [ruby-dev:25699]
* ext/etc/etc.c (Init_etc): sGroup needs HAVE_ST_GR_PASSWD check
[ruby-dev:25675]
* misc/ruby-mode.el: [ruby-core:04415]
* lib/rdoc/generators/html_generator.rb: [ruby-core:04412]
* lib/rdoc/generators/ri_generator.rb: ditto.
* struct.c (make_struct): fixed: [ruby-core:04402]
* ext/curses/curses.c (window_color_set): [ruby-core:04393]
* ext/socket/socket.c (Init_socket): SO_REUSEPORT added.
[ruby-talk:130092]
* object.c: [ruby-doc:818]
* parse.y (open_args): fix too verbose warnings for the space
before argument parentheses. [ruby-dev:25492]
* parse.y (parser_yylex): ditto.
* parse.y (parser_yylex): the first expression in the parentheses
should not be a command. [ruby-dev:25492]
* lib/irb/context.rb (IRB::Context::initialize): [ruby-core:04330]
* object.c (Init_Object): remove Object#type. [ruby-core:04335]
* st.c (st_foreach): report success/failure by return value.
[ruby-Bugs-1396]
* parse.y: forgot to initialize parser struct. [ruby-dev:25492]
* parse.y (parser_yylex): no tLABEL on EXPR_BEG.
[ruby-talk:127711]
* document updates - [ruby-core:04296], [ruby-core:04301],
[ruby-core:04302], [ruby-core:04307]
* dir.c (rb_push_glob): should work for NUL delimited patterns.
* dir.c (rb_glob2): should aware of offset in the pattern.
* string.c (rb_str_new4): should propagate taintedness.
* env.h: rename member names in struct FRAME; last_func -> callee,
orig_func -> this_func, last_class -> this_class.
* struct.c (rb_struct_set): use original method name, not callee
name, to retrieve member slot. [ruby-core:04268]
* time.c (time_strftime): protect from format modification from GC
finalizers.
* object.c (Init_Object): remove rb_obj_id_obsolete()
* eval.c (rb_mod_define_method): incomplete subclass check.
[ruby-dev:25464]
* gc.c (rb_data_object_alloc): klass may be NULL.
[ruby-list:40498]
* bignum.c (rb_big_rand): should return positive random number.
[ruby-dev:25401]
* bignum.c (rb_big_rand): do not use rb_big_modulo to generate
random bignums. [ruby-dev:25396]
* variable.c (rb_autoload): [ruby-dev:25373]
* eval.c (svalue_to_avalue): [ruby-dev:25366]
* string.c (rb_str_justify): [ruby-dev:25367]
* io.c (rb_f_select): [ruby-dev:25312]
* ext/socket/socket.c (sock_s_getservbyport): [ruby-talk:124072]
* struct.c (make_struct): [ruby-dev:25249]
* dir.c (dir_open_dir): new function. [ruby-dev:25242]
* io.c (rb_f_open): add type check for return value from to_open.
* lib/pstore.rb (PStore#transaction): Use the empty content when a
file is not found. [ruby-dev:24561]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8068 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-03-04 09:47:45 +03:00
|
|
|
}
|
2000-04-10 09:48:43 +04:00
|
|
|
rb_str_cat2(str, ">");
|
2006-08-31 14:47:44 +04:00
|
|
|
RSTRING_PTR(str)[0] = '#';
|
1999-01-20 07:59:39 +03:00
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj.inspect -> string
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2012-01-06 11:06:22 +04:00
|
|
|
* Returns a string containing a human-readable representation of <i>obj</i>.
|
2019-03-22 14:04:59 +03:00
|
|
|
* The default #inspect shows the object's class name, an encoding of
|
2019-12-30 17:07:35 +03:00
|
|
|
* its memory address, and a list of the instance variables and their
|
2019-03-22 14:04:59 +03:00
|
|
|
* values (by calling #inspect on each of them). User defined classes
|
|
|
|
* should override this method to provide a better representation of
|
|
|
|
* <i>obj</i>. When overriding this method, it should return a string
|
|
|
|
* whose encoding is compatible with the default external encoding.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* [ 1, 2, 3..4, 'five' ].inspect #=> "[1, 2, 3..4, \"five\"]"
|
2008-03-09 04:04:46 +03:00
|
|
|
* Time.new.inspect #=> "2008-03-08 19:43:39 +0900"
|
2012-01-06 11:06:22 +04:00
|
|
|
*
|
|
|
|
* class Foo
|
|
|
|
* end
|
|
|
|
* Foo.new.inspect #=> "#<Foo:0x0300c868>"
|
|
|
|
*
|
|
|
|
* class Bar
|
|
|
|
* def initialize
|
|
|
|
* @bar = 1
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* Bar.new.inspect #=> "#<Bar:0x0300c868 @bar=1>"
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_obj_inspect(VALUE obj)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2012-08-15 15:50:01 +04:00
|
|
|
if (rb_ivar_count(obj) > 0) {
|
|
|
|
VALUE str;
|
2012-08-17 18:29:00 +04:00
|
|
|
VALUE c = rb_class_name(CLASS_OF(obj));
|
2007-09-28 10:21:46 +04:00
|
|
|
|
2012-08-17 18:29:00 +04:00
|
|
|
str = rb_sprintf("-<%"PRIsVALUE":%p", c, (void*)obj);
|
2012-08-15 15:50:01 +04:00
|
|
|
return rb_exec_recursive(inspect_obj, obj, str);
|
2012-08-17 18:29:00 +04:00
|
|
|
}
|
|
|
|
else {
|
2009-10-22 00:17:27 +04:00
|
|
|
return rb_any_to_s(obj);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-01 04:31:00 +04:00
|
|
|
static VALUE
|
|
|
|
class_or_module_required(VALUE c)
|
|
|
|
{
|
2020-06-16 04:49:02 +03:00
|
|
|
switch (OBJ_BUILTIN_TYPE(c)) {
|
2012-06-01 04:31:00 +04:00
|
|
|
case T_MODULE:
|
|
|
|
case T_CLASS:
|
|
|
|
case T_ICLASS:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
rb_raise(rb_eTypeError, "class or module required");
|
|
|
|
}
|
|
|
|
return c;
|
|
|
|
}
|
2003-12-28 09:33:07 +03:00
|
|
|
|
2014-04-14 11:59:42 +04:00
|
|
|
static VALUE class_search_ancestor(VALUE cl, VALUE c);
|
|
|
|
|
2021-03-11 10:34:49 +03:00
|
|
|
/*
|
2003-12-28 09:33:07 +03:00
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj.instance_of?(class) -> true or false
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Returns <code>true</code> if <i>obj</i> is an instance of the given
|
2019-03-22 14:04:59 +03:00
|
|
|
* class. See also Object#kind_of?.
|
2012-01-11 21:19:54 +04:00
|
|
|
*
|
|
|
|
* class A; end
|
|
|
|
* class B < A; end
|
|
|
|
* class C < B; end
|
|
|
|
*
|
|
|
|
* b = B.new
|
|
|
|
* b.instance_of? A #=> false
|
|
|
|
* b.instance_of? B #=> true
|
|
|
|
* b.instance_of? C #=> false
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_obj_is_instance_of(VALUE obj, VALUE c)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2012-06-01 04:31:00 +04:00
|
|
|
c = class_or_module_required(c);
|
2021-08-02 06:06:44 +03:00
|
|
|
return RBOOL(rb_obj_class(obj) == c);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2022-01-26 06:16:57 +03:00
|
|
|
// Returns whether c is a proper (c != cl) subclass of cl
|
|
|
|
// Both c and cl must be T_CLASS
|
|
|
|
static VALUE
|
|
|
|
class_search_class_ancestor(VALUE cl, VALUE c)
|
|
|
|
{
|
|
|
|
RUBY_ASSERT(RB_TYPE_P(c, T_CLASS));
|
|
|
|
RUBY_ASSERT(RB_TYPE_P(cl, T_CLASS));
|
|
|
|
|
|
|
|
size_t c_depth = RCLASS_SUPERCLASS_DEPTH(c);
|
|
|
|
size_t cl_depth = RCLASS_SUPERCLASS_DEPTH(cl);
|
|
|
|
VALUE *classes = RCLASS_SUPERCLASSES(cl);
|
|
|
|
|
|
|
|
// If c's inheritance chain is longer, it cannot be an ancestor
|
|
|
|
// We are checking for a proper subclass so don't check if they are equal
|
|
|
|
if (cl_depth <= c_depth)
|
|
|
|
return Qfalse;
|
|
|
|
|
|
|
|
// Otherwise check that c is in cl's inheritance chain
|
|
|
|
return RBOOL(classes[c_depth] == c);
|
|
|
|
}
|
2003-12-28 09:33:07 +03:00
|
|
|
|
2021-03-11 10:34:49 +03:00
|
|
|
/*
|
2003-12-28 09:33:07 +03:00
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj.is_a?(class) -> true or false
|
|
|
|
* obj.kind_of?(class) -> true or false
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Returns <code>true</code> if <i>class</i> is the class of
|
|
|
|
* <i>obj</i>, or if <i>class</i> is one of the superclasses of
|
|
|
|
* <i>obj</i> or modules included in <i>obj</i>.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* module M; end
|
|
|
|
* class A
|
|
|
|
* include M
|
|
|
|
* end
|
|
|
|
* class B < A; end
|
|
|
|
* class C < B; end
|
2012-01-11 21:19:54 +04:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* b = B.new
|
2012-01-11 21:19:54 +04:00
|
|
|
* b.is_a? A #=> true
|
|
|
|
* b.is_a? B #=> true
|
|
|
|
* b.is_a? C #=> false
|
|
|
|
* b.is_a? M #=> true
|
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* b.kind_of? A #=> true
|
|
|
|
* b.kind_of? B #=> true
|
|
|
|
* b.kind_of? C #=> false
|
|
|
|
* b.kind_of? M #=> true
|
|
|
|
*/
|
2007-06-10 07:06:15 +04:00
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_obj_is_kind_of(VALUE obj, VALUE c)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
1998-01-16 15:19:22 +03:00
|
|
|
VALUE cl = CLASS_OF(obj);
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2022-01-26 06:16:57 +03:00
|
|
|
RUBY_ASSERT(RB_TYPE_P(cl, T_CLASS));
|
|
|
|
|
|
|
|
// Fastest path: If the object's class is an exact match we know `c` is a
|
|
|
|
// class without checking type and can return immediately.
|
|
|
|
if (cl == c) return Qtrue;
|
|
|
|
|
2022-03-10 22:06:29 +03:00
|
|
|
// Note: YJIT needs this function to never allocate and never raise when
|
|
|
|
// `c` is a class or a module.
|
|
|
|
|
2022-02-19 10:05:23 +03:00
|
|
|
if (LIKELY(RB_TYPE_P(c, T_CLASS))) {
|
|
|
|
// Fast path: Both are T_CLASS
|
|
|
|
return class_search_class_ancestor(cl, c);
|
|
|
|
}
|
|
|
|
else if (RB_TYPE_P(c, T_ICLASS)) {
|
|
|
|
// First check if we inherit the includer
|
|
|
|
// If we do we can return true immediately
|
|
|
|
VALUE includer = RCLASS_INCLUDER(c);
|
|
|
|
if (cl == includer) return Qtrue;
|
|
|
|
|
|
|
|
// Usually includer is a T_CLASS here, except when including into an
|
|
|
|
// already included Module.
|
|
|
|
// If it is a class, attempt the fast class-to-class check and return
|
|
|
|
// true if there is a match.
|
|
|
|
if (RB_TYPE_P(includer, T_CLASS) && class_search_class_ancestor(cl, includer))
|
|
|
|
return Qtrue;
|
|
|
|
|
|
|
|
// We don't include the ICLASS directly, so must check if we inherit
|
|
|
|
// the module via another include
|
|
|
|
return RBOOL(class_search_ancestor(cl, RCLASS_ORIGIN(c)));
|
|
|
|
}
|
|
|
|
else if (RB_TYPE_P(c, T_MODULE)) {
|
|
|
|
// Slow path: check each ancestor in the linked list and its method table
|
|
|
|
return RBOOL(class_search_ancestor(cl, RCLASS_ORIGIN(c)));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rb_raise(rb_eTypeError, "class or module required");
|
|
|
|
UNREACHABLE_RETURN(Qfalse);
|
|
|
|
}
|
2014-04-14 11:59:42 +04:00
|
|
|
}
|
|
|
|
|
2022-01-26 06:16:57 +03:00
|
|
|
|
2014-04-14 11:59:42 +04:00
|
|
|
static VALUE
|
|
|
|
class_search_ancestor(VALUE cl, VALUE c)
|
|
|
|
{
|
1998-01-16 15:19:22 +03:00
|
|
|
while (cl) {
|
2022-01-26 06:16:57 +03:00
|
|
|
if (cl == c || RCLASS_M_TBL(cl) == RCLASS_M_TBL(c))
|
|
|
|
return cl;
|
|
|
|
cl = RCLASS_SUPER(cl);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2014-04-14 11:59:42 +04:00
|
|
|
return 0;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \private */
|
2014-04-14 11:59:42 +04:00
|
|
|
VALUE
|
|
|
|
rb_class_search_ancestor(VALUE cl, VALUE c)
|
|
|
|
{
|
|
|
|
cl = class_or_module_required(cl);
|
|
|
|
c = class_or_module_required(c);
|
|
|
|
return class_search_ancestor(cl, RCLASS_ORIGIN(c));
|
|
|
|
}
|
2003-12-28 09:33:07 +03:00
|
|
|
|
2006-11-22 11:37:12 +03:00
|
|
|
|
2006-10-13 13:25:15 +04:00
|
|
|
/*
|
|
|
|
* Document-method: inherited
|
|
|
|
*
|
|
|
|
* call-seq:
|
|
|
|
* inherited(subclass)
|
|
|
|
*
|
|
|
|
* Callback invoked whenever a subclass of the current class is created.
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
*
|
|
|
|
* class Foo
|
2012-03-17 01:57:24 +04:00
|
|
|
* def self.inherited(subclass)
|
|
|
|
* puts "New subclass: #{subclass}"
|
|
|
|
* end
|
2006-10-13 13:25:15 +04:00
|
|
|
* end
|
|
|
|
*
|
|
|
|
* class Bar < Foo
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* class Baz < Bar
|
|
|
|
* end
|
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* <em>produces:</em>
|
2006-10-13 13:25:15 +04:00
|
|
|
*
|
|
|
|
* New subclass: Bar
|
|
|
|
* New subclass: Baz
|
|
|
|
*/
|
2021-02-07 17:35:06 +03:00
|
|
|
#define rb_obj_class_inherited rb_obj_dummy1
|
2006-10-13 13:25:15 +04:00
|
|
|
|
2011-06-17 04:11:20 +04:00
|
|
|
/* Document-method: method_added
|
|
|
|
*
|
|
|
|
* call-seq:
|
|
|
|
* method_added(method_name)
|
|
|
|
*
|
|
|
|
* Invoked as a callback whenever an instance method is added to the
|
|
|
|
* receiver.
|
|
|
|
*
|
|
|
|
* module Chatty
|
|
|
|
* def self.method_added(method_name)
|
|
|
|
* puts "Adding #{method_name.inspect}"
|
|
|
|
* end
|
|
|
|
* def self.some_class_method() end
|
|
|
|
* def some_instance_method() end
|
|
|
|
* end
|
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* <em>produces:</em>
|
2011-06-17 04:11:20 +04:00
|
|
|
*
|
|
|
|
* Adding :some_instance_method
|
|
|
|
*
|
|
|
|
*/
|
2021-02-07 17:35:06 +03:00
|
|
|
#define rb_obj_mod_method_added rb_obj_dummy1
|
2011-06-17 04:11:20 +04:00
|
|
|
|
|
|
|
/* Document-method: method_removed
|
|
|
|
*
|
|
|
|
* call-seq:
|
|
|
|
* method_removed(method_name)
|
|
|
|
*
|
|
|
|
* Invoked as a callback whenever an instance method is removed from the
|
|
|
|
* receiver.
|
|
|
|
*
|
|
|
|
* module Chatty
|
|
|
|
* def self.method_removed(method_name)
|
|
|
|
* puts "Removing #{method_name.inspect}"
|
|
|
|
* end
|
|
|
|
* def self.some_class_method() end
|
|
|
|
* def some_instance_method() end
|
|
|
|
* class << self
|
|
|
|
* remove_method :some_class_method
|
|
|
|
* end
|
|
|
|
* remove_method :some_instance_method
|
|
|
|
* end
|
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* <em>produces:</em>
|
2011-06-17 04:11:20 +04:00
|
|
|
*
|
|
|
|
* Removing :some_instance_method
|
|
|
|
*
|
|
|
|
*/
|
2021-02-07 17:35:06 +03:00
|
|
|
#define rb_obj_mod_method_removed rb_obj_dummy1
|
2011-06-17 04:11:20 +04:00
|
|
|
|
2021-02-07 17:09:00 +03:00
|
|
|
/* Document-method: method_undefined
|
|
|
|
*
|
|
|
|
* call-seq:
|
|
|
|
* method_undefined(method_name)
|
|
|
|
*
|
|
|
|
* Invoked as a callback whenever an instance method is undefined from the
|
|
|
|
* receiver.
|
|
|
|
*
|
|
|
|
* module Chatty
|
|
|
|
* def self.method_undefined(method_name)
|
|
|
|
* puts "Undefining #{method_name.inspect}"
|
|
|
|
* end
|
|
|
|
* def self.some_class_method() end
|
|
|
|
* def some_instance_method() end
|
|
|
|
* class << self
|
|
|
|
* undef_method :some_class_method
|
|
|
|
* end
|
|
|
|
* undef_method :some_instance_method
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* <em>produces:</em>
|
|
|
|
*
|
|
|
|
* Undefining :some_instance_method
|
|
|
|
*
|
|
|
|
*/
|
2021-02-07 17:35:06 +03:00
|
|
|
#define rb_obj_mod_method_undefined rb_obj_dummy1
|
2021-02-07 17:09:00 +03:00
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
2004-08-30 18:23:19 +04:00
|
|
|
* Document-method: singleton_method_added
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
|
|
|
* call-seq:
|
|
|
|
* singleton_method_added(symbol)
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Invoked as a callback whenever a singleton method is added to the
|
|
|
|
* receiver.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* module Chatty
|
|
|
|
* def Chatty.singleton_method_added(id)
|
|
|
|
* puts "Adding #{id.id2name}"
|
|
|
|
* end
|
|
|
|
* def self.one() end
|
|
|
|
* def two() end
|
|
|
|
* def Chatty.three() end
|
|
|
|
* end
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* <em>produces:</em>
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Adding singleton_method_added
|
|
|
|
* Adding one
|
|
|
|
* Adding three
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
2021-02-07 17:10:12 +03:00
|
|
|
#define rb_obj_singleton_method_added rb_obj_dummy1
|
2003-12-28 09:33:07 +03:00
|
|
|
|
|
|
|
/*
|
2004-08-30 18:23:19 +04:00
|
|
|
* Document-method: singleton_method_removed
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
|
|
|
* call-seq:
|
|
|
|
* singleton_method_removed(symbol)
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Invoked as a callback whenever a singleton method is removed from
|
|
|
|
* the receiver.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* module Chatty
|
|
|
|
* def Chatty.singleton_method_removed(id)
|
|
|
|
* puts "Removing #{id.id2name}"
|
|
|
|
* end
|
|
|
|
* def self.one() end
|
|
|
|
* def two() end
|
|
|
|
* def Chatty.three() end
|
2010-05-23 12:48:44 +04:00
|
|
|
* class << self
|
2003-12-28 09:33:07 +03:00
|
|
|
* remove_method :three
|
|
|
|
* remove_method :one
|
|
|
|
* end
|
|
|
|
* end
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* <em>produces:</em>
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Removing three
|
|
|
|
* Removing one
|
|
|
|
*/
|
2021-02-07 17:10:12 +03:00
|
|
|
#define rb_obj_singleton_method_removed rb_obj_dummy1
|
2003-12-28 09:33:07 +03:00
|
|
|
|
|
|
|
/*
|
2004-08-30 18:23:19 +04:00
|
|
|
* Document-method: singleton_method_undefined
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
|
|
|
* call-seq:
|
|
|
|
* singleton_method_undefined(symbol)
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Invoked as a callback whenever a singleton method is undefined in
|
|
|
|
* the receiver.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* module Chatty
|
|
|
|
* def Chatty.singleton_method_undefined(id)
|
|
|
|
* puts "Undefining #{id.id2name}"
|
|
|
|
* end
|
|
|
|
* def Chatty.one() end
|
|
|
|
* class << self
|
|
|
|
* undef_method(:one)
|
|
|
|
* end
|
|
|
|
* end
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* <em>produces:</em>
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Undefining one
|
|
|
|
*/
|
2021-02-07 17:10:12 +03:00
|
|
|
#define rb_obj_singleton_method_undefined rb_obj_dummy1
|
2003-12-28 09:33:07 +03:00
|
|
|
|
2021-05-22 13:04:01 +03:00
|
|
|
/* Document-method: const_added
|
|
|
|
*
|
|
|
|
* call-seq:
|
|
|
|
* const_added(const_name)
|
|
|
|
*
|
|
|
|
* Invoked as a callback whenever a constant is assigned on the receiver
|
|
|
|
*
|
|
|
|
* module Chatty
|
|
|
|
* def self.const_added(const_name)
|
|
|
|
* super
|
|
|
|
* puts "Added #{const_name.inspect}"
|
|
|
|
* end
|
|
|
|
* FOO = 1
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* <em>produces:</em>
|
|
|
|
*
|
|
|
|
* Added :FOO
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#define rb_obj_mod_const_added rb_obj_dummy1
|
|
|
|
|
2013-07-09 16:03:07 +04:00
|
|
|
/*
|
|
|
|
* Document-method: extended
|
|
|
|
*
|
|
|
|
* call-seq:
|
|
|
|
* extended(othermod)
|
|
|
|
*
|
|
|
|
* The equivalent of <tt>included</tt>, but for extended modules.
|
|
|
|
*
|
|
|
|
* module A
|
|
|
|
* def self.extended(mod)
|
|
|
|
* puts "#{self} extended in #{mod}"
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* module Enumerable
|
|
|
|
* extend A
|
|
|
|
* end
|
|
|
|
* # => prints "A extended in Enumerable"
|
|
|
|
*/
|
2021-02-07 17:35:06 +03:00
|
|
|
#define rb_obj_mod_extended rb_obj_dummy1
|
2003-12-28 09:33:07 +03:00
|
|
|
|
2004-08-30 18:23:19 +04:00
|
|
|
/*
|
|
|
|
* Document-method: included
|
|
|
|
*
|
|
|
|
* call-seq:
|
2013-07-09 16:03:07 +04:00
|
|
|
* included(othermod)
|
2004-08-30 18:23:19 +04:00
|
|
|
*
|
|
|
|
* Callback invoked whenever the receiver is included in another
|
|
|
|
* module or class. This should be used in preference to
|
|
|
|
* <tt>Module.append_features</tt> if your code wants to perform some
|
|
|
|
* action when a module is included in another.
|
|
|
|
*
|
|
|
|
* module A
|
|
|
|
* def A.included(mod)
|
|
|
|
* puts "#{self} included in #{mod}"
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* module Enumerable
|
|
|
|
* include A
|
|
|
|
* end
|
2013-02-23 03:18:33 +04:00
|
|
|
* # => prints "A included in Enumerable"
|
|
|
|
*/
|
2021-02-07 17:35:06 +03:00
|
|
|
#define rb_obj_mod_included rb_obj_dummy1
|
2013-02-23 03:18:33 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-method: prepended
|
|
|
|
*
|
|
|
|
* call-seq:
|
2013-07-09 16:03:07 +04:00
|
|
|
* prepended(othermod)
|
2013-02-23 03:18:33 +04:00
|
|
|
*
|
|
|
|
* The equivalent of <tt>included</tt>, but for prepended modules.
|
|
|
|
*
|
|
|
|
* module A
|
|
|
|
* def self.prepended(mod)
|
|
|
|
* puts "#{self} prepended to #{mod}"
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* module Enumerable
|
|
|
|
* prepend A
|
|
|
|
* end
|
|
|
|
* # => prints "A prepended to Enumerable"
|
2004-08-30 18:23:19 +04:00
|
|
|
*/
|
2021-02-07 17:35:06 +03:00
|
|
|
#define rb_obj_mod_prepended rb_obj_dummy1
|
2004-08-30 18:23:19 +04:00
|
|
|
|
2009-12-21 02:05:07 +03:00
|
|
|
/*
|
|
|
|
* Document-method: initialize
|
|
|
|
*
|
|
|
|
* call-seq:
|
2010-10-30 05:25:41 +04:00
|
|
|
* BasicObject.new
|
2009-12-21 02:05:07 +03:00
|
|
|
*
|
2010-10-30 05:25:41 +04:00
|
|
|
* Returns a new BasicObject.
|
2009-12-21 02:05:07 +03:00
|
|
|
*/
|
2021-02-07 17:10:12 +03:00
|
|
|
#define rb_obj_initialize rb_obj_dummy0
|
2004-08-30 18:23:19 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Not documented
|
|
|
|
*/
|
2003-12-28 09:33:07 +03:00
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
static VALUE
|
2020-12-05 08:46:34 +03:00
|
|
|
rb_obj_dummy(void)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
2019-08-29 04:57:48 +03:00
|
|
|
static VALUE
|
|
|
|
rb_obj_dummy0(VALUE _)
|
|
|
|
{
|
|
|
|
return rb_obj_dummy();
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_obj_dummy1(VALUE _x, VALUE _y)
|
|
|
|
{
|
|
|
|
return rb_obj_dummy();
|
|
|
|
}
|
|
|
|
|
2021-03-11 10:34:49 +03:00
|
|
|
/*
|
2003-12-28 09:33:07 +03:00
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj.freeze -> obj
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Prevents further modifications to <i>obj</i>. A
|
2021-04-01 19:16:58 +03:00
|
|
|
* FrozenError will be raised if modification is attempted.
|
2003-12-28 09:33:07 +03:00
|
|
|
* There is no way to unfreeze a frozen object. See also
|
2019-03-22 14:04:59 +03:00
|
|
|
* Object#frozen?.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2009-05-24 17:37:43 +04:00
|
|
|
* This method returns self.
|
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* a = [ "a", "b", "c" ]
|
|
|
|
* a.freeze
|
|
|
|
* a << "z"
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* <em>produces:</em>
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2017-12-12 03:46:34 +03:00
|
|
|
* prog.rb:3:in `<<': can't modify frozen Array (FrozenError)
|
2003-12-28 09:33:07 +03:00
|
|
|
* from prog.rb:3
|
2014-01-09 21:34:14 +04:00
|
|
|
*
|
2016-10-26 09:11:23 +03:00
|
|
|
* Objects of the following classes are always frozen: Integer,
|
|
|
|
* Float, Symbol.
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
2000-02-01 06:12:21 +03:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_obj_freeze(VALUE obj)
|
2000-02-01 06:12:21 +03:00
|
|
|
{
|
2001-01-18 11:43:14 +03:00
|
|
|
if (!OBJ_FROZEN(obj)) {
|
2001-01-15 10:01:00 +03:00
|
|
|
OBJ_FREEZE(obj);
|
2007-12-18 11:28:39 +03:00
|
|
|
if (SPECIAL_CONST_P(obj)) {
|
2014-09-11 09:37:32 +04:00
|
|
|
rb_bug("special consts should be frozen.");
|
2007-12-18 11:28:39 +03:00
|
|
|
}
|
2001-01-15 10:01:00 +03:00
|
|
|
}
|
2000-02-01 06:12:21 +03:00
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2007-12-18 11:28:39 +03:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_obj_frozen_p(VALUE obj)
|
2000-02-01 06:12:21 +03:00
|
|
|
{
|
2021-08-02 06:06:44 +03:00
|
|
|
return RBOOL(OBJ_FROZEN(obj));
|
2000-02-01 06:12:21 +03:00
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
|
|
|
|
/*
|
2003-12-28 23:47:56 +03:00
|
|
|
* Document-class: NilClass
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
|
|
|
* The class of the singleton object <code>nil</code>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* nil.to_s -> ""
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2006-09-07 20:11:28 +04:00
|
|
|
* Always returns the empty string.
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
Optimize dynamic string interpolation for symbol/true/false/nil/0-9
This provides a significant speedup for symbol, true, false,
nil, and 0-9, class/module, and a small speedup in most other cases.
Speedups (using included benchmarks):
:symbol :: 60%
0-9 :: 50%
Class/Module :: 50%
nil/true/false :: 20%
integer :: 10%
[] :: 10%
"" :: 3%
One reason this approach is faster is it reduces the number of
VM instructions for each interpolated value.
Initial idea, approach, and benchmarks from Eric Wong. I applied
the same approach against the master branch, updating it to handle
the significant internal changes since this was first proposed 4
years ago (such as CALL_INFO/CALL_CACHE -> CALL_DATA). I also
expanded it to optimize true/false/nil/0-9/class/module, and added
handling of missing methods, refined methods, and RUBY_DEBUG.
This renames the tostring insn to anytostring, and adds an
objtostring insn that implements the optimization. This requires
making a few functions non-static, and adding some non-static
functions.
This disables 4 YJIT tests. Those tests should be reenabled after
YJIT optimizes the new objtostring insn.
Implements [Feature #13715]
Co-authored-by: Eric Wong <e@80x24.org>
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Co-authored-by: Yusuke Endoh <mame@ruby-lang.org>
Co-authored-by: Koichi Sasada <ko1@atdot.net>
2021-11-19 02:10:20 +03:00
|
|
|
MJIT_FUNC_EXPORTED VALUE
|
|
|
|
rb_nil_to_s(VALUE obj)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2019-09-26 18:27:47 +03:00
|
|
|
return rb_cNilClass_to_s;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2005-10-21 13:00:02 +04:00
|
|
|
/*
|
2006-11-06 13:27:59 +03:00
|
|
|
* Document-method: to_a
|
|
|
|
*
|
2005-10-21 13:00:02 +04:00
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* nil.to_a -> []
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2005-10-21 13:00:02 +04:00
|
|
|
* Always returns an empty array.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2005-10-21 13:00:02 +04:00
|
|
|
* nil.to_a #=> []
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
* sprintf.c (rb_str_format): allow %c to print one character
string (e.g. ?x).
* lib/tempfile.rb (Tempfile::make_tmpname): put dot between
basename and pid. [ruby-talk:196272]
* parse.y (do_block): remove -> style block.
* parse.y (parser_yylex): remove tLAMBDA_ARG.
* eval.c (rb_call0): binding for the return event hook should have
consistent scope. [ruby-core:07928]
* eval.c (proc_invoke): return behavior should depend whether it
is surrounded by a lambda or a mere block.
* eval.c (formal_assign): handles post splat arguments.
* eval.c (rb_call0): ditto.
* st.c (strhash): use FNV-1a hash.
* parse.y (parser_yylex): removed experimental ';;' terminator.
* eval.c (rb_node_arity): should be aware of post splat arguments.
* eval.c (rb_proc_arity): ditto.
* parse.y (f_args): syntax rule enhanced to support arguments
after the splat.
* parse.y (block_param): ditto for block parameters.
* parse.y (f_post_arg): mandatory formal arguments after the splat
argument.
* parse.y (new_args_gen): generate nodes for mandatory formal
arguments after the splat argument.
* eval.c (rb_eval): dispatch mandatory formal arguments after the
splat argument.
* parse.y (args): allow more than one splat in the argument list.
* parse.y (method_call): allow aref [] to accept all kind of
method argument, including assocs, splat, and block argument.
* eval.c (SETUP_ARGS0): prepare block argument as well.
* lib/mathn.rb (Integer): remove Integer#gcd2. [ruby-core:07931]
* eval.c (error_line): print receivers true/false/nil specially.
* eval.c (rb_proc_yield): handles parameters in yield semantics.
* eval.c (nil_yield): gives LocalJumpError to denote no block
error.
* io.c (rb_io_getc): now takes one-character string.
* string.c (rb_str_hash): use FNV-1a hash from Fowler/Noll/Vo
hashing algorithm.
* string.c (rb_str_aref): str[0] now returns 1 character string,
instead of a fixnum. [Ruby2]
* parse.y (parser_yylex): ?c now returns 1 character string,
instead of a fixnum. [Ruby2]
* string.c (rb_str_aset): no longer support fixnum insertion.
* eval.c (umethod_bind): should not update original class.
[ruby-dev:28636]
* eval.c (ev_const_get): should support constant access from
within instance_eval(). [ruby-dev:28327]
* time.c (time_timeval): should round for usec floating
number. [ruby-core:07896]
* time.c (time_add): ditto.
* dir.c (sys_warning): should not call a vararg function
rb_sys_warning() indirectly. [ruby-core:07886]
* numeric.c (flo_divmod): the first element of Float#divmod should
be an integer. [ruby-dev:28589]
* test/ruby/test_float.rb: add tests for divmod, div, modulo and remainder.
* re.c (rb_reg_initialize): should not allow modifying literal
regexps. frozen check moved from rb_reg_initialize_m as well.
* re.c (rb_reg_initialize): should not modify untainted objects in
safe levels higher than 3.
* re.c (rb_memcmp): type change from char* to const void*.
* dir.c (dir_close): should not close untainted dir stream.
* dir.c (GetDIR): add tainted/frozen check for each dir operation.
* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_symbol_arg):
typo fixed. a patch from Florian Gross <florg at florg.net>.
* eval.c (EXEC_EVENT_HOOK): trace_func may remove itself from
event_hooks. no guarantee for arbitrary hook deletion.
[ruby-dev:28632]
* util.c (ruby_strtod): differ addition to minimize error.
[ruby-dev:28619]
* util.c (ruby_strtod): should not raise ERANGE when the input
string does not have any digits. [ruby-dev:28629]
* eval.c (proc_invoke): should restore old ruby_frame->block.
thanks to ts <decoux at moulon.inra.fr>. [ruby-core:07833]
also fix [ruby-dev:28614] as well.
* signal.c (trap): sig should be less then NSIG. Coverity found
this bug. a patch from Kevin Tew <tewk at tewk.com>.
[ruby-core:07823]
* math.c (math_log2): add new method inspired by
[ruby-talk:191237].
* math.c (math_log): add optional base argument to Math::log().
[ruby-talk:191308]
* ext/syck/emitter.c (syck_scan_scalar): avoid accessing
uninitialized array element. a patch from Pat Eyler
<rubypate at gmail.com>. [ruby-core:07809]
* array.c (rb_ary_fill): initialize local variables first. a
patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07810]
* ext/syck/yaml2byte.c (syck_yaml2byte_handler): need to free
type_tag. a patch from Pat Eyler <rubypate at gmail.com>.
[ruby-core:07808]
* ext/socket/socket.c (make_hostent_internal): accept ai_family
check from Sam Roberts <sroberts at uniserve.com>.
[ruby-core:07691]
* util.c (ruby_strtod): should not cut off 18 digits for no
reason. [ruby-core:07796]
* array.c (rb_ary_fill): internalize local variable "beg" to
pacify Coverity. [ruby-core:07770]
* pack.c (pack_unpack): now supports CRLF newlines. a patch from
<tommy at tmtm.org>. [ruby-dev:28601]
* applied code clean-up patch from Stefan Huehner
<stefan at huehner.org>. [ruby-core:07764]
* lib/jcode.rb (String::tr_s): should have translated non
squeezing character sequence (i.e. a character) as well. thanks
to Hiroshi Ichikawa <gimite at gimite.ddo.jp> [ruby-list:42090]
* ext/socket/socket.c: document update patch from Sam Roberts
<sroberts at uniserve.com>. [ruby-core:07701]
* lib/mathn.rb (Integer): need not to remove gcd2. a patch from
NARUSE, Yui <naruse at airemix.com>. [ruby-dev:28570]
* parse.y (arg): too much NEW_LIST()
* eval.c (SETUP_ARGS0): remove unnecessary access to nd_alen.
* eval.c (rb_eval): use ARGSCAT for NODE_OP_ASGN1.
[ruby-dev:28585]
* parse.y (arg): use NODE_ARGSCAT for placeholder.
* lib/getoptlong.rb (GetoptLong::get): RDoc update patch from
mathew <meta at pobox.com>. [ruby-core:07738]
* variable.c (rb_const_set): raise error when no target klass is
supplied. [ruby-dev:28582]
* prec.c (prec_prec_f): documentation patch from
<gerardo.santana at gmail.com>. [ruby-core:07689]
* bignum.c (rb_big_pow): second operand may be too big even if
it's a Fixnum. [ruby-talk:187984]
* README.EXT: update symbol description. [ruby-talk:188104]
* COPYING: explicitly note GPLv2. [ruby-talk:187922]
* parse.y: remove some obsolete syntax rules (unparenthesized
method calls in argument list).
* eval.c (rb_call0): insecure calling should be checked for non
NODE_SCOPE method invocations too.
* eval.c (rb_alias): should preserve the current safe level as
well as method definition.
* process.c (rb_f_sleep): remove RDoc description about SIGALRM
which is not valid on the current implementation. [ruby-dev:28464]
Thu Mar 23 21:40:47 2006 K.Kosako <sndgk393 AT ybb.ne.jp>
* eval.c (method_missing): should support argument splat in
super. a bug in combination of super, splat and
method_missing. [ruby-talk:185438]
* configure.in: Solaris SunPro compiler -rapth patch from
<kuwa at labs.fujitsu.com>. [ruby-dev:28443]
* configure.in: remove enable_rpath=no for Solaris.
[ruby-dev:28440]
* ext/win32ole/win32ole.c (ole_val2olevariantdata): change behavior
of converting OLE Variant object with VT_ARRAY|VT_UI1 and Ruby
String object.
* ruby.1: a clarification patch from David Lutterkort
<dlutter at redhat.com>. [ruby-core:7508]
* lib/rdoc/ri/ri_paths.rb (RI::Paths): adding paths from rubygems
directories. a patch from Eric Hodel <drbrain at segment7.net>.
[ruby-core:07423]
* eval.c (rb_clear_cache_by_class): clearing wrong cache.
* ext/extmk.rb: use :remove_destination to install extension libraries
to avoid SEGV. [ruby-dev:28417]
* eval.c (rb_thread_fd_writable): should not re-schedule output
from KILLED thread (must be error printing).
* array.c (rb_ary_flatten_bang): allow specifying recursion
level. [ruby-talk:182170]
* array.c (rb_ary_flatten): ditto.
* gc.c (add_heap): a heap_slots may overflow. a patch from Stefan
Weil <weil at mail.berlios.de>.
* eval.c (rb_call): use separate cache for fcall/vcall
invocation.
* eval.c (rb_eval): NODE_FCALL, NODE_VCALL can call local
functions.
* eval.c (rb_mod_local): a new method to specify newly added
visibility "local".
* eval.c (search_method): search for local methods which are
visible only from the current class.
* class.c (rb_class_local_methods): a method to list local methods.
* object.c (Init_Object): add BasicObject class as a top level
BlankSlate class.
* ruby.h (SYM2ID): should not cast to signed long.
[ruby-core:07414]
* class.c (rb_include_module): allow module duplication.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10235 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2006-06-10 01:20:17 +04:00
|
|
|
nil_to_a(VALUE obj)
|
2005-10-21 13:00:02 +04:00
|
|
|
{
|
|
|
|
return rb_ary_new2(0);
|
|
|
|
}
|
|
|
|
|
2012-04-24 07:46:55 +04:00
|
|
|
/*
|
|
|
|
* Document-method: to_h
|
|
|
|
*
|
|
|
|
* call-seq:
|
|
|
|
* nil.to_h -> {}
|
|
|
|
*
|
|
|
|
* Always returns an empty hash.
|
|
|
|
*
|
|
|
|
* nil.to_h #=> {}
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
nil_to_h(VALUE obj)
|
|
|
|
{
|
|
|
|
return rb_hash_new();
|
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* nil.inspect -> "nil"
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
|
|
|
* Always returns the string "nil".
|
|
|
|
*/
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
nil_inspect(VALUE obj)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
* string.c (rb_str_usascii_new{,2}: defined.
(rb_str_new): set US-ASCII and ENC_CODERANGE_7BIT when empty
string.
* encoding.c (rb_usascii_encoding, rb_usascii_encindex): defined.
(rb_enc_inspect, enc_name, rb_locale_charmap, rb_enc_name_list_i):
use rb_str_ascii_new.
* array.c (recursive_join, inspect_ary): ditto.
* object.c (nil_to_s, nil_inspect, true_to_s, false_to_s,
rb_mod_to_s): ditto.
* hash.c (inspect_hash, rb_hash_inspect, rb_f_getenv, env_fetch,
env_clear, env_to_s, env_inspect): ditto.
* numeric.c (flo_to_s, int_chr, rb_fix2str): ditto.
* bignum.c (rb_big2str): ditto.
* file.c (rb_file_ftype, rb_file_s_dirname, rb_file_s_extname,
file_inspect_join, Init_file): ditto.
* test/ruby/test_ruby_m17n.rb: add checks for encoding of string.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15244 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-01-25 19:40:02 +03:00
|
|
|
return rb_usascii_str_new2("nil");
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2018-11-26 10:55:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* nil =~ other -> nil
|
|
|
|
*
|
|
|
|
* Dummy pattern matching -- always returns nil.
|
2020-07-27 08:54:46 +03:00
|
|
|
*
|
|
|
|
* This method makes it possible to `while gets =~ /re/ do`.
|
2018-11-26 10:55:07 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
nil_match(VALUE obj1, VALUE obj2)
|
|
|
|
{
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
2003-12-27 09:09:08 +03:00
|
|
|
/***********************************************************************
|
2004-01-12 06:11:25 +03:00
|
|
|
* Document-class: TrueClass
|
2003-12-27 09:09:08 +03:00
|
|
|
*
|
|
|
|
* The global value <code>true</code> is the only instance of class
|
2019-03-22 14:04:59 +03:00
|
|
|
* TrueClass and represents a logically true value in
|
2003-12-27 09:09:08 +03:00
|
|
|
* boolean expressions. The class provides operators allowing
|
|
|
|
* <code>true</code> to be used in logical expressions.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* true.to_s -> "true"
|
2003-12-27 09:09:08 +03:00
|
|
|
*
|
|
|
|
* The string representation of <code>true</code> is "true".
|
|
|
|
*/
|
|
|
|
|
Optimize dynamic string interpolation for symbol/true/false/nil/0-9
This provides a significant speedup for symbol, true, false,
nil, and 0-9, class/module, and a small speedup in most other cases.
Speedups (using included benchmarks):
:symbol :: 60%
0-9 :: 50%
Class/Module :: 50%
nil/true/false :: 20%
integer :: 10%
[] :: 10%
"" :: 3%
One reason this approach is faster is it reduces the number of
VM instructions for each interpolated value.
Initial idea, approach, and benchmarks from Eric Wong. I applied
the same approach against the master branch, updating it to handle
the significant internal changes since this was first proposed 4
years ago (such as CALL_INFO/CALL_CACHE -> CALL_DATA). I also
expanded it to optimize true/false/nil/0-9/class/module, and added
handling of missing methods, refined methods, and RUBY_DEBUG.
This renames the tostring insn to anytostring, and adds an
objtostring insn that implements the optimization. This requires
making a few functions non-static, and adding some non-static
functions.
This disables 4 YJIT tests. Those tests should be reenabled after
YJIT optimizes the new objtostring insn.
Implements [Feature #13715]
Co-authored-by: Eric Wong <e@80x24.org>
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Co-authored-by: Yusuke Endoh <mame@ruby-lang.org>
Co-authored-by: Koichi Sasada <ko1@atdot.net>
2021-11-19 02:10:20 +03:00
|
|
|
MJIT_FUNC_EXPORTED VALUE
|
|
|
|
rb_true_to_s(VALUE obj)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2019-09-26 18:27:47 +03:00
|
|
|
return rb_cTrueClass_to_s;
|
1999-01-20 07:59:39 +03:00
|
|
|
}
|
|
|
|
|
2003-12-27 09:09:08 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* true & obj -> true or false
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-27 09:09:08 +03:00
|
|
|
* And---Returns <code>false</code> if <i>obj</i> is
|
|
|
|
* <code>nil</code> or <code>false</code>, <code>true</code> otherwise.
|
|
|
|
*/
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
true_and(VALUE obj, VALUE obj2)
|
1999-01-20 07:59:39 +03:00
|
|
|
{
|
2021-08-02 06:06:44 +03:00
|
|
|
return RBOOL(RTEST(obj2));
|
1999-01-20 07:59:39 +03:00
|
|
|
}
|
|
|
|
|
2003-12-27 09:09:08 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* true | obj -> true
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* Or---Returns <code>true</code>. As <i>obj</i> is an argument to
|
2003-12-27 09:09:08 +03:00
|
|
|
* a method call, it is always evaluated; there is no short-circuit
|
|
|
|
* evaluation in this case.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-27 09:09:08 +03:00
|
|
|
* true | puts("or")
|
|
|
|
* true || puts("logical or")
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-27 09:09:08 +03:00
|
|
|
* <em>produces:</em>
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-27 09:09:08 +03:00
|
|
|
* or
|
|
|
|
*/
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
true_or(VALUE obj, VALUE obj2)
|
1999-01-20 07:59:39 +03:00
|
|
|
{
|
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
|
2003-12-27 09:09:08 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* true ^ obj -> !obj
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-27 09:09:08 +03:00
|
|
|
* Exclusive Or---Returns <code>true</code> if <i>obj</i> is
|
|
|
|
* <code>nil</code> or <code>false</code>, <code>false</code>
|
|
|
|
* otherwise.
|
|
|
|
*/
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
true_xor(VALUE obj, VALUE obj2)
|
1999-01-20 07:59:39 +03:00
|
|
|
{
|
2022-01-01 09:41:00 +03:00
|
|
|
return rb_obj_not(obj2);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2003-12-21 10:28:54 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Document-class: FalseClass
|
|
|
|
*
|
|
|
|
* The global value <code>false</code> is the only instance of class
|
2019-03-22 14:04:59 +03:00
|
|
|
* FalseClass and represents a logically false value in
|
2003-12-21 10:28:54 +03:00
|
|
|
* boolean expressions. The class provides operators allowing
|
|
|
|
* <code>false</code> to participate correctly in logical expressions.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-21 10:28:54 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* false.to_s -> "false"
|
2003-12-21 10:28:54 +03:00
|
|
|
*
|
2017-07-22 11:07:58 +03:00
|
|
|
* The string representation of <code>false</code> is "false".
|
2003-12-21 10:28:54 +03:00
|
|
|
*/
|
|
|
|
|
Optimize dynamic string interpolation for symbol/true/false/nil/0-9
This provides a significant speedup for symbol, true, false,
nil, and 0-9, class/module, and a small speedup in most other cases.
Speedups (using included benchmarks):
:symbol :: 60%
0-9 :: 50%
Class/Module :: 50%
nil/true/false :: 20%
integer :: 10%
[] :: 10%
"" :: 3%
One reason this approach is faster is it reduces the number of
VM instructions for each interpolated value.
Initial idea, approach, and benchmarks from Eric Wong. I applied
the same approach against the master branch, updating it to handle
the significant internal changes since this was first proposed 4
years ago (such as CALL_INFO/CALL_CACHE -> CALL_DATA). I also
expanded it to optimize true/false/nil/0-9/class/module, and added
handling of missing methods, refined methods, and RUBY_DEBUG.
This renames the tostring insn to anytostring, and adds an
objtostring insn that implements the optimization. This requires
making a few functions non-static, and adding some non-static
functions.
This disables 4 YJIT tests. Those tests should be reenabled after
YJIT optimizes the new objtostring insn.
Implements [Feature #13715]
Co-authored-by: Eric Wong <e@80x24.org>
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Co-authored-by: Yusuke Endoh <mame@ruby-lang.org>
Co-authored-by: Koichi Sasada <ko1@atdot.net>
2021-11-19 02:10:20 +03:00
|
|
|
MJIT_FUNC_EXPORTED VALUE
|
|
|
|
rb_false_to_s(VALUE obj)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2019-09-26 18:27:47 +03:00
|
|
|
return rb_cFalseClass_to_s;
|
1999-01-20 07:59:39 +03:00
|
|
|
}
|
|
|
|
|
2003-12-21 10:28:54 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* false & obj -> false
|
|
|
|
* nil & obj -> false
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-21 10:28:54 +03:00
|
|
|
* And---Returns <code>false</code>. <i>obj</i> is always
|
|
|
|
* evaluated as it is the argument to a method call---there is no
|
|
|
|
* short-circuit evaluation in this case.
|
|
|
|
*/
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
false_and(VALUE obj, VALUE obj2)
|
1999-01-20 07:59:39 +03:00
|
|
|
{
|
|
|
|
return Qfalse;
|
|
|
|
}
|
|
|
|
|
2003-12-21 10:28:54 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* false | obj -> true or false
|
|
|
|
* nil | obj -> true or false
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-21 10:28:54 +03:00
|
|
|
* Or---Returns <code>false</code> if <i>obj</i> is
|
|
|
|
* <code>nil</code> or <code>false</code>; <code>true</code> otherwise.
|
|
|
|
*/
|
|
|
|
|
2020-05-06 19:51:03 +03:00
|
|
|
#define false_or true_and
|
2003-12-21 10:28:54 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* false ^ obj -> true or false
|
|
|
|
* nil ^ obj -> true or false
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-21 10:28:54 +03:00
|
|
|
* Exclusive Or---If <i>obj</i> is <code>nil</code> or
|
|
|
|
* <code>false</code>, returns <code>false</code>; otherwise, returns
|
|
|
|
* <code>true</code>.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-21 10:28:54 +03:00
|
|
|
*/
|
|
|
|
|
2020-05-06 19:51:03 +03:00
|
|
|
#define false_xor true_and
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
2013-05-31 11:04:33 +04:00
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* nil.nil? -> true
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
|
|
|
* Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>.
|
|
|
|
*/
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_true(VALUE obj)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
1999-01-20 07:59:39 +03:00
|
|
|
return Qtrue;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
2013-05-31 11:04:33 +04:00
|
|
|
* call-seq:
|
2014-12-09 12:20:05 +03:00
|
|
|
* obj.nil? -> true or false
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
|
|
|
* Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>.
|
2014-12-09 12:20:05 +03:00
|
|
|
*
|
|
|
|
* Object.new.nil? #=> false
|
|
|
|
* nil.nil? #=> true
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
2019-08-02 17:25:38 +03:00
|
|
|
MJIT_FUNC_EXPORTED VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_false(VALUE obj)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
1999-01-20 07:59:39 +03:00
|
|
|
return Qfalse;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2007-12-09 19:39:49 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj !~ other -> true or false
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2009-01-13 15:29:54 +03:00
|
|
|
* Returns true if two objects do not match (using the <i>=~</i>
|
|
|
|
* method), otherwise false.
|
2007-12-09 19:39:49 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_obj_not_match(VALUE obj1, VALUE obj2)
|
|
|
|
{
|
2007-12-10 02:25:20 +03:00
|
|
|
VALUE result = rb_funcall(obj1, id_match, 1, obj2);
|
2022-01-01 09:41:00 +03:00
|
|
|
return rb_obj_not(result);
|
2007-12-09 19:39:49 +03:00
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
|
2010-08-20 09:13:39 +04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* obj <=> other -> 0 or nil
|
|
|
|
*
|
2013-07-09 17:25:57 +04:00
|
|
|
* Returns 0 if +obj+ and +other+ are the same object
|
|
|
|
* or <code>obj == other</code>, otherwise nil.
|
2013-02-23 06:11:53 +04:00
|
|
|
*
|
2019-03-22 14:04:59 +03:00
|
|
|
* The #<=> is used by various methods to compare objects, for example
|
2013-02-23 06:11:53 +04:00
|
|
|
* Enumerable#sort, Enumerable#max etc.
|
|
|
|
*
|
2019-03-22 14:04:59 +03:00
|
|
|
* Your implementation of #<=> should return one of the following values: -1, 0,
|
2013-02-23 06:11:53 +04:00
|
|
|
* 1 or nil. -1 means self is smaller than other. 0 means self is equal to other.
|
|
|
|
* 1 means self is bigger than other. Nil means the two values could not be
|
|
|
|
* compared.
|
|
|
|
*
|
2019-03-22 14:04:59 +03:00
|
|
|
* When you define #<=>, you can include Comparable to gain the
|
|
|
|
* methods #<=, #<, #==, #>=, #> and #between?.
|
2010-08-20 09:13:39 +04:00
|
|
|
*/
|
2009-10-24 20:48:05 +04:00
|
|
|
static VALUE
|
|
|
|
rb_obj_cmp(VALUE obj1, VALUE obj2)
|
|
|
|
{
|
2020-05-06 01:09:56 +03:00
|
|
|
if (rb_equal(obj1, obj2))
|
2009-10-24 20:48:05 +04:00
|
|
|
return INT2FIX(0);
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/***********************************************************************
|
|
|
|
*
|
2004-01-02 09:01:12 +03:00
|
|
|
* Document-class: Module
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
2019-03-22 14:04:59 +03:00
|
|
|
* A Module is a collection of methods and constants. The
|
2003-12-28 09:33:07 +03:00
|
|
|
* methods in a module may be instance methods or module methods.
|
|
|
|
* Instance methods appear as methods in a class when the module is
|
|
|
|
* included, module methods do not. Conversely, module methods may be
|
|
|
|
* called without creating an encapsulating object, while instance
|
2019-03-22 14:04:59 +03:00
|
|
|
* methods may not. (See Module#module_function.)
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2009-11-03 20:46:28 +03:00
|
|
|
* In the descriptions that follow, the parameter <i>sym</i> refers
|
2003-12-28 09:33:07 +03:00
|
|
|
* to a symbol, which is either a quoted string or a
|
2019-03-22 14:04:59 +03:00
|
|
|
* Symbol (such as <code>:name</code>).
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* module Mod
|
|
|
|
* include Math
|
|
|
|
* CONST = 1
|
|
|
|
* def meth
|
|
|
|
* # ...
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* Mod.class #=> Module
|
2008-03-09 04:04:46 +03:00
|
|
|
* Mod.constants #=> [:CONST, :PI, :E]
|
|
|
|
* Mod.instance_methods #=> [:meth]
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
2004-01-02 09:01:12 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* mod.to_s -> string
|
2004-01-02 09:01:12 +03:00
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* Returns a string representing this module or class. For basic
|
2004-01-02 09:01:12 +03:00
|
|
|
* classes and modules, this is the name. For singletons, we
|
|
|
|
* show information on the thing we're attached to as well.
|
|
|
|
*/
|
|
|
|
|
Optimize dynamic string interpolation for symbol/true/false/nil/0-9
This provides a significant speedup for symbol, true, false,
nil, and 0-9, class/module, and a small speedup in most other cases.
Speedups (using included benchmarks):
:symbol :: 60%
0-9 :: 50%
Class/Module :: 50%
nil/true/false :: 20%
integer :: 10%
[] :: 10%
"" :: 3%
One reason this approach is faster is it reduces the number of
VM instructions for each interpolated value.
Initial idea, approach, and benchmarks from Eric Wong. I applied
the same approach against the master branch, updating it to handle
the significant internal changes since this was first proposed 4
years ago (such as CALL_INFO/CALL_CACHE -> CALL_DATA). I also
expanded it to optimize true/false/nil/0-9/class/module, and added
handling of missing methods, refined methods, and RUBY_DEBUG.
This renames the tostring insn to anytostring, and adds an
objtostring insn that implements the optimization. This requires
making a few functions non-static, and adding some non-static
functions.
This disables 4 YJIT tests. Those tests should be reenabled after
YJIT optimizes the new objtostring insn.
Implements [Feature #13715]
Co-authored-by: Eric Wong <e@80x24.org>
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Co-authored-by: Yusuke Endoh <mame@ruby-lang.org>
Co-authored-by: Koichi Sasada <ko1@atdot.net>
2021-11-19 02:10:20 +03:00
|
|
|
MJIT_FUNC_EXPORTED VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_mod_to_s(VALUE klass)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
* revised r37993 to avoid SEGV/ILL in tests. In r37993, a method
entry with VM_METHOD_TYPE_REFINED holds only the original method
definition, so ci->me is set to a method entry allocated in the
stack, and it causes SEGV/ILL. In this commit, a method entry
with VM_METHOD_TYPE_REFINED holds the whole original method entry.
Furthermore, rb_thread_mark() is changed to mark cfp->klass to
avoid GC for iclasses created by copy_refinement_iclass().
* vm_method.c (rb_method_entry_make): add a method entry with
VM_METHOD_TYPE_REFINED to the class refined by the refinement if
the target module is a refinement. When a method entry with
VM_METHOD_TYPE_UNDEF is invoked by vm_call_method(), a method with
the same name is searched in refinements. If such a method is
found, the method is invoked. Otherwise, the original method in
the refined class (rb_method_definition_t::body.orig_me) is
invoked. This change is made to simplify the normal method lookup
and to improve the performance of normal method calls.
* vm_method.c (EXPR1, search_method, rb_method_entry),
vm_eval.c (rb_call0, rb_search_method_entry): do not use
refinements for method lookup.
* vm_insnhelper.c (vm_call_method): search methods in refinements if
ci->me is VM_METHOD_TYPE_REFINED. If the method is called by
super (i.e., ci->call == vm_call_super_method), skip the same
method entry as the current method to avoid infinite call of the
same method.
* class.c (include_modules_at): add a refined method entry for each
method defined in a module included in a refinement.
* class.c (rb_prepend_module): set an empty table to
RCLASS_M_TBL(klass) to add refined method entries, because
refinements should have priority over prepended modules.
* proc.c (mnew): use rb_method_entry_with_refinements() to get
a refined method.
* vm.c (rb_thread_mark): mark cfp->klass for iclasses created by
copy_refinement_iclass().
* vm.c (Init_VM), cont.c (fiber_init): initialize th->cfp->klass.
* test/ruby/test_refinement.rb (test_inline_method_cache): do not skip
the test because it should pass successfully.
* test/ruby/test_refinement.rb (test_redefine_refined_method): new
test for the case a refined method is redefined.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38236 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-12-06 17:08:41 +04:00
|
|
|
ID id_defined_at;
|
2012-11-02 12:53:06 +04:00
|
|
|
VALUE refined_class, defined_at;
|
|
|
|
|
2001-05-11 09:24:59 +04:00
|
|
|
if (FL_TEST(klass, FL_SINGLETON)) {
|
2013-01-15 18:07:22 +04:00
|
|
|
VALUE s = rb_usascii_str_new2("#<Class:");
|
2013-05-02 11:54:17 +04:00
|
|
|
VALUE v = rb_ivar_get(klass, id__attached__);
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2013-01-15 18:07:24 +04:00
|
|
|
if (CLASS_OR_MODULE_P(v)) {
|
2002-02-25 12:16:25 +03:00
|
|
|
rb_str_append(s, rb_inspect(v));
|
2013-01-15 18:07:24 +04:00
|
|
|
}
|
|
|
|
else {
|
2002-02-25 12:16:25 +03:00
|
|
|
rb_str_append(s, rb_any_to_s(v));
|
|
|
|
}
|
2001-05-11 09:24:59 +04:00
|
|
|
rb_str_cat2(s, ">");
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2001-05-11 09:24:59 +04:00
|
|
|
return s;
|
|
|
|
}
|
* revised r37993 to avoid SEGV/ILL in tests. In r37993, a method
entry with VM_METHOD_TYPE_REFINED holds only the original method
definition, so ci->me is set to a method entry allocated in the
stack, and it causes SEGV/ILL. In this commit, a method entry
with VM_METHOD_TYPE_REFINED holds the whole original method entry.
Furthermore, rb_thread_mark() is changed to mark cfp->klass to
avoid GC for iclasses created by copy_refinement_iclass().
* vm_method.c (rb_method_entry_make): add a method entry with
VM_METHOD_TYPE_REFINED to the class refined by the refinement if
the target module is a refinement. When a method entry with
VM_METHOD_TYPE_UNDEF is invoked by vm_call_method(), a method with
the same name is searched in refinements. If such a method is
found, the method is invoked. Otherwise, the original method in
the refined class (rb_method_definition_t::body.orig_me) is
invoked. This change is made to simplify the normal method lookup
and to improve the performance of normal method calls.
* vm_method.c (EXPR1, search_method, rb_method_entry),
vm_eval.c (rb_call0, rb_search_method_entry): do not use
refinements for method lookup.
* vm_insnhelper.c (vm_call_method): search methods in refinements if
ci->me is VM_METHOD_TYPE_REFINED. If the method is called by
super (i.e., ci->call == vm_call_super_method), skip the same
method entry as the current method to avoid infinite call of the
same method.
* class.c (include_modules_at): add a refined method entry for each
method defined in a module included in a refinement.
* class.c (rb_prepend_module): set an empty table to
RCLASS_M_TBL(klass) to add refined method entries, because
refinements should have priority over prepended modules.
* proc.c (mnew): use rb_method_entry_with_refinements() to get
a refined method.
* vm.c (rb_thread_mark): mark cfp->klass for iclasses created by
copy_refinement_iclass().
* vm.c (Init_VM), cont.c (fiber_init): initialize th->cfp->klass.
* test/ruby/test_refinement.rb (test_inline_method_cache): do not skip
the test because it should pass successfully.
* test/ruby/test_refinement.rb (test_redefine_refined_method): new
test for the case a refined method is redefined.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38236 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-12-06 17:08:41 +04:00
|
|
|
refined_class = rb_refinement_module_get_refined_class(klass);
|
2012-11-02 12:53:06 +04:00
|
|
|
if (!NIL_P(refined_class)) {
|
|
|
|
VALUE s = rb_usascii_str_new2("#<refinement:");
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2012-11-02 12:53:06 +04:00
|
|
|
rb_str_concat(s, rb_inspect(refined_class));
|
|
|
|
rb_str_cat2(s, "@");
|
|
|
|
CONST_ID(id_defined_at, "__defined_at__");
|
|
|
|
defined_at = rb_attr_get(klass, id_defined_at);
|
|
|
|
rb_str_concat(s, rb_inspect(defined_at));
|
|
|
|
rb_str_cat2(s, ">");
|
|
|
|
return s;
|
|
|
|
}
|
2019-06-10 23:46:57 +03:00
|
|
|
return rb_class_name(klass);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2004-06-16 18:21:34 +04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* mod.freeze -> mod
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2004-06-16 18:21:34 +04:00
|
|
|
* Prevents further modifications to <i>mod</i>.
|
2009-05-24 17:37:43 +04:00
|
|
|
*
|
|
|
|
* This method returns self.
|
2004-06-16 18:21:34 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_mod_freeze(VALUE mod)
|
2004-06-16 18:21:34 +04:00
|
|
|
{
|
2008-03-06 04:33:56 +03:00
|
|
|
rb_class_name(mod);
|
2004-06-16 18:21:34 +04:00
|
|
|
return rb_obj_freeze(mod);
|
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* mod === obj -> true or false
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* Case Equality---Returns <code>true</code> if <i>obj</i> is an
|
2016-06-28 03:56:31 +03:00
|
|
|
* instance of <i>mod</i> or an instance of one of <i>mod</i>'s descendants.
|
2015-08-07 22:00:59 +03:00
|
|
|
* Of limited use for modules, but can be used in <code>case</code> statements
|
|
|
|
* to classify objects by class.
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_mod_eqq(VALUE mod, VALUE arg)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
1999-01-20 07:59:39 +03:00
|
|
|
return rb_obj_is_kind_of(arg, mod);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2021-03-11 10:34:49 +03:00
|
|
|
/*
|
2003-12-28 09:33:07 +03:00
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* mod <= other -> true, false, or nil
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
|
|
|
* Returns true if <i>mod</i> is a subclass of <i>other</i> or
|
2009-02-22 17:23:33 +03:00
|
|
|
* is the same as <i>other</i>. Returns
|
|
|
|
* <code>nil</code> if there's no relationship between the two.
|
|
|
|
* (Think of the relationship in terms of the class definition:
|
2016-10-07 08:18:57 +03:00
|
|
|
* "class A < B" implies "A < B".)
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
2004-02-10 14:49:14 +03:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_class_inherited_p(VALUE mod, VALUE arg)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
2002-01-23 10:30:43 +03:00
|
|
|
if (mod == arg) return Qtrue;
|
2022-03-06 00:03:33 +03:00
|
|
|
|
|
|
|
if (RB_TYPE_P(arg, T_CLASS) && RB_TYPE_P(mod, T_CLASS)) {
|
|
|
|
// comparison between classes
|
|
|
|
size_t mod_depth = RCLASS_SUPERCLASS_DEPTH(mod);
|
|
|
|
size_t arg_depth = RCLASS_SUPERCLASS_DEPTH(arg);
|
|
|
|
if (arg_depth < mod_depth) {
|
|
|
|
// check if mod < arg
|
|
|
|
return RCLASS_SUPERCLASSES(mod)[arg_depth] == arg ?
|
|
|
|
Qtrue :
|
|
|
|
Qnil;
|
2022-07-27 12:42:27 +03:00
|
|
|
}
|
|
|
|
else if (arg_depth > mod_depth) {
|
2022-03-06 00:03:33 +03:00
|
|
|
// check if mod > arg
|
|
|
|
return RCLASS_SUPERCLASSES(arg)[mod_depth] == mod ?
|
|
|
|
Qfalse :
|
|
|
|
Qnil;
|
2022-07-27 12:42:27 +03:00
|
|
|
}
|
|
|
|
else {
|
2022-03-06 00:03:33 +03:00
|
|
|
// Depths match, and we know they aren't equal: no relation
|
|
|
|
return Qnil;
|
|
|
|
}
|
2022-07-27 12:42:27 +03:00
|
|
|
}
|
|
|
|
else {
|
2022-03-06 00:03:33 +03:00
|
|
|
if (!CLASS_OR_MODULE_P(arg) && !RB_TYPE_P(arg, T_ICLASS)) {
|
|
|
|
rb_raise(rb_eTypeError, "compared with non class/module");
|
|
|
|
}
|
|
|
|
if (class_search_ancestor(mod, RCLASS_ORIGIN(arg))) {
|
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
/* not mod < arg; check if mod > arg */
|
|
|
|
if (class_search_ancestor(arg, mod)) {
|
|
|
|
return Qfalse;
|
|
|
|
}
|
|
|
|
return Qnil;
|
2003-05-15 11:57:07 +04:00
|
|
|
}
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* mod < other -> true, false, or nil
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
2009-02-22 17:23:33 +03:00
|
|
|
* Returns true if <i>mod</i> is a subclass of <i>other</i>. Returns
|
2022-04-11 09:33:29 +03:00
|
|
|
* <code>false</code> if <i>mod</i> is the same as <i>other</i>
|
|
|
|
* or <i>mod</i> is an ancestor of <i>other</i>.
|
|
|
|
* Returns <code>nil</code> if there's no relationship between the two.
|
2009-02-22 17:23:33 +03:00
|
|
|
* (Think of the relationship in terms of the class definition:
|
2016-10-07 08:18:57 +03:00
|
|
|
* "class A < B" implies "A < B".)
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_mod_lt(VALUE mod, VALUE arg)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
1999-01-20 07:59:39 +03:00
|
|
|
if (mod == arg) return Qfalse;
|
2004-02-10 14:49:14 +03:00
|
|
|
return rb_class_inherited_p(mod, arg);
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* mod >= other -> true, false, or nil
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
|
|
|
* Returns true if <i>mod</i> is an ancestor of <i>other</i>, or the
|
2009-02-22 17:23:33 +03:00
|
|
|
* two modules are the same. Returns
|
|
|
|
* <code>nil</code> if there's no relationship between the two.
|
|
|
|
* (Think of the relationship in terms of the class definition:
|
2016-10-07 08:18:57 +03:00
|
|
|
* "class A < B" implies "B > A".)
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_mod_ge(VALUE mod, VALUE arg)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
2013-01-15 18:07:24 +04:00
|
|
|
if (!CLASS_OR_MODULE_P(arg)) {
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_raise(rb_eTypeError, "compared with non class/module");
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
2004-02-10 14:49:14 +03:00
|
|
|
return rb_class_inherited_p(arg, mod);
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* mod > other -> true, false, or nil
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
2009-02-22 17:23:33 +03:00
|
|
|
* Returns true if <i>mod</i> is an ancestor of <i>other</i>. Returns
|
2022-04-11 09:33:29 +03:00
|
|
|
* <code>false</code> if <i>mod</i> is the same as <i>other</i>
|
|
|
|
* or <i>mod</i> is a descendant of <i>other</i>.
|
|
|
|
* Returns <code>nil</code> if there's no relationship between the two.
|
2009-02-22 17:23:33 +03:00
|
|
|
* (Think of the relationship in terms of the class definition:
|
2016-10-07 08:18:57 +03:00
|
|
|
* "class A < B" implies "B > A".)
|
2003-12-28 09:33:07 +03:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_mod_gt(VALUE mod, VALUE arg)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
1999-01-20 07:59:39 +03:00
|
|
|
if (mod == arg) return Qfalse;
|
|
|
|
return rb_mod_ge(mod, arg);
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2013-02-23 07:35:38 +04:00
|
|
|
* module <=> other_module -> -1, 0, +1, or nil
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2013-02-23 07:35:38 +04:00
|
|
|
* Comparison---Returns -1, 0, +1 or nil depending on whether +module+
|
|
|
|
* includes +other_module+, they are the same, or if +module+ is included by
|
2015-11-12 06:50:58 +03:00
|
|
|
* +other_module+.
|
2013-02-23 07:35:38 +04:00
|
|
|
*
|
|
|
|
* Returns +nil+ if +module+ has no relationship with +other_module+, if
|
|
|
|
* +other_module+ is not a module, or if the two values are incomparable.
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_mod_cmp(VALUE mod, VALUE arg)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
2003-05-15 11:57:07 +04:00
|
|
|
VALUE cmp;
|
1998-01-16 15:19:22 +03:00
|
|
|
|
2002-01-23 10:30:43 +03:00
|
|
|
if (mod == arg) return INT2FIX(0);
|
2013-01-15 18:07:24 +04:00
|
|
|
if (!CLASS_OR_MODULE_P(arg)) {
|
2002-12-19 12:20:20 +03:00
|
|
|
return Qnil;
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
2004-02-10 14:49:14 +03:00
|
|
|
cmp = rb_class_inherited_p(mod, arg);
|
2003-05-19 10:27:06 +04:00
|
|
|
if (NIL_P(cmp)) return Qnil;
|
2003-05-15 11:57:07 +04:00
|
|
|
if (cmp) {
|
|
|
|
return INT2FIX(-1);
|
2002-01-23 10:30:43 +03:00
|
|
|
}
|
2003-05-15 11:57:07 +04:00
|
|
|
return INT2FIX(1);
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
2020-07-26 05:52:19 +03:00
|
|
|
static VALUE rb_mod_initialize_exec(VALUE module);
|
2002-01-23 10:30:43 +03:00
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* Module.new -> mod
|
|
|
|
* Module.new {|mod| block } -> mod
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Creates a new anonymous module. If a block is given, it is passed
|
|
|
|
* the module object, and the block is evaluated in the context of this
|
2019-03-22 14:04:59 +03:00
|
|
|
* module like #module_eval.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2010-09-18 10:56:41 +04:00
|
|
|
* fred = Module.new do
|
2003-12-28 09:33:07 +03:00
|
|
|
* def meth1
|
|
|
|
* "hello"
|
|
|
|
* end
|
|
|
|
* def meth2
|
|
|
|
* "bye"
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* a = "my string"
|
2010-09-18 10:56:41 +04:00
|
|
|
* a.extend(fred) #=> "my string"
|
2003-12-28 09:33:07 +03:00
|
|
|
* a.meth1 #=> "hello"
|
|
|
|
* a.meth2 #=> "bye"
|
2010-09-18 10:56:41 +04:00
|
|
|
*
|
|
|
|
* Assign the module to a constant (name starting uppercase) if you
|
|
|
|
* want to treat it like a regular module.
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_mod_initialize(VALUE module)
|
2020-07-26 05:52:19 +03:00
|
|
|
{
|
|
|
|
return rb_mod_initialize_exec(module);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_mod_initialize_exec(VALUE module)
|
1999-01-20 07:59:39 +03:00
|
|
|
{
|
2003-08-07 01:50:06 +04:00
|
|
|
if (rb_block_given_p()) {
|
2006-10-07 06:53:24 +04:00
|
|
|
rb_mod_module_exec(1, &module, module);
|
2003-08-07 01:50:06 +04:00
|
|
|
}
|
|
|
|
return Qnil;
|
1999-01-20 07:59:39 +03:00
|
|
|
}
|
|
|
|
|
2014-07-28 15:28:55 +04:00
|
|
|
/* :nodoc: */
|
2014-06-07 06:41:01 +04:00
|
|
|
static VALUE
|
2019-08-26 07:11:46 +03:00
|
|
|
rb_mod_initialize_clone(int argc, VALUE* argv, VALUE clone)
|
2014-06-07 06:41:01 +04:00
|
|
|
{
|
2019-08-26 07:11:46 +03:00
|
|
|
VALUE ret, orig, opts;
|
|
|
|
rb_scan_args(argc, argv, "1:", &orig, &opts);
|
|
|
|
ret = rb_obj_init_clone(argc, argv, clone);
|
2014-06-07 06:41:01 +04:00
|
|
|
if (OBJ_FROZEN(orig))
|
|
|
|
rb_class_name(clone);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2003-12-19 18:18:09 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-09-18 10:56:41 +04:00
|
|
|
* Class.new(super_class=Object) -> a_class
|
|
|
|
* Class.new(super_class=Object) { |mod| ... } -> a_class
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-19 18:18:09 +03:00
|
|
|
* Creates a new anonymous (unnamed) class with the given superclass
|
2019-03-22 14:04:59 +03:00
|
|
|
* (or Object if no parameter is given). You can give a
|
2003-12-19 18:18:09 +03:00
|
|
|
* class a name by assigning the class object to a constant.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2010-09-18 10:56:41 +04:00
|
|
|
* If a block is given, it is passed the class object, and the block
|
2016-08-24 06:57:58 +03:00
|
|
|
* is evaluated in the context of this class like
|
2019-03-22 14:04:59 +03:00
|
|
|
* #class_eval.
|
2010-09-18 10:56:41 +04:00
|
|
|
*
|
|
|
|
* fred = Class.new do
|
|
|
|
* def meth1
|
|
|
|
* "hello"
|
|
|
|
* end
|
|
|
|
* def meth2
|
|
|
|
* "bye"
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* a = fred.new #=> #<#<Class:0x100381890>:0x100376b98>
|
|
|
|
* a.meth1 #=> "hello"
|
|
|
|
* a.meth2 #=> "bye"
|
|
|
|
*
|
|
|
|
* Assign the class to a constant (name starting uppercase) if you
|
|
|
|
* want to treat it like a regular class.
|
2003-12-19 18:18:09 +03:00
|
|
|
*/
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_class_initialize(int argc, VALUE *argv, VALUE klass)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2003-08-07 01:50:06 +04:00
|
|
|
VALUE super;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2010-01-13 05:57:48 +03:00
|
|
|
if (RCLASS_SUPER(klass) != 0 || klass == rb_cBasicObject) {
|
2003-08-07 01:50:06 +04:00
|
|
|
rb_raise(rb_eTypeError, "already initialized class");
|
|
|
|
}
|
2018-12-05 04:09:44 +03:00
|
|
|
if (rb_check_arity(argc, 0, 1) == 0) {
|
1999-01-20 07:59:39 +03:00
|
|
|
super = rb_cObject;
|
|
|
|
}
|
2003-12-21 11:29:06 +03:00
|
|
|
else {
|
2018-12-05 04:09:44 +03:00
|
|
|
super = argv[0];
|
2003-12-21 11:29:06 +03:00
|
|
|
rb_check_inheritable(super);
|
2012-08-16 14:15:28 +04:00
|
|
|
if (super != rb_cBasicObject && !RCLASS_SUPER(super)) {
|
|
|
|
rb_raise(rb_eTypeError, "can't inherit uninitialized class");
|
|
|
|
}
|
2003-12-21 11:29:06 +03:00
|
|
|
}
|
* include/ruby/ruby.h: constify RBasic::klass and add
RBASIC_CLASS(obj) macro which returns a class of `obj'.
This change is a part of RGENGC branch [ruby-trunk - Feature #8339].
* object.c: add new function rb_obj_reveal().
This function reveal interal (hidden) object by rb_obj_hide().
Note that do not change class before and after hiding.
Only permitted example is:
klass = RBASIC_CLASS(obj);
rb_obj_hide(obj);
....
rb_obj_reveal(obj, klass);
TODO: API design. rb_obj_reveal() should be replaced with others.
TODO: modify constified variables using cast may be harmful for
compiler's analysis and optimizaton.
Any idea to prohibt inserting RBasic::klass directly?
If rename RBasic::klass and force to use RBASIC_CLASS(obj),
then all codes such as `RBASIC(obj)->klass' will be
compilation error. Is it acceptable? (We have similar
experience at Ruby 1.9,
for example "RARRAY(ary)->ptr" to "RARRAY_PTR(ary)".
* internal.h: add some macros.
* RBASIC_CLEAR_CLASS(obj) clear RBasic::klass to make it internal
object.
* RBASIC_SET_CLASS(obj, cls) set RBasic::klass.
* RBASIC_SET_CLASS_RAW(obj, cls) same as RBASIC_SET_CLASS
without write barrier (planned).
* RCLASS_SET_SUPER(a, b) set super class of a.
* array.c, class.c, compile.c, encoding.c, enum.c, error.c, eval.c,
file.c, gc.c, hash.c, io.c, iseq.c, marshal.c, object.c,
parse.y, proc.c, process.c, random.c, ruby.c, sprintf.c,
string.c, thread.c, transcode.c, vm.c, vm_eval.c, win32/file.c:
Use above macros and functions to access RBasic::klass.
* ext/coverage/coverage.c, ext/readline/readline.c,
ext/socket/ancdata.c, ext/socket/init.c,
* ext/zlib/zlib.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40691 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-05-13 14:49:11 +04:00
|
|
|
RCLASS_SET_SUPER(klass, super);
|
2002-01-10 23:18:39 +03:00
|
|
|
rb_make_metaclass(klass, RBASIC(super)->klass);
|
|
|
|
rb_class_inherited(super, klass);
|
2020-07-26 05:52:19 +03:00
|
|
|
rb_mod_initialize_exec(klass);
|
1998-01-16 15:13:05 +03:00
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
return klass;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \private */
|
2015-12-02 10:27:22 +03:00
|
|
|
void
|
|
|
|
rb_undefined_alloc(VALUE klass)
|
|
|
|
{
|
|
|
|
rb_raise(rb_eTypeError, "allocator undefined for %"PRIsVALUE,
|
|
|
|
klass);
|
|
|
|
}
|
|
|
|
|
2019-11-06 05:17:09 +03:00
|
|
|
static rb_alloc_func_t class_get_alloc_func(VALUE klass);
|
|
|
|
static VALUE class_call_alloc_func(rb_alloc_func_t allocator, VALUE klass);
|
|
|
|
|
2003-12-19 18:18:09 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* class.allocate() -> obj
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2008-06-04 13:55:14 +04:00
|
|
|
* Allocates space for a new object of <i>class</i>'s class and does not
|
|
|
|
* call initialize on the new instance. The returned object must be an
|
|
|
|
* instance of <i>class</i>.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2008-06-04 13:55:14 +04:00
|
|
|
* klass = Class.new do
|
|
|
|
* def initialize(*args)
|
|
|
|
* @initialized = true
|
|
|
|
* end
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2008-06-04 13:55:14 +04:00
|
|
|
* def initialized?
|
|
|
|
* @initialized || false
|
|
|
|
* end
|
|
|
|
* end
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2008-06-04 13:55:14 +04:00
|
|
|
* klass.allocate.initialized? #=> false
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-19 18:18:09 +03:00
|
|
|
*/
|
|
|
|
|
2019-11-06 05:17:09 +03:00
|
|
|
static VALUE
|
|
|
|
rb_class_alloc_m(VALUE klass)
|
|
|
|
{
|
|
|
|
rb_alloc_func_t allocator = class_get_alloc_func(klass);
|
|
|
|
if (!rb_obj_respond_to(klass, rb_intern("allocate"), 1)) {
|
|
|
|
rb_raise(rb_eTypeError, "calling %"PRIsVALUE".allocate is prohibited",
|
|
|
|
klass);
|
|
|
|
}
|
|
|
|
return class_call_alloc_func(allocator, klass);
|
|
|
|
}
|
|
|
|
|
2017-01-02 03:22:46 +03:00
|
|
|
static VALUE
|
|
|
|
rb_class_alloc(VALUE klass)
|
2001-10-03 11:19:19 +04:00
|
|
|
{
|
2019-11-06 05:17:09 +03:00
|
|
|
rb_alloc_func_t allocator = class_get_alloc_func(klass);
|
|
|
|
return class_call_alloc_func(allocator, klass);
|
|
|
|
}
|
|
|
|
|
|
|
|
static rb_alloc_func_t
|
|
|
|
class_get_alloc_func(VALUE klass)
|
|
|
|
{
|
2012-09-08 13:52:26 +04:00
|
|
|
rb_alloc_func_t allocator;
|
2001-10-03 11:19:19 +04:00
|
|
|
|
2007-09-28 10:21:46 +04:00
|
|
|
if (RCLASS_SUPER(klass) == 0 && klass != rb_cBasicObject) {
|
2003-08-07 01:50:06 +04:00
|
|
|
rb_raise(rb_eTypeError, "can't instantiate uninitialized class");
|
|
|
|
}
|
2003-05-17 03:28:31 +04:00
|
|
|
if (FL_TEST(klass, FL_SINGLETON)) {
|
2004-11-16 07:55:14 +03:00
|
|
|
rb_raise(rb_eTypeError, "can't create instance of singleton class");
|
2003-05-17 03:28:31 +04:00
|
|
|
}
|
2012-09-08 13:52:26 +04:00
|
|
|
allocator = rb_get_alloc_func(klass);
|
|
|
|
if (!allocator) {
|
2015-12-02 10:27:22 +03:00
|
|
|
rb_undefined_alloc(klass);
|
2012-09-08 13:52:26 +04:00
|
|
|
}
|
2019-11-06 05:17:09 +03:00
|
|
|
return allocator;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
class_call_alloc_func(rb_alloc_func_t allocator, VALUE klass)
|
|
|
|
{
|
|
|
|
VALUE obj;
|
2012-09-08 13:52:26 +04:00
|
|
|
|
2015-10-29 08:32:57 +03:00
|
|
|
RUBY_DTRACE_CREATE_HOOK(OBJECT, rb_class2name(klass));
|
* probes.d: add DTrace probe declarations. [ruby-core:27448]
* array.c (empty_ary_alloc, ary_new): added array create DTrace probe.
* compile.c (rb_insns_name): allowing DTrace probes to access
instruction sequence name.
* Makefile.in: translate probes.d file to appropriate header file.
* common.mk: declare dependencies on the DTrace header.
* configure.in: add a test for existence of DTrace.
* eval.c (setup_exception): add a probe for when an exception is
raised.
* gc.c: Add DTrace probes for mark begin and end, and sweep begin and
end.
* hash.c (empty_hash_alloc): Add a probe for hash allocation.
* insns.def: Add probes for function entry and return.
* internal.h: function declaration for compile.c change.
* load.c (rb_f_load): add probes for `load` entry and exit, require
entry and exit, and wrapping search_required for load path search.
* object.c (rb_obj_alloc): added a probe for general object creation.
* parse.y (yycompile0): added a probe around parse and compile phase.
* string.c (empty_str_alloc, str_new): DTrace probes for string
allocation.
* test/dtrace/*: tests for DTrace probes.
* vm.c (vm_invoke_proc): add probes for function return on exception
raise, hash create, and instruction sequence execution.
* vm_core.h: add probe declarations for function entry and exit.
* vm_dump.c: add probes header file.
* vm_eval.c (vm_call0_cfunc, vm_call0_cfunc_with_frame): add probe on
function entry and return.
* vm_exec.c: expose instruction number to instruction name function.
* vm_insnshelper.c: add function entry and exit probes for cfunc
methods.
* vm_insnhelper.h: vm usage information is always collected, so
uncomment the functions.
12 19:14:50 2012 Akinori MUSHA <knu@iDaemons.org>
* configure.in (isinf, isnan): isinf() and isnan() are macros on
DragonFly which cannot be found by AC_REPLACE_FUNCS(). This
workaround enforces the fact that they exist on DragonFly.
12 15:59:38 2012 Shugo Maeda <shugo@ruby-lang.org>
* vm_core.h (rb_call_info_t::refinements), compile.c (new_callinfo),
vm_insnhelper.c (vm_search_method): revert r37616 because it's too
slow. [ruby-dev:46477]
* test/ruby/test_refinement.rb (test_inline_method_cache): skip
the test until the bug is fixed efficiently.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37631 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-11-13 01:52:12 +04:00
|
|
|
|
2012-09-08 13:52:26 +04:00
|
|
|
obj = (*allocator)(klass);
|
* probes.d: add DTrace probe declarations. [ruby-core:27448]
* array.c (empty_ary_alloc, ary_new): added array create DTrace probe.
* compile.c (rb_insns_name): allowing DTrace probes to access
instruction sequence name.
* Makefile.in: translate probes.d file to appropriate header file.
* common.mk: declare dependencies on the DTrace header.
* configure.in: add a test for existence of DTrace.
* eval.c (setup_exception): add a probe for when an exception is
raised.
* gc.c: Add DTrace probes for mark begin and end, and sweep begin and
end.
* hash.c (empty_hash_alloc): Add a probe for hash allocation.
* insns.def: Add probes for function entry and return.
* internal.h: function declaration for compile.c change.
* load.c (rb_f_load): add probes for `load` entry and exit, require
entry and exit, and wrapping search_required for load path search.
* object.c (rb_obj_alloc): added a probe for general object creation.
* parse.y (yycompile0): added a probe around parse and compile phase.
* string.c (empty_str_alloc, str_new): DTrace probes for string
allocation.
* test/dtrace/*: tests for DTrace probes.
* vm.c (vm_invoke_proc): add probes for function return on exception
raise, hash create, and instruction sequence execution.
* vm_core.h: add probe declarations for function entry and exit.
* vm_dump.c: add probes header file.
* vm_eval.c (vm_call0_cfunc, vm_call0_cfunc_with_frame): add probe on
function entry and return.
* vm_exec.c: expose instruction number to instruction name function.
* vm_insnshelper.c: add function entry and exit probes for cfunc
methods.
* vm_insnhelper.h: vm usage information is always collected, so
uncomment the functions.
12 19:14:50 2012 Akinori MUSHA <knu@iDaemons.org>
* configure.in (isinf, isnan): isinf() and isnan() are macros on
DragonFly which cannot be found by AC_REPLACE_FUNCS(). This
workaround enforces the fact that they exist on DragonFly.
12 15:59:38 2012 Shugo Maeda <shugo@ruby-lang.org>
* vm_core.h (rb_call_info_t::refinements), compile.c (new_callinfo),
vm_insnhelper.c (vm_search_method): revert r37616 because it's too
slow. [ruby-dev:46477]
* test/ruby/test_refinement.rb (test_inline_method_cache): skip
the test until the bug is fixed efficiently.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37631 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-11-13 01:52:12 +04:00
|
|
|
|
2001-10-03 11:19:19 +04:00
|
|
|
if (rb_obj_class(obj) != rb_class_real(klass)) {
|
|
|
|
rb_raise(rb_eTypeError, "wrong instance allocation");
|
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2017-01-02 03:22:46 +03:00
|
|
|
VALUE
|
|
|
|
rb_obj_alloc(VALUE klass)
|
|
|
|
{
|
|
|
|
Check_Type(klass, T_CLASS);
|
|
|
|
return rb_class_alloc(klass);
|
|
|
|
}
|
|
|
|
|
2003-12-19 18:18:09 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* class.new(args, ...) -> obj
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2019-03-22 14:04:59 +03:00
|
|
|
* Calls #allocate to create a new object of <i>class</i>'s class,
|
|
|
|
* then invokes that object's #initialize method, passing it
|
|
|
|
* <i>args</i>. This is the method that ends up getting called
|
|
|
|
* whenever an object is constructed using <code>.new</code>.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-19 18:18:09 +03:00
|
|
|
*/
|
|
|
|
|
2020-05-08 06:58:19 +03:00
|
|
|
VALUE
|
|
|
|
rb_class_new_instance_pass_kw(int argc, const VALUE *argv, VALUE klass)
|
2001-10-03 11:19:19 +04:00
|
|
|
{
|
|
|
|
VALUE obj;
|
|
|
|
|
2017-01-02 03:22:46 +03:00
|
|
|
obj = rb_class_alloc(klass);
|
2019-09-14 11:49:33 +03:00
|
|
|
rb_obj_call_init_kw(obj, argc, argv, RB_PASS_CALLED_KEYWORDS);
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_class_new_instance_kw(int argc, const VALUE *argv, VALUE klass, int kw_splat)
|
|
|
|
{
|
|
|
|
VALUE obj;
|
|
|
|
Check_Type(klass, T_CLASS);
|
|
|
|
|
|
|
|
obj = rb_class_alloc(klass);
|
|
|
|
rb_obj_call_init_kw(obj, argc, argv, kw_splat);
|
2001-10-03 11:19:19 +04:00
|
|
|
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2017-01-02 03:03:28 +03:00
|
|
|
VALUE
|
|
|
|
rb_class_new_instance(int argc, const VALUE *argv, VALUE klass)
|
|
|
|
{
|
2022-08-15 13:40:45 +03:00
|
|
|
return rb_class_new_instance_kw(argc, argv, klass, RB_NO_KEYWORDS);
|
2017-01-02 03:03:28 +03:00
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/**
|
2003-12-19 18:18:09 +03:00
|
|
|
* call-seq:
|
|
|
|
* class.superclass -> a_super_class or nil
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-19 18:18:09 +03:00
|
|
|
* Returns the superclass of <i>class</i>, or <code>nil</code>.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2008-03-09 04:04:46 +03:00
|
|
|
* File.superclass #=> IO
|
|
|
|
* IO.superclass #=> Object
|
|
|
|
* Object.superclass #=> BasicObject
|
2008-06-22 04:51:17 +04:00
|
|
|
* class Foo; end
|
|
|
|
* class Bar < Foo; end
|
|
|
|
* Bar.superclass #=> Foo
|
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* Returns nil when the given class does not have a parent class:
|
2008-06-22 04:51:17 +04:00
|
|
|
*
|
2008-03-09 04:04:46 +03:00
|
|
|
* BasicObject.superclass #=> nil
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2017-07-22 09:30:53 +03:00
|
|
|
*--
|
|
|
|
* Returns the superclass of \a klass. Equivalent to \c Class\#superclass in Ruby.
|
|
|
|
*
|
|
|
|
* It skips modules.
|
|
|
|
* \param[in] klass a Class object
|
|
|
|
* \return the superclass, or \c Qnil if \a klass does not have a parent class.
|
|
|
|
* \sa rb_class_get_superclass
|
|
|
|
*++
|
2003-12-19 18:18:09 +03:00
|
|
|
*/
|
|
|
|
|
2011-05-18 17:41:54 +04:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_class_superclass(VALUE klass)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2022-03-05 10:31:37 +03:00
|
|
|
RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS));
|
|
|
|
|
2007-09-28 10:21:46 +04:00
|
|
|
VALUE super = RCLASS_SUPER(klass);
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2003-08-07 01:50:06 +04:00
|
|
|
if (!super) {
|
2007-11-19 11:49:42 +03:00
|
|
|
if (klass == rb_cBasicObject) return Qnil;
|
2003-08-07 01:50:06 +04:00
|
|
|
rb_raise(rb_eTypeError, "uninitialized class");
|
2022-07-27 12:42:27 +03:00
|
|
|
}
|
|
|
|
else {
|
2022-03-05 10:31:37 +03:00
|
|
|
super = RCLASS_SUPERCLASSES(klass)[RCLASS_SUPERCLASS_DEPTH(klass) - 1];
|
|
|
|
RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS));
|
|
|
|
return super;
|
2003-08-07 01:50:06 +04:00
|
|
|
}
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2011-06-18 07:05:11 +04:00
|
|
|
VALUE
|
|
|
|
rb_class_get_superclass(VALUE klass)
|
|
|
|
{
|
2013-12-20 09:10:07 +04:00
|
|
|
return RCLASS(klass)->super;
|
2011-06-18 07:05:11 +04:00
|
|
|
}
|
|
|
|
|
2019-07-09 04:58:12 +03:00
|
|
|
static const char bad_instance_name[] = "`%1$s' is not allowed as an instance variable name";
|
|
|
|
static const char bad_class_name[] = "`%1$s' is not allowed as a class variable name";
|
|
|
|
static const char bad_const_name[] = "wrong constant name %1$s";
|
|
|
|
static const char bad_attr_name[] = "invalid attribute name `%1$s'";
|
|
|
|
#define wrong_constant_name bad_const_name
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \private */
|
2019-07-09 04:58:12 +03:00
|
|
|
#define id_for_var(obj, name, type) id_for_setter(obj, name, type, bad_##type##_name)
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \private */
|
2015-10-28 09:24:12 +03:00
|
|
|
#define id_for_setter(obj, name, type, message) \
|
|
|
|
check_setter_id(obj, &(name), rb_is_##type##_id, rb_is_##type##_name, message, strlen(message))
|
2013-04-08 18:57:29 +04:00
|
|
|
static ID
|
2015-10-28 09:24:12 +03:00
|
|
|
check_setter_id(VALUE obj, VALUE *pname,
|
|
|
|
int (*valid_id_p)(ID), int (*valid_name_p)(VALUE),
|
|
|
|
const char *message, size_t message_len)
|
2013-04-08 18:57:29 +04:00
|
|
|
{
|
2015-10-28 09:24:12 +03:00
|
|
|
ID id = rb_check_id(pname);
|
|
|
|
VALUE name = *pname;
|
|
|
|
|
|
|
|
if (id ? !valid_id_p(id) : !valid_name_p(name)) {
|
|
|
|
rb_name_err_raise_str(rb_fstring_new(message, message_len),
|
|
|
|
obj, name);
|
2013-04-08 18:57:29 +04:00
|
|
|
}
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
2013-10-09 18:57:04 +04:00
|
|
|
static int
|
|
|
|
rb_is_attr_name(VALUE name)
|
|
|
|
{
|
|
|
|
return rb_is_local_name(name) || rb_is_const_name(name);
|
|
|
|
}
|
|
|
|
|
2014-11-21 19:11:55 +03:00
|
|
|
static int
|
2015-10-28 09:24:12 +03:00
|
|
|
rb_is_attr_id(ID id)
|
2014-11-21 19:11:55 +03:00
|
|
|
{
|
2015-10-28 09:24:12 +03:00
|
|
|
return rb_is_local_id(id) || rb_is_const_id(id);
|
2014-11-21 19:11:55 +03:00
|
|
|
}
|
|
|
|
|
2013-10-09 18:57:04 +04:00
|
|
|
static ID
|
2015-10-28 09:24:12 +03:00
|
|
|
id_for_attr(VALUE obj, VALUE name)
|
2013-10-09 18:57:04 +04:00
|
|
|
{
|
2019-07-09 04:58:12 +03:00
|
|
|
ID id = id_for_var(obj, name, attr);
|
2015-10-28 09:24:12 +03:00
|
|
|
if (!id) id = rb_intern_str(name);
|
|
|
|
return id;
|
2013-10-09 18:57:04 +04:00
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2020-12-18 19:40:31 +03:00
|
|
|
* attr_reader(symbol, ...) -> array
|
|
|
|
* attr(symbol, ...) -> array
|
|
|
|
* attr_reader(string, ...) -> array
|
|
|
|
* attr(string, ...) -> array
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Creates instance variables and corresponding methods that return the
|
|
|
|
* value of each instance variable. Equivalent to calling
|
|
|
|
* ``<code>attr</code><i>:name</i>'' on each name in turn.
|
2013-02-24 08:24:52 +04:00
|
|
|
* String arguments are converted to symbols.
|
2020-12-25 01:09:51 +03:00
|
|
|
* Returns an array of defined method names as symbols.
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_mod_attr_reader(int argc, VALUE *argv, VALUE klass)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
|
|
|
int i;
|
2020-12-18 21:11:35 +03:00
|
|
|
VALUE names = rb_ary_new2(argc);
|
1998-01-16 15:19:22 +03:00
|
|
|
|
|
|
|
for (i=0; i<argc; i++) {
|
2020-12-18 21:11:35 +03:00
|
|
|
ID id = id_for_attr(klass, argv[i]);
|
|
|
|
rb_attr(klass, id, TRUE, FALSE, TRUE);
|
|
|
|
rb_ary_push(names, ID2SYM(id));
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
2020-12-18 21:11:35 +03:00
|
|
|
return names;
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/**
|
|
|
|
* call-seq:
|
2020-12-18 19:40:31 +03:00
|
|
|
* attr(name, ...) -> array
|
|
|
|
* attr(name, true) -> array
|
|
|
|
* attr(name, false) -> array
|
2017-07-22 09:30:53 +03:00
|
|
|
*
|
2019-03-22 14:04:59 +03:00
|
|
|
* The first form is equivalent to #attr_reader.
|
2017-07-22 09:30:53 +03:00
|
|
|
* The second form is equivalent to <code>attr_accessor(name)</code> but deprecated.
|
|
|
|
* The last form is equivalent to <code>attr_reader(name)</code> but deprecated.
|
2020-12-25 01:09:51 +03:00
|
|
|
* Returns an array of defined method names as symbols.
|
2017-07-22 09:30:53 +03:00
|
|
|
*--
|
|
|
|
* \private
|
2017-07-22 15:26:19 +03:00
|
|
|
* \todo can be static?
|
2017-07-22 09:30:53 +03:00
|
|
|
*++
|
|
|
|
*/
|
2006-07-20 21:30:01 +04:00
|
|
|
VALUE
|
|
|
|
rb_mod_attr(int argc, VALUE *argv, VALUE klass)
|
|
|
|
{
|
|
|
|
if (argc == 2 && (argv[1] == Qtrue || argv[1] == Qfalse)) {
|
2020-12-18 21:11:35 +03:00
|
|
|
ID id = id_for_attr(klass, argv[0]);
|
|
|
|
VALUE names = rb_ary_new();
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2020-12-18 21:11:35 +03:00
|
|
|
rb_category_warning(RB_WARN_CATEGORY_DEPRECATED, "optional boolean argument is obsoleted");
|
|
|
|
rb_attr(klass, id, 1, RTEST(argv[1]), TRUE);
|
|
|
|
rb_ary_push(names, ID2SYM(id));
|
2020-12-18 06:10:20 +03:00
|
|
|
if (argv[1] == Qtrue) rb_ary_push(names, ID2SYM(rb_id_attrset(id)));
|
2020-12-18 21:11:35 +03:00
|
|
|
return names;
|
2006-07-20 21:30:01 +04:00
|
|
|
}
|
|
|
|
return rb_mod_attr_reader(argc, argv, klass);
|
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2020-12-18 19:40:31 +03:00
|
|
|
* attr_writer(symbol, ...) -> array
|
|
|
|
* attr_writer(string, ...) -> array
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Creates an accessor method to allow assignment to the attribute
|
2013-01-29 22:58:37 +04:00
|
|
|
* <i>symbol</i><code>.id2name</code>.
|
2013-02-24 08:24:52 +04:00
|
|
|
* String arguments are converted to symbols.
|
2020-12-25 01:09:51 +03:00
|
|
|
* Returns an array of defined method names as symbols.
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_mod_attr_writer(int argc, VALUE *argv, VALUE klass)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
|
|
|
int i;
|
2020-12-18 21:11:35 +03:00
|
|
|
VALUE names = rb_ary_new2(argc);
|
1998-01-16 15:19:22 +03:00
|
|
|
|
|
|
|
for (i=0; i<argc; i++) {
|
2020-12-18 21:11:35 +03:00
|
|
|
ID id = id_for_attr(klass, argv[i]);
|
|
|
|
rb_attr(klass, id, FALSE, TRUE, TRUE);
|
2020-12-18 21:20:09 +03:00
|
|
|
rb_ary_push(names, ID2SYM(rb_id_attrset(id)));
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
2020-12-18 21:11:35 +03:00
|
|
|
return names;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2020-12-18 19:40:31 +03:00
|
|
|
* attr_accessor(symbol, ...) -> array
|
|
|
|
* attr_accessor(string, ...) -> array
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2006-07-20 21:30:01 +04:00
|
|
|
* Defines a named attribute for this module, where the name is
|
|
|
|
* <i>symbol.</i><code>id2name</code>, creating an instance variable
|
|
|
|
* (<code>@name</code>) and a corresponding access method to read it.
|
|
|
|
* Also creates a method called <code>name=</code> to set the attribute.
|
2013-02-24 08:24:52 +04:00
|
|
|
* String arguments are converted to symbols.
|
2020-12-25 01:09:51 +03:00
|
|
|
* Returns an array of defined method names as symbols.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* module Mod
|
2020-12-18 19:40:31 +03:00
|
|
|
* attr_accessor(:one, :two) #=> [:one, :one=, :two, :two=]
|
2003-12-28 09:33:07 +03:00
|
|
|
* end
|
2008-03-09 04:04:46 +03:00
|
|
|
* Mod.instance_methods.sort #=> [:one, :one=, :two, :two=]
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_mod_attr_accessor(int argc, VALUE *argv, VALUE klass)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
|
|
|
int i;
|
2020-12-18 21:11:35 +03:00
|
|
|
VALUE names = rb_ary_new2(argc * 2);
|
1998-01-16 15:19:22 +03:00
|
|
|
|
|
|
|
for (i=0; i<argc; i++) {
|
2020-12-18 21:11:35 +03:00
|
|
|
ID id = id_for_attr(klass, argv[i]);
|
|
|
|
|
|
|
|
rb_attr(klass, id, TRUE, TRUE, TRUE);
|
2020-12-18 21:20:09 +03:00
|
|
|
rb_ary_push(names, ID2SYM(id));
|
|
|
|
rb_ary_push(names, ID2SYM(rb_id_attrset(id)));
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
2020-12-18 21:11:35 +03:00
|
|
|
return names;
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* mod.const_get(sym, inherit=true) -> obj
|
2012-10-27 01:31:23 +04:00
|
|
|
* mod.const_get(str, inherit=true) -> obj
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* Checks for a constant with the given name in <i>mod</i>.
|
2011-05-27 17:55:21 +04:00
|
|
|
* If +inherit+ is set, the lookup will also search
|
2014-12-09 12:20:05 +03:00
|
|
|
* the ancestors (and +Object+ if <i>mod</i> is a +Module+).
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2011-05-27 17:55:21 +04:00
|
|
|
* The value of the constant is returned if a definition is found,
|
|
|
|
* otherwise a +NameError+ is raised.
|
2006-01-17 17:05:49 +03:00
|
|
|
*
|
2011-05-27 17:55:21 +04:00
|
|
|
* Math.const_get(:PI) #=> 3.14159265358979
|
2012-10-27 01:31:23 +04:00
|
|
|
*
|
|
|
|
* This method will recursively look up constant names if a namespaced
|
|
|
|
* class name is provided. For example:
|
|
|
|
*
|
|
|
|
* module Foo; class Bar; end end
|
|
|
|
* Object.const_get 'Foo::Bar'
|
|
|
|
*
|
|
|
|
* The +inherit+ flag is respected on each lookup. For example:
|
|
|
|
*
|
|
|
|
* module Foo
|
|
|
|
* class Bar
|
|
|
|
* VAL = 10
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* class Baz < Bar; end
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* Object.const_get 'Foo::Baz::VAL' # => 10
|
|
|
|
* Object.const_get 'Foo::Baz::VAL', false # => NameError
|
2013-10-24 07:48:54 +04:00
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* If the argument is not a valid constant name a +NameError+ will be
|
2013-10-24 07:48:54 +04:00
|
|
|
* raised with a warning "wrong constant name".
|
|
|
|
*
|
|
|
|
* Object.const_get 'foobar' #=> NameError: wrong constant name foobar
|
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
static VALUE
|
2006-01-17 17:05:49 +03:00
|
|
|
rb_mod_const_get(int argc, VALUE *argv, VALUE mod)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
2006-01-17 17:05:49 +03:00
|
|
|
VALUE name, recur;
|
2012-10-27 01:31:23 +04:00
|
|
|
rb_encoding *enc;
|
2012-12-19 14:34:13 +04:00
|
|
|
const char *pbeg, *p, *path, *pend;
|
2006-01-17 17:05:49 +03:00
|
|
|
ID id;
|
2001-05-02 08:22:21 +04:00
|
|
|
|
2014-11-21 19:11:55 +03:00
|
|
|
rb_check_arity(argc, 1, 2);
|
|
|
|
name = argv[0];
|
|
|
|
recur = (argc == 1) ? Qtrue : argv[1];
|
2012-10-27 01:31:23 +04:00
|
|
|
|
2013-12-14 06:11:37 +04:00
|
|
|
if (SYMBOL_P(name)) {
|
2014-11-21 19:11:55 +03:00
|
|
|
if (!rb_is_const_sym(name)) goto wrong_name;
|
|
|
|
id = rb_check_id(&name);
|
|
|
|
if (!id) return rb_const_missing(mod, name);
|
2013-12-14 05:50:49 +04:00
|
|
|
return RTEST(recur) ? rb_const_get(mod, id) : rb_const_get_at(mod, id);
|
2012-10-27 01:31:23 +04:00
|
|
|
}
|
|
|
|
|
2013-12-14 06:24:47 +04:00
|
|
|
path = StringValuePtr(name);
|
2012-10-27 01:31:23 +04:00
|
|
|
enc = rb_enc_get(name);
|
|
|
|
|
|
|
|
if (!rb_enc_asciicompat(enc)) {
|
|
|
|
rb_raise(rb_eArgError, "invalid class path encoding (non ASCII)");
|
|
|
|
}
|
|
|
|
|
|
|
|
pbeg = p = path;
|
2012-12-19 14:34:13 +04:00
|
|
|
pend = path + RSTRING_LEN(name);
|
2012-11-06 15:42:24 +04:00
|
|
|
|
2012-12-22 14:40:03 +04:00
|
|
|
if (p >= pend || !*p) {
|
2020-06-16 04:50:53 +03:00
|
|
|
goto wrong_name;
|
2012-11-06 15:42:24 +04:00
|
|
|
}
|
|
|
|
|
2012-12-22 14:26:40 +04:00
|
|
|
if (p + 2 < pend && p[0] == ':' && p[1] == ':') {
|
2012-11-06 15:42:24 +04:00
|
|
|
mod = rb_cObject;
|
|
|
|
p += 2;
|
|
|
|
pbeg = p;
|
|
|
|
}
|
|
|
|
|
2012-12-19 14:34:13 +04:00
|
|
|
while (p < pend) {
|
2012-11-07 04:16:03 +04:00
|
|
|
VALUE part;
|
2012-12-22 19:04:57 +04:00
|
|
|
long len, beglen;
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2012-12-19 14:34:13 +04:00
|
|
|
while (p < pend && *p != ':') p++;
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2012-12-22 14:40:03 +04:00
|
|
|
if (pbeg == p) goto wrong_name;
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2014-07-09 10:14:41 +04:00
|
|
|
id = rb_check_id_cstr(pbeg, len = p-pbeg, enc);
|
2012-12-22 19:04:57 +04:00
|
|
|
beglen = pbeg-path;
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2012-12-22 14:26:40 +04:00
|
|
|
if (p < pend && p[0] == ':') {
|
2012-12-22 14:40:03 +04:00
|
|
|
if (p + 2 >= pend || p[1] != ':') goto wrong_name;
|
2012-10-27 01:31:23 +04:00
|
|
|
p += 2;
|
|
|
|
pbeg = p;
|
2011-07-26 20:05:35 +04:00
|
|
|
}
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2012-10-27 01:31:23 +04:00
|
|
|
if (!RB_TYPE_P(mod, T_MODULE) && !RB_TYPE_P(mod, T_CLASS)) {
|
2012-12-22 19:04:57 +04:00
|
|
|
rb_raise(rb_eTypeError, "%"PRIsVALUE" does not refer to class/module",
|
|
|
|
QUOTE(name));
|
2011-07-26 20:05:35 +04:00
|
|
|
}
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2012-12-22 14:40:03 +04:00
|
|
|
if (!id) {
|
2013-12-14 07:38:22 +04:00
|
|
|
part = rb_str_subseq(name, beglen, len);
|
|
|
|
OBJ_FREEZE(part);
|
2018-04-10 03:41:47 +03:00
|
|
|
if (!rb_is_const_name(part)) {
|
2015-10-28 09:24:12 +03:00
|
|
|
name = part;
|
|
|
|
goto wrong_name;
|
2012-12-22 14:40:03 +04:00
|
|
|
}
|
|
|
|
else if (!rb_method_basic_definition_p(CLASS_OF(mod), id_const_missing)) {
|
2014-11-21 19:11:55 +03:00
|
|
|
part = rb_str_intern(part);
|
|
|
|
mod = rb_const_missing(mod, part);
|
|
|
|
continue;
|
2012-12-22 14:40:03 +04:00
|
|
|
}
|
|
|
|
else {
|
2016-02-19 19:54:08 +03:00
|
|
|
rb_mod_const_missing(mod, part);
|
2012-12-22 14:40:03 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!rb_is_const_id(id)) {
|
2015-10-28 09:24:12 +03:00
|
|
|
name = ID2SYM(id);
|
|
|
|
goto wrong_name;
|
2012-12-22 14:40:03 +04:00
|
|
|
}
|
2019-04-08 16:47:37 +03:00
|
|
|
#if 0
|
|
|
|
mod = rb_const_get_0(mod, id, beglen > 0 || !RTEST(recur), RTEST(recur), FALSE);
|
|
|
|
#else
|
|
|
|
if (!RTEST(recur)) {
|
|
|
|
mod = rb_const_get_at(mod, id);
|
|
|
|
}
|
|
|
|
else if (beglen == 0) {
|
|
|
|
mod = rb_const_get(mod, id);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mod = rb_const_get_from(mod, id);
|
|
|
|
}
|
|
|
|
#endif
|
2011-07-26 20:05:35 +04:00
|
|
|
}
|
2012-10-27 01:31:23 +04:00
|
|
|
|
|
|
|
return mod;
|
2020-06-16 04:50:53 +03:00
|
|
|
|
|
|
|
wrong_name:
|
|
|
|
rb_name_err_raise(wrong_constant_name, mod, name);
|
2020-06-24 10:23:59 +03:00
|
|
|
UNREACHABLE_RETURN(Qundef);
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* mod.const_set(sym, obj) -> obj
|
2013-10-24 07:48:54 +04:00
|
|
|
* mod.const_set(str, obj) -> obj
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Sets the named constant to the given object, returning that object.
|
|
|
|
* Creates a new constant if no constant with the given name previously
|
|
|
|
* existed.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* Math.const_set("HIGH_SCHOOL_PI", 22.0/7.0) #=> 3.14285714285714
|
|
|
|
* Math::HIGH_SCHOOL_PI - Math::PI #=> 0.00126448926734968
|
2013-10-24 07:48:54 +04:00
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* If +sym+ or +str+ is not a valid constant name a +NameError+ will be
|
2013-10-24 07:48:54 +04:00
|
|
|
* raised with a warning "wrong constant name".
|
|
|
|
*
|
|
|
|
* Object.const_set('foobar', 42) #=> NameError: wrong constant name foobar
|
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_mod_const_set(VALUE mod, VALUE name, VALUE value)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
2019-07-09 04:58:12 +03:00
|
|
|
ID id = id_for_var(mod, name, const);
|
2015-10-28 09:24:12 +03:00
|
|
|
if (!id) id = rb_intern_str(name);
|
2013-04-04 12:18:54 +04:00
|
|
|
rb_const_set(mod, id, value);
|
use id_table for constant tables
valgrind 3.9.0 on x86-64 reports a minor reduction in memory usage
when loading only RubyGems and RDoc by running: ruby -rrdoc -eexit
before: HEAP SUMMARY:
in use at exit: 2,913,448 bytes in 27,394 blocks
total heap usage: 48,362 allocs, 20,968 frees, 9,034,621 bytes alloc
after: HEAP SUMMARY:
in use at exit: 2,880,056 bytes in 26,712 blocks
total heap usage: 47,791 allocs, 21,079 frees, 9,046,507 bytes alloc
* class.c (struct clone_const_arg): adjust for id_table
(clone_const): ditto
(clone_const_i): ditto
(rb_mod_init_copy): ditto
(rb_singleton_class_clone_and_attach): ditto
(rb_include_class_new): ditto
(include_modules_at): ditto
* constant.h (rb_free_const_table): ditto
* gc.c (free_const_entry_i): ditto
(rb_free_const_table): ditto
(obj_memsize_of): ditto
(mark_const_entry_i): ditto
(mark_const_tbl): ditto
* internal.h (struct rb_classext_struct): ditto
* object.c (rb_mod_const_set): resolve class name on assignment
* variable.c (const_update): replace with const_tbl_update
(const_tbl_update): new function
(fc_i): adjust for id_table
(find_class_path): ditto
(autoload_const_set): st_update => const_tbl_update
(rb_const_remove): adjust for id_table
(sv_i): ditto
(rb_local_constants_i): ditto
(rb_local_constants): ditto
(rb_mod_const_at): ditto
(rb_mod_const_set): ditto
(rb_const_lookup): ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53376 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-12-29 23:19:14 +03:00
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* mod.const_defined?(sym, inherit=true) -> true or false
|
2013-10-24 07:48:54 +04:00
|
|
|
* mod.const_defined?(str, inherit=true) -> true or false
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2014-11-08 19:54:15 +03:00
|
|
|
* Says whether _mod_ or its ancestors have a constant with the given name:
|
2011-05-27 17:55:21 +04:00
|
|
|
*
|
2014-11-08 19:54:15 +03:00
|
|
|
* Float.const_defined?(:EPSILON) #=> true, found in Float itself
|
|
|
|
* Float.const_defined?("String") #=> true, found in Object (ancestor)
|
|
|
|
* BasicObject.const_defined?(:Hash) #=> false
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2014-11-08 19:54:15 +03:00
|
|
|
* If _mod_ is a +Module+, additionally +Object+ and its ancestors are checked:
|
2013-10-24 07:48:54 +04:00
|
|
|
*
|
2014-11-08 19:54:15 +03:00
|
|
|
* Math.const_defined?(:String) #=> true, found in Object
|
|
|
|
*
|
|
|
|
* In each of the checked classes or modules, if the constant is not present
|
|
|
|
* but there is an autoload for it, +true+ is returned directly without
|
|
|
|
* autoloading:
|
|
|
|
*
|
|
|
|
* module Admin
|
|
|
|
* autoload :User, 'admin/user'
|
|
|
|
* end
|
|
|
|
* Admin.const_defined?(:User) #=> true
|
|
|
|
*
|
|
|
|
* If the constant is not found the callback +const_missing+ is *not* called
|
|
|
|
* and the method returns +false+.
|
|
|
|
*
|
|
|
|
* If +inherit+ is false, the lookup only checks the constants in the receiver:
|
|
|
|
*
|
|
|
|
* IO.const_defined?(:SYNC) #=> true, found in File::Constants (ancestor)
|
|
|
|
* IO.const_defined?(:SYNC, false) #=> false, not found in IO itself
|
|
|
|
*
|
|
|
|
* In this case, the same logic for autoloading applies.
|
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* If the argument is not a valid constant name a +NameError+ is raised with the
|
2014-11-08 19:54:15 +03:00
|
|
|
* message "wrong constant name _name_":
|
2013-10-24 07:48:54 +04:00
|
|
|
*
|
2014-11-08 19:54:15 +03:00
|
|
|
* Hash.const_defined? 'foobar' #=> NameError: wrong constant name foobar
|
2013-10-24 07:48:54 +04:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
static VALUE
|
2006-01-17 17:05:49 +03:00
|
|
|
rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
2006-01-17 17:05:49 +03:00
|
|
|
VALUE name, recur;
|
2013-12-14 06:25:58 +04:00
|
|
|
rb_encoding *enc;
|
|
|
|
const char *pbeg, *p, *path, *pend;
|
2006-01-17 17:05:49 +03:00
|
|
|
ID id;
|
2001-05-02 08:22:21 +04:00
|
|
|
|
2014-11-21 19:11:55 +03:00
|
|
|
rb_check_arity(argc, 1, 2);
|
|
|
|
name = argv[0];
|
|
|
|
recur = (argc == 1) ? Qtrue : argv[1];
|
2013-12-14 06:25:58 +04:00
|
|
|
|
|
|
|
if (SYMBOL_P(name)) {
|
2014-11-21 19:11:55 +03:00
|
|
|
if (!rb_is_const_sym(name)) goto wrong_name;
|
|
|
|
id = rb_check_id(&name);
|
|
|
|
if (!id) return Qfalse;
|
2013-12-14 06:25:58 +04:00
|
|
|
return RTEST(recur) ? rb_const_defined(mod, id) : rb_const_defined_at(mod, id);
|
|
|
|
}
|
|
|
|
|
|
|
|
path = StringValuePtr(name);
|
|
|
|
enc = rb_enc_get(name);
|
|
|
|
|
|
|
|
if (!rb_enc_asciicompat(enc)) {
|
|
|
|
rb_raise(rb_eArgError, "invalid class path encoding (non ASCII)");
|
|
|
|
}
|
|
|
|
|
|
|
|
pbeg = p = path;
|
|
|
|
pend = path + RSTRING_LEN(name);
|
|
|
|
|
|
|
|
if (p >= pend || !*p) {
|
2020-06-16 04:52:30 +03:00
|
|
|
goto wrong_name;
|
2013-12-14 06:25:58 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
if (p + 2 < pend && p[0] == ':' && p[1] == ':') {
|
|
|
|
mod = rb_cObject;
|
|
|
|
p += 2;
|
|
|
|
pbeg = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (p < pend) {
|
|
|
|
VALUE part;
|
|
|
|
long len, beglen;
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2013-12-14 06:25:58 +04:00
|
|
|
while (p < pend && *p != ':') p++;
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2013-12-14 06:25:58 +04:00
|
|
|
if (pbeg == p) goto wrong_name;
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2014-07-09 10:14:41 +04:00
|
|
|
id = rb_check_id_cstr(pbeg, len = p-pbeg, enc);
|
2013-12-14 06:25:58 +04:00
|
|
|
beglen = pbeg-path;
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2013-12-14 06:25:58 +04:00
|
|
|
if (p < pend && p[0] == ':') {
|
|
|
|
if (p + 2 >= pend || p[1] != ':') goto wrong_name;
|
|
|
|
p += 2;
|
|
|
|
pbeg = p;
|
|
|
|
}
|
2022-07-21 19:23:58 +03:00
|
|
|
|
2013-12-14 06:25:58 +04:00
|
|
|
if (!id) {
|
2013-12-14 07:38:22 +04:00
|
|
|
part = rb_str_subseq(name, beglen, len);
|
|
|
|
OBJ_FREEZE(part);
|
2018-04-10 03:41:47 +03:00
|
|
|
if (!rb_is_const_name(part)) {
|
2015-10-28 09:24:12 +03:00
|
|
|
name = part;
|
|
|
|
goto wrong_name;
|
2013-12-14 06:25:58 +04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
return Qfalse;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!rb_is_const_id(id)) {
|
2015-10-28 09:24:12 +03:00
|
|
|
name = ID2SYM(id);
|
|
|
|
goto wrong_name;
|
2013-12-14 06:25:58 +04:00
|
|
|
}
|
2019-04-08 16:47:37 +03:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
mod = rb_const_search(mod, id, beglen > 0 || !RTEST(recur), RTEST(recur), FALSE);
|
2022-11-15 07:24:08 +03:00
|
|
|
if (UNDEF_P(mod)) return Qfalse;
|
2019-04-08 16:47:37 +03:00
|
|
|
#else
|
|
|
|
if (!RTEST(recur)) {
|
2013-12-14 06:25:58 +04:00
|
|
|
if (!rb_const_defined_at(mod, id))
|
|
|
|
return Qfalse;
|
2019-05-07 13:00:57 +03:00
|
|
|
if (p == pend) return Qtrue;
|
2013-12-14 06:25:58 +04:00
|
|
|
mod = rb_const_get_at(mod, id);
|
|
|
|
}
|
2019-04-08 16:47:37 +03:00
|
|
|
else if (beglen == 0) {
|
|
|
|
if (!rb_const_defined(mod, id))
|
|
|
|
return Qfalse;
|
2019-05-07 13:00:57 +03:00
|
|
|
if (p == pend) return Qtrue;
|
2019-04-08 16:47:37 +03:00
|
|
|
mod = rb_const_get(mod, id);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (!rb_const_defined_from(mod, id))
|
|
|
|
return Qfalse;
|
2019-05-07 13:00:57 +03:00
|
|
|
if (p == pend) return Qtrue;
|
2019-04-08 16:47:37 +03:00
|
|
|
mod = rb_const_get_from(mod, id);
|
|
|
|
}
|
|
|
|
#endif
|
2013-12-14 06:25:58 +04:00
|
|
|
|
|
|
|
if (p < pend && !RB_TYPE_P(mod, T_MODULE) && !RB_TYPE_P(mod, T_CLASS)) {
|
|
|
|
rb_raise(rb_eTypeError, "%"PRIsVALUE" does not refer to class/module",
|
|
|
|
QUOTE(name));
|
2011-07-23 19:05:03 +04:00
|
|
|
}
|
|
|
|
}
|
2013-12-14 06:25:58 +04:00
|
|
|
|
|
|
|
return Qtrue;
|
2020-06-16 04:52:30 +03:00
|
|
|
|
|
|
|
wrong_name:
|
|
|
|
rb_name_err_raise(wrong_constant_name, mod, name);
|
2020-06-24 10:23:59 +03:00
|
|
|
UNREACHABLE_RETURN(Qundef);
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
2019-12-13 19:59:23 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* mod.const_source_location(sym, inherit=true) -> [String, Integer]
|
|
|
|
* mod.const_source_location(str, inherit=true) -> [String, Integer]
|
|
|
|
*
|
2020-01-19 14:49:15 +03:00
|
|
|
* Returns the Ruby source filename and line number containing the definition
|
|
|
|
* of the constant specified. If the named constant is not found, +nil+ is returned.
|
2019-12-13 19:59:23 +03:00
|
|
|
* If the constant is found, but its source location can not be extracted
|
|
|
|
* (constant is defined in C code), empty array is returned.
|
|
|
|
*
|
|
|
|
* _inherit_ specifies whether to lookup in <code>mod.ancestors</code> (+true+
|
|
|
|
* by default).
|
|
|
|
*
|
|
|
|
* # test.rb:
|
2020-01-24 03:46:34 +03:00
|
|
|
* class A # line 1
|
2019-12-13 19:59:23 +03:00
|
|
|
* C1 = 1
|
2020-01-19 14:49:15 +03:00
|
|
|
* C2 = 2
|
2019-12-13 19:59:23 +03:00
|
|
|
* end
|
|
|
|
*
|
2020-01-24 03:46:34 +03:00
|
|
|
* module M # line 6
|
2020-01-19 14:49:15 +03:00
|
|
|
* C3 = 3
|
2019-12-13 19:59:23 +03:00
|
|
|
* end
|
|
|
|
*
|
2020-01-24 03:46:34 +03:00
|
|
|
* class B < A # line 10
|
2019-12-13 19:59:23 +03:00
|
|
|
* include M
|
2020-01-19 14:49:15 +03:00
|
|
|
* C4 = 4
|
2019-12-13 19:59:23 +03:00
|
|
|
* end
|
|
|
|
*
|
|
|
|
* class A # continuation of A definition
|
2020-01-19 14:49:15 +03:00
|
|
|
* C2 = 8 # constant redefinition; warned yet allowed
|
2019-12-13 19:59:23 +03:00
|
|
|
* end
|
|
|
|
*
|
2020-01-24 03:46:34 +03:00
|
|
|
* p B.const_source_location('C4') # => ["test.rb", 12]
|
|
|
|
* p B.const_source_location('C3') # => ["test.rb", 7]
|
2019-12-13 19:59:23 +03:00
|
|
|
* p B.const_source_location('C1') # => ["test.rb", 2]
|
|
|
|
*
|
2020-01-19 14:49:15 +03:00
|
|
|
* p B.const_source_location('C3', false) # => nil -- don't lookup in ancestors
|
|
|
|
*
|
|
|
|
* p A.const_source_location('C2') # => ["test.rb", 16] -- actual (last) definition place
|
2019-12-13 19:59:23 +03:00
|
|
|
*
|
2020-01-24 03:46:34 +03:00
|
|
|
* p Object.const_source_location('B') # => ["test.rb", 10] -- top-level constant could be looked through Object
|
2020-01-19 14:49:15 +03:00
|
|
|
* p Object.const_source_location('A') # => ["test.rb", 1] -- class reopening is NOT considered new definition
|
2019-12-13 19:59:23 +03:00
|
|
|
*
|
|
|
|
* p B.const_source_location('A') # => ["test.rb", 1] -- because Object is in ancestors
|
|
|
|
* p M.const_source_location('A') # => ["test.rb", 1] -- Object is not ancestor, but additionally checked for modules
|
|
|
|
*
|
|
|
|
* p Object.const_source_location('A::C1') # => ["test.rb", 2] -- nesting is supported
|
|
|
|
* p Object.const_source_location('String') # => [] -- constant is defined in C code
|
|
|
|
*
|
|
|
|
*
|
|
|
|
*/
|
2018-12-13 15:49:05 +03:00
|
|
|
static VALUE
|
|
|
|
rb_mod_const_source_location(int argc, VALUE *argv, VALUE mod)
|
|
|
|
{
|
|
|
|
VALUE name, recur, loc = Qnil;
|
|
|
|
rb_encoding *enc;
|
|
|
|
const char *pbeg, *p, *path, *pend;
|
|
|
|
ID id;
|
|
|
|
|
|
|
|
rb_check_arity(argc, 1, 2);
|
|
|
|
name = argv[0];
|
|
|
|
recur = (argc == 1) ? Qtrue : argv[1];
|
|
|
|
|
|
|
|
if (SYMBOL_P(name)) {
|
2019-06-22 19:47:40 +03:00
|
|
|
if (!rb_is_const_sym(name)) goto wrong_name;
|
|
|
|
id = rb_check_id(&name);
|
|
|
|
if (!id) return Qnil;
|
|
|
|
return RTEST(recur) ? rb_const_source_location(mod, id) : rb_const_source_location_at(mod, id);
|
2018-12-13 15:49:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
path = StringValuePtr(name);
|
|
|
|
enc = rb_enc_get(name);
|
|
|
|
|
|
|
|
if (!rb_enc_asciicompat(enc)) {
|
2019-06-22 19:47:40 +03:00
|
|
|
rb_raise(rb_eArgError, "invalid class path encoding (non ASCII)");
|
2018-12-13 15:49:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
pbeg = p = path;
|
|
|
|
pend = path + RSTRING_LEN(name);
|
|
|
|
|
|
|
|
if (p >= pend || !*p) {
|
2020-06-16 04:53:31 +03:00
|
|
|
goto wrong_name;
|
2018-12-13 15:49:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
if (p + 2 < pend && p[0] == ':' && p[1] == ':') {
|
2019-06-22 19:47:40 +03:00
|
|
|
mod = rb_cObject;
|
|
|
|
p += 2;
|
|
|
|
pbeg = p;
|
2018-12-13 15:49:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
while (p < pend) {
|
2019-06-22 19:47:40 +03:00
|
|
|
VALUE part;
|
|
|
|
long len, beglen;
|
2018-12-13 15:49:05 +03:00
|
|
|
|
2019-06-22 19:47:40 +03:00
|
|
|
while (p < pend && *p != ':') p++;
|
2018-12-13 15:49:05 +03:00
|
|
|
|
2019-06-22 19:47:40 +03:00
|
|
|
if (pbeg == p) goto wrong_name;
|
2018-12-13 15:49:05 +03:00
|
|
|
|
2019-06-22 19:47:40 +03:00
|
|
|
id = rb_check_id_cstr(pbeg, len = p-pbeg, enc);
|
|
|
|
beglen = pbeg-path;
|
2018-12-13 15:49:05 +03:00
|
|
|
|
2019-06-22 19:47:40 +03:00
|
|
|
if (p < pend && p[0] == ':') {
|
|
|
|
if (p + 2 >= pend || p[1] != ':') goto wrong_name;
|
|
|
|
p += 2;
|
|
|
|
pbeg = p;
|
|
|
|
}
|
2018-12-13 15:49:05 +03:00
|
|
|
|
2019-06-22 19:47:40 +03:00
|
|
|
if (!id) {
|
|
|
|
part = rb_str_subseq(name, beglen, len);
|
|
|
|
OBJ_FREEZE(part);
|
|
|
|
if (!rb_is_const_name(part)) {
|
|
|
|
name = part;
|
|
|
|
goto wrong_name;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!rb_is_const_id(id)) {
|
|
|
|
name = ID2SYM(id);
|
|
|
|
goto wrong_name;
|
|
|
|
}
|
|
|
|
if (p < pend) {
|
|
|
|
if (RTEST(recur)) {
|
|
|
|
mod = rb_const_get(mod, id);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
mod = rb_const_get_at(mod, id);
|
|
|
|
}
|
|
|
|
if (!RB_TYPE_P(mod, T_MODULE) && !RB_TYPE_P(mod, T_CLASS)) {
|
|
|
|
rb_raise(rb_eTypeError, "%"PRIsVALUE" does not refer to class/module",
|
|
|
|
QUOTE(name));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (RTEST(recur)) {
|
|
|
|
loc = rb_const_source_location(mod, id);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
loc = rb_const_source_location_at(mod, id);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
recur = Qfalse;
|
2018-12-13 15:49:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return loc;
|
2020-06-16 04:53:31 +03:00
|
|
|
|
|
|
|
wrong_name:
|
|
|
|
rb_name_err_raise(wrong_constant_name, mod, name);
|
2020-06-24 10:23:59 +03:00
|
|
|
UNREACHABLE_RETURN(Qundef);
|
2018-12-13 15:49:05 +03:00
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj.instance_variable_get(symbol) -> obj
|
2013-02-24 08:24:52 +04:00
|
|
|
* obj.instance_variable_get(string) -> obj
|
2007-03-02 01:59:12 +03:00
|
|
|
*
|
|
|
|
* Returns the value of the given instance variable, or nil if the
|
2007-03-03 09:53:38 +03:00
|
|
|
* instance variable is not set. The <code>@</code> part of the
|
|
|
|
* variable name should be included for regular instance
|
2019-03-22 14:04:59 +03:00
|
|
|
* variables. Throws a NameError exception if the
|
2007-03-03 09:53:38 +03:00
|
|
|
* supplied symbol is not valid as an instance variable name.
|
2013-02-24 08:24:52 +04:00
|
|
|
* String arguments are converted to symbols.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* class Fred
|
|
|
|
* def initialize(p1, p2)
|
|
|
|
* @a, @b = p1, p2
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* fred = Fred.new('cat', 99)
|
|
|
|
* fred.instance_variable_get(:@a) #=> "cat"
|
|
|
|
* fred.instance_variable_get("@b") #=> 99
|
|
|
|
*/
|
2007-06-10 07:06:15 +04:00
|
|
|
|
2003-02-10 12:40:13 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_obj_ivar_get(VALUE obj, VALUE iv)
|
2003-02-10 12:40:13 +03:00
|
|
|
{
|
2019-07-09 04:58:12 +03:00
|
|
|
ID id = id_for_var(obj, iv, instance);
|
2003-02-10 12:40:13 +03:00
|
|
|
|
2011-07-23 19:05:03 +04:00
|
|
|
if (!id) {
|
2015-10-28 09:24:12 +03:00
|
|
|
return Qnil;
|
2003-02-10 12:40:13 +03:00
|
|
|
}
|
|
|
|
return rb_ivar_get(obj, id);
|
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj.instance_variable_set(symbol, obj) -> obj
|
2013-02-24 08:24:52 +04:00
|
|
|
* obj.instance_variable_set(string, obj) -> obj
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* Sets the instance variable named by <i>symbol</i> to the given
|
2020-06-11 00:54:15 +03:00
|
|
|
* object. This may circumvent the encapsulation intended by
|
2020-06-10 20:49:28 +03:00
|
|
|
* the author of the class, so it should be used with care.
|
|
|
|
* The variable does not have to exist prior to this call.
|
2013-02-24 08:24:52 +04:00
|
|
|
* If the instance variable name is passed as a string, that string
|
|
|
|
* is converted to a symbol.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* class Fred
|
|
|
|
* def initialize(p1, p2)
|
|
|
|
* @a, @b = p1, p2
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* fred = Fred.new('cat', 99)
|
|
|
|
* fred.instance_variable_set(:@a, 'dog') #=> "dog"
|
* array.c: replace rb_protect_inspect() and rb_inspecting_p() by
rb_exec_recursive() in eval.c.
* eval.c (rb_exec_recursive): new function.
* array.c (rb_ary_join): use rb_exec_recursive().
* array.c (rb_ary_inspect, rb_ary_hash): ditto.
* file.c (rb_file_join): ditto.
* hash.c (rb_hash_inspect, rb_hash_to_s, rb_hash_hash): ditto.
* io.c (rb_io_puts): ditto.
* object.c (rb_obj_inspect): ditto
* struct.c (rb_struct_inspect): ditto.
* lib/set.rb (SortedSet::setup): a hack to shut up warning.
[ruby-talk:132866]
* lib/time.rb (Time::strptime): add new function. inspired by
[ruby-talk:132815].
* lib/parsedate.rb (ParseDate::strptime): ditto.
* regparse.c: move st_*_strend() functions from st.c. fixed some
potential memory leaks.
* exception error messages updated. [ruby-core:04497]
* ext/socket/socket.c (Init_socket): add bunch of Socket
constants. Patch from Sam Roberts <sroberts@uniserve.com>.
[ruby-core:04409]
* array.c (rb_ary_s_create): no need for negative argc check.
[ruby-core:04463]
* array.c (rb_ary_unshift_m): ditto.
* lib/xmlrpc/parser.rb (XMLRPC::FaultException): make it subclass
of StandardError class, not Exception class. [ruby-core:04429]
* parse.y (fcall_gen): lvar(arg) will be evaluated as
lvar.call(arg) when lvar is a defined local variable. [new]
* object.c (rb_class_initialize): call inherited method before
calling initializing block.
* eval.c (rb_thread_start_1): initialize newly pushed frame.
* lib/open3.rb (Open3::popen3): $? should not be EXIT_FAILURE.
fixed: [ruby-core:04444]
* eval.c (is_defined): NODE_IASGN is an assignment.
* ext/readline/readline.c (Readline.readline): use rl_outstream
and rl_instream. [ruby-dev:25699]
* ext/etc/etc.c (Init_etc): sGroup needs HAVE_ST_GR_PASSWD check
[ruby-dev:25675]
* misc/ruby-mode.el: [ruby-core:04415]
* lib/rdoc/generators/html_generator.rb: [ruby-core:04412]
* lib/rdoc/generators/ri_generator.rb: ditto.
* struct.c (make_struct): fixed: [ruby-core:04402]
* ext/curses/curses.c (window_color_set): [ruby-core:04393]
* ext/socket/socket.c (Init_socket): SO_REUSEPORT added.
[ruby-talk:130092]
* object.c: [ruby-doc:818]
* parse.y (open_args): fix too verbose warnings for the space
before argument parentheses. [ruby-dev:25492]
* parse.y (parser_yylex): ditto.
* parse.y (parser_yylex): the first expression in the parentheses
should not be a command. [ruby-dev:25492]
* lib/irb/context.rb (IRB::Context::initialize): [ruby-core:04330]
* object.c (Init_Object): remove Object#type. [ruby-core:04335]
* st.c (st_foreach): report success/failure by return value.
[ruby-Bugs-1396]
* parse.y: forgot to initialize parser struct. [ruby-dev:25492]
* parse.y (parser_yylex): no tLABEL on EXPR_BEG.
[ruby-talk:127711]
* document updates - [ruby-core:04296], [ruby-core:04301],
[ruby-core:04302], [ruby-core:04307]
* dir.c (rb_push_glob): should work for NUL delimited patterns.
* dir.c (rb_glob2): should aware of offset in the pattern.
* string.c (rb_str_new4): should propagate taintedness.
* env.h: rename member names in struct FRAME; last_func -> callee,
orig_func -> this_func, last_class -> this_class.
* struct.c (rb_struct_set): use original method name, not callee
name, to retrieve member slot. [ruby-core:04268]
* time.c (time_strftime): protect from format modification from GC
finalizers.
* object.c (Init_Object): remove rb_obj_id_obsolete()
* eval.c (rb_mod_define_method): incomplete subclass check.
[ruby-dev:25464]
* gc.c (rb_data_object_alloc): klass may be NULL.
[ruby-list:40498]
* bignum.c (rb_big_rand): should return positive random number.
[ruby-dev:25401]
* bignum.c (rb_big_rand): do not use rb_big_modulo to generate
random bignums. [ruby-dev:25396]
* variable.c (rb_autoload): [ruby-dev:25373]
* eval.c (svalue_to_avalue): [ruby-dev:25366]
* string.c (rb_str_justify): [ruby-dev:25367]
* io.c (rb_f_select): [ruby-dev:25312]
* ext/socket/socket.c (sock_s_getservbyport): [ruby-talk:124072]
* struct.c (make_struct): [ruby-dev:25249]
* dir.c (dir_open_dir): new function. [ruby-dev:25242]
* io.c (rb_f_open): add type check for return value from to_open.
* lib/pstore.rb (PStore#transaction): Use the empty content when a
file is not found. [ruby-dev:24561]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@8068 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-03-04 09:47:45 +03:00
|
|
|
* fred.instance_variable_set(:@c, 'cat') #=> "cat"
|
|
|
|
* fred.inspect #=> "#<Fred:0x401b3da8 @a=\"dog\", @b=99, @c=\"cat\">"
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
2003-02-10 12:40:13 +03:00
|
|
|
static VALUE
|
2022-11-15 18:52:39 +03:00
|
|
|
rb_obj_ivar_set_m(VALUE obj, VALUE iv, VALUE val)
|
2003-02-10 12:40:13 +03:00
|
|
|
{
|
2019-07-09 04:58:12 +03:00
|
|
|
ID id = id_for_var(obj, iv, instance);
|
2015-10-28 09:24:12 +03:00
|
|
|
if (!id) id = rb_intern_str(iv);
|
2013-04-04 12:18:54 +04:00
|
|
|
return rb_ivar_set(obj, id, val);
|
2003-02-10 12:40:13 +03:00
|
|
|
}
|
|
|
|
|
2006-09-18 19:43:06 +04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj.instance_variable_defined?(symbol) -> true or false
|
2013-02-24 08:24:52 +04:00
|
|
|
* obj.instance_variable_defined?(string) -> true or false
|
2006-09-18 19:43:06 +04:00
|
|
|
*
|
|
|
|
* Returns <code>true</code> if the given instance variable is
|
|
|
|
* defined in <i>obj</i>.
|
2013-02-24 08:24:52 +04:00
|
|
|
* String arguments are converted to symbols.
|
2006-09-18 19:43:06 +04:00
|
|
|
*
|
|
|
|
* class Fred
|
|
|
|
* def initialize(p1, p2)
|
|
|
|
* @a, @b = p1, p2
|
|
|
|
* end
|
|
|
|
* end
|
|
|
|
* fred = Fred.new('cat', 99)
|
|
|
|
* fred.instance_variable_defined?(:@a) #=> true
|
|
|
|
* fred.instance_variable_defined?("@b") #=> true
|
|
|
|
* fred.instance_variable_defined?("@c") #=> false
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_obj_ivar_defined(VALUE obj, VALUE iv)
|
|
|
|
{
|
2019-07-09 04:58:12 +03:00
|
|
|
ID id = id_for_var(obj, iv, instance);
|
2006-09-18 19:43:06 +04:00
|
|
|
|
2011-07-23 19:05:03 +04:00
|
|
|
if (!id) {
|
2015-10-28 09:24:12 +03:00
|
|
|
return Qfalse;
|
2006-09-18 19:43:06 +04:00
|
|
|
}
|
|
|
|
return rb_ivar_defined(obj, id);
|
|
|
|
}
|
|
|
|
|
2004-03-23 22:14:16 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* mod.class_variable_get(symbol) -> obj
|
2013-02-24 08:24:52 +04:00
|
|
|
* mod.class_variable_get(string) -> obj
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2004-03-23 22:14:16 +03:00
|
|
|
* Returns the value of the given class variable (or throws a
|
2019-03-22 14:04:59 +03:00
|
|
|
* NameError exception). The <code>@@</code> part of the
|
2014-12-09 12:20:05 +03:00
|
|
|
* variable name should be included for regular class variables.
|
2013-02-24 08:24:52 +04:00
|
|
|
* String arguments are converted to symbols.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2004-03-23 22:14:16 +03:00
|
|
|
* class Fred
|
|
|
|
* @@foo = 99
|
|
|
|
* end
|
2006-09-18 19:43:06 +04:00
|
|
|
* Fred.class_variable_get(:@@foo) #=> 99
|
2004-03-23 22:14:16 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_mod_cvar_get(VALUE obj, VALUE iv)
|
2004-03-23 22:14:16 +03:00
|
|
|
{
|
2019-07-09 04:58:12 +03:00
|
|
|
ID id = id_for_var(obj, iv, class);
|
2004-03-23 22:14:16 +03:00
|
|
|
|
2011-07-23 19:05:03 +04:00
|
|
|
if (!id) {
|
2015-10-28 09:24:12 +03:00
|
|
|
rb_name_err_raise("uninitialized class variable %1$s in %2$s",
|
|
|
|
obj, iv);
|
2004-03-23 22:14:16 +03:00
|
|
|
}
|
|
|
|
return rb_cvar_get(obj, id);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj.class_variable_set(symbol, obj) -> obj
|
2013-02-24 08:24:52 +04:00
|
|
|
* obj.class_variable_set(string, obj) -> obj
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* Sets the class variable named by <i>symbol</i> to the given
|
|
|
|
* object.
|
2013-02-24 08:24:52 +04:00
|
|
|
* If the class variable name is passed as a string, that string
|
|
|
|
* is converted to a symbol.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2004-03-23 22:14:16 +03:00
|
|
|
* class Fred
|
|
|
|
* @@foo = 99
|
|
|
|
* def foo
|
|
|
|
* @@foo
|
|
|
|
* end
|
|
|
|
* end
|
2006-09-18 19:43:06 +04:00
|
|
|
* Fred.class_variable_set(:@@foo, 101) #=> 101
|
2004-03-23 22:14:16 +03:00
|
|
|
* Fred.new.foo #=> 101
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_mod_cvar_set(VALUE obj, VALUE iv, VALUE val)
|
2004-03-23 22:14:16 +03:00
|
|
|
{
|
2019-07-09 04:58:12 +03:00
|
|
|
ID id = id_for_var(obj, iv, class);
|
2015-10-28 09:24:12 +03:00
|
|
|
if (!id) id = rb_intern_str(iv);
|
2013-04-04 12:18:54 +04:00
|
|
|
rb_cvar_set(obj, id, val);
|
2004-03-23 22:14:16 +03:00
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2006-09-18 19:43:06 +04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* obj.class_variable_defined?(symbol) -> true or false
|
2013-02-24 08:24:52 +04:00
|
|
|
* obj.class_variable_defined?(string) -> true or false
|
2006-09-18 19:43:06 +04:00
|
|
|
*
|
|
|
|
* Returns <code>true</code> if the given class variable is defined
|
|
|
|
* in <i>obj</i>.
|
2013-02-24 08:24:52 +04:00
|
|
|
* String arguments are converted to symbols.
|
2006-09-18 19:43:06 +04:00
|
|
|
*
|
|
|
|
* class Fred
|
|
|
|
* @@foo = 99
|
|
|
|
* end
|
|
|
|
* Fred.class_variable_defined?(:@@foo) #=> true
|
|
|
|
* Fred.class_variable_defined?(:@@bar) #=> false
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_mod_cvar_defined(VALUE obj, VALUE iv)
|
|
|
|
{
|
2019-07-09 04:58:12 +03:00
|
|
|
ID id = id_for_var(obj, iv, class);
|
2006-09-18 19:43:06 +04:00
|
|
|
|
2011-07-23 19:05:03 +04:00
|
|
|
if (!id) {
|
2015-10-28 09:24:12 +03:00
|
|
|
return Qfalse;
|
2006-09-18 19:43:06 +04:00
|
|
|
}
|
|
|
|
return rb_cvar_defined(obj, id);
|
|
|
|
}
|
|
|
|
|
2013-12-08 12:54:23 +04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* mod.singleton_class? -> true or false
|
|
|
|
*
|
|
|
|
* Returns <code>true</code> if <i>mod</i> is a singleton class or
|
|
|
|
* <code>false</code> if it is an ordinary class or module.
|
|
|
|
*
|
|
|
|
* class C
|
|
|
|
* end
|
|
|
|
* C.singleton_class? #=> false
|
|
|
|
* C.singleton_class.singleton_class? #=> true
|
|
|
|
*/
|
|
|
|
|
2013-08-08 18:01:23 +04:00
|
|
|
static VALUE
|
|
|
|
rb_mod_singleton_p(VALUE klass)
|
|
|
|
{
|
2021-08-02 06:06:44 +03:00
|
|
|
return RBOOL(RB_TYPE_P(klass, T_CLASS) && FL_TEST(klass, FL_SINGLETON));
|
2013-08-08 18:01:23 +04:00
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \private */
|
2014-05-20 10:28:52 +04:00
|
|
|
static const struct conv_method_tbl {
|
2015-06-26 11:57:45 +03:00
|
|
|
const char method[6];
|
|
|
|
unsigned short id;
|
2008-08-28 15:50:31 +04:00
|
|
|
} conv_method_names[] = {
|
2015-06-26 11:57:45 +03:00
|
|
|
#define M(n) {#n, (unsigned short)idTo_##n}
|
2014-05-20 10:28:52 +04:00
|
|
|
M(int),
|
|
|
|
M(ary),
|
|
|
|
M(str),
|
|
|
|
M(sym),
|
|
|
|
M(hash),
|
|
|
|
M(proc),
|
|
|
|
M(io),
|
|
|
|
M(a),
|
|
|
|
M(s),
|
2014-05-20 12:28:33 +04:00
|
|
|
M(i),
|
2021-12-08 12:02:02 +03:00
|
|
|
M(f),
|
2017-04-14 08:19:12 +03:00
|
|
|
M(r),
|
2014-05-20 10:28:52 +04:00
|
|
|
#undef M
|
2008-08-28 15:50:31 +04:00
|
|
|
};
|
2013-01-30 02:00:58 +04:00
|
|
|
#define IMPLICIT_CONVERSIONS 7
|
2008-08-28 15:50:31 +04:00
|
|
|
|
2017-09-15 05:01:59 +03:00
|
|
|
static int
|
|
|
|
conv_method_index(const char *method)
|
|
|
|
{
|
|
|
|
static const char prefix[] = "to_";
|
|
|
|
|
|
|
|
if (strncmp(prefix, method, sizeof(prefix)-1) == 0) {
|
|
|
|
const char *const meth = &method[sizeof(prefix)-1];
|
|
|
|
int i;
|
|
|
|
for (i=0; i < numberof(conv_method_names); i++) {
|
|
|
|
if (conv_method_names[i].method[0] == meth[0] &&
|
|
|
|
strcmp(conv_method_names[i].method, meth) == 0) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return numberof(conv_method_names);
|
|
|
|
}
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
static VALUE
|
2017-05-31 15:30:57 +03:00
|
|
|
convert_type_with_id(VALUE val, const char *tname, ID method, int raise, int index)
|
1999-01-20 07:59:39 +03:00
|
|
|
{
|
2017-05-31 15:30:57 +03:00
|
|
|
VALUE r = rb_check_funcall(val, method, 0, 0);
|
2022-11-15 07:24:08 +03:00
|
|
|
if (UNDEF_P(r)) {
|
2002-01-04 17:15:33 +03:00
|
|
|
if (raise) {
|
2017-09-15 05:01:59 +03:00
|
|
|
const char *msg =
|
|
|
|
((index < 0 ? conv_method_index(rb_id2name(method)) : index)
|
|
|
|
< IMPLICIT_CONVERSIONS) ?
|
2014-01-30 10:16:15 +04:00
|
|
|
"no implicit conversion of" : "can't convert";
|
|
|
|
const char *cname = NIL_P(val) ? "nil" :
|
|
|
|
val == Qtrue ? "true" :
|
|
|
|
val == Qfalse ? "false" :
|
|
|
|
NULL;
|
|
|
|
if (cname)
|
|
|
|
rb_raise(rb_eTypeError, "%s %s into %s", msg, cname, tname);
|
|
|
|
rb_raise(rb_eTypeError, "%s %"PRIsVALUE" into %s", msg,
|
|
|
|
rb_obj_class(val),
|
2002-01-04 17:15:33 +03:00
|
|
|
tname);
|
|
|
|
}
|
2009-10-29 07:55:10 +03:00
|
|
|
return Qnil;
|
2002-01-04 17:15:33 +03:00
|
|
|
}
|
2009-10-29 07:55:10 +03:00
|
|
|
return r;
|
1999-01-20 07:59:39 +03:00
|
|
|
}
|
|
|
|
|
2017-05-31 15:30:57 +03:00
|
|
|
static VALUE
|
|
|
|
convert_type(VALUE val, const char *tname, const char *method, int raise)
|
|
|
|
{
|
2017-09-15 05:01:59 +03:00
|
|
|
int i = conv_method_index(method);
|
|
|
|
ID m = i < numberof(conv_method_names) ?
|
|
|
|
conv_method_names[i].id : rb_intern(method);
|
2017-05-31 15:30:57 +03:00
|
|
|
return convert_type_with_id(val, tname, m, raise, i);
|
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \private */
|
2014-01-30 10:16:15 +04:00
|
|
|
NORETURN(static void conversion_mismatch(VALUE, const char *, const char *, VALUE));
|
|
|
|
static void
|
|
|
|
conversion_mismatch(VALUE val, const char *tname, const char *method, VALUE result)
|
|
|
|
{
|
|
|
|
VALUE cname = rb_obj_class(val);
|
|
|
|
rb_raise(rb_eTypeError,
|
|
|
|
"can't convert %"PRIsVALUE" to %s (%"PRIsVALUE"#%s gives %"PRIsVALUE")",
|
|
|
|
cname, tname, cname, method, rb_obj_class(result));
|
|
|
|
}
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_convert_type(VALUE val, int type, const char *tname, const char *method)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2002-01-04 17:15:33 +03:00
|
|
|
VALUE v;
|
1999-01-20 07:59:39 +03:00
|
|
|
|
|
|
|
if (TYPE(val) == type) return val;
|
2009-07-18 12:05:32 +04:00
|
|
|
v = convert_type(val, tname, method, TRUE);
|
2002-01-04 17:15:33 +03:00
|
|
|
if (TYPE(v) != type) {
|
2014-01-30 10:16:15 +04:00
|
|
|
conversion_mismatch(val, tname, method, v);
|
2000-08-31 09:29:54 +04:00
|
|
|
}
|
2002-01-04 17:15:33 +03:00
|
|
|
return v;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \private */
|
2017-05-31 15:30:57 +03:00
|
|
|
VALUE
|
|
|
|
rb_convert_type_with_id(VALUE val, int type, const char *tname, ID method)
|
|
|
|
{
|
|
|
|
VALUE v;
|
|
|
|
|
|
|
|
if (TYPE(val) == type) return val;
|
2017-09-15 05:01:59 +03:00
|
|
|
v = convert_type_with_id(val, tname, method, TRUE, -1);
|
2017-05-31 15:30:57 +03:00
|
|
|
if (TYPE(v) != type) {
|
|
|
|
conversion_mismatch(val, tname, RSTRING_PTR(rb_id2str(method)), v);
|
|
|
|
}
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2001-11-29 18:57:25 +03:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_check_convert_type(VALUE val, int type, const char *tname, const char *method)
|
2001-11-29 18:57:25 +03:00
|
|
|
{
|
2002-01-04 17:15:33 +03:00
|
|
|
VALUE v;
|
2001-11-29 18:57:25 +03:00
|
|
|
|
2002-04-24 08:54:16 +04:00
|
|
|
/* always convert T_DATA */
|
|
|
|
if (TYPE(val) == type && type != T_DATA) return val;
|
2009-07-18 12:05:32 +04:00
|
|
|
v = convert_type(val, tname, method, FALSE);
|
2002-01-04 17:15:33 +03:00
|
|
|
if (NIL_P(v)) return Qnil;
|
|
|
|
if (TYPE(v) != type) {
|
2014-01-30 10:16:15 +04:00
|
|
|
conversion_mismatch(val, tname, method, v);
|
2001-11-29 18:57:25 +03:00
|
|
|
}
|
2002-01-04 17:15:33 +03:00
|
|
|
return v;
|
2001-11-29 18:57:25 +03:00
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \private */
|
mjit_compile.c: merge initial JIT compiler
which has been developed by Takashi Kokubun <takashikkbn@gmail> as
YARV-MJIT. Many of its bugs are fixed by wanabe <s.wanabe@gmail.com>.
This JIT compiler is designed to be a safe migration path to introduce
JIT compiler to MRI. So this commit does not include any bytecode
changes or dynamic instruction modifications, which are done in original
MJIT.
This commit even strips off some aggressive optimizations from
YARV-MJIT, and thus it's slower than YARV-MJIT too. But it's still
fairly faster than Ruby 2.5 in some benchmarks (attached below).
Note that this JIT compiler passes `make test`, `make test-all`, `make
test-spec` without JIT, and even with JIT. Not only it's perfectly safe
with JIT disabled because it does not replace VM instructions unlike
MJIT, but also with JIT enabled it stably runs Ruby applications
including Rails applications.
I'm expecting this version as just "initial" JIT compiler. I have many
optimization ideas which are skipped for initial merging, and you may
easily replace this JIT compiler with a faster one by just replacing
mjit_compile.c. `mjit_compile` interface is designed for the purpose.
common.mk: update dependencies for mjit_compile.c.
internal.h: declare `rb_vm_insn_addr2insn` for MJIT.
vm.c: exclude some definitions if `-DMJIT_HEADER` is provided to
compiler. This avoids to include some functions which take a long time
to compile, e.g. vm_exec_core. Some of the purpose is achieved in
transform_mjit_header.rb (see `IGNORED_FUNCTIONS`) but others are
manually resolved for now. Load mjit_helper.h for MJIT header.
mjit_helper.h: New. This is a file used only by JIT-ed code. I'll
refactor `mjit_call_cfunc` later.
vm_eval.c: add some #ifdef switches to skip compiling some functions
like Init_vm_eval.
win32/mkexports.rb: export thread/ec functions, which are used by MJIT.
include/ruby/defines.h: add MJIT_FUNC_EXPORTED macro alis to clarify
that a function is exported only for MJIT.
array.c: export a function used by MJIT.
bignum.c: ditto.
class.c: ditto.
compile.c: ditto.
error.c: ditto.
gc.c: ditto.
hash.c: ditto.
iseq.c: ditto.
numeric.c: ditto.
object.c: ditto.
proc.c: ditto.
re.c: ditto.
st.c: ditto.
string.c: ditto.
thread.c: ditto.
variable.c: ditto.
vm_backtrace.c: ditto.
vm_insnhelper.c: ditto.
vm_method.c: ditto.
I would like to improve maintainability of function exports, but I
believe this way is acceptable as initial merging if we clarify the
new exports are for MJIT (so that we can use them as TODO list to fix)
and add unit tests to detect unresolved symbols.
I'll add unit tests of JIT compilations in succeeding commits.
Author: Takashi Kokubun <takashikkbn@gmail.com>
Contributor: wanabe <s.wanabe@gmail.com>
Part of [Feature #14235]
---
* Known issues
* Code generated by gcc is faster than clang. The benchmark may be worse
in macOS. Following benchmark result is provided by gcc w/ Linux.
* Performance is decreased when Google Chrome is running
* JIT can work on MinGW, but it doesn't improve performance at least
in short running benchmark.
* Currently it doesn't perform well with Rails. We'll try to fix this
before release.
---
* Benchmark reslts
Benchmarked with:
Intel 4.0GHz i7-4790K with 16GB memory under x86-64 Ubuntu 8 Cores
- 2.0.0-p0: Ruby 2.0.0-p0
- r62186: Ruby trunk (early 2.6.0), before MJIT changes
- JIT off: On this commit, but without `--jit` option
- JIT on: On this commit, and with `--jit` option
** Optcarrot fps
Benchmark: https://github.com/mame/optcarrot
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:--------|:--------|:--------|:--------|:--------|
|fps |37.32 |51.46 |51.31 |58.88 |
|vs 2.0.0 |1.00x |1.38x |1.37x |1.58x |
** MJIT benchmarks
Benchmark: https://github.com/benchmark-driver/mjit-benchmarks
(Original: https://github.com/vnmakarov/ruby/tree/rtl_mjit_branch/MJIT-benchmarks)
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:----------|:--------|:--------|:--------|:--------|
|aread |1.00 |1.09 |1.07 |2.19 |
|aref |1.00 |1.13 |1.11 |2.22 |
|aset |1.00 |1.50 |1.45 |2.64 |
|awrite |1.00 |1.17 |1.13 |2.20 |
|call |1.00 |1.29 |1.26 |2.02 |
|const2 |1.00 |1.10 |1.10 |2.19 |
|const |1.00 |1.11 |1.10 |2.19 |
|fannk |1.00 |1.04 |1.02 |1.00 |
|fib |1.00 |1.32 |1.31 |1.84 |
|ivread |1.00 |1.13 |1.12 |2.43 |
|ivwrite |1.00 |1.23 |1.21 |2.40 |
|mandelbrot |1.00 |1.13 |1.16 |1.28 |
|meteor |1.00 |2.97 |2.92 |3.17 |
|nbody |1.00 |1.17 |1.15 |1.49 |
|nest-ntimes|1.00 |1.22 |1.20 |1.39 |
|nest-while |1.00 |1.10 |1.10 |1.37 |
|norm |1.00 |1.18 |1.16 |1.24 |
|nsvb |1.00 |1.16 |1.16 |1.17 |
|red-black |1.00 |1.02 |0.99 |1.12 |
|sieve |1.00 |1.30 |1.28 |1.62 |
|trees |1.00 |1.14 |1.13 |1.19 |
|while |1.00 |1.12 |1.11 |2.41 |
** Discourse's script/bench.rb
Benchmark: https://github.com/discourse/discourse/blob/v1.8.7/script/bench.rb
NOTE: Rails performance was somehow a little degraded with JIT for now.
We should fix this.
(At least I know opt_aref is performing badly in JIT and I have an idea
to fix it. Please wait for the fix.)
*** JIT off
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 17
75: 18
90: 22
99: 29
home_admin:
50: 21
75: 21
90: 27
99: 40
topic_admin:
50: 17
75: 18
90: 22
99: 32
categories:
50: 35
75: 41
90: 43
99: 77
home:
50: 39
75: 46
90: 49
99: 95
topic:
50: 46
75: 52
90: 56
99: 101
*** JIT on
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 19
75: 21
90: 25
99: 33
home_admin:
50: 24
75: 26
90: 30
99: 35
topic_admin:
50: 19
75: 20
90: 25
99: 30
categories:
50: 40
75: 44
90: 48
99: 76
home:
50: 42
75: 48
90: 51
99: 89
topic:
50: 49
75: 55
90: 58
99: 99
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62197 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 14:22:28 +03:00
|
|
|
MJIT_FUNC_EXPORTED VALUE
|
2017-05-31 15:30:57 +03:00
|
|
|
rb_check_convert_type_with_id(VALUE val, int type, const char *tname, ID method)
|
|
|
|
{
|
|
|
|
VALUE v;
|
|
|
|
|
|
|
|
/* always convert T_DATA */
|
|
|
|
if (TYPE(val) == type && type != T_DATA) return val;
|
2017-09-15 05:01:59 +03:00
|
|
|
v = convert_type_with_id(val, tname, method, FALSE, -1);
|
2017-05-31 15:30:57 +03:00
|
|
|
if (NIL_P(v)) return Qnil;
|
|
|
|
if (TYPE(v) != type) {
|
|
|
|
conversion_mismatch(val, tname, RSTRING_PTR(rb_id2str(method)), v);
|
|
|
|
}
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2018-03-07 10:43:07 +03:00
|
|
|
#define try_to_int(val, mid, raise) \
|
|
|
|
convert_type_with_id(val, "Integer", mid, raise, -1)
|
2002-06-28 18:42:46 +04:00
|
|
|
|
2018-10-07 07:02:46 +03:00
|
|
|
ALWAYS_INLINE(static VALUE rb_to_integer_with_id_exception(VALUE val, const char *method, ID mid, int raise));
|
|
|
|
/* Integer specific rb_check_convert_type_with_id */
|
2018-11-03 15:24:49 +03:00
|
|
|
static inline VALUE
|
2018-10-07 07:02:46 +03:00
|
|
|
rb_to_integer_with_id_exception(VALUE val, const char *method, ID mid, int raise)
|
1999-08-13 09:45:20 +04:00
|
|
|
{
|
2008-02-11 20:46:52 +03:00
|
|
|
VALUE v;
|
|
|
|
|
2018-03-07 10:43:07 +03:00
|
|
|
if (RB_INTEGER_TYPE_P(val)) return val;
|
2018-10-07 07:02:46 +03:00
|
|
|
v = try_to_int(val, mid, raise);
|
|
|
|
if (!raise && NIL_P(v)) return Qnil;
|
2018-02-26 10:57:15 +03:00
|
|
|
if (!RB_INTEGER_TYPE_P(v)) {
|
|
|
|
conversion_mismatch(val, "Integer", method, v);
|
2000-11-13 08:39:35 +03:00
|
|
|
}
|
2002-01-04 17:15:33 +03:00
|
|
|
return v;
|
2000-11-13 08:39:35 +03:00
|
|
|
}
|
2018-10-07 07:02:46 +03:00
|
|
|
#define rb_to_integer(val, method, mid) \
|
|
|
|
rb_to_integer_with_id_exception(val, method, mid, TRUE)
|
2000-11-13 08:39:35 +03:00
|
|
|
|
2005-08-04 08:31:33 +04:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_check_to_integer(VALUE val, const char *method)
|
2005-08-04 08:31:33 +04:00
|
|
|
{
|
2008-02-11 20:46:52 +03:00
|
|
|
VALUE v;
|
|
|
|
|
2021-07-20 13:21:37 +03:00
|
|
|
if (RB_INTEGER_TYPE_P(val)) return val;
|
2009-07-18 12:05:32 +04:00
|
|
|
v = convert_type(val, "Integer", method, FALSE);
|
2018-02-26 10:57:15 +03:00
|
|
|
if (!RB_INTEGER_TYPE_P(v)) {
|
|
|
|
return Qnil;
|
2005-08-04 08:31:33 +04:00
|
|
|
}
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2000-11-13 08:39:35 +03:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_to_int(VALUE val)
|
2000-11-13 08:39:35 +03:00
|
|
|
{
|
2018-03-07 10:43:07 +03:00
|
|
|
return rb_to_integer(val, "to_int", idTo_int);
|
2000-11-13 08:39:35 +03:00
|
|
|
}
|
|
|
|
|
2011-12-11 05:37:50 +04:00
|
|
|
VALUE
|
|
|
|
rb_check_to_int(VALUE val)
|
|
|
|
{
|
2018-03-07 10:43:07 +03:00
|
|
|
if (RB_INTEGER_TYPE_P(val)) return val;
|
|
|
|
val = try_to_int(val, idTo_int, FALSE);
|
|
|
|
if (RB_INTEGER_TYPE_P(val)) return val;
|
|
|
|
return Qnil;
|
2011-12-11 05:37:50 +04:00
|
|
|
}
|
|
|
|
|
2009-10-03 14:18:14 +04:00
|
|
|
static VALUE
|
2018-03-15 10:19:43 +03:00
|
|
|
rb_check_to_i(VALUE val)
|
|
|
|
{
|
|
|
|
if (RB_INTEGER_TYPE_P(val)) return val;
|
|
|
|
val = try_to_int(val, idTo_i, FALSE);
|
|
|
|
if (RB_INTEGER_TYPE_P(val)) return val;
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_convert_to_integer(VALUE val, int base, int raise_exception)
|
2000-11-13 08:39:35 +03:00
|
|
|
{
|
2004-11-29 09:09:40 +03:00
|
|
|
VALUE tmp;
|
|
|
|
|
2020-06-16 04:56:56 +03:00
|
|
|
if (base) {
|
|
|
|
tmp = rb_check_string_type(val);
|
|
|
|
|
|
|
|
if (! NIL_P(tmp)) {
|
|
|
|
val = tmp;
|
|
|
|
}
|
|
|
|
else if (! raise_exception) {
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rb_raise(rb_eArgError, "base specified for non string value");
|
|
|
|
}
|
|
|
|
}
|
2016-10-27 03:42:11 +03:00
|
|
|
if (RB_FLOAT_TYPE_P(val)) {
|
2020-06-16 04:56:56 +03:00
|
|
|
double f = RFLOAT_VALUE(val);
|
2019-01-12 12:36:52 +03:00
|
|
|
if (!raise_exception && !isfinite(f)) return Qnil;
|
2018-03-15 10:19:43 +03:00
|
|
|
if (FIXABLE(f)) return LONG2FIX((long)f);
|
|
|
|
return rb_dbl2big(f);
|
2016-10-27 03:42:11 +03:00
|
|
|
}
|
|
|
|
else if (RB_INTEGER_TYPE_P(val)) {
|
2018-03-15 10:19:43 +03:00
|
|
|
return val;
|
2016-10-27 03:42:11 +03:00
|
|
|
}
|
|
|
|
else if (RB_TYPE_P(val, T_STRING)) {
|
2018-03-15 10:19:43 +03:00
|
|
|
return rb_str_convert_to_inum(val, base, TRUE, raise_exception);
|
2016-10-27 03:42:11 +03:00
|
|
|
}
|
|
|
|
else if (NIL_P(val)) {
|
2018-03-15 10:19:43 +03:00
|
|
|
if (!raise_exception) return Qnil;
|
|
|
|
rb_raise(rb_eTypeError, "can't convert nil into Integer");
|
1999-08-13 09:45:20 +04:00
|
|
|
}
|
2018-03-15 10:19:43 +03:00
|
|
|
|
|
|
|
tmp = rb_protect(rb_check_to_int, val, NULL);
|
|
|
|
if (RB_INTEGER_TYPE_P(tmp)) return tmp;
|
|
|
|
rb_set_errinfo(Qnil);
|
2022-10-20 08:07:35 +03:00
|
|
|
if (!NIL_P(tmp = rb_check_string_type(val))) {
|
|
|
|
return rb_str_convert_to_inum(tmp, base, TRUE, raise_exception);
|
|
|
|
}
|
2018-03-15 10:19:43 +03:00
|
|
|
|
|
|
|
if (!raise_exception) {
|
|
|
|
VALUE result = rb_protect(rb_check_to_i, val, NULL);
|
|
|
|
rb_set_errinfo(Qnil);
|
|
|
|
return result;
|
2002-06-28 18:42:46 +04:00
|
|
|
}
|
2009-10-03 14:18:14 +04:00
|
|
|
|
2018-03-15 10:19:43 +03:00
|
|
|
return rb_to_integer(val, "to_i", idTo_i);
|
2009-10-03 14:18:14 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
|
|
|
rb_Integer(VALUE val)
|
|
|
|
{
|
2018-03-15 10:19:43 +03:00
|
|
|
return rb_convert_to_integer(val, 0, TRUE);
|
|
|
|
}
|
|
|
|
|
2018-10-07 07:02:46 +03:00
|
|
|
VALUE
|
|
|
|
rb_check_integer_type(VALUE val)
|
|
|
|
{
|
|
|
|
return rb_to_integer_with_id_exception(val, "to_int", idTo_int, FALSE);
|
|
|
|
}
|
|
|
|
|
2019-07-11 13:20:53 +03:00
|
|
|
int
|
2022-05-24 10:48:34 +03:00
|
|
|
rb_bool_expected(VALUE obj, const char *flagname, int raise)
|
2018-03-15 10:19:43 +03:00
|
|
|
{
|
2019-07-11 13:20:53 +03:00
|
|
|
switch (obj) {
|
2022-05-24 10:48:34 +03:00
|
|
|
case Qtrue:
|
|
|
|
return TRUE;
|
|
|
|
case Qfalse:
|
|
|
|
return FALSE;
|
|
|
|
default: {
|
|
|
|
static const char message[] = "expected true or false as %s: %+"PRIsVALUE;
|
|
|
|
if (raise) {
|
|
|
|
rb_raise(rb_eArgError, message, flagname, obj);
|
|
|
|
}
|
|
|
|
rb_warning(message, flagname, obj);
|
|
|
|
return !NIL_P(obj);
|
|
|
|
}
|
2018-03-15 10:19:43 +03:00
|
|
|
}
|
2019-07-11 13:20:53 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
rb_opts_exception_p(VALUE opts, int default_value)
|
|
|
|
{
|
2021-07-18 13:55:33 +03:00
|
|
|
static const ID kwds[1] = {idException};
|
2019-07-11 13:20:53 +03:00
|
|
|
VALUE exception;
|
|
|
|
if (rb_get_kwargs(opts, kwds, 0, 1, &exception))
|
2022-05-24 10:48:34 +03:00
|
|
|
return rb_bool_expected(exception, "exception", TRUE);
|
2019-07-11 13:20:53 +03:00
|
|
|
return default_value;
|
1999-08-13 09:45:20 +04:00
|
|
|
}
|
|
|
|
|
2019-07-11 13:20:53 +03:00
|
|
|
#define opts_exception_p(opts) rb_opts_exception_p((opts), TRUE)
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2022-04-27 14:00:22 +03:00
|
|
|
* Integer(object, base = 0, exception: true) -> integer or nil
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2022-04-27 14:00:22 +03:00
|
|
|
* Returns an integer converted from +object+.
|
2018-12-23 01:39:31 +03:00
|
|
|
*
|
2022-04-27 14:00:22 +03:00
|
|
|
* Tries to convert +object+ to an integer
|
|
|
|
* using +to_int+ first and +to_i+ second;
|
|
|
|
* see below for exceptions.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2022-09-08 05:49:21 +03:00
|
|
|
* With a non-zero +base+, +object+ must be a string or convertible
|
|
|
|
* to a string.
|
|
|
|
*
|
|
|
|
* ==== numeric objects
|
|
|
|
*
|
2022-04-27 14:00:22 +03:00
|
|
|
* With integer argument +object+ given, returns +object+:
|
2018-12-23 01:39:31 +03:00
|
|
|
*
|
2022-04-27 14:00:22 +03:00
|
|
|
* Integer(1) # => 1
|
|
|
|
* Integer(-1) # => -1
|
|
|
|
*
|
|
|
|
* With floating-point argument +object+ given,
|
|
|
|
* returns +object+ truncated to an intger:
|
|
|
|
*
|
|
|
|
* Integer(1.9) # => 1 # Rounds toward zero.
|
|
|
|
* Integer(-1.9) # => -1 # Rounds toward zero.
|
|
|
|
*
|
2022-09-08 05:49:21 +03:00
|
|
|
* ==== string objects
|
|
|
|
*
|
2022-04-27 14:00:22 +03:00
|
|
|
* With string argument +object+ and zero +base+ given,
|
|
|
|
* returns +object+ converted to an integer in base 10:
|
|
|
|
*
|
|
|
|
* Integer('100') # => 100
|
|
|
|
* Integer('-100') # => -100
|
|
|
|
*
|
|
|
|
* With +base+ zero, string +object+ may contain leading characters
|
2022-09-08 05:49:21 +03:00
|
|
|
* to specify the actual base (radix indicator):
|
2022-04-27 14:00:22 +03:00
|
|
|
*
|
|
|
|
* Integer('0100') # => 64 # Leading '0' specifies base 8.
|
|
|
|
* Integer('0b100') # => 4 # Leading '0b', specifies base 2.
|
|
|
|
* Integer('0x100') # => 256 # Leading '0x' specifies base 16.
|
|
|
|
*
|
2022-09-08 05:49:21 +03:00
|
|
|
* With a positive +base+ (in range 2..36) given, returns +object+
|
|
|
|
* converted to an integer in the given base:
|
2022-04-27 14:00:22 +03:00
|
|
|
*
|
|
|
|
* Integer('100', 2) # => 4
|
|
|
|
* Integer('100', 8) # => 64
|
|
|
|
* Integer('-100', 16) # => -256
|
|
|
|
*
|
2022-09-08 05:49:21 +03:00
|
|
|
* With a negative +base+ (in range -36..-2) given, returns +object+
|
|
|
|
* converted to an integer in the radix indicator if exists or
|
|
|
|
* +-base+:
|
|
|
|
*
|
|
|
|
* Integer('0x100', -2) # => 256
|
|
|
|
* Integer('100', -2) # => 4
|
|
|
|
* Integer('0b100', -8) # => 4
|
|
|
|
* Integer('100', -8) # => 64
|
|
|
|
* Integer('0o100', -10) # => 64
|
|
|
|
* Integer('100', -10) # => 100
|
|
|
|
*
|
|
|
|
* +base+ -1 is equal the -10 case.
|
|
|
|
*
|
2022-04-27 14:00:22 +03:00
|
|
|
* When converting strings, surrounding whitespace and embedded underscores
|
|
|
|
* are allowed and ignored:
|
|
|
|
*
|
|
|
|
* Integer(' 100 ') # => 100
|
|
|
|
* Integer('-1_0_0', 16) # => -256
|
|
|
|
*
|
2022-09-08 05:49:21 +03:00
|
|
|
* ==== other classes
|
|
|
|
*
|
2022-04-27 14:00:22 +03:00
|
|
|
* Examples with +object+ of various other classes:
|
|
|
|
*
|
|
|
|
* Integer(Rational(9, 10)) # => 0 # Rounds toward zero.
|
|
|
|
* Integer(Complex(2, 0)) # => 2 # Imaginary part must be zero.
|
|
|
|
* Integer(Time.now) # => 1650974042
|
|
|
|
*
|
2022-09-08 05:49:21 +03:00
|
|
|
* ==== keywords
|
|
|
|
*
|
2022-04-27 14:00:22 +03:00
|
|
|
* With optional keyword argument +exception+ given as +true+ (the default):
|
|
|
|
*
|
|
|
|
* - Raises TypeError if +object+ does not respond to +to_int+ or +to_i+.
|
|
|
|
* - Raises TypeError if +object+ is +nil+.
|
|
|
|
* - Raise ArgumentError if +object+ is an invalid string.
|
|
|
|
*
|
|
|
|
* With +exception+ given as +false+, an exception of any kind is suppressed
|
|
|
|
* and +nil+ is returned.
|
2018-12-23 01:39:31 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
1999-08-13 09:45:20 +04:00
|
|
|
static VALUE
|
2009-10-03 14:18:14 +04:00
|
|
|
rb_f_integer(int argc, VALUE *argv, VALUE obj)
|
1999-08-13 09:45:20 +04:00
|
|
|
{
|
2018-03-15 10:19:43 +03:00
|
|
|
VALUE arg = Qnil, opts = Qnil;
|
2009-10-03 14:18:14 +04:00
|
|
|
int base = 0;
|
|
|
|
|
2018-07-22 19:03:58 +03:00
|
|
|
if (argc > 1) {
|
|
|
|
int narg = 1;
|
|
|
|
VALUE vbase = rb_check_to_int(argv[1]);
|
|
|
|
if (!NIL_P(vbase)) {
|
|
|
|
base = NUM2INT(vbase);
|
|
|
|
narg = 2;
|
|
|
|
}
|
|
|
|
if (argc > narg) {
|
|
|
|
VALUE hash = rb_check_hash_type(argv[argc-1]);
|
|
|
|
if (!NIL_P(hash)) {
|
|
|
|
opts = rb_extract_keywords(&hash);
|
|
|
|
if (!hash) --argc;
|
|
|
|
}
|
|
|
|
}
|
2009-10-03 14:18:14 +04:00
|
|
|
}
|
2018-07-22 19:03:58 +03:00
|
|
|
rb_check_arity(argc, 1, 2);
|
|
|
|
arg = argv[0];
|
2018-03-15 10:19:43 +03:00
|
|
|
|
|
|
|
return rb_convert_to_integer(arg, base, opts_exception_p(opts));
|
1999-08-13 09:45:20 +04:00
|
|
|
}
|
|
|
|
|
2018-03-15 10:19:45 +03:00
|
|
|
static double
|
|
|
|
rb_cstr_to_dbl_raise(const char *p, int badcheck, int raise, int *error)
|
2002-02-01 13:23:22 +03:00
|
|
|
{
|
|
|
|
const char *q;
|
|
|
|
char *end;
|
|
|
|
double d;
|
2006-07-18 05:55:15 +04:00
|
|
|
const char *ellipsis = "";
|
|
|
|
int w;
|
2009-07-18 12:05:32 +04:00
|
|
|
enum {max_width = 20};
|
|
|
|
#define OutOfRange() ((end - p > max_width) ? \
|
2018-03-15 10:19:45 +03:00
|
|
|
(w = max_width, ellipsis = "...") : \
|
|
|
|
(w = (int)(end - p), ellipsis = ""))
|
2002-02-01 13:23:22 +03:00
|
|
|
|
2002-10-17 11:27:00 +04:00
|
|
|
if (!p) return 0.0;
|
2002-02-01 13:23:22 +03:00
|
|
|
q = p;
|
2008-03-01 18:08:13 +03:00
|
|
|
while (ISSPACE(*p)) p++;
|
2010-04-01 08:32:43 +04:00
|
|
|
|
|
|
|
if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
|
2018-03-15 10:19:45 +03:00
|
|
|
return 0.0;
|
2010-04-01 08:32:43 +04:00
|
|
|
}
|
|
|
|
|
2002-02-01 13:23:22 +03:00
|
|
|
d = strtod(p, &end);
|
2003-07-10 02:28:42 +04:00
|
|
|
if (errno == ERANGE) {
|
2018-03-15 10:19:45 +03:00
|
|
|
OutOfRange();
|
|
|
|
rb_warning("Float %.*s%s out of range", w, p, ellipsis);
|
|
|
|
errno = 0;
|
2003-07-10 02:28:42 +04:00
|
|
|
}
|
2002-02-01 13:23:22 +03:00
|
|
|
if (p == end) {
|
2018-03-15 10:19:45 +03:00
|
|
|
if (badcheck) {
|
2020-06-16 05:22:04 +03:00
|
|
|
goto bad;
|
2018-03-15 10:19:45 +03:00
|
|
|
}
|
|
|
|
return d;
|
2002-02-01 13:23:22 +03:00
|
|
|
}
|
|
|
|
if (*end) {
|
2018-03-15 10:19:45 +03:00
|
|
|
char buf[DBL_DIG * 4 + 10];
|
|
|
|
char *n = buf;
|
2018-05-02 16:37:18 +03:00
|
|
|
char *const init_e = buf + DBL_DIG * 4;
|
|
|
|
char *e = init_e;
|
2018-03-15 10:19:45 +03:00
|
|
|
char prev = 0;
|
2018-05-04 09:12:12 +03:00
|
|
|
int dot_seen = FALSE;
|
2018-03-15 10:19:45 +03:00
|
|
|
|
2018-05-04 09:12:12 +03:00
|
|
|
switch (*p) {case '+': case '-': prev = *n++ = *p++;}
|
|
|
|
if (*p == '0') {
|
|
|
|
prev = *n++ = '0';
|
|
|
|
while (*++p == '0');
|
|
|
|
}
|
2018-03-15 10:19:45 +03:00
|
|
|
while (p < end && n < e) prev = *n++ = *p++;
|
|
|
|
while (*p) {
|
|
|
|
if (*p == '_') {
|
|
|
|
/* remove an underscore between digits */
|
|
|
|
if (n == buf || !ISDIGIT(prev) || (++p, !ISDIGIT(*p))) {
|
|
|
|
if (badcheck) goto bad;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
prev = *p++;
|
2018-05-04 09:12:12 +03:00
|
|
|
if (e == init_e && (prev == 'e' || prev == 'E' || prev == 'p' || prev == 'P')) {
|
2018-05-02 16:37:18 +03:00
|
|
|
e = buf + sizeof(buf) - 1;
|
2018-05-04 09:12:12 +03:00
|
|
|
*n++ = prev;
|
|
|
|
switch (*p) {case '+': case '-': prev = *n++ = *p++;}
|
|
|
|
if (*p == '0') {
|
|
|
|
prev = *n++ = '0';
|
|
|
|
while (*++p == '0');
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
else if (ISSPACE(prev)) {
|
|
|
|
while (ISSPACE(*p)) ++p;
|
|
|
|
if (*p) {
|
|
|
|
if (badcheck) goto bad;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (prev == '.' ? dot_seen++ : !ISDIGIT(prev)) {
|
|
|
|
if (badcheck) goto bad;
|
|
|
|
break;
|
2018-05-02 16:37:18 +03:00
|
|
|
}
|
2018-03-15 10:19:45 +03:00
|
|
|
if (n < e) *n++ = prev;
|
|
|
|
}
|
|
|
|
*n = '\0';
|
|
|
|
p = buf;
|
|
|
|
|
|
|
|
if (!badcheck && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
d = strtod(p, &end);
|
|
|
|
if (errno == ERANGE) {
|
|
|
|
OutOfRange();
|
|
|
|
rb_warning("Float %.*s%s out of range", w, p, ellipsis);
|
|
|
|
errno = 0;
|
|
|
|
}
|
|
|
|
if (badcheck) {
|
|
|
|
if (!end || p == end) goto bad;
|
|
|
|
while (*end && ISSPACE(*end)) end++;
|
|
|
|
if (*end) goto bad;
|
|
|
|
}
|
2002-02-01 13:23:22 +03:00
|
|
|
}
|
|
|
|
if (errno == ERANGE) {
|
2018-03-15 10:19:45 +03:00
|
|
|
errno = 0;
|
|
|
|
OutOfRange();
|
|
|
|
rb_raise(rb_eArgError, "Float %.*s%s out of range", w, q, ellipsis);
|
2002-02-01 13:23:22 +03:00
|
|
|
}
|
|
|
|
return d;
|
2020-06-16 05:22:04 +03:00
|
|
|
|
|
|
|
bad:
|
2020-06-24 10:23:59 +03:00
|
|
|
if (raise) {
|
2020-06-16 05:22:04 +03:00
|
|
|
rb_invalid_str(q, "Float()");
|
2020-06-24 10:23:59 +03:00
|
|
|
UNREACHABLE_RETURN(nan(""));
|
|
|
|
}
|
2020-06-16 05:22:04 +03:00
|
|
|
else {
|
|
|
|
if (error) *error = 1;
|
|
|
|
return 0.0;
|
|
|
|
}
|
2002-02-01 13:23:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
double
|
2018-03-15 10:19:45 +03:00
|
|
|
rb_cstr_to_dbl(const char *p, int badcheck)
|
|
|
|
{
|
|
|
|
return rb_cstr_to_dbl_raise(p, badcheck, TRUE, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static double
|
|
|
|
rb_str_to_dbl_raise(VALUE str, int badcheck, int raise, int *error)
|
2002-02-01 13:23:22 +03:00
|
|
|
{
|
|
|
|
char *s;
|
2002-08-21 19:47:54 +04:00
|
|
|
long len;
|
2011-01-24 15:30:02 +03:00
|
|
|
double ret;
|
2011-01-27 15:46:30 +03:00
|
|
|
VALUE v = 0;
|
2002-02-01 13:23:22 +03:00
|
|
|
|
|
|
|
StringValue(str);
|
2006-08-31 14:47:44 +04:00
|
|
|
s = RSTRING_PTR(str);
|
|
|
|
len = RSTRING_LEN(str);
|
2002-10-17 11:27:00 +04:00
|
|
|
if (s) {
|
2009-07-18 12:05:32 +04:00
|
|
|
if (badcheck && memchr(s, '\0', len)) {
|
2018-03-15 10:19:45 +03:00
|
|
|
if (raise)
|
|
|
|
rb_raise(rb_eArgError, "string for Float contains null byte");
|
|
|
|
else {
|
|
|
|
if (error) *error = 1;
|
|
|
|
return 0.0;
|
|
|
|
}
|
2009-07-18 12:05:32 +04:00
|
|
|
}
|
2002-10-17 11:27:00 +04:00
|
|
|
if (s[len]) { /* no sentinel somehow */
|
2017-09-01 11:16:38 +03:00
|
|
|
char *p = ALLOCV(v, (size_t)len + 1);
|
2002-10-17 11:27:00 +04:00
|
|
|
MEMCPY(p, s, char, len);
|
|
|
|
p[len] = '\0';
|
|
|
|
s = p;
|
|
|
|
}
|
2002-02-01 13:23:22 +03:00
|
|
|
}
|
2018-03-15 10:19:45 +03:00
|
|
|
ret = rb_cstr_to_dbl_raise(s, badcheck, raise, error);
|
2011-01-27 15:46:30 +03:00
|
|
|
if (v)
|
|
|
|
ALLOCV_END(v);
|
2011-01-24 15:30:02 +03:00
|
|
|
return ret;
|
2002-02-01 13:23:22 +03:00
|
|
|
}
|
|
|
|
|
2018-03-15 10:19:45 +03:00
|
|
|
FUNC_MINIMIZED(double rb_str_to_dbl(VALUE str, int badcheck));
|
|
|
|
|
|
|
|
double
|
|
|
|
rb_str_to_dbl(VALUE str, int badcheck)
|
|
|
|
{
|
|
|
|
return rb_str_to_dbl_raise(str, badcheck, TRUE, NULL);
|
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \cond INTERNAL_MACRO */
|
2015-08-13 08:36:33 +03:00
|
|
|
#define fix2dbl_without_to_f(x) (double)FIX2LONG(x)
|
|
|
|
#define big2dbl_without_to_f(x) rb_big2dbl(x)
|
|
|
|
#define int2dbl_without_to_f(x) \
|
|
|
|
(FIXNUM_P(x) ? fix2dbl_without_to_f(x) : big2dbl_without_to_f(x))
|
2018-10-02 21:03:43 +03:00
|
|
|
#define num2dbl_without_to_f(x) \
|
|
|
|
(FIXNUM_P(x) ? fix2dbl_without_to_f(x) : \
|
2021-09-03 14:50:12 +03:00
|
|
|
RB_BIGNUM_TYPE_P(x) ? big2dbl_without_to_f(x) : \
|
2018-10-02 21:03:43 +03:00
|
|
|
(Check_Type(x, T_FLOAT), RFLOAT_VALUE(x)))
|
2018-10-02 19:42:21 +03:00
|
|
|
static inline double
|
|
|
|
rat2dbl_without_to_f(VALUE x)
|
|
|
|
{
|
|
|
|
VALUE num = rb_rational_num(x);
|
|
|
|
VALUE den = rb_rational_den(x);
|
2018-10-02 21:03:43 +03:00
|
|
|
return num2dbl_without_to_f(num) / num2dbl_without_to_f(den);
|
2018-10-02 19:42:21 +03:00
|
|
|
}
|
2015-08-13 08:36:33 +03:00
|
|
|
|
|
|
|
#define special_const_to_float(val, pre, post) \
|
|
|
|
switch (val) { \
|
|
|
|
case Qnil: \
|
2017-05-02 10:35:20 +03:00
|
|
|
rb_raise_static(rb_eTypeError, pre "nil" post); \
|
2015-08-13 08:36:33 +03:00
|
|
|
case Qtrue: \
|
2017-05-02 10:35:20 +03:00
|
|
|
rb_raise_static(rb_eTypeError, pre "true" post); \
|
2015-08-13 08:36:33 +03:00
|
|
|
case Qfalse: \
|
2017-05-02 10:35:20 +03:00
|
|
|
rb_raise_static(rb_eTypeError, pre "false" post); \
|
2015-08-13 08:36:33 +03:00
|
|
|
}
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \endcond */
|
2015-08-13 08:36:33 +03:00
|
|
|
|
|
|
|
static inline void
|
|
|
|
conversion_to_float(VALUE val)
|
|
|
|
{
|
|
|
|
special_const_to_float(val, "can't convert ", " into Float");
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
implicit_conversion_to_float(VALUE val)
|
|
|
|
{
|
|
|
|
special_const_to_float(val, "no implicit conversion to float from ", "");
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2018-03-15 10:19:45 +03:00
|
|
|
to_float(VALUE *valp, int raise_exception)
|
2015-08-13 08:36:33 +03:00
|
|
|
{
|
|
|
|
VALUE val = *valp;
|
|
|
|
if (SPECIAL_CONST_P(val)) {
|
|
|
|
if (FIXNUM_P(val)) {
|
|
|
|
*valp = DBL2NUM(fix2dbl_without_to_f(val));
|
|
|
|
return T_FLOAT;
|
|
|
|
}
|
|
|
|
else if (FLONUM_P(val)) {
|
|
|
|
return T_FLOAT;
|
|
|
|
}
|
2018-03-15 10:19:45 +03:00
|
|
|
else if (raise_exception) {
|
2015-08-13 08:36:33 +03:00
|
|
|
conversion_to_float(val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
int type = BUILTIN_TYPE(val);
|
|
|
|
switch (type) {
|
|
|
|
case T_FLOAT:
|
|
|
|
return T_FLOAT;
|
|
|
|
case T_BIGNUM:
|
|
|
|
*valp = DBL2NUM(big2dbl_without_to_f(val));
|
|
|
|
return T_FLOAT;
|
|
|
|
case T_RATIONAL:
|
|
|
|
*valp = DBL2NUM(rat2dbl_without_to_f(val));
|
|
|
|
return T_FLOAT;
|
|
|
|
case T_STRING:
|
|
|
|
return T_STRING;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return T_NONE;
|
|
|
|
}
|
|
|
|
|
2018-03-15 10:19:45 +03:00
|
|
|
static VALUE
|
|
|
|
convert_type_to_float_protected(VALUE val)
|
|
|
|
{
|
|
|
|
return rb_convert_type_with_id(val, T_FLOAT, "Float", id_to_f);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_convert_to_float(VALUE val, int raise_exception)
|
|
|
|
{
|
|
|
|
switch (to_float(&val, raise_exception)) {
|
|
|
|
case T_FLOAT:
|
|
|
|
return val;
|
|
|
|
case T_STRING:
|
|
|
|
if (!raise_exception) {
|
|
|
|
int e = 0;
|
|
|
|
double x = rb_str_to_dbl_raise(val, TRUE, raise_exception, &e);
|
|
|
|
return e ? Qnil : DBL2NUM(x);
|
|
|
|
}
|
|
|
|
return DBL2NUM(rb_str_to_dbl(val, TRUE));
|
|
|
|
case T_NONE:
|
|
|
|
if (SPECIAL_CONST_P(val) && !raise_exception)
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!raise_exception) {
|
|
|
|
int state;
|
|
|
|
VALUE result = rb_protect(convert_type_to_float_protected, val, &state);
|
|
|
|
if (state) rb_set_errinfo(Qnil);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rb_convert_type_with_id(val, T_FLOAT, "Float", id_to_f);
|
|
|
|
}
|
|
|
|
|
|
|
|
FUNC_MINIMIZED(VALUE rb_Float(VALUE val));
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_Float(VALUE val)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2018-03-15 10:19:45 +03:00
|
|
|
return rb_convert_to_float(val, TRUE);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2021-11-18 07:26:40 +03:00
|
|
|
static VALUE
|
|
|
|
rb_f_float1(rb_execution_context_t *ec, VALUE obj, VALUE arg)
|
|
|
|
{
|
|
|
|
return rb_convert_to_float(arg, TRUE);
|
|
|
|
}
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
static VALUE
|
2020-04-22 03:49:13 +03:00
|
|
|
rb_f_float(rb_execution_context_t *ec, VALUE obj, VALUE arg, VALUE opts)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
2022-05-24 10:48:34 +03:00
|
|
|
int exception = rb_bool_expected(opts, "exception", TRUE);
|
2020-04-22 03:49:13 +03:00
|
|
|
return rb_convert_to_float(arg, exception);
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
2015-08-13 08:36:33 +03:00
|
|
|
static VALUE
|
|
|
|
numeric_to_float(VALUE val)
|
2008-12-29 16:40:33 +03:00
|
|
|
{
|
2008-12-31 17:30:50 +03:00
|
|
|
if (!rb_obj_is_kind_of(val, rb_cNumeric)) {
|
2015-08-13 08:36:33 +03:00
|
|
|
rb_raise(rb_eTypeError, "can't convert %"PRIsVALUE" into Float",
|
|
|
|
rb_obj_class(val));
|
2008-12-31 17:30:50 +03:00
|
|
|
}
|
2018-02-26 17:30:39 +03:00
|
|
|
return rb_convert_type_with_id(val, T_FLOAT, "Float", id_to_f);
|
2008-12-29 16:40:33 +03:00
|
|
|
}
|
|
|
|
|
2015-08-13 08:36:33 +03:00
|
|
|
VALUE
|
|
|
|
rb_to_float(VALUE val)
|
|
|
|
{
|
2018-03-15 10:19:45 +03:00
|
|
|
switch (to_float(&val, TRUE)) {
|
2015-08-13 08:36:33 +03:00
|
|
|
case T_FLOAT:
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
return numeric_to_float(val);
|
|
|
|
}
|
|
|
|
|
2009-08-26 14:20:30 +04:00
|
|
|
VALUE
|
|
|
|
rb_check_to_float(VALUE val)
|
|
|
|
{
|
2021-09-11 03:56:59 +03:00
|
|
|
if (RB_FLOAT_TYPE_P(val)) return val;
|
2009-08-26 14:20:30 +04:00
|
|
|
if (!rb_obj_is_kind_of(val, rb_cNumeric)) {
|
|
|
|
return Qnil;
|
|
|
|
}
|
2018-02-26 17:39:16 +03:00
|
|
|
return rb_check_convert_type_with_id(val, T_FLOAT, "Float", id_to_f);
|
2009-08-26 14:20:30 +04:00
|
|
|
}
|
|
|
|
|
2015-08-13 08:36:33 +03:00
|
|
|
static inline int
|
|
|
|
basic_to_f_p(VALUE klass)
|
|
|
|
{
|
|
|
|
return rb_method_basic_definition_p(klass, id_to_f);
|
|
|
|
}
|
1999-08-13 09:45:20 +04:00
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \private */
|
2015-08-13 08:36:33 +03:00
|
|
|
double
|
|
|
|
rb_num_to_dbl(VALUE val)
|
|
|
|
{
|
|
|
|
if (SPECIAL_CONST_P(val)) {
|
|
|
|
if (FIXNUM_P(val)) {
|
Use Integer instead of Fixnum and Bignum.
* object.c, numeric.c, enum.c, ext/-test-/bignum/mul.c,
lib/rexml/quickpath.rb, lib/rexml/text.rb, lib/rexml/xpath_parser.rb,
lib/rubygems/specification.rb, lib/uri/generic.rb,
bootstraptest/test_eval.rb, basictest/test.rb,
test/-ext-/bignum/test_big2str.rb, test/-ext-/bignum/test_div.rb,
test/-ext-/bignum/test_mul.rb, test/-ext-/bignum/test_str2big.rb,
test/csv/test_data_converters.rb, test/date/test_date.rb,
test/json/test_json_generate.rb, test/minitest/test_minitest_mock.rb,
test/openssl/test_cipher.rb, test/rexml/test_jaxen.rb,
test/ruby/test_array.rb, test/ruby/test_basicinstructions.rb,
test/ruby/test_bignum.rb, test/ruby/test_case.rb,
test/ruby/test_class.rb, test/ruby/test_complex.rb,
test/ruby/test_enum.rb, test/ruby/test_eval.rb,
test/ruby/test_iseq.rb, test/ruby/test_literal.rb,
test/ruby/test_math.rb, test/ruby/test_module.rb,
test/ruby/test_numeric.rb, test/ruby/test_range.rb,
test/ruby/test_rational.rb, test/ruby/test_refinement.rb,
test/ruby/test_rubyvm.rb, test/ruby/test_struct.rb,
test/ruby/test_variable.rb, test/rubygems/test_gem_specification.rb,
test/thread/test_queue.rb: Use Integer instead of Fixnum and Bignum.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55029 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-05-17 16:15:57 +03:00
|
|
|
if (basic_to_f_p(rb_cInteger))
|
2015-08-13 08:36:33 +03:00
|
|
|
return fix2dbl_without_to_f(val);
|
|
|
|
}
|
|
|
|
else if (FLONUM_P(val)) {
|
|
|
|
return rb_float_flonum_value(val);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
conversion_to_float(val);
|
|
|
|
}
|
1999-08-13 09:45:20 +04:00
|
|
|
}
|
2015-08-13 08:36:33 +03:00
|
|
|
else {
|
|
|
|
switch (BUILTIN_TYPE(val)) {
|
|
|
|
case T_FLOAT:
|
|
|
|
return rb_float_noflonum_value(val);
|
|
|
|
case T_BIGNUM:
|
Use Integer instead of Fixnum and Bignum.
* object.c, numeric.c, enum.c, ext/-test-/bignum/mul.c,
lib/rexml/quickpath.rb, lib/rexml/text.rb, lib/rexml/xpath_parser.rb,
lib/rubygems/specification.rb, lib/uri/generic.rb,
bootstraptest/test_eval.rb, basictest/test.rb,
test/-ext-/bignum/test_big2str.rb, test/-ext-/bignum/test_div.rb,
test/-ext-/bignum/test_mul.rb, test/-ext-/bignum/test_str2big.rb,
test/csv/test_data_converters.rb, test/date/test_date.rb,
test/json/test_json_generate.rb, test/minitest/test_minitest_mock.rb,
test/openssl/test_cipher.rb, test/rexml/test_jaxen.rb,
test/ruby/test_array.rb, test/ruby/test_basicinstructions.rb,
test/ruby/test_bignum.rb, test/ruby/test_case.rb,
test/ruby/test_class.rb, test/ruby/test_complex.rb,
test/ruby/test_enum.rb, test/ruby/test_eval.rb,
test/ruby/test_iseq.rb, test/ruby/test_literal.rb,
test/ruby/test_math.rb, test/ruby/test_module.rb,
test/ruby/test_numeric.rb, test/ruby/test_range.rb,
test/ruby/test_rational.rb, test/ruby/test_refinement.rb,
test/ruby/test_rubyvm.rb, test/ruby/test_struct.rb,
test/ruby/test_variable.rb, test/rubygems/test_gem_specification.rb,
test/thread/test_queue.rb: Use Integer instead of Fixnum and Bignum.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55029 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-05-17 16:15:57 +03:00
|
|
|
if (basic_to_f_p(rb_cInteger))
|
2015-08-13 08:36:33 +03:00
|
|
|
return big2dbl_without_to_f(val);
|
|
|
|
break;
|
|
|
|
case T_RATIONAL:
|
|
|
|
if (basic_to_f_p(rb_cRational))
|
|
|
|
return rat2dbl_without_to_f(val);
|
|
|
|
break;
|
2020-04-08 09:13:37 +03:00
|
|
|
default:
|
|
|
|
break;
|
2015-08-13 08:36:33 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
val = numeric_to_float(val);
|
|
|
|
return RFLOAT_VALUE(val);
|
|
|
|
}
|
1999-08-13 09:45:20 +04:00
|
|
|
|
2015-08-13 08:36:33 +03:00
|
|
|
double
|
|
|
|
rb_num2dbl(VALUE val)
|
|
|
|
{
|
|
|
|
if (SPECIAL_CONST_P(val)) {
|
|
|
|
if (FIXNUM_P(val)) {
|
|
|
|
return fix2dbl_without_to_f(val);
|
|
|
|
}
|
|
|
|
else if (FLONUM_P(val)) {
|
|
|
|
return rb_float_flonum_value(val);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
implicit_conversion_to_float(val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
switch (BUILTIN_TYPE(val)) {
|
|
|
|
case T_FLOAT:
|
|
|
|
return rb_float_noflonum_value(val);
|
|
|
|
case T_BIGNUM:
|
|
|
|
return big2dbl_without_to_f(val);
|
|
|
|
case T_RATIONAL:
|
|
|
|
return rat2dbl_without_to_f(val);
|
|
|
|
case T_STRING:
|
|
|
|
rb_raise(rb_eTypeError, "no implicit conversion to float from string");
|
2020-04-08 09:13:37 +03:00
|
|
|
default:
|
|
|
|
break;
|
2015-08-13 08:36:33 +03:00
|
|
|
}
|
|
|
|
}
|
2018-02-26 17:30:39 +03:00
|
|
|
val = rb_convert_type_with_id(val, T_FLOAT, "Float", id_to_f);
|
2015-08-13 08:36:33 +03:00
|
|
|
return RFLOAT_VALUE(val);
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_String(VALUE val)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
2011-03-29 16:56:40 +04:00
|
|
|
VALUE tmp = rb_check_string_type(val);
|
|
|
|
if (NIL_P(tmp))
|
2017-05-31 15:30:57 +03:00
|
|
|
tmp = rb_convert_type_with_id(val, T_STRING, "String", idTo_s);
|
2011-03-29 16:56:40 +04:00
|
|
|
return tmp;
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2022-04-25 23:59:09 +03:00
|
|
|
* String(object) -> object or new_string
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2022-04-27 14:00:22 +03:00
|
|
|
* Returns a string converted from +object+.
|
2014-11-04 06:33:50 +03:00
|
|
|
*
|
2022-04-25 23:59:09 +03:00
|
|
|
* Tries to convert +object+ to a string
|
|
|
|
* using +to_str+ first and +to_s+ second:
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2022-04-25 23:59:09 +03:00
|
|
|
* String([0, 1, 2]) # => "[0, 1, 2]"
|
|
|
|
* String(0..5) # => "0..5"
|
|
|
|
* String({foo: 0, bar: 1}) # => "{:foo=>0, :bar=>1}"
|
|
|
|
*
|
|
|
|
* Raises +TypeError+ if +object+ cannot be converted to a string.
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_f_string(VALUE obj, VALUE arg)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
1999-01-20 07:59:39 +03:00
|
|
|
return rb_String(arg);
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_Array(VALUE val)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
2003-05-26 12:22:33 +04:00
|
|
|
VALUE tmp = rb_check_array_type(val);
|
2000-09-12 09:37:38 +04:00
|
|
|
|
2003-05-26 12:22:33 +04:00
|
|
|
if (NIL_P(tmp)) {
|
2018-01-27 12:27:47 +03:00
|
|
|
tmp = rb_check_to_array(val);
|
2006-12-28 09:34:02 +03:00
|
|
|
if (NIL_P(tmp)) {
|
|
|
|
return rb_ary_new3(1, val);
|
|
|
|
}
|
2000-09-12 09:37:38 +04:00
|
|
|
}
|
2003-05-26 12:22:33 +04:00
|
|
|
return tmp;
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2022-04-25 23:59:09 +03:00
|
|
|
* Array(object) -> object or new_array
|
|
|
|
*
|
|
|
|
* Returns an array converted from +object+.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2022-04-25 23:59:09 +03:00
|
|
|
* Tries to convert +object+ to an array
|
|
|
|
* using +to_ary+ first and +to_a+ second:
|
2013-02-19 07:32:11 +04:00
|
|
|
*
|
2022-04-25 23:59:09 +03:00
|
|
|
* Array([0, 1, 2]) # => [0, 1, 2]
|
|
|
|
* Array({foo: 0, bar: 1}) # => [[:foo, 0], [:bar, 1]]
|
|
|
|
* Array(0..4) # => [0, 1, 2, 3, 4]
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2022-04-25 23:59:09 +03:00
|
|
|
* Returns +object+ in an array, <tt>[object]</tt>,
|
|
|
|
* if +object+ cannot be converted:
|
|
|
|
*
|
|
|
|
* Array(:foo) # => [:foo]
|
2017-10-22 02:44:15 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
static VALUE
|
* array.c: moved to ANSI function style from K&R function style.
(used protoize on windows, so still K&R remains on #ifdef part of
other platforms. And `foo _((boo))' stuff is still there)
[ruby-dev:26975]
* bignum.c, class.c, compar.c, dir.c, dln.c, dmyext.c, enum.c,
enumerator.c, error.c, eval.c, file.c, gc.c, hash.c, inits.c,
io.c, main.c, marshal.c, math.c, numeric.c, object.c, pack.c,
prec.c, process.c, random.c, range.c, re.c, regcomp.c, regenc.c,
regerror.c, regexec.c, regparse.c, regparse.h, ruby.c, signal.c,
sprintf.c, st.c, string.c, struct.c, time.c, util.h, variable.c,
version.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2005-09-12 14:44:21 +04:00
|
|
|
rb_f_array(VALUE obj, VALUE arg)
|
1998-01-16 15:19:22 +03:00
|
|
|
{
|
1999-01-20 07:59:39 +03:00
|
|
|
return rb_Array(arg);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/**
|
|
|
|
* Equivalent to \c Kernel\#Hash in Ruby
|
|
|
|
*/
|
2012-01-24 08:02:30 +04:00
|
|
|
VALUE
|
|
|
|
rb_Hash(VALUE val)
|
|
|
|
{
|
2012-01-24 11:21:33 +04:00
|
|
|
VALUE tmp;
|
|
|
|
|
2012-01-24 08:02:30 +04:00
|
|
|
if (NIL_P(val)) return rb_hash_new();
|
2012-01-24 11:21:33 +04:00
|
|
|
tmp = rb_check_hash_type(val);
|
2012-01-24 08:02:30 +04:00
|
|
|
if (NIL_P(tmp)) {
|
2012-01-24 08:29:07 +04:00
|
|
|
if (RB_TYPE_P(val, T_ARRAY) && RARRAY_LEN(val) == 0)
|
2012-01-24 08:02:30 +04:00
|
|
|
return rb_hash_new();
|
|
|
|
rb_raise(rb_eTypeError, "can't convert %s into Hash", rb_obj_classname(val));
|
|
|
|
}
|
|
|
|
return tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2022-04-25 23:59:09 +03:00
|
|
|
* Hash(object) -> object or new_hash
|
|
|
|
*
|
|
|
|
* Returns a hash converted from +object+.
|
|
|
|
*
|
|
|
|
* - If +object+ is:
|
|
|
|
*
|
|
|
|
* - A hash, returns +object+.
|
|
|
|
* - An empty array or +nil+, returns an empty hash.
|
|
|
|
*
|
|
|
|
* - Otherwise, if <tt>object.to_hash</tt> returns a hash, returns that hash.
|
|
|
|
* - Otherwise, returns TypeError.
|
|
|
|
*
|
|
|
|
* Examples:
|
2012-01-24 08:02:30 +04:00
|
|
|
*
|
2022-04-25 23:59:09 +03:00
|
|
|
* Hash({foo: 0, bar: 1}) # => {:foo=>0, :bar=>1}
|
|
|
|
* Hash(nil) # => {}
|
|
|
|
* Hash([]) # => {}
|
2012-01-24 08:02:30 +04:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
rb_f_hash(VALUE obj, VALUE arg)
|
|
|
|
{
|
|
|
|
return rb_Hash(arg);
|
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \private */
|
2015-11-09 15:27:26 +03:00
|
|
|
struct dig_method {
|
|
|
|
VALUE klass;
|
|
|
|
int basic;
|
|
|
|
};
|
|
|
|
|
|
|
|
static ID id_dig;
|
|
|
|
|
|
|
|
static int
|
|
|
|
dig_basic_p(VALUE obj, struct dig_method *cache)
|
|
|
|
{
|
|
|
|
VALUE klass = RBASIC_CLASS(obj);
|
|
|
|
if (klass != cache->klass) {
|
|
|
|
cache->klass = klass;
|
|
|
|
cache->basic = rb_method_basic_definition_p(klass, id_dig);
|
|
|
|
}
|
|
|
|
return cache->basic;
|
|
|
|
}
|
|
|
|
|
2015-12-12 12:52:36 +03:00
|
|
|
static void
|
|
|
|
no_dig_method(int found, VALUE recv, ID mid, int argc, const VALUE *argv, VALUE data)
|
|
|
|
{
|
|
|
|
if (!found) {
|
|
|
|
rb_raise(rb_eTypeError, "%"PRIsVALUE" does not have #dig method",
|
|
|
|
CLASS_OF(data));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*! \private */
|
2015-11-09 15:27:26 +03:00
|
|
|
VALUE
|
|
|
|
rb_obj_dig(int argc, VALUE *argv, VALUE obj, VALUE notfound)
|
|
|
|
{
|
2015-11-16 12:21:56 +03:00
|
|
|
struct dig_method hash = {Qnil}, ary = {Qnil}, strt = {Qnil};
|
2015-11-09 15:27:26 +03:00
|
|
|
|
|
|
|
for (; argc > 0; ++argv, --argc) {
|
2015-12-12 12:52:36 +03:00
|
|
|
if (NIL_P(obj)) return notfound;
|
2015-11-09 15:27:26 +03:00
|
|
|
if (!SPECIAL_CONST_P(obj)) {
|
|
|
|
switch (BUILTIN_TYPE(obj)) {
|
|
|
|
case T_HASH:
|
|
|
|
if (dig_basic_p(obj, &hash)) {
|
|
|
|
obj = rb_hash_aref(obj, *argv);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case T_ARRAY:
|
|
|
|
if (dig_basic_p(obj, &ary)) {
|
|
|
|
obj = rb_ary_at(obj, *argv);
|
|
|
|
continue;
|
|
|
|
}
|
2015-11-16 12:21:56 +03:00
|
|
|
break;
|
|
|
|
case T_STRUCT:
|
|
|
|
if (dig_basic_p(obj, &strt)) {
|
|
|
|
obj = rb_struct_lookup(obj, *argv);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
2020-04-08 09:13:37 +03:00
|
|
|
default:
|
|
|
|
break;
|
2015-11-09 15:27:26 +03:00
|
|
|
}
|
|
|
|
}
|
2019-09-18 22:08:14 +03:00
|
|
|
return rb_check_funcall_with_hook_kw(obj, id_dig, argc, argv,
|
|
|
|
no_dig_method, obj,
|
2019-10-04 22:51:57 +03:00
|
|
|
RB_NO_KEYWORDS);
|
2015-11-09 15:27:26 +03:00
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2019-08-29 04:23:14 +03:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2022-05-05 17:01:12 +03:00
|
|
|
* sprintf(format_string *objects) -> string
|
2019-08-29 04:23:14 +03:00
|
|
|
*
|
2022-05-05 17:01:12 +03:00
|
|
|
* Returns the string resulting from formatting +objects+
|
|
|
|
* into +format_string+.
|
2019-08-29 04:23:14 +03:00
|
|
|
*
|
2022-05-05 17:01:12 +03:00
|
|
|
* For details on +format_string+, see
|
|
|
|
* {Format Specifications}[rdoc-ref:format_specifications.rdoc].
|
2019-08-29 04:23:14 +03:00
|
|
|
*
|
2022-05-05 17:01:12 +03:00
|
|
|
* Kernel#format is an alias for Kernel#sprintf.
|
2019-08-29 04:23:14 +03:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2019-08-28 12:19:11 +03:00
|
|
|
static VALUE
|
|
|
|
f_sprintf(int c, const VALUE *v, VALUE _)
|
|
|
|
{
|
|
|
|
return rb_f_sprintf(c, v);
|
|
|
|
}
|
|
|
|
|
2003-12-19 18:18:09 +03:00
|
|
|
/*
|
|
|
|
* Document-class: Class
|
|
|
|
*
|
|
|
|
* Classes in Ruby are first-class objects---each is an instance of
|
2019-03-22 14:04:59 +03:00
|
|
|
* class Class.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2011-10-11 00:54:45 +04:00
|
|
|
* Typically, you create a new class by using:
|
|
|
|
*
|
|
|
|
* class Name
|
2014-12-09 12:20:05 +03:00
|
|
|
* # some code describing the class behavior
|
2011-10-11 00:54:45 +04:00
|
|
|
* end
|
|
|
|
*
|
|
|
|
* When a new class is created, an object of type Class is initialized and
|
2019-03-22 14:04:59 +03:00
|
|
|
* assigned to a global constant (Name in this case).
|
2011-10-11 00:54:45 +04:00
|
|
|
*
|
|
|
|
* When <code>Name.new</code> is called to create a new object, the
|
2019-03-22 14:04:59 +03:00
|
|
|
* #new method in Class is run by default.
|
|
|
|
* This can be demonstrated by overriding #new in Class:
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-19 18:18:09 +03:00
|
|
|
* class Class
|
2014-12-09 12:20:05 +03:00
|
|
|
* alias old_new new
|
|
|
|
* def new(*args)
|
|
|
|
* print "Creating a new ", self.name, "\n"
|
|
|
|
* old_new(*args)
|
|
|
|
* end
|
|
|
|
* end
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* class Name
|
|
|
|
* end
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2014-12-09 12:20:05 +03:00
|
|
|
* n = Name.new
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-19 18:18:09 +03:00
|
|
|
* <em>produces:</em>
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2003-12-19 18:18:09 +03:00
|
|
|
* Creating a new Name
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2004-01-02 09:01:12 +03:00
|
|
|
* Classes, modules, and objects are interrelated. In the diagram
|
2005-05-11 11:00:32 +04:00
|
|
|
* that follows, the vertical arrows represent inheritance, and the
|
2014-12-09 12:20:05 +03:00
|
|
|
* parentheses metaclasses. All metaclasses are instances
|
2004-01-02 09:01:12 +03:00
|
|
|
* of the class `Class'.
|
2009-06-29 19:34:30 +04:00
|
|
|
* +---------+ +-...
|
|
|
|
* | | |
|
|
|
|
* BasicObject-----|-->(BasicObject)-------|-...
|
|
|
|
* ^ | ^ |
|
|
|
|
* | | | |
|
|
|
|
* Object---------|----->(Object)---------|-...
|
|
|
|
* ^ | ^ |
|
|
|
|
* | | | |
|
|
|
|
* +-------+ | +--------+ |
|
|
|
|
* | | | | | |
|
|
|
|
* | Module-|---------|--->(Module)-|-...
|
|
|
|
* | ^ | | ^ |
|
|
|
|
* | | | | | |
|
|
|
|
* | Class-|---------|---->(Class)-|-...
|
|
|
|
* | ^ | | ^ |
|
|
|
|
* | +---+ | +----+
|
|
|
|
* | |
|
|
|
|
* obj--->OtherClass---------->(OtherClass)-----------...
|
2006-12-31 18:02:22 +03:00
|
|
|
*
|
2003-12-19 18:18:09 +03:00
|
|
|
*/
|
|
|
|
|
2003-12-28 09:33:07 +03:00
|
|
|
|
2011-06-28 02:51:42 +04:00
|
|
|
/* Document-class: BasicObject
|
|
|
|
*
|
|
|
|
* BasicObject is the parent class of all classes in Ruby. It's an explicit
|
|
|
|
* blank class.
|
2011-07-27 10:44:39 +04:00
|
|
|
*
|
|
|
|
* BasicObject can be used for creating object hierarchies independent of
|
|
|
|
* Ruby's object hierarchy, proxy objects like the Delegator class, or other
|
|
|
|
* uses where namespace pollution from Ruby's methods and classes must be
|
|
|
|
* avoided.
|
|
|
|
*
|
|
|
|
* To avoid polluting BasicObject for other users an appropriately named
|
|
|
|
* subclass of BasicObject should be created instead of directly modifying
|
|
|
|
* BasicObject:
|
|
|
|
*
|
|
|
|
* class MyObjectSystem < BasicObject
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* BasicObject does not include Kernel (for methods like +puts+) and
|
|
|
|
* BasicObject is outside of the namespace of the standard library so common
|
2014-12-09 12:20:05 +03:00
|
|
|
* classes will not be found without using a full class path.
|
2011-07-27 10:44:39 +04:00
|
|
|
*
|
|
|
|
* A variety of strategies can be used to provide useful portions of the
|
|
|
|
* standard library to subclasses of BasicObject. A subclass could
|
|
|
|
* <code>include Kernel</code> to obtain +puts+, +exit+, etc. A custom
|
|
|
|
* Kernel-like module could be created and included or delegation can be used
|
|
|
|
* via #method_missing:
|
|
|
|
*
|
|
|
|
* class MyObjectSystem < BasicObject
|
|
|
|
* DELEGATE = [:puts, :p]
|
|
|
|
*
|
|
|
|
* def method_missing(name, *args, &block)
|
2019-08-15 18:20:52 +03:00
|
|
|
* return super unless DELEGATE.include? name
|
2011-07-27 10:44:39 +04:00
|
|
|
* ::Kernel.send(name, *args, &block)
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* def respond_to_missing?(name, include_private = false)
|
2012-06-19 17:58:30 +04:00
|
|
|
* DELEGATE.include?(name) or super
|
2011-07-27 10:44:39 +04:00
|
|
|
* end
|
|
|
|
* end
|
|
|
|
*
|
|
|
|
* Access to classes and modules from the Ruby standard library can be
|
|
|
|
* obtained in a BasicObject subclass by referencing the desired constant
|
|
|
|
* from the root like <code>::File</code> or <code>::Enumerator</code>.
|
|
|
|
* Like #method_missing, #const_missing can be used to delegate constant
|
|
|
|
* lookup to +Object+:
|
|
|
|
*
|
|
|
|
* class MyObjectSystem < BasicObject
|
|
|
|
* def self.const_missing(name)
|
|
|
|
* ::Object.const_get(name)
|
|
|
|
* end
|
|
|
|
* end
|
2021-05-14 01:19:07 +03:00
|
|
|
*
|
|
|
|
* === What's Here
|
|
|
|
*
|
|
|
|
* These are the methods defined for \BasicObject:
|
|
|
|
*
|
2022-03-29 14:19:51 +03:00
|
|
|
* - ::new: Returns a new \BasicObject instance.
|
2022-03-26 15:07:06 +03:00
|
|
|
* - #!: Returns the boolean negation of +self+: +true+ or +false+.
|
|
|
|
* - #!=: Returns whether +self+ and the given object are _not_ equal.
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #==: Returns whether +self+ and the given object are equivalent.
|
2022-04-14 06:55:44 +03:00
|
|
|
* - #__id__: Returns the integer object identifier for +self+.
|
|
|
|
* - #__send__: Calls the method identified by the given symbol.
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #equal?: Returns whether +self+ and the given object are the same object.
|
|
|
|
* - #instance_eval: Evaluates the given string or block in the context of +self+.
|
|
|
|
* - #instance_exec: Executes the given block in the context of +self+,
|
|
|
|
* passing the given arguments.
|
2021-05-14 01:19:07 +03:00
|
|
|
*
|
2011-06-28 02:51:42 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* Document-class: Object
|
2009-06-29 20:52:57 +04:00
|
|
|
*
|
2011-10-11 00:54:45 +04:00
|
|
|
* Object is the default root of all Ruby objects. Object inherits from
|
|
|
|
* BasicObject which allows creating alternate object hierarchies. Methods
|
2014-12-09 12:20:05 +03:00
|
|
|
* on Object are available to all classes unless explicitly overridden.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2011-06-28 02:51:42 +04:00
|
|
|
* Object mixes in the Kernel module, making the built-in kernel functions
|
2011-10-11 00:54:45 +04:00
|
|
|
* globally accessible. Although the instance methods of Object are defined
|
2011-06-28 02:51:42 +04:00
|
|
|
* by the Kernel module, we have chosen to document them here for clarity.
|
2009-02-22 17:23:33 +03:00
|
|
|
*
|
2011-10-11 00:54:45 +04:00
|
|
|
* When referencing constants in classes inheriting from Object you do not
|
|
|
|
* need to use the full namespace. For example, referencing +File+ inside
|
|
|
|
* +YourClass+ will find the top-level File class.
|
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
* In the descriptions of Object's methods, the parameter <i>symbol</i> refers
|
2011-06-28 02:51:42 +04:00
|
|
|
* to a symbol, which is either a quoted string or a Symbol (such as
|
|
|
|
* <code>:name</code>).
|
2021-05-18 16:16:29 +03:00
|
|
|
*
|
|
|
|
* == What's Here
|
|
|
|
*
|
|
|
|
* First, what's elsewhere. \Class \Object:
|
|
|
|
*
|
2022-02-06 18:30:11 +03:00
|
|
|
* - Inherits from {class BasicObject}[rdoc-ref:BasicObject@What-27s+Here].
|
|
|
|
* - Includes {module Kernel}[rdoc-ref:Kernel@What-27s+Here].
|
2021-05-18 16:16:29 +03:00
|
|
|
*
|
|
|
|
* Here, class \Object provides methods for:
|
|
|
|
*
|
2022-02-06 18:37:06 +03:00
|
|
|
* - {Querying}[rdoc-ref:Object@Querying]
|
|
|
|
* - {Instance Variables}[rdoc-ref:Object@Instance+Variables]
|
|
|
|
* - {Other}[rdoc-ref:Object@Other]
|
2021-05-18 16:16:29 +03:00
|
|
|
*
|
|
|
|
* === Querying
|
|
|
|
*
|
2022-03-26 15:07:06 +03:00
|
|
|
* - #!~: Returns +true+ if +self+ does not match the given object,
|
2022-03-29 14:19:51 +03:00
|
|
|
* otherwise +false+.
|
2022-03-26 15:07:06 +03:00
|
|
|
* - #<=>: Returns 0 if +self+ and the given object +object+ are the same
|
2022-03-29 14:19:51 +03:00
|
|
|
* object, or if <tt>self == object</tt>; otherwise returns +nil+.
|
|
|
|
* - #===: Implements case equality, effectively the same as calling #==.
|
|
|
|
* - #eql?: Implements hash equality, effectively the same as calling #==.
|
|
|
|
* - #kind_of? (aliased as #is_a?): Returns whether given argument is an ancestor
|
|
|
|
* of the singleton class of +self+.
|
|
|
|
* - #instance_of?: Returns whether +self+ is an instance of the given class.
|
|
|
|
* - #instance_variable_defined?: Returns whether the given instance variable
|
|
|
|
* is defined in +self+.
|
|
|
|
* - #method: Returns the Method object for the given method in +self+.
|
|
|
|
* - #methods: Returns an array of symbol names of public and protected methods
|
|
|
|
* in +self+.
|
|
|
|
* - #nil?: Returns +false+. (Only +nil+ responds +true+ to method <tt>nil?</tt>.)
|
|
|
|
* - #object_id: Returns an integer corresponding to +self+ that is unique
|
|
|
|
* for the current process
|
|
|
|
* - #private_methods: Returns an array of the symbol names
|
|
|
|
* of the private methods in +self+.
|
|
|
|
* - #protected_methods: Returns an array of the symbol names
|
|
|
|
* of the protected methods in +self+.
|
|
|
|
* - #public_method: Returns the Method object for the given public method in +self+.
|
|
|
|
* - #public_methods: Returns an array of the symbol names
|
|
|
|
* of the public methods in +self+.
|
|
|
|
* - #respond_to?: Returns whether +self+ responds to the given method.
|
|
|
|
* - #singleton_class: Returns the singleton class of +self+.
|
|
|
|
* - #singleton_method: Returns the Method object for the given singleton method
|
|
|
|
* in +self+.
|
|
|
|
* - #singleton_methods: Returns an array of the symbol names
|
|
|
|
* of the singleton methods in +self+.
|
|
|
|
*
|
|
|
|
* - #define_singleton_method: Defines a singleton method in +self+
|
|
|
|
* for the given symbol method-name and block or proc.
|
|
|
|
* - #extend: Includes the given modules in the singleton class of +self+.
|
|
|
|
* - #public_send: Calls the given public method in +self+ with the given argument.
|
|
|
|
* - #send: Calls the given method in +self+ with the given argument.
|
2021-05-18 16:16:29 +03:00
|
|
|
*
|
|
|
|
* === Instance Variables
|
|
|
|
*
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #instance_variable_get: Returns the value of the given instance variable
|
|
|
|
* in +self+, or +nil+ if the instance variable is not set.
|
|
|
|
* - #instance_variable_set: Sets the value of the given instance variable in +self+
|
|
|
|
* to the given object.
|
|
|
|
* - #instance_variables: Returns an array of the symbol names
|
|
|
|
* of the instance variables in +self+.
|
|
|
|
* - #remove_instance_variable: Removes the named instance variable from +self+.
|
2021-05-18 16:16:29 +03:00
|
|
|
*
|
|
|
|
* === Other
|
|
|
|
*
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #clone: Returns a shallow copy of +self+, including singleton class
|
|
|
|
* and frozen state.
|
|
|
|
* - #define_singleton_method: Defines a singleton method in +self+
|
|
|
|
* for the given symbol method-name and block or proc.
|
|
|
|
* - #display: Prints +self+ to the given \IO stream or <tt>$stdout</tt>.
|
|
|
|
* - #dup: Returns a shallow unfrozen copy of +self+.
|
|
|
|
* - #enum_for (aliased as #to_enum): Returns an Enumerator for +self+
|
|
|
|
* using the using the given method, arguments, and block.
|
|
|
|
* - #extend: Includes the given modules in the singleton class of +self+.
|
|
|
|
* - #freeze: Prevents further modifications to +self+.
|
|
|
|
* - #hash: Returns the integer hash value for +self+.
|
|
|
|
* - #inspect: Returns a human-readable string representation of +self+.
|
|
|
|
* - #itself: Returns +self+.
|
|
|
|
* - #method_missing: Method called when an undefined method is called on +self+.
|
|
|
|
* - #public_send: Calls the given public method in +self+ with the given argument.
|
|
|
|
* - #send: Calls the given method in +self+ with the given argument.
|
|
|
|
* - #to_s: Returns a string representation of +self+.
|
2021-05-18 16:16:29 +03:00
|
|
|
*
|
2003-12-28 09:33:07 +03:00
|
|
|
*/
|
|
|
|
|
2017-07-22 09:30:53 +03:00
|
|
|
/*!
|
|
|
|
*--
|
|
|
|
* \private
|
|
|
|
* Initializes the world of objects and classes.
|
|
|
|
*
|
|
|
|
* At first, the function bootstraps the class hierarchy.
|
|
|
|
* It initializes the most fundamental classes and their metaclasses.
|
|
|
|
* - \c BasicObject
|
|
|
|
* - \c Object
|
|
|
|
* - \c Module
|
|
|
|
* - \c Class
|
|
|
|
* After the bootstrap step, the class hierarchy becomes as the following
|
|
|
|
* diagram.
|
|
|
|
*
|
|
|
|
* \image html boottime-classes.png
|
|
|
|
*
|
|
|
|
* Then, the function defines classes, modules and methods as usual.
|
|
|
|
* \ingroup class
|
|
|
|
*++
|
|
|
|
*/
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
void
|
2015-08-13 08:36:33 +03:00
|
|
|
InitVM_Object(void)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2009-08-31 09:55:57 +04:00
|
|
|
Init_class_hierarchy();
|
|
|
|
|
2011-06-28 02:51:42 +04:00
|
|
|
#if 0
|
|
|
|
// teach RDoc about these classes
|
|
|
|
rb_cBasicObject = rb_define_class("BasicObject", Qnil);
|
|
|
|
rb_cObject = rb_define_class("Object", rb_cBasicObject);
|
|
|
|
rb_cModule = rb_define_class("Module", rb_cObject);
|
|
|
|
rb_cClass = rb_define_class("Class", rb_cModule);
|
2021-10-21 10:21:08 +03:00
|
|
|
rb_cRefinement = rb_define_class("Refinement", rb_cModule);
|
2011-06-28 02:51:42 +04:00
|
|
|
#endif
|
|
|
|
|
2021-02-07 17:10:12 +03:00
|
|
|
rb_define_private_method(rb_cBasicObject, "initialize", rb_obj_initialize, 0);
|
* sprintf.c (rb_str_format): allow %c to print one character
string (e.g. ?x).
* lib/tempfile.rb (Tempfile::make_tmpname): put dot between
basename and pid. [ruby-talk:196272]
* parse.y (do_block): remove -> style block.
* parse.y (parser_yylex): remove tLAMBDA_ARG.
* eval.c (rb_call0): binding for the return event hook should have
consistent scope. [ruby-core:07928]
* eval.c (proc_invoke): return behavior should depend whether it
is surrounded by a lambda or a mere block.
* eval.c (formal_assign): handles post splat arguments.
* eval.c (rb_call0): ditto.
* st.c (strhash): use FNV-1a hash.
* parse.y (parser_yylex): removed experimental ';;' terminator.
* eval.c (rb_node_arity): should be aware of post splat arguments.
* eval.c (rb_proc_arity): ditto.
* parse.y (f_args): syntax rule enhanced to support arguments
after the splat.
* parse.y (block_param): ditto for block parameters.
* parse.y (f_post_arg): mandatory formal arguments after the splat
argument.
* parse.y (new_args_gen): generate nodes for mandatory formal
arguments after the splat argument.
* eval.c (rb_eval): dispatch mandatory formal arguments after the
splat argument.
* parse.y (args): allow more than one splat in the argument list.
* parse.y (method_call): allow aref [] to accept all kind of
method argument, including assocs, splat, and block argument.
* eval.c (SETUP_ARGS0): prepare block argument as well.
* lib/mathn.rb (Integer): remove Integer#gcd2. [ruby-core:07931]
* eval.c (error_line): print receivers true/false/nil specially.
* eval.c (rb_proc_yield): handles parameters in yield semantics.
* eval.c (nil_yield): gives LocalJumpError to denote no block
error.
* io.c (rb_io_getc): now takes one-character string.
* string.c (rb_str_hash): use FNV-1a hash from Fowler/Noll/Vo
hashing algorithm.
* string.c (rb_str_aref): str[0] now returns 1 character string,
instead of a fixnum. [Ruby2]
* parse.y (parser_yylex): ?c now returns 1 character string,
instead of a fixnum. [Ruby2]
* string.c (rb_str_aset): no longer support fixnum insertion.
* eval.c (umethod_bind): should not update original class.
[ruby-dev:28636]
* eval.c (ev_const_get): should support constant access from
within instance_eval(). [ruby-dev:28327]
* time.c (time_timeval): should round for usec floating
number. [ruby-core:07896]
* time.c (time_add): ditto.
* dir.c (sys_warning): should not call a vararg function
rb_sys_warning() indirectly. [ruby-core:07886]
* numeric.c (flo_divmod): the first element of Float#divmod should
be an integer. [ruby-dev:28589]
* test/ruby/test_float.rb: add tests for divmod, div, modulo and remainder.
* re.c (rb_reg_initialize): should not allow modifying literal
regexps. frozen check moved from rb_reg_initialize_m as well.
* re.c (rb_reg_initialize): should not modify untainted objects in
safe levels higher than 3.
* re.c (rb_memcmp): type change from char* to const void*.
* dir.c (dir_close): should not close untainted dir stream.
* dir.c (GetDIR): add tainted/frozen check for each dir operation.
* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_symbol_arg):
typo fixed. a patch from Florian Gross <florg at florg.net>.
* eval.c (EXEC_EVENT_HOOK): trace_func may remove itself from
event_hooks. no guarantee for arbitrary hook deletion.
[ruby-dev:28632]
* util.c (ruby_strtod): differ addition to minimize error.
[ruby-dev:28619]
* util.c (ruby_strtod): should not raise ERANGE when the input
string does not have any digits. [ruby-dev:28629]
* eval.c (proc_invoke): should restore old ruby_frame->block.
thanks to ts <decoux at moulon.inra.fr>. [ruby-core:07833]
also fix [ruby-dev:28614] as well.
* signal.c (trap): sig should be less then NSIG. Coverity found
this bug. a patch from Kevin Tew <tewk at tewk.com>.
[ruby-core:07823]
* math.c (math_log2): add new method inspired by
[ruby-talk:191237].
* math.c (math_log): add optional base argument to Math::log().
[ruby-talk:191308]
* ext/syck/emitter.c (syck_scan_scalar): avoid accessing
uninitialized array element. a patch from Pat Eyler
<rubypate at gmail.com>. [ruby-core:07809]
* array.c (rb_ary_fill): initialize local variables first. a
patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07810]
* ext/syck/yaml2byte.c (syck_yaml2byte_handler): need to free
type_tag. a patch from Pat Eyler <rubypate at gmail.com>.
[ruby-core:07808]
* ext/socket/socket.c (make_hostent_internal): accept ai_family
check from Sam Roberts <sroberts at uniserve.com>.
[ruby-core:07691]
* util.c (ruby_strtod): should not cut off 18 digits for no
reason. [ruby-core:07796]
* array.c (rb_ary_fill): internalize local variable "beg" to
pacify Coverity. [ruby-core:07770]
* pack.c (pack_unpack): now supports CRLF newlines. a patch from
<tommy at tmtm.org>. [ruby-dev:28601]
* applied code clean-up patch from Stefan Huehner
<stefan at huehner.org>. [ruby-core:07764]
* lib/jcode.rb (String::tr_s): should have translated non
squeezing character sequence (i.e. a character) as well. thanks
to Hiroshi Ichikawa <gimite at gimite.ddo.jp> [ruby-list:42090]
* ext/socket/socket.c: document update patch from Sam Roberts
<sroberts at uniserve.com>. [ruby-core:07701]
* lib/mathn.rb (Integer): need not to remove gcd2. a patch from
NARUSE, Yui <naruse at airemix.com>. [ruby-dev:28570]
* parse.y (arg): too much NEW_LIST()
* eval.c (SETUP_ARGS0): remove unnecessary access to nd_alen.
* eval.c (rb_eval): use ARGSCAT for NODE_OP_ASGN1.
[ruby-dev:28585]
* parse.y (arg): use NODE_ARGSCAT for placeholder.
* lib/getoptlong.rb (GetoptLong::get): RDoc update patch from
mathew <meta at pobox.com>. [ruby-core:07738]
* variable.c (rb_const_set): raise error when no target klass is
supplied. [ruby-dev:28582]
* prec.c (prec_prec_f): documentation patch from
<gerardo.santana at gmail.com>. [ruby-core:07689]
* bignum.c (rb_big_pow): second operand may be too big even if
it's a Fixnum. [ruby-talk:187984]
* README.EXT: update symbol description. [ruby-talk:188104]
* COPYING: explicitly note GPLv2. [ruby-talk:187922]
* parse.y: remove some obsolete syntax rules (unparenthesized
method calls in argument list).
* eval.c (rb_call0): insecure calling should be checked for non
NODE_SCOPE method invocations too.
* eval.c (rb_alias): should preserve the current safe level as
well as method definition.
* process.c (rb_f_sleep): remove RDoc description about SIGALRM
which is not valid on the current implementation. [ruby-dev:28464]
Thu Mar 23 21:40:47 2006 K.Kosako <sndgk393 AT ybb.ne.jp>
* eval.c (method_missing): should support argument splat in
super. a bug in combination of super, splat and
method_missing. [ruby-talk:185438]
* configure.in: Solaris SunPro compiler -rapth patch from
<kuwa at labs.fujitsu.com>. [ruby-dev:28443]
* configure.in: remove enable_rpath=no for Solaris.
[ruby-dev:28440]
* ext/win32ole/win32ole.c (ole_val2olevariantdata): change behavior
of converting OLE Variant object with VT_ARRAY|VT_UI1 and Ruby
String object.
* ruby.1: a clarification patch from David Lutterkort
<dlutter at redhat.com>. [ruby-core:7508]
* lib/rdoc/ri/ri_paths.rb (RI::Paths): adding paths from rubygems
directories. a patch from Eric Hodel <drbrain at segment7.net>.
[ruby-core:07423]
* eval.c (rb_clear_cache_by_class): clearing wrong cache.
* ext/extmk.rb: use :remove_destination to install extension libraries
to avoid SEGV. [ruby-dev:28417]
* eval.c (rb_thread_fd_writable): should not re-schedule output
from KILLED thread (must be error printing).
* array.c (rb_ary_flatten_bang): allow specifying recursion
level. [ruby-talk:182170]
* array.c (rb_ary_flatten): ditto.
* gc.c (add_heap): a heap_slots may overflow. a patch from Stefan
Weil <weil at mail.berlios.de>.
* eval.c (rb_call): use separate cache for fcall/vcall
invocation.
* eval.c (rb_eval): NODE_FCALL, NODE_VCALL can call local
functions.
* eval.c (rb_mod_local): a new method to specify newly added
visibility "local".
* eval.c (search_method): search for local methods which are
visible only from the current class.
* class.c (rb_class_local_methods): a method to list local methods.
* object.c (Init_Object): add BasicObject class as a top level
BlankSlate class.
* ruby.h (SYM2ID): should not cast to signed long.
[ruby-core:07414]
* class.c (rb_include_module): allow module duplication.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10235 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2006-06-10 01:20:17 +04:00
|
|
|
rb_define_alloc_func(rb_cBasicObject, rb_class_allocate_instance);
|
|
|
|
rb_define_method(rb_cBasicObject, "==", rb_obj_equal, 1);
|
|
|
|
rb_define_method(rb_cBasicObject, "equal?", rb_obj_equal, 1);
|
2007-12-18 08:50:37 +03:00
|
|
|
rb_define_method(rb_cBasicObject, "!", rb_obj_not, 0);
|
2007-12-09 19:39:49 +03:00
|
|
|
rb_define_method(rb_cBasicObject, "!=", rb_obj_not_equal, 1);
|
* sprintf.c (rb_str_format): allow %c to print one character
string (e.g. ?x).
* lib/tempfile.rb (Tempfile::make_tmpname): put dot between
basename and pid. [ruby-talk:196272]
* parse.y (do_block): remove -> style block.
* parse.y (parser_yylex): remove tLAMBDA_ARG.
* eval.c (rb_call0): binding for the return event hook should have
consistent scope. [ruby-core:07928]
* eval.c (proc_invoke): return behavior should depend whether it
is surrounded by a lambda or a mere block.
* eval.c (formal_assign): handles post splat arguments.
* eval.c (rb_call0): ditto.
* st.c (strhash): use FNV-1a hash.
* parse.y (parser_yylex): removed experimental ';;' terminator.
* eval.c (rb_node_arity): should be aware of post splat arguments.
* eval.c (rb_proc_arity): ditto.
* parse.y (f_args): syntax rule enhanced to support arguments
after the splat.
* parse.y (block_param): ditto for block parameters.
* parse.y (f_post_arg): mandatory formal arguments after the splat
argument.
* parse.y (new_args_gen): generate nodes for mandatory formal
arguments after the splat argument.
* eval.c (rb_eval): dispatch mandatory formal arguments after the
splat argument.
* parse.y (args): allow more than one splat in the argument list.
* parse.y (method_call): allow aref [] to accept all kind of
method argument, including assocs, splat, and block argument.
* eval.c (SETUP_ARGS0): prepare block argument as well.
* lib/mathn.rb (Integer): remove Integer#gcd2. [ruby-core:07931]
* eval.c (error_line): print receivers true/false/nil specially.
* eval.c (rb_proc_yield): handles parameters in yield semantics.
* eval.c (nil_yield): gives LocalJumpError to denote no block
error.
* io.c (rb_io_getc): now takes one-character string.
* string.c (rb_str_hash): use FNV-1a hash from Fowler/Noll/Vo
hashing algorithm.
* string.c (rb_str_aref): str[0] now returns 1 character string,
instead of a fixnum. [Ruby2]
* parse.y (parser_yylex): ?c now returns 1 character string,
instead of a fixnum. [Ruby2]
* string.c (rb_str_aset): no longer support fixnum insertion.
* eval.c (umethod_bind): should not update original class.
[ruby-dev:28636]
* eval.c (ev_const_get): should support constant access from
within instance_eval(). [ruby-dev:28327]
* time.c (time_timeval): should round for usec floating
number. [ruby-core:07896]
* time.c (time_add): ditto.
* dir.c (sys_warning): should not call a vararg function
rb_sys_warning() indirectly. [ruby-core:07886]
* numeric.c (flo_divmod): the first element of Float#divmod should
be an integer. [ruby-dev:28589]
* test/ruby/test_float.rb: add tests for divmod, div, modulo and remainder.
* re.c (rb_reg_initialize): should not allow modifying literal
regexps. frozen check moved from rb_reg_initialize_m as well.
* re.c (rb_reg_initialize): should not modify untainted objects in
safe levels higher than 3.
* re.c (rb_memcmp): type change from char* to const void*.
* dir.c (dir_close): should not close untainted dir stream.
* dir.c (GetDIR): add tainted/frozen check for each dir operation.
* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_symbol_arg):
typo fixed. a patch from Florian Gross <florg at florg.net>.
* eval.c (EXEC_EVENT_HOOK): trace_func may remove itself from
event_hooks. no guarantee for arbitrary hook deletion.
[ruby-dev:28632]
* util.c (ruby_strtod): differ addition to minimize error.
[ruby-dev:28619]
* util.c (ruby_strtod): should not raise ERANGE when the input
string does not have any digits. [ruby-dev:28629]
* eval.c (proc_invoke): should restore old ruby_frame->block.
thanks to ts <decoux at moulon.inra.fr>. [ruby-core:07833]
also fix [ruby-dev:28614] as well.
* signal.c (trap): sig should be less then NSIG. Coverity found
this bug. a patch from Kevin Tew <tewk at tewk.com>.
[ruby-core:07823]
* math.c (math_log2): add new method inspired by
[ruby-talk:191237].
* math.c (math_log): add optional base argument to Math::log().
[ruby-talk:191308]
* ext/syck/emitter.c (syck_scan_scalar): avoid accessing
uninitialized array element. a patch from Pat Eyler
<rubypate at gmail.com>. [ruby-core:07809]
* array.c (rb_ary_fill): initialize local variables first. a
patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07810]
* ext/syck/yaml2byte.c (syck_yaml2byte_handler): need to free
type_tag. a patch from Pat Eyler <rubypate at gmail.com>.
[ruby-core:07808]
* ext/socket/socket.c (make_hostent_internal): accept ai_family
check from Sam Roberts <sroberts at uniserve.com>.
[ruby-core:07691]
* util.c (ruby_strtod): should not cut off 18 digits for no
reason. [ruby-core:07796]
* array.c (rb_ary_fill): internalize local variable "beg" to
pacify Coverity. [ruby-core:07770]
* pack.c (pack_unpack): now supports CRLF newlines. a patch from
<tommy at tmtm.org>. [ruby-dev:28601]
* applied code clean-up patch from Stefan Huehner
<stefan at huehner.org>. [ruby-core:07764]
* lib/jcode.rb (String::tr_s): should have translated non
squeezing character sequence (i.e. a character) as well. thanks
to Hiroshi Ichikawa <gimite at gimite.ddo.jp> [ruby-list:42090]
* ext/socket/socket.c: document update patch from Sam Roberts
<sroberts at uniserve.com>. [ruby-core:07701]
* lib/mathn.rb (Integer): need not to remove gcd2. a patch from
NARUSE, Yui <naruse at airemix.com>. [ruby-dev:28570]
* parse.y (arg): too much NEW_LIST()
* eval.c (SETUP_ARGS0): remove unnecessary access to nd_alen.
* eval.c (rb_eval): use ARGSCAT for NODE_OP_ASGN1.
[ruby-dev:28585]
* parse.y (arg): use NODE_ARGSCAT for placeholder.
* lib/getoptlong.rb (GetoptLong::get): RDoc update patch from
mathew <meta at pobox.com>. [ruby-core:07738]
* variable.c (rb_const_set): raise error when no target klass is
supplied. [ruby-dev:28582]
* prec.c (prec_prec_f): documentation patch from
<gerardo.santana at gmail.com>. [ruby-core:07689]
* bignum.c (rb_big_pow): second operand may be too big even if
it's a Fixnum. [ruby-talk:187984]
* README.EXT: update symbol description. [ruby-talk:188104]
* COPYING: explicitly note GPLv2. [ruby-talk:187922]
* parse.y: remove some obsolete syntax rules (unparenthesized
method calls in argument list).
* eval.c (rb_call0): insecure calling should be checked for non
NODE_SCOPE method invocations too.
* eval.c (rb_alias): should preserve the current safe level as
well as method definition.
* process.c (rb_f_sleep): remove RDoc description about SIGALRM
which is not valid on the current implementation. [ruby-dev:28464]
Thu Mar 23 21:40:47 2006 K.Kosako <sndgk393 AT ybb.ne.jp>
* eval.c (method_missing): should support argument splat in
super. a bug in combination of super, splat and
method_missing. [ruby-talk:185438]
* configure.in: Solaris SunPro compiler -rapth patch from
<kuwa at labs.fujitsu.com>. [ruby-dev:28443]
* configure.in: remove enable_rpath=no for Solaris.
[ruby-dev:28440]
* ext/win32ole/win32ole.c (ole_val2olevariantdata): change behavior
of converting OLE Variant object with VT_ARRAY|VT_UI1 and Ruby
String object.
* ruby.1: a clarification patch from David Lutterkort
<dlutter at redhat.com>. [ruby-core:7508]
* lib/rdoc/ri/ri_paths.rb (RI::Paths): adding paths from rubygems
directories. a patch from Eric Hodel <drbrain at segment7.net>.
[ruby-core:07423]
* eval.c (rb_clear_cache_by_class): clearing wrong cache.
* ext/extmk.rb: use :remove_destination to install extension libraries
to avoid SEGV. [ruby-dev:28417]
* eval.c (rb_thread_fd_writable): should not re-schedule output
from KILLED thread (must be error printing).
* array.c (rb_ary_flatten_bang): allow specifying recursion
level. [ruby-talk:182170]
* array.c (rb_ary_flatten): ditto.
* gc.c (add_heap): a heap_slots may overflow. a patch from Stefan
Weil <weil at mail.berlios.de>.
* eval.c (rb_call): use separate cache for fcall/vcall
invocation.
* eval.c (rb_eval): NODE_FCALL, NODE_VCALL can call local
functions.
* eval.c (rb_mod_local): a new method to specify newly added
visibility "local".
* eval.c (search_method): search for local methods which are
visible only from the current class.
* class.c (rb_class_local_methods): a method to list local methods.
* object.c (Init_Object): add BasicObject class as a top level
BlankSlate class.
* ruby.h (SYM2ID): should not cast to signed long.
[ruby-core:07414]
* class.c (rb_include_module): allow module duplication.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10235 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2006-06-10 01:20:17 +04:00
|
|
|
|
2021-02-07 17:10:12 +03:00
|
|
|
rb_define_private_method(rb_cBasicObject, "singleton_method_added", rb_obj_singleton_method_added, 1);
|
|
|
|
rb_define_private_method(rb_cBasicObject, "singleton_method_removed", rb_obj_singleton_method_removed, 1);
|
|
|
|
rb_define_private_method(rb_cBasicObject, "singleton_method_undefined", rb_obj_singleton_method_undefined, 1);
|
2007-12-11 09:23:21 +03:00
|
|
|
|
2012-06-01 01:41:21 +04:00
|
|
|
/* Document-module: Kernel
|
|
|
|
*
|
|
|
|
* The Kernel module is included by class Object, so its methods are
|
|
|
|
* available in every Ruby object.
|
|
|
|
*
|
|
|
|
* The Kernel instance methods are documented in class Object while the
|
|
|
|
* module methods are documented here. These methods are called without a
|
|
|
|
* receiver and thus can be called in functional form:
|
|
|
|
*
|
|
|
|
* sprintf "%.1f", 1.234 #=> "1.2"
|
|
|
|
*
|
2021-05-13 20:09:07 +03:00
|
|
|
* == What's Here
|
|
|
|
*
|
|
|
|
* \Module \Kernel provides methods that are useful for:
|
|
|
|
*
|
2022-02-06 18:37:06 +03:00
|
|
|
* - {Converting}[rdoc-ref:Kernel@Converting]
|
|
|
|
* - {Querying}[rdoc-ref:Kernel@Querying]
|
|
|
|
* - {Exiting}[rdoc-ref:Kernel@Exiting]
|
|
|
|
* - {Exceptions}[rdoc-ref:Kernel@Exceptions]
|
|
|
|
* - {IO}[rdoc-ref:Kernel@IO]
|
|
|
|
* - {Procs}[rdoc-ref:Kernel@Procs]
|
|
|
|
* - {Tracing}[rdoc-ref:Kernel@Tracing]
|
|
|
|
* - {Subprocesses}[rdoc-ref:Kernel@Subprocesses]
|
|
|
|
* - {Loading}[rdoc-ref:Kernel@Loading]
|
|
|
|
* - {Yielding}[rdoc-ref:Kernel@Yielding]
|
|
|
|
* - {Random Values}[rdoc-ref:Kernel@Random+Values]
|
|
|
|
* - {Other}[rdoc-ref:Kernel@Other]
|
2021-05-13 20:09:07 +03:00
|
|
|
*
|
|
|
|
* === Converting
|
|
|
|
*
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #Array: Returns an Array based on the given argument.
|
|
|
|
* - #Complex: Returns a Complex based on the given arguments.
|
|
|
|
* - #Float: Returns a Float based on the given arguments.
|
|
|
|
* - #Hash: Returns a Hash based on the given argument.
|
|
|
|
* - #Integer: Returns an Integer based on the given arguments.
|
|
|
|
* - #Rational: Returns a Rational based on the given arguments.
|
|
|
|
* - #String: Returns a String based on the given argument.
|
2021-05-13 20:09:07 +03:00
|
|
|
*
|
|
|
|
* === Querying
|
|
|
|
*
|
2022-04-14 06:55:44 +03:00
|
|
|
* - #__callee__: Returns the called name of the current method as a symbol.
|
|
|
|
* - #__dir__: Returns the path to the directory from which the current
|
|
|
|
* method is called.
|
|
|
|
* - #__method__: Returns the name of the current method as a symbol.
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #autoload?: Returns the file to be loaded when the given module is referenced.
|
|
|
|
* - #binding: Returns a Binding for the context at the point of call.
|
|
|
|
* - #block_given?: Returns +true+ if a block was passed to the calling method.
|
|
|
|
* - #caller: Returns the current execution stack as an array of strings.
|
|
|
|
* - #caller_locations: Returns the current execution stack as an array
|
|
|
|
* of Thread::Backtrace::Location objects.
|
|
|
|
* - #class: Returns the class of +self+.
|
|
|
|
* - #frozen?: Returns whether +self+ is frozen.
|
|
|
|
* - #global_variables: Returns an array of global variables as symbols.
|
|
|
|
* - #local_variables: Returns an array of local variables as symbols.
|
|
|
|
* - #test: Performs specified tests on the given single file or pair of files.
|
2021-05-13 20:09:07 +03:00
|
|
|
*
|
|
|
|
* === Exiting
|
|
|
|
*
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #abort: Exits the current process after printing the given arguments.
|
|
|
|
* - #at_exit: Executes the given block when the process exits.
|
|
|
|
* - #exit: Exits the current process after calling any registered
|
|
|
|
* +at_exit+ handlers.
|
|
|
|
* - #exit!: Exits the current process without calling any registered
|
|
|
|
* +at_exit+ handlers.
|
2021-05-13 20:09:07 +03:00
|
|
|
*
|
|
|
|
* === Exceptions
|
|
|
|
*
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #catch: Executes the given block, possibly catching a thrown object.
|
|
|
|
* - #raise (aliased as #fail): Raises an exception based on the given arguments.
|
|
|
|
* - #throw: Returns from the active catch block waiting for the given tag.
|
2021-05-13 20:09:07 +03:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* === \IO
|
|
|
|
*
|
2022-03-29 14:19:51 +03:00
|
|
|
* - ::pp: Prints the given objects in pretty form.
|
|
|
|
* - #gets: Returns and assigns to <tt>$_</tt> the next line from the current input.
|
|
|
|
* - #open: Creates an IO object connected to the given stream, file, or subprocess.
|
|
|
|
* - #p: Prints the given objects' inspect output to the standard output.
|
|
|
|
* - #print: Prints the given objects to standard output without a newline.
|
|
|
|
* - #printf: Prints the string resulting from applying the given format string
|
|
|
|
* to any additional arguments.
|
|
|
|
* - #putc: Equivalent to <tt.$stdout.putc(object)</tt> for the given object.
|
|
|
|
* - #puts: Equivalent to <tt>$stdout.puts(*objects)</tt> for the given objects.
|
|
|
|
* - #readline: Similar to #gets, but raises an exception at the end of file.
|
|
|
|
* - #readlines: Returns an array of the remaining lines from the current input.
|
|
|
|
* - #select: Same as IO.select.
|
2021-05-13 20:09:07 +03:00
|
|
|
*
|
|
|
|
* === Procs
|
|
|
|
*
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #lambda: Returns a lambda proc for the given block.
|
|
|
|
* - #proc: Returns a new Proc; equivalent to Proc.new.
|
2021-05-13 20:09:07 +03:00
|
|
|
*
|
|
|
|
* === Tracing
|
|
|
|
*
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #set_trace_func: Sets the given proc as the handler for tracing,
|
|
|
|
* or disables tracing if given +nil+.
|
|
|
|
* - #trace_var: Starts tracing assignments to the given global variable.
|
|
|
|
* - #untrace_var: Disables tracing of assignments to the given global variable.
|
2021-05-13 20:09:07 +03:00
|
|
|
*
|
|
|
|
* === Subprocesses
|
|
|
|
*
|
2022-04-14 08:56:22 +03:00
|
|
|
* - {\`command`}[rdoc-ref:Kernel#`]: Returns the standard output of running
|
|
|
|
* +command+ in a subshell.
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #exec: Replaces current process with a new process.
|
|
|
|
* - #fork: Forks the current process into two processes.
|
|
|
|
* - #spawn: Executes the given command and returns its pid without waiting
|
|
|
|
* for completion.
|
|
|
|
* - #system: Executes the given command in a subshell.
|
2021-05-13 20:09:07 +03:00
|
|
|
*
|
|
|
|
* === Loading
|
|
|
|
*
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #autoload: Registers the given file to be loaded when the given constant
|
|
|
|
* is first referenced.
|
|
|
|
* - #load: Loads the given Ruby file.
|
|
|
|
* - #require: Loads the given Ruby file unless it has already been loaded.
|
|
|
|
* - #require_relative: Loads the Ruby file path relative to the calling file,
|
|
|
|
* unless it has already been loaded.
|
2021-05-13 20:09:07 +03:00
|
|
|
*
|
|
|
|
* === Yielding
|
|
|
|
*
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #tap: Yields +self+ to the given block; returns +self+.
|
|
|
|
* - #then (aliased as #yield_self): Yields +self+ to the block
|
|
|
|
* and returns the result of the block.
|
2021-05-13 20:09:07 +03:00
|
|
|
*
|
|
|
|
* === \Random Values
|
|
|
|
*
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #rand: Returns a pseudo-random floating point number
|
|
|
|
* strictly between 0.0 and 1.0.
|
|
|
|
* - #srand: Seeds the pseudo-random number generator with the given number.
|
2021-05-13 20:09:07 +03:00
|
|
|
*
|
|
|
|
* === Other
|
|
|
|
*
|
2022-03-29 14:19:51 +03:00
|
|
|
* - #eval: Evaluates the given string as Ruby code.
|
|
|
|
* - #loop: Repeatedly executes the given block.
|
|
|
|
* - #sleep: Suspends the current thread for the given number of seconds.
|
|
|
|
* - #sprintf (aliased as #format): Returns the string resulting from applying
|
|
|
|
* the given format string to any additional arguments.
|
|
|
|
* - #syscall: Runs an operating system call.
|
|
|
|
* - #trap: Specifies the handling of system signals.
|
|
|
|
* - #warn: Issue a warning based on the given messages and options.
|
2021-05-13 20:09:07 +03:00
|
|
|
*
|
2012-06-01 01:41:21 +04:00
|
|
|
*/
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_mKernel = rb_define_module("Kernel");
|
|
|
|
rb_include_module(rb_cObject, rb_mKernel);
|
2021-02-07 17:35:06 +03:00
|
|
|
rb_define_private_method(rb_cClass, "inherited", rb_obj_class_inherited, 1);
|
|
|
|
rb_define_private_method(rb_cModule, "included", rb_obj_mod_included, 1);
|
|
|
|
rb_define_private_method(rb_cModule, "extended", rb_obj_mod_extended, 1);
|
|
|
|
rb_define_private_method(rb_cModule, "prepended", rb_obj_mod_prepended, 1);
|
|
|
|
rb_define_private_method(rb_cModule, "method_added", rb_obj_mod_method_added, 1);
|
2021-05-22 13:04:01 +03:00
|
|
|
rb_define_private_method(rb_cModule, "const_added", rb_obj_mod_const_added, 1);
|
2021-02-07 17:35:06 +03:00
|
|
|
rb_define_private_method(rb_cModule, "method_removed", rb_obj_mod_method_removed, 1);
|
|
|
|
rb_define_private_method(rb_cModule, "method_undefined", rb_obj_mod_method_undefined, 1);
|
1998-01-16 15:13:05 +03:00
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_define_method(rb_mKernel, "nil?", rb_false, 0);
|
2020-05-06 01:11:42 +03:00
|
|
|
rb_define_method(rb_mKernel, "===", case_equal, 1);
|
2007-12-09 19:39:49 +03:00
|
|
|
rb_define_method(rb_mKernel, "!~", rb_obj_not_match, 1);
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_define_method(rb_mKernel, "eql?", rb_obj_equal, 1);
|
2019-08-24 19:09:53 +03:00
|
|
|
rb_define_method(rb_mKernel, "hash", rb_obj_hash, 0); /* in hash.c */
|
2009-10-24 20:48:05 +04:00
|
|
|
rb_define_method(rb_mKernel, "<=>", rb_obj_cmp, 1);
|
1999-01-20 07:59:39 +03:00
|
|
|
|
2010-03-23 12:38:54 +03:00
|
|
|
rb_define_method(rb_mKernel, "singleton_class", rb_obj_singleton_class, 0);
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_define_method(rb_mKernel, "dup", rb_obj_dup, 0);
|
2014-08-02 05:26:58 +04:00
|
|
|
rb_define_method(rb_mKernel, "itself", rb_obj_itself, 0);
|
2003-05-19 09:41:08 +04:00
|
|
|
rb_define_method(rb_mKernel, "initialize_copy", rb_obj_init_copy, 1);
|
2010-02-08 10:43:54 +03:00
|
|
|
rb_define_method(rb_mKernel, "initialize_dup", rb_obj_init_dup_clone, 1);
|
2019-08-26 07:11:46 +03:00
|
|
|
rb_define_method(rb_mKernel, "initialize_clone", rb_obj_init_clone, -1);
|
1999-01-20 07:59:39 +03:00
|
|
|
|
2000-02-01 06:12:21 +03:00
|
|
|
rb_define_method(rb_mKernel, "freeze", rb_obj_freeze, 0);
|
1999-01-20 07:59:39 +03:00
|
|
|
|
|
|
|
rb_define_method(rb_mKernel, "to_s", rb_any_to_s, 0);
|
|
|
|
rb_define_method(rb_mKernel, "inspect", rb_obj_inspect, 0);
|
2012-07-03 01:12:48 +04:00
|
|
|
rb_define_method(rb_mKernel, "methods", rb_obj_methods, -1); /* in class.c */
|
2004-01-10 20:39:07 +03:00
|
|
|
rb_define_method(rb_mKernel, "singleton_methods", rb_obj_singleton_methods, -1); /* in class.c */
|
2012-07-03 01:12:48 +04:00
|
|
|
rb_define_method(rb_mKernel, "protected_methods", rb_obj_protected_methods, -1); /* in class.c */
|
|
|
|
rb_define_method(rb_mKernel, "private_methods", rb_obj_private_methods, -1); /* in class.c */
|
|
|
|
rb_define_method(rb_mKernel, "public_methods", rb_obj_public_methods, -1); /* in class.c */
|
2004-01-10 20:39:07 +03:00
|
|
|
rb_define_method(rb_mKernel, "instance_variables", rb_obj_instance_variables, 0); /* in variable.c */
|
2003-02-10 12:40:13 +03:00
|
|
|
rb_define_method(rb_mKernel, "instance_variable_get", rb_obj_ivar_get, 1);
|
2022-11-15 18:52:39 +03:00
|
|
|
rb_define_method(rb_mKernel, "instance_variable_set", rb_obj_ivar_set_m, 2);
|
2006-09-18 19:43:06 +04:00
|
|
|
rb_define_method(rb_mKernel, "instance_variable_defined?", rb_obj_ivar_defined, 1);
|
2012-12-01 13:16:57 +04:00
|
|
|
rb_define_method(rb_mKernel, "remove_instance_variable",
|
|
|
|
rb_obj_remove_instance_variable, 1); /* in variable.c */
|
1999-01-20 07:59:39 +03:00
|
|
|
|
|
|
|
rb_define_method(rb_mKernel, "instance_of?", rb_obj_is_instance_of, 1);
|
|
|
|
rb_define_method(rb_mKernel, "kind_of?", rb_obj_is_kind_of, 1);
|
|
|
|
rb_define_method(rb_mKernel, "is_a?", rb_obj_is_kind_of, 1);
|
|
|
|
|
2019-08-28 12:19:11 +03:00
|
|
|
rb_define_global_function("sprintf", f_sprintf, -1);
|
|
|
|
rb_define_global_function("format", f_sprintf, -1);
|
1999-01-20 07:59:39 +03:00
|
|
|
|
2009-10-03 14:18:14 +04:00
|
|
|
rb_define_global_function("Integer", rb_f_integer, -1);
|
1999-01-20 07:59:39 +03:00
|
|
|
|
|
|
|
rb_define_global_function("String", rb_f_string, 1);
|
|
|
|
rb_define_global_function("Array", rb_f_array, 1);
|
2012-01-24 08:02:30 +04:00
|
|
|
rb_define_global_function("Hash", rb_f_hash, 1);
|
1999-01-20 07:59:39 +03:00
|
|
|
|
|
|
|
rb_cNilClass = rb_define_class("NilClass", rb_cObject);
|
2019-09-26 18:27:47 +03:00
|
|
|
rb_cNilClass_to_s = rb_fstring_enc_lit("", rb_usascii_encoding());
|
|
|
|
rb_gc_register_mark_object(rb_cNilClass_to_s);
|
Optimize dynamic string interpolation for symbol/true/false/nil/0-9
This provides a significant speedup for symbol, true, false,
nil, and 0-9, class/module, and a small speedup in most other cases.
Speedups (using included benchmarks):
:symbol :: 60%
0-9 :: 50%
Class/Module :: 50%
nil/true/false :: 20%
integer :: 10%
[] :: 10%
"" :: 3%
One reason this approach is faster is it reduces the number of
VM instructions for each interpolated value.
Initial idea, approach, and benchmarks from Eric Wong. I applied
the same approach against the master branch, updating it to handle
the significant internal changes since this was first proposed 4
years ago (such as CALL_INFO/CALL_CACHE -> CALL_DATA). I also
expanded it to optimize true/false/nil/0-9/class/module, and added
handling of missing methods, refined methods, and RUBY_DEBUG.
This renames the tostring insn to anytostring, and adds an
objtostring insn that implements the optimization. This requires
making a few functions non-static, and adding some non-static
functions.
This disables 4 YJIT tests. Those tests should be reenabled after
YJIT optimizes the new objtostring insn.
Implements [Feature #13715]
Co-authored-by: Eric Wong <e@80x24.org>
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Co-authored-by: Yusuke Endoh <mame@ruby-lang.org>
Co-authored-by: Koichi Sasada <ko1@atdot.net>
2021-11-19 02:10:20 +03:00
|
|
|
rb_define_method(rb_cNilClass, "to_s", rb_nil_to_s, 0);
|
2005-10-21 13:00:02 +04:00
|
|
|
rb_define_method(rb_cNilClass, "to_a", nil_to_a, 0);
|
2012-04-24 07:46:55 +04:00
|
|
|
rb_define_method(rb_cNilClass, "to_h", nil_to_h, 0);
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_define_method(rb_cNilClass, "inspect", nil_inspect, 0);
|
2018-11-26 10:55:07 +03:00
|
|
|
rb_define_method(rb_cNilClass, "=~", nil_match, 1);
|
1999-08-13 09:45:20 +04:00
|
|
|
rb_define_method(rb_cNilClass, "&", false_and, 1);
|
|
|
|
rb_define_method(rb_cNilClass, "|", false_or, 1);
|
|
|
|
rb_define_method(rb_cNilClass, "^", false_xor, 1);
|
2020-05-06 01:11:42 +03:00
|
|
|
rb_define_method(rb_cNilClass, "===", case_equal, 1);
|
1999-01-20 07:59:39 +03:00
|
|
|
|
|
|
|
rb_define_method(rb_cNilClass, "nil?", rb_true, 0);
|
2002-12-20 11:33:17 +03:00
|
|
|
rb_undef_alloc_func(rb_cNilClass);
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_undef_method(CLASS_OF(rb_cNilClass), "new");
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2004-06-16 18:21:34 +04:00
|
|
|
rb_define_method(rb_cModule, "freeze", rb_mod_freeze, 0);
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_define_method(rb_cModule, "===", rb_mod_eqq, 1);
|
2002-05-21 09:39:19 +04:00
|
|
|
rb_define_method(rb_cModule, "==", rb_obj_equal, 1);
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_define_method(rb_cModule, "<=>", rb_mod_cmp, 1);
|
|
|
|
rb_define_method(rb_cModule, "<", rb_mod_lt, 1);
|
2004-02-10 14:49:14 +03:00
|
|
|
rb_define_method(rb_cModule, "<=", rb_class_inherited_p, 1);
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_define_method(rb_cModule, ">", rb_mod_gt, 1);
|
|
|
|
rb_define_method(rb_cModule, ">=", rb_mod_ge, 1);
|
2004-01-18 17:16:47 +03:00
|
|
|
rb_define_method(rb_cModule, "initialize_copy", rb_mod_init_copy, 1); /* in class.c */
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_define_method(rb_cModule, "to_s", rb_mod_to_s, 0);
|
2012-08-15 15:50:01 +04:00
|
|
|
rb_define_alias(rb_cModule, "inspect", "to_s");
|
2004-01-10 20:39:07 +03:00
|
|
|
rb_define_method(rb_cModule, "included_modules", rb_mod_included_modules, 0); /* in class.c */
|
2004-01-08 05:21:28 +03:00
|
|
|
rb_define_method(rb_cModule, "include?", rb_mod_include_p, 1); /* in class.c */
|
|
|
|
rb_define_method(rb_cModule, "name", rb_mod_name, 0); /* in variable.c */
|
|
|
|
rb_define_method(rb_cModule, "ancestors", rb_mod_ancestors, 0); /* in class.c */
|
1999-01-20 07:59:39 +03:00
|
|
|
|
2017-11-29 20:47:47 +03:00
|
|
|
rb_define_method(rb_cModule, "attr", rb_mod_attr, -1);
|
|
|
|
rb_define_method(rb_cModule, "attr_reader", rb_mod_attr_reader, -1);
|
|
|
|
rb_define_method(rb_cModule, "attr_writer", rb_mod_attr_writer, -1);
|
|
|
|
rb_define_method(rb_cModule, "attr_accessor", rb_mod_attr_accessor, -1);
|
1999-01-20 07:59:39 +03:00
|
|
|
|
2002-12-20 11:33:17 +03:00
|
|
|
rb_define_alloc_func(rb_cModule, rb_module_s_alloc);
|
2020-07-26 07:20:19 +03:00
|
|
|
rb_undef_method(rb_singleton_class(rb_cModule), "allocate");
|
2002-01-23 10:30:43 +03:00
|
|
|
rb_define_method(rb_cModule, "initialize", rb_mod_initialize, 0);
|
2019-08-26 07:11:46 +03:00
|
|
|
rb_define_method(rb_cModule, "initialize_clone", rb_mod_initialize_clone, -1);
|
2004-01-10 20:39:07 +03:00
|
|
|
rb_define_method(rb_cModule, "instance_methods", rb_class_instance_methods, -1); /* in class.c */
|
2009-02-22 17:23:33 +03:00
|
|
|
rb_define_method(rb_cModule, "public_instance_methods",
|
2004-01-08 05:21:28 +03:00
|
|
|
rb_class_public_instance_methods, -1); /* in class.c */
|
2009-02-22 17:23:33 +03:00
|
|
|
rb_define_method(rb_cModule, "protected_instance_methods",
|
2004-01-08 05:21:28 +03:00
|
|
|
rb_class_protected_instance_methods, -1); /* in class.c */
|
2009-02-22 17:23:33 +03:00
|
|
|
rb_define_method(rb_cModule, "private_instance_methods",
|
2004-01-08 05:21:28 +03:00
|
|
|
rb_class_private_instance_methods, -1); /* in class.c */
|
2022-06-06 19:57:32 +03:00
|
|
|
rb_define_method(rb_cModule, "undefined_instance_methods",
|
|
|
|
rb_class_undefined_instance_methods, 0); /* in class.c */
|
2003-12-28 09:33:07 +03:00
|
|
|
|
2006-12-04 18:19:33 +03:00
|
|
|
rb_define_method(rb_cModule, "constants", rb_mod_constants, -1); /* in variable.c */
|
2006-01-17 17:05:49 +03:00
|
|
|
rb_define_method(rb_cModule, "const_get", rb_mod_const_get, -1);
|
1999-12-14 09:50:43 +03:00
|
|
|
rb_define_method(rb_cModule, "const_set", rb_mod_const_set, 2);
|
2006-01-17 17:05:49 +03:00
|
|
|
rb_define_method(rb_cModule, "const_defined?", rb_mod_const_defined, -1);
|
2018-12-13 15:49:05 +03:00
|
|
|
rb_define_method(rb_cModule, "const_source_location", rb_mod_const_source_location, -1);
|
2009-02-22 17:23:33 +03:00
|
|
|
rb_define_private_method(rb_cModule, "remove_const",
|
2004-01-08 05:21:28 +03:00
|
|
|
rb_mod_remove_const, 1); /* in variable.c */
|
2009-02-22 17:23:33 +03:00
|
|
|
rb_define_method(rb_cModule, "const_missing",
|
2004-01-08 05:21:28 +03:00
|
|
|
rb_mod_const_missing, 1); /* in variable.c */
|
2009-02-22 17:23:33 +03:00
|
|
|
rb_define_method(rb_cModule, "class_variables",
|
2012-07-19 10:41:47 +04:00
|
|
|
rb_mod_class_variables, -1); /* in variable.c */
|
2009-02-22 17:23:33 +03:00
|
|
|
rb_define_method(rb_cModule, "remove_class_variable",
|
2005-09-08 08:42:46 +04:00
|
|
|
rb_mod_remove_cvar, 1); /* in variable.c */
|
|
|
|
rb_define_method(rb_cModule, "class_variable_get", rb_mod_cvar_get, 1);
|
|
|
|
rb_define_method(rb_cModule, "class_variable_set", rb_mod_cvar_set, 2);
|
2006-09-18 19:43:06 +04:00
|
|
|
rb_define_method(rb_cModule, "class_variable_defined?", rb_mod_cvar_defined, 1);
|
2012-05-08 00:35:59 +04:00
|
|
|
rb_define_method(rb_cModule, "public_constant", rb_mod_public_constant, -1); /* in variable.c */
|
|
|
|
rb_define_method(rb_cModule, "private_constant", rb_mod_private_constant, -1); /* in variable.c */
|
2015-07-30 07:20:00 +03:00
|
|
|
rb_define_method(rb_cModule, "deprecate_constant", rb_mod_deprecate_constant, -1); /* in variable.c */
|
2013-08-08 18:01:23 +04:00
|
|
|
rb_define_method(rb_cModule, "singleton_class?", rb_mod_singleton_p, 0);
|
1999-01-20 07:59:39 +03:00
|
|
|
|
2020-07-26 07:20:19 +03:00
|
|
|
rb_define_method(rb_singleton_class(rb_cClass), "allocate", rb_class_alloc_m, 0);
|
2019-11-06 05:17:09 +03:00
|
|
|
rb_define_method(rb_cClass, "allocate", rb_class_alloc_m, 0);
|
2020-05-08 06:58:19 +03:00
|
|
|
rb_define_method(rb_cClass, "new", rb_class_new_instance_pass_kw, -1);
|
2002-01-23 10:30:43 +03:00
|
|
|
rb_define_method(rb_cClass, "initialize", rb_class_initialize, -1);
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_define_method(rb_cClass, "superclass", rb_class_superclass, 0);
|
2021-10-28 15:07:11 +03:00
|
|
|
rb_define_method(rb_cClass, "subclasses", rb_class_subclasses, 0); /* in class.c */
|
2022-09-27 01:19:22 +03:00
|
|
|
rb_define_method(rb_cClass, "attached_object", rb_class_attached_object, 0); /* in class.c */
|
2003-08-07 01:50:06 +04:00
|
|
|
rb_define_alloc_func(rb_cClass, rb_class_s_alloc);
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_undef_method(rb_cClass, "extend_object");
|
|
|
|
rb_undef_method(rb_cClass, "append_features");
|
2013-08-13 16:52:25 +04:00
|
|
|
rb_undef_method(rb_cClass, "prepend_features");
|
1999-01-20 07:59:39 +03:00
|
|
|
|
|
|
|
rb_cTrueClass = rb_define_class("TrueClass", rb_cObject);
|
2019-09-26 18:27:47 +03:00
|
|
|
rb_cTrueClass_to_s = rb_fstring_enc_lit("true", rb_usascii_encoding());
|
|
|
|
rb_gc_register_mark_object(rb_cTrueClass_to_s);
|
Optimize dynamic string interpolation for symbol/true/false/nil/0-9
This provides a significant speedup for symbol, true, false,
nil, and 0-9, class/module, and a small speedup in most other cases.
Speedups (using included benchmarks):
:symbol :: 60%
0-9 :: 50%
Class/Module :: 50%
nil/true/false :: 20%
integer :: 10%
[] :: 10%
"" :: 3%
One reason this approach is faster is it reduces the number of
VM instructions for each interpolated value.
Initial idea, approach, and benchmarks from Eric Wong. I applied
the same approach against the master branch, updating it to handle
the significant internal changes since this was first proposed 4
years ago (such as CALL_INFO/CALL_CACHE -> CALL_DATA). I also
expanded it to optimize true/false/nil/0-9/class/module, and added
handling of missing methods, refined methods, and RUBY_DEBUG.
This renames the tostring insn to anytostring, and adds an
objtostring insn that implements the optimization. This requires
making a few functions non-static, and adding some non-static
functions.
This disables 4 YJIT tests. Those tests should be reenabled after
YJIT optimizes the new objtostring insn.
Implements [Feature #13715]
Co-authored-by: Eric Wong <e@80x24.org>
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Co-authored-by: Yusuke Endoh <mame@ruby-lang.org>
Co-authored-by: Koichi Sasada <ko1@atdot.net>
2021-11-19 02:10:20 +03:00
|
|
|
rb_define_method(rb_cTrueClass, "to_s", rb_true_to_s, 0);
|
2012-08-15 15:50:01 +04:00
|
|
|
rb_define_alias(rb_cTrueClass, "inspect", "to_s");
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_define_method(rb_cTrueClass, "&", true_and, 1);
|
|
|
|
rb_define_method(rb_cTrueClass, "|", true_or, 1);
|
|
|
|
rb_define_method(rb_cTrueClass, "^", true_xor, 1);
|
2020-05-06 01:11:42 +03:00
|
|
|
rb_define_method(rb_cTrueClass, "===", case_equal, 1);
|
2002-12-20 11:33:17 +03:00
|
|
|
rb_undef_alloc_func(rb_cTrueClass);
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_undef_method(CLASS_OF(rb_cTrueClass), "new");
|
|
|
|
|
|
|
|
rb_cFalseClass = rb_define_class("FalseClass", rb_cObject);
|
2019-09-26 18:27:47 +03:00
|
|
|
rb_cFalseClass_to_s = rb_fstring_enc_lit("false", rb_usascii_encoding());
|
|
|
|
rb_gc_register_mark_object(rb_cFalseClass_to_s);
|
Optimize dynamic string interpolation for symbol/true/false/nil/0-9
This provides a significant speedup for symbol, true, false,
nil, and 0-9, class/module, and a small speedup in most other cases.
Speedups (using included benchmarks):
:symbol :: 60%
0-9 :: 50%
Class/Module :: 50%
nil/true/false :: 20%
integer :: 10%
[] :: 10%
"" :: 3%
One reason this approach is faster is it reduces the number of
VM instructions for each interpolated value.
Initial idea, approach, and benchmarks from Eric Wong. I applied
the same approach against the master branch, updating it to handle
the significant internal changes since this was first proposed 4
years ago (such as CALL_INFO/CALL_CACHE -> CALL_DATA). I also
expanded it to optimize true/false/nil/0-9/class/module, and added
handling of missing methods, refined methods, and RUBY_DEBUG.
This renames the tostring insn to anytostring, and adds an
objtostring insn that implements the optimization. This requires
making a few functions non-static, and adding some non-static
functions.
This disables 4 YJIT tests. Those tests should be reenabled after
YJIT optimizes the new objtostring insn.
Implements [Feature #13715]
Co-authored-by: Eric Wong <e@80x24.org>
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
Co-authored-by: Yusuke Endoh <mame@ruby-lang.org>
Co-authored-by: Koichi Sasada <ko1@atdot.net>
2021-11-19 02:10:20 +03:00
|
|
|
rb_define_method(rb_cFalseClass, "to_s", rb_false_to_s, 0);
|
2012-08-15 15:50:01 +04:00
|
|
|
rb_define_alias(rb_cFalseClass, "inspect", "to_s");
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_define_method(rb_cFalseClass, "&", false_and, 1);
|
|
|
|
rb_define_method(rb_cFalseClass, "|", false_or, 1);
|
|
|
|
rb_define_method(rb_cFalseClass, "^", false_xor, 1);
|
2020-05-06 01:11:42 +03:00
|
|
|
rb_define_method(rb_cFalseClass, "===", case_equal, 1);
|
2002-12-20 11:33:17 +03:00
|
|
|
rb_undef_alloc_func(rb_cFalseClass);
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_undef_method(CLASS_OF(rb_cFalseClass), "new");
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2015-08-13 08:36:33 +03:00
|
|
|
|
2020-03-17 13:37:07 +03:00
|
|
|
#include "kernel.rbinc"
|
2021-06-03 06:04:56 +03:00
|
|
|
#include "nilclass.rbinc"
|
2020-03-17 13:37:07 +03:00
|
|
|
|
2015-08-13 08:36:33 +03:00
|
|
|
void
|
|
|
|
Init_Object(void)
|
|
|
|
{
|
2015-11-09 15:27:26 +03:00
|
|
|
id_dig = rb_intern_const("dig");
|
2015-08-13 08:36:33 +03:00
|
|
|
InitVM(Object);
|
|
|
|
}
|
2017-07-22 09:30:53 +03:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \}
|
|
|
|
*/
|