2000-05-09 08:53:16 +04:00
|
|
|
/**********************************************************************
|
1998-01-16 15:13:05 +03:00
|
|
|
|
|
|
|
ruby.c -
|
|
|
|
|
|
|
|
$Author$
|
|
|
|
created at: Tue Aug 10 12:47:31 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-09 08:53:16 +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
|
|
|
|
|
|
|
#include <ctype.h>
|
1998-01-16 15:13:05 +03:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <sys/types.h>
|
2019-12-04 11:16:30 +03:00
|
|
|
|
|
|
|
#ifdef __CYGWIN__
|
|
|
|
# include <windows.h>
|
|
|
|
# include <sys/cygwin.h>
|
|
|
|
#endif
|
1999-01-20 07:59:39 +03:00
|
|
|
|
|
|
|
#ifdef __hpux
|
2019-12-04 11:16:30 +03:00
|
|
|
# include <sys/pstat.h>
|
1999-01-20 07:59:39 +03:00
|
|
|
#endif
|
2019-12-04 11:16:30 +03:00
|
|
|
|
2009-03-09 18:06:22 +03:00
|
|
|
#if defined(LOAD_RELATIVE) && defined(HAVE_DLADDR)
|
2019-12-04 11:16:30 +03:00
|
|
|
# include <dlfcn.h>
|
2009-03-09 18:06:22 +03:00
|
|
|
#endif
|
1998-01-16 15:13:05 +03:00
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
#ifdef HAVE_UNISTD_H
|
2019-12-04 11:16:30 +03:00
|
|
|
# include <unistd.h>
|
1998-01-16 15:19:22 +03:00
|
|
|
#endif
|
2019-12-04 11:16:30 +03:00
|
|
|
|
2007-09-29 00:29:32 +04:00
|
|
|
#if defined(HAVE_FCNTL_H)
|
2019-12-04 11:16:30 +03:00
|
|
|
# include <fcntl.h>
|
2007-09-29 00:29:32 +04:00
|
|
|
#elif defined(HAVE_SYS_FCNTL_H)
|
2019-12-04 11:16:30 +03:00
|
|
|
# include <sys/fcntl.h>
|
2007-09-29 00:29:32 +04:00
|
|
|
#endif
|
2019-12-04 11:16:30 +03:00
|
|
|
|
2004-03-12 14:19:22 +03:00
|
|
|
#ifdef HAVE_SYS_PARAM_H
|
|
|
|
# include <sys/param.h>
|
|
|
|
#endif
|
2019-12-04 11:16:30 +03:00
|
|
|
|
|
|
|
#include "dln.h"
|
|
|
|
#include "eval_intern.h"
|
|
|
|
#include "internal.h"
|
|
|
|
#include "internal/error.h"
|
|
|
|
#include "internal/file.h"
|
|
|
|
#include "internal/inits.h"
|
|
|
|
#include "internal/io.h"
|
|
|
|
#include "internal/load.h"
|
|
|
|
#include "internal/loadpath.h"
|
|
|
|
#include "internal/missing.h"
|
|
|
|
#include "internal/object.h"
|
|
|
|
#include "internal/parse.h"
|
2020-05-02 15:34:10 +03:00
|
|
|
#include "internal/process.h"
|
2020-01-09 17:52:01 +03:00
|
|
|
#include "internal/variable.h"
|
2019-12-04 11:16:30 +03:00
|
|
|
#include "mjit.h"
|
|
|
|
#include "ruby/encoding.h"
|
|
|
|
#include "ruby/thread.h"
|
|
|
|
#include "ruby/util.h"
|
|
|
|
#include "ruby/version.h"
|
|
|
|
|
2004-03-12 14:19:22 +03:00
|
|
|
#ifndef MAXPATHLEN
|
|
|
|
# define MAXPATHLEN 1024
|
|
|
|
#endif
|
2015-10-17 07:03:23 +03:00
|
|
|
#ifndef O_ACCMODE
|
|
|
|
# define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
|
|
|
|
#endif
|
1999-01-20 07:59:39 +03:00
|
|
|
|
2018-08-10 08:02:35 +03:00
|
|
|
void Init_ruby_description(void);
|
|
|
|
|
1999-01-20 07:59:39 +03:00
|
|
|
#ifndef HAVE_STDLIB_H
|
1998-01-16 15:13:05 +03:00
|
|
|
char *getenv();
|
1999-01-20 07:59:39 +03:00
|
|
|
#endif
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2013-10-14 07:22:24 +04:00
|
|
|
#ifndef DISABLE_RUBYGEMS
|
|
|
|
# define DISABLE_RUBYGEMS 0
|
|
|
|
#endif
|
|
|
|
#if DISABLE_RUBYGEMS
|
2012-11-23 12:31:52 +04:00
|
|
|
#define DEFAULT_RUBYGEMS_ENABLED "disabled"
|
|
|
|
#else
|
|
|
|
#define DEFAULT_RUBYGEMS_ENABLED "enabled"
|
|
|
|
#endif
|
|
|
|
|
2019-12-20 17:05:22 +03:00
|
|
|
void rb_warning_category_update(unsigned int mask, unsigned int bits);
|
|
|
|
|
2016-03-08 18:21:22 +03:00
|
|
|
#define COMMA ,
|
2015-09-23 17:43:45 +03:00
|
|
|
#define FEATURE_BIT(bit) (1U << feature_##bit)
|
2016-03-08 18:21:22 +03:00
|
|
|
#define EACH_FEATURES(X, SEP) \
|
2016-02-07 13:21:27 +03:00
|
|
|
X(gems) \
|
2016-03-08 18:21:22 +03:00
|
|
|
SEP \
|
2016-02-07 13:21:27 +03:00
|
|
|
X(did_you_mean) \
|
2016-03-08 18:21:22 +03:00
|
|
|
SEP \
|
2016-02-07 13:21:27 +03:00
|
|
|
X(rubyopt) \
|
2016-03-08 18:21:22 +03:00
|
|
|
SEP \
|
2016-02-07 13:21:27 +03:00
|
|
|
X(frozen_string_literal) \
|
2018-07-18 15:45:54 +03:00
|
|
|
SEP \
|
|
|
|
X(jit) \
|
2016-02-07 13:21:27 +03:00
|
|
|
/* END OF FEATURES */
|
2016-03-08 18:21:22 +03:00
|
|
|
#define EACH_DEBUG_FEATURES(X, SEP) \
|
2016-02-09 10:36:27 +03:00
|
|
|
X(frozen_string_literal) \
|
|
|
|
/* END OF DEBUG FEATURES */
|
2016-02-08 04:30:22 +03:00
|
|
|
#define AMBIGUOUS_FEATURE_NAMES 0 /* no ambiguous feature names now */
|
2016-03-08 18:21:22 +03:00
|
|
|
#define DEFINE_FEATURE(bit) feature_##bit
|
|
|
|
#define DEFINE_DEBUG_FEATURE(bit) feature_debug_##bit
|
2015-09-23 17:43:45 +03:00
|
|
|
enum feature_flag_bits {
|
2016-03-08 18:21:22 +03:00
|
|
|
EACH_FEATURES(DEFINE_FEATURE, COMMA),
|
2016-02-09 10:42:21 +03:00
|
|
|
feature_debug_flag_first,
|
|
|
|
feature_debug_flag_begin = feature_debug_flag_first - 1,
|
2016-03-08 18:21:22 +03:00
|
|
|
EACH_DEBUG_FEATURES(DEFINE_DEBUG_FEATURE, COMMA),
|
2015-09-23 17:43:45 +03:00
|
|
|
feature_flag_count
|
2008-02-24 00:13:05 +03:00
|
|
|
};
|
|
|
|
|
2015-11-25 11:02:29 +03:00
|
|
|
#define DEBUG_BIT(bit) (1U << feature_debug_##bit)
|
|
|
|
|
2008-05-20 07:13:52 +04:00
|
|
|
#define DUMP_BIT(bit) (1U << dump_##bit)
|
2016-03-08 18:21:22 +03:00
|
|
|
#define DEFINE_DUMP(bit) dump_##bit
|
|
|
|
#define EACH_DUMPS(X, SEP) \
|
2016-02-09 11:24:37 +03:00
|
|
|
X(version) \
|
2016-03-08 18:21:22 +03:00
|
|
|
SEP \
|
2016-02-09 11:24:37 +03:00
|
|
|
X(copyright) \
|
2016-03-08 18:21:22 +03:00
|
|
|
SEP \
|
2016-02-09 11:24:37 +03:00
|
|
|
X(usage) \
|
2016-03-08 18:21:22 +03:00
|
|
|
SEP \
|
2016-02-09 11:24:37 +03:00
|
|
|
X(help) \
|
2016-03-08 18:21:22 +03:00
|
|
|
SEP \
|
2016-02-09 11:24:37 +03:00
|
|
|
X(yydebug) \
|
2016-03-08 18:21:22 +03:00
|
|
|
SEP \
|
2016-02-09 11:24:37 +03:00
|
|
|
X(syntax) \
|
2016-03-08 18:21:22 +03:00
|
|
|
SEP \
|
2016-02-09 11:24:37 +03:00
|
|
|
X(parsetree) \
|
2016-03-08 18:21:22 +03:00
|
|
|
SEP \
|
2016-02-09 11:24:37 +03:00
|
|
|
X(parsetree_with_comment) \
|
2016-03-08 18:21:22 +03:00
|
|
|
SEP \
|
2016-02-09 11:24:37 +03:00
|
|
|
X(insns) \
|
|
|
|
/* END OF DUMPS */
|
2008-05-20 07:13:52 +04:00
|
|
|
enum dump_flag_bits {
|
2012-08-09 13:33:49 +04:00
|
|
|
dump_version_v,
|
2016-03-08 18:21:22 +03:00
|
|
|
EACH_DUMPS(DEFINE_DUMP, COMMA),
|
2016-12-07 17:39:24 +03:00
|
|
|
dump_exit_bits = (DUMP_BIT(yydebug) | DUMP_BIT(syntax) |
|
|
|
|
DUMP_BIT(parsetree) | DUMP_BIT(parsetree_with_comment) |
|
|
|
|
DUMP_BIT(insns))
|
2008-05-20 07:13:52 +04:00
|
|
|
};
|
|
|
|
|
2016-08-19 13:44:53 +03:00
|
|
|
typedef struct ruby_cmdline_options ruby_cmdline_options_t;
|
|
|
|
|
2019-03-30 17:31:35 +03:00
|
|
|
typedef struct {
|
|
|
|
unsigned int mask;
|
|
|
|
unsigned int set;
|
|
|
|
} ruby_features_t;
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
rb_feature_set_to(ruby_features_t *feat, unsigned int bit_mask, unsigned int bit_set)
|
|
|
|
{
|
|
|
|
feat->mask |= bit_mask;
|
|
|
|
feat->set = (feat->set & ~bit_mask) | bit_set;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define FEATURE_SET_TO(feat, bit_mask, bit_set) \
|
|
|
|
rb_feature_set_to(&(feat), bit_mask, bit_set)
|
|
|
|
#define FEATURE_SET(feat, bits) FEATURE_SET_TO(feat, bits, bits)
|
2019-12-20 16:50:46 +03:00
|
|
|
#define FEATURE_SET_RESTORE(feat, save) FEATURE_SET_TO(feat, (save).mask, (save).set & (save).mask)
|
2019-03-30 17:31:35 +03:00
|
|
|
#define FEATURE_SET_P(feat, bits) ((feat).set & (bits))
|
|
|
|
|
2016-08-19 13:44:53 +03:00
|
|
|
struct ruby_cmdline_options {
|
2008-05-31 13:28:20 +04:00
|
|
|
const char *script;
|
2008-04-15 21:26:29 +04:00
|
|
|
VALUE script_name;
|
2007-09-29 01:47:31 +04:00
|
|
|
VALUE e_script;
|
2008-01-25 07:18:14 +03:00
|
|
|
struct {
|
|
|
|
struct {
|
|
|
|
VALUE name;
|
|
|
|
int index;
|
|
|
|
} enc;
|
2008-10-07 21:39:44 +04:00
|
|
|
} src, ext, intern;
|
2008-06-09 08:20:07 +04:00
|
|
|
VALUE req_list;
|
2019-03-30 17:31:35 +03:00
|
|
|
ruby_features_t features;
|
2019-12-20 17:05:22 +03:00
|
|
|
ruby_features_t warn;
|
2017-05-28 12:49:29 +03:00
|
|
|
unsigned int dump;
|
2018-10-20 09:53:00 +03:00
|
|
|
#if USE_MJIT
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
struct mjit_options mjit;
|
2018-10-20 09:53:00 +03:00
|
|
|
#endif
|
2017-05-28 12:49:29 +03:00
|
|
|
int sflag, xflag;
|
2015-12-29 13:12:48 +03:00
|
|
|
unsigned int warning: 1;
|
2017-05-28 12:49:29 +03:00
|
|
|
unsigned int verbose: 1;
|
|
|
|
unsigned int do_loop: 1;
|
|
|
|
unsigned int do_print: 1;
|
|
|
|
unsigned int do_line: 1;
|
|
|
|
unsigned int do_split: 1;
|
|
|
|
unsigned int do_search: 1;
|
|
|
|
unsigned int setids: 2;
|
2007-09-29 01:47:31 +04:00
|
|
|
};
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2016-08-19 13:44:53 +03:00
|
|
|
static void init_ids(ruby_cmdline_options_t *);
|
2008-06-09 08:20:07 +04:00
|
|
|
|
|
|
|
#define src_encoding_index GET_VM()->src_encoding_index
|
|
|
|
|
2015-11-19 08:58:31 +03:00
|
|
|
enum {
|
|
|
|
COMPILATION_FEATURES = (
|
|
|
|
0
|
|
|
|
| FEATURE_BIT(frozen_string_literal)
|
2015-11-25 11:02:29 +03:00
|
|
|
| FEATURE_BIT(debug_frozen_string_literal)
|
2015-11-19 08:58:31 +03:00
|
|
|
),
|
|
|
|
DEFAULT_FEATURES = (
|
2016-02-09 10:42:21 +03:00
|
|
|
(FEATURE_BIT(debug_flag_first)-1)
|
2015-11-19 08:58:31 +03:00
|
|
|
#if DISABLE_RUBYGEMS
|
|
|
|
& ~FEATURE_BIT(gems)
|
|
|
|
#endif
|
|
|
|
& ~FEATURE_BIT(frozen_string_literal)
|
2018-07-18 15:45:54 +03:00
|
|
|
& ~FEATURE_BIT(jit)
|
2015-11-19 08:58:31 +03:00
|
|
|
)
|
|
|
|
};
|
|
|
|
|
2016-08-19 13:44:53 +03:00
|
|
|
static ruby_cmdline_options_t *
|
|
|
|
cmdline_options_init(ruby_cmdline_options_t *opt)
|
2008-06-09 08:20:07 +04:00
|
|
|
{
|
|
|
|
MEMZERO(opt, *opt, 1);
|
|
|
|
init_ids(opt);
|
|
|
|
opt->src.enc.index = src_encoding_index;
|
2009-05-17 04:47:49 +04:00
|
|
|
opt->ext.enc.index = -1;
|
|
|
|
opt->intern.enc.index = -1;
|
2019-03-30 17:31:35 +03:00
|
|
|
opt->features.set = DEFAULT_FEATURES;
|
2018-07-02 10:42:24 +03:00
|
|
|
#ifdef MJIT_FORCE_ENABLE /* to use with: ./configure cppflags="-DMJIT_FORCE_ENABLE" */
|
2019-03-30 17:31:35 +03:00
|
|
|
opt->features.set |= FEATURE_BIT(jit);
|
2018-07-02 10:42:24 +03:00
|
|
|
#endif
|
2008-06-09 08:20:07 +04:00
|
|
|
return opt;
|
|
|
|
}
|
|
|
|
|
2017-10-29 18:51:23 +03:00
|
|
|
static rb_ast_t *load_file(VALUE parser, VALUE fname, VALUE f, int script,
|
2017-05-28 12:49:30 +03:00
|
|
|
ruby_cmdline_options_t *opt);
|
|
|
|
static VALUE open_load_file(VALUE fname_v, int *xflag);
|
2017-01-31 15:54:59 +03:00
|
|
|
static void forbid_setid(const char *, const ruby_cmdline_options_t *);
|
2010-12-28 01:37:59 +03:00
|
|
|
#define forbid_setid(s) forbid_setid((s), opt)
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2007-09-29 01:50:01 +04:00
|
|
|
static struct {
|
2007-09-29 01:47:31 +04:00
|
|
|
int argc;
|
|
|
|
char **argv;
|
|
|
|
} origarg;
|
1998-01-16 15:19:22 +03:00
|
|
|
|
2020-03-27 17:18:42 +03:00
|
|
|
static const char esc_standout[] = "\n\033[1;7m";
|
|
|
|
static const char esc_bold[] = "\033[1m";
|
|
|
|
static const char esc_reset[] = "\033[0m";
|
|
|
|
static const char esc_none[] = "";
|
|
|
|
|
2015-05-24 05:20:10 +03:00
|
|
|
static void
|
2020-04-12 07:00:27 +03:00
|
|
|
show_usage_line(const char *str, unsigned int namelen, unsigned int secondlen, int help, int highlight, unsigned int w)
|
2015-05-24 05:20:10 +03:00
|
|
|
{
|
2020-03-27 17:18:42 +03:00
|
|
|
const char *sb = highlight ? esc_bold : esc_none;
|
|
|
|
const char *se = highlight ? esc_reset : esc_none;
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
const int wrap = help && namelen + secondlen - 1 > w;
|
2020-03-27 17:18:42 +03:00
|
|
|
printf(" %s%.*s%-*.*s%s%-*s%s\n", sb, namelen-1, str,
|
2015-05-24 05:20:10 +03:00
|
|
|
(wrap ? 0 : w - namelen + 1),
|
2020-03-27 17:18:42 +03:00
|
|
|
(help ? secondlen-1 : 0), str + namelen, se,
|
2015-05-24 05:20:10 +03:00
|
|
|
(wrap ? w + 3 : 0), (wrap ? "\n" : ""),
|
|
|
|
str + namelen + secondlen);
|
|
|
|
}
|
|
|
|
|
1999-08-13 09:45:20 +04:00
|
|
|
static void
|
2020-04-12 07:00:27 +03:00
|
|
|
usage(const char *name, int help, int highlight, int columns)
|
1999-08-13 09:45:20 +04:00
|
|
|
{
|
|
|
|
/* This message really ought to be max 23 lines.
|
1999-12-07 12:25:55 +03:00
|
|
|
* Removed -h because the user already knows that option. Others? */
|
1999-08-13 09:45:20 +04:00
|
|
|
|
2012-11-23 12:31:52 +04:00
|
|
|
struct message {
|
|
|
|
const char *str;
|
|
|
|
unsigned short namelen, secondlen;
|
2006-12-31 18:02:22 +03:00
|
|
|
};
|
2012-11-23 12:31:52 +04:00
|
|
|
#define M(shortopt, longopt, desc) { \
|
|
|
|
shortopt " " longopt " " desc, \
|
|
|
|
(unsigned short)sizeof(shortopt), \
|
|
|
|
(unsigned short)sizeof(longopt), \
|
|
|
|
}
|
|
|
|
static const struct message usage_msg[] = {
|
|
|
|
M("-0[octal]", "", "specify record separator (\\0, if no argument)"),
|
|
|
|
M("-a", "", "autosplit mode with -n or -p (splits $_ into $F)"),
|
|
|
|
M("-c", "", "check syntax only"),
|
|
|
|
M("-Cdirectory", "", "cd to directory before executing your script"),
|
|
|
|
M("-d", ", --debug", "set debugging flags (set $DEBUG to true)"),
|
|
|
|
M("-e 'command'", "", "one line of script. Several -e's allowed. Omit [programfile]"),
|
|
|
|
M("-Eex[:in]", ", --encoding=ex[:in]", "specify the default external and internal character encodings"),
|
|
|
|
M("-Fpattern", "", "split() pattern for autosplit (-a)"),
|
|
|
|
M("-i[extension]", "", "edit ARGV files in place (make backup if extension supplied)"),
|
|
|
|
M("-Idirectory", "", "specify $LOAD_PATH directory (may be used more than once)"),
|
|
|
|
M("-l", "", "enable line ending processing"),
|
|
|
|
M("-n", "", "assume 'while gets(); ... end' loop around your script"),
|
|
|
|
M("-p", "", "assume loop like -n but print line also like sed"),
|
|
|
|
M("-rlibrary", "", "require the library before executing your script"),
|
|
|
|
M("-s", "", "enable some switch parsing for switches after script name"),
|
|
|
|
M("-S", "", "look for the script using PATH environment variable"),
|
2018-03-26 19:25:05 +03:00
|
|
|
M("-v", "", "print the version number, then turn on verbose mode"),
|
2012-11-23 12:31:52 +04:00
|
|
|
M("-w", "", "turn warnings on for your script"),
|
2019-12-20 17:05:22 +03:00
|
|
|
M("-W[level=2|:category]", "", "set warning level; 0=silence, 1=medium, 2=verbose"),
|
2012-11-23 12:31:52 +04:00
|
|
|
M("-x[directory]", "", "strip off text before #!ruby line and perhaps cd to directory"),
|
2018-11-19 17:00:49 +03:00
|
|
|
M("--jit", "", "enable JIT with default options (experimental)"),
|
|
|
|
M("--jit-[option]","", "enable JIT with an option (experimental)"),
|
2012-11-23 12:31:52 +04:00
|
|
|
M("-h", "", "show this message, --help for more info"),
|
|
|
|
};
|
|
|
|
static const struct message help_msg[] = {
|
2017-09-20 08:01:09 +03:00
|
|
|
M("--copyright", "", "print the copyright"),
|
|
|
|
M("--dump={insns|parsetree|...}[,...]", "",
|
|
|
|
"dump debug information. see below for available dump list"),
|
|
|
|
M("--enable={gems|rubyopt|...}[,...]", ", --disable={gems|rubyopt|...}[,...]",
|
|
|
|
"enable or disable features. see below for available features"),
|
|
|
|
M("--external-encoding=encoding", ", --internal-encoding=encoding",
|
2013-01-11 18:38:57 +04:00
|
|
|
"specify the default external or internal character encoding"),
|
2018-03-26 19:25:05 +03:00
|
|
|
M("--verbose", "", "turn on verbose mode and disable script from stdin"),
|
2018-03-27 03:44:34 +03:00
|
|
|
M("--version", "", "print the version number, then exit"),
|
2017-09-20 08:01:09 +03:00
|
|
|
M("--help", "", "show this message, -h for short message"),
|
2020-05-14 19:22:56 +03:00
|
|
|
M("--backtrace-limit=num", "", "limit the maximum length of backtrace"),
|
2017-09-20 08:01:09 +03:00
|
|
|
};
|
|
|
|
static const struct message dumps[] = {
|
|
|
|
M("insns", "", "instruction sequences"),
|
|
|
|
M("yydebug", "", "yydebug of yacc parser generator"),
|
|
|
|
M("parsetree", "", "AST"),
|
|
|
|
M("parsetree_with_comment", "", "AST with comments"),
|
2012-11-23 12:31:52 +04:00
|
|
|
};
|
|
|
|
static const struct message features[] = {
|
|
|
|
M("gems", "", "rubygems (default: "DEFAULT_RUBYGEMS_ENABLED")"),
|
2015-09-09 10:57:31 +03:00
|
|
|
M("did_you_mean", "", "did_you_mean (default: "DEFAULT_RUBYGEMS_ENABLED")"),
|
2012-11-23 12:31:52 +04:00
|
|
|
M("rubyopt", "", "RUBYOPT environment variable (default: enabled)"),
|
2015-09-27 09:47:00 +03:00
|
|
|
M("frozen-string-literal", "", "freeze all string literals (default: disabled)"),
|
2018-11-19 17:00:49 +03:00
|
|
|
M("jit", "", "JIT compiler (default: disabled)"),
|
2012-11-23 12:31:52 +04:00
|
|
|
};
|
2019-12-20 17:05:22 +03:00
|
|
|
static const struct message warn_categories[] = {
|
|
|
|
M("deprecated", "", "deprecated features"),
|
2019-12-24 06:11:42 +03:00
|
|
|
M("experimental", "", "experimental features"),
|
2019-12-20 17:05:22 +03:00
|
|
|
};
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
static const struct message mjit_options[] = {
|
2018-11-19 17:00:49 +03:00
|
|
|
M("--jit-warnings", "", "Enable printing JIT warnings"),
|
2019-12-01 11:56:27 +03:00
|
|
|
M("--jit-debug", "", "Enable JIT debugging (very slow), or add cflags if specified"),
|
2019-12-23 03:07:07 +03:00
|
|
|
M("--jit-wait", "", "Wait until JIT compilation finishes every time (for testing)"),
|
2018-11-19 17:00:49 +03:00
|
|
|
M("--jit-save-temps", "", "Save JIT temporary files in $TMP or /tmp (for testing)"),
|
|
|
|
M("--jit-verbose=num", "", "Print JIT logs of level num or less to stderr (default: 0)"),
|
Change defaults of --jit options
* --jit-min-calls: 5 -> 10000
--jit-min-calls=5 obviously can compile non hotspot. This was not a
problem for MJIT-benchmarks and Optcarrot because the former has very
few hot optimiziable methods and the latter is likely to trigger
compilation of hotspot by its intensive calls to optimizable hotspot
methods and has a very short window to allow limited compilations.
In real-world applications, it has more time to compile more methods and
it pressures computer's limited resources like icache. We should avoid
compiling too many methods. Also compiling many methods exhausts time
budget for compilation in one ruby process lifetime and delays the "JIT
compaction" of Ruby 2.6.
JVM is known to use 1,500 for C1 (client) compiler and 10,000 for C2
(server) compiler for -XX:CompileThreshold by default.
https://docs.oracle.com/javase/8/embedded/develop-apps-platforms/codecache.htm
When things are called X,000 times, requiring 10,000 can eliminate
compilation of methods which are called only once in these X,000
iterations and obviously not hotspot. And in fact things like
unicorn-worker-killer restarts unicorn process every 4096 requests.
So I felt 10,000 is good for such an environment.
* --jit-max-cache: 1000 -> 100
By the same reason stated above, we should not allow compiling many
methods especially on MJIT which has a larger overhead due to poor code
locality by dlopen and whose code is also likely to be bigger by just
inlining many VM instructions with -O3 rather than directly generating
low-level code.
In JVM -XX:ReservedCodeCacheSize is 32M for reserved and 48M for maximum.
--jit-max-cache=1,000 could be closer to it, but in this case MJIT's
compilation is slow due to data synchronization between threads (to be
improved in Ruby 2.7 though) and we do not want to delay the "JIT
compaction" for a long time.
So I chose a really conservative number for this, but by having method
inlining in the future, wider range could be optimized even with this
value.
* Optcarrot
--disable-gems, --benchmark Lan_Master.nes 12 attempts.
No significant impact.
| r67276 | r67276 --jit | after --jit |
|:-------------------|:------------------|:------------------|
| 50.44369263063978 | 72.87390680773056 | 73.47873485047297 |
| 50.58788746124193 | 78.06820808947026 | 78.29723420171945 |
| 50.77509250801378 | 80.29010348842613 | 78.94689404460769 |
| 50.935361702064405 | 80.42796829926374 | 80.39539527351525 |
| 51.27352672981195 | 81.98758158033202 | 81.6754198664817 |
| 51.720715743242124 | 82.00118535811626 | 82.22960569251283 |
| 51.89643169822524 | 82.2290091613556 | 82.5013636146388 |
| 51.95895898113868 | 82.37318990939565 | 82.74002377794454 |
| 52.10124886807968 | 82.48796686037502 | 83.23354941183932 |
| 52.292280637519376 | 83.0265226541066 | 84.01552618012572 |
| 52.51856237784144 | 83.8797360318052 | 84.8588319093393 |
| 52.65076845986818 | 84.80037351256634 | 85.13577756273656 |
* Railsbench
`WARMUP=20000 BENCHMARK=1000 bin/bench` of https://github.com/k0kubun/railsbench.
It gets closer to --disable=jit.
| | r67276 | r67276 | after |
| | | --jit | --jit |
|:----------|:-------|:-------|:-------|
| req/s | 891.3 | 742.2 | 841.5 |
|:----------|:-------|:-------|:-------|
| 50%ile ms | 1.00 | 1.21 | 1.08 |
| 66%ile ms | 1.02 | 1.24 | 1.09 |
| 75%ile ms | 1.03 | 1.28 | 1.10 |
| 80%ile ms | 1.03 | 1.30 | 1.11 |
| 90%ile ms | 1.09 | 1.42 | 1.15 |
| 95%ile ms | 1.32 | 1.65 | 1.27 |
| 98%ile ms | 4.79 | 2.23 | 1.81 |
| 99%ile ms | 5.68 | 7.52 | 6.64 |
|100%ile ms | 6.52 | 9.69 | 8.59 |
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67277 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-17 08:13:38 +03:00
|
|
|
M("--jit-max-cache=num", "", "Max number of methods to be JIT-ed in a cache (default: 100)"),
|
|
|
|
M("--jit-min-calls=num", "", "Number of calls to trigger JIT (for testing, default: 10000)"),
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
};
|
2015-05-24 05:20:10 +03:00
|
|
|
int i;
|
2020-03-27 17:18:42 +03:00
|
|
|
const char *sb = highlight ? esc_standout+1 : esc_none;
|
|
|
|
const char *se = highlight ? esc_reset : esc_none;
|
2015-05-24 05:20:10 +03:00
|
|
|
const int num = numberof(usage_msg) - (help ? 1 : 0);
|
2020-04-12 07:00:27 +03:00
|
|
|
unsigned int w = (columns > 80 ? (columns - 79) / 2 : 0) + 16;
|
|
|
|
#define SHOW(m) show_usage_line((m).str, (m).namelen, (m).secondlen, help, highlight, w)
|
1999-08-13 09:45:20 +04:00
|
|
|
|
2020-03-27 17:18:42 +03:00
|
|
|
printf("%sUsage:%s %s [switches] [--] [programfile] [arguments]\n", sb, se, name);
|
2012-11-23 12:31:52 +04:00
|
|
|
for (i = 0; i < num; ++i)
|
|
|
|
SHOW(usage_msg[i]);
|
|
|
|
|
|
|
|
if (!help) return;
|
|
|
|
|
2020-03-27 17:18:42 +03:00
|
|
|
if (highlight) sb = esc_standout;
|
|
|
|
|
2012-11-23 12:31:52 +04:00
|
|
|
for (i = 0; i < numberof(help_msg); ++i)
|
|
|
|
SHOW(help_msg[i]);
|
2020-03-27 17:18:42 +03:00
|
|
|
printf("%s""Dump List:%s\n", sb, se);
|
2017-09-20 08:01:09 +03:00
|
|
|
for (i = 0; i < numberof(dumps); ++i)
|
|
|
|
SHOW(dumps[i]);
|
2020-03-27 17:18:42 +03:00
|
|
|
printf("%s""Features:%s\n", sb, se);
|
2012-11-23 12:31:52 +04:00
|
|
|
for (i = 0; i < numberof(features); ++i)
|
|
|
|
SHOW(features[i]);
|
2020-03-27 17:18:42 +03:00
|
|
|
printf("%s""Warning categories:%s\n", sb, se);
|
2019-12-20 17:05:22 +03:00
|
|
|
for (i = 0; i < numberof(warn_categories); ++i)
|
|
|
|
SHOW(warn_categories[i]);
|
2020-03-27 17:18:42 +03:00
|
|
|
printf("%s""JIT options (experimental):%s\n", sb, se);
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
for (i = 0; i < numberof(mjit_options); ++i)
|
|
|
|
SHOW(mjit_options[i]);
|
1999-08-13 09:45:20 +04:00
|
|
|
}
|
|
|
|
|
2014-04-16 12:46:31 +04:00
|
|
|
#define rubylib_path_new rb_str_new
|
1999-08-13 09:45:20 +04:00
|
|
|
|
2007-07-26 08:38:07 +04:00
|
|
|
static void
|
|
|
|
push_include(const char *path, VALUE (*filter)(VALUE))
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
1999-08-13 09:45:20 +04:00
|
|
|
const char sep = PATH_SEP_CHAR;
|
2007-07-26 08:38:07 +04:00
|
|
|
const char *p, *s;
|
2008-04-30 13:03:03 +04:00
|
|
|
VALUE load_path = GET_VM()->load_path;
|
1999-01-20 07:59:39 +03:00
|
|
|
|
2007-07-26 08:38:07 +04:00
|
|
|
p = path;
|
|
|
|
while (*p) {
|
|
|
|
while (*p == sep)
|
|
|
|
p++;
|
|
|
|
if (!*p) break;
|
|
|
|
for (s = p; *s && *s != sep; s = CharNext(s));
|
2014-04-16 12:46:31 +04:00
|
|
|
rb_ary_push(load_path, (*filter)(rubylib_path_new(p, s - p)));
|
2007-07-26 08:38:07 +04:00
|
|
|
p = s;
|
1999-01-20 07:59:39 +03:00
|
|
|
}
|
2007-07-26 08:38:07 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef __CYGWIN__
|
|
|
|
static void
|
|
|
|
push_include_cygwin(const char *path, VALUE (*filter)(VALUE))
|
|
|
|
{
|
|
|
|
const char *p, *s;
|
|
|
|
char rubylib[FILENAME_MAX];
|
|
|
|
VALUE buf = 0;
|
|
|
|
|
|
|
|
p = path;
|
|
|
|
while (*p) {
|
|
|
|
unsigned int len;
|
|
|
|
while (*p == ';')
|
|
|
|
p++;
|
|
|
|
if (!*p) break;
|
|
|
|
for (s = p; *s && *s != ';'; s = CharNext(s));
|
|
|
|
len = s - p;
|
|
|
|
if (*s) {
|
|
|
|
if (!buf) {
|
|
|
|
buf = rb_str_new(p, len);
|
|
|
|
p = RSTRING_PTR(buf);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
else {
|
2007-07-26 08:38:07 +04:00
|
|
|
rb_str_resize(buf, len);
|
|
|
|
p = strncpy(RSTRING_PTR(buf), p, len);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
}
|
2010-11-11 15:24:41 +03:00
|
|
|
#ifdef HAVE_CYGWIN_CONV_PATH
|
|
|
|
#define CONV_TO_POSIX_PATH(p, lib) \
|
2010-12-28 01:37:59 +03:00
|
|
|
cygwin_conv_path(CCP_WIN_A_TO_POSIX|CCP_RELATIVE, (p), (lib), sizeof(lib))
|
2010-11-11 15:24:41 +03:00
|
|
|
#else
|
2014-04-17 12:24:15 +04:00
|
|
|
# error no cygwin_conv_path
|
2010-11-11 15:24:41 +03:00
|
|
|
#endif
|
|
|
|
if (CONV_TO_POSIX_PATH(p, rubylib) == 0)
|
2007-07-26 08:38:07 +04:00
|
|
|
p = rubylib;
|
|
|
|
push_include(p, filter);
|
|
|
|
if (!*s) break;
|
|
|
|
p = s + 1;
|
2000-08-01 13:25:37 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-26 08:38:07 +04:00
|
|
|
#define push_include push_include_cygwin
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void
|
|
|
|
ruby_push_include(const char *path, VALUE (*filter)(VALUE))
|
|
|
|
{
|
|
|
|
if (path == 0)
|
|
|
|
return;
|
|
|
|
push_include(path, filter);
|
|
|
|
}
|
|
|
|
|
2005-04-21 01:44:20 +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
|
|
|
identical_path(VALUE path)
|
2005-04-21 01:44:20 +04:00
|
|
|
{
|
|
|
|
return path;
|
|
|
|
}
|
2008-12-15 05:32:21 +03:00
|
|
|
static VALUE
|
|
|
|
locale_path(VALUE path)
|
|
|
|
{
|
|
|
|
rb_enc_associate(path, rb_locale_encoding());
|
|
|
|
return path;
|
|
|
|
}
|
2005-04-21 01:44:20 +04:00
|
|
|
|
2007-07-26 08:38:07 +04:00
|
|
|
void
|
2005-04-21 01:44:20 +04:00
|
|
|
ruby_incpush(const char *path)
|
|
|
|
{
|
2008-12-15 05:32:21 +03:00
|
|
|
ruby_push_include(path, locale_path);
|
2005-04-21 01:44:20 +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
|
|
|
expand_include_path(VALUE path)
|
2005-04-21 01:44:20 +04:00
|
|
|
{
|
2006-08-31 14:47:44 +04:00
|
|
|
char *p = RSTRING_PTR(path);
|
2006-12-31 18:02:22 +03:00
|
|
|
if (!p)
|
|
|
|
return path;
|
|
|
|
if (*p == '.' && p[1] == '/')
|
|
|
|
return path;
|
2005-04-21 01:44:20 +04:00
|
|
|
return rb_file_expand_path(path, Qnil);
|
|
|
|
}
|
|
|
|
|
2009-01-21 07:59:20 +03:00
|
|
|
void
|
2005-04-21 01:44:20 +04:00
|
|
|
ruby_incpush_expand(const char *path)
|
|
|
|
{
|
|
|
|
ruby_push_include(path, expand_include_path);
|
|
|
|
}
|
|
|
|
|
2014-11-29 10:53:17 +03:00
|
|
|
#undef UTF8_PATH
|
2007-05-18 06:11:42 +04:00
|
|
|
#if defined _WIN32 || defined __CYGWIN__
|
|
|
|
static HMODULE libruby;
|
|
|
|
|
|
|
|
BOOL WINAPI
|
|
|
|
DllMain(HINSTANCE dll, DWORD reason, LPVOID reserved)
|
|
|
|
{
|
|
|
|
if (reason == DLL_PROCESS_ATTACH)
|
|
|
|
libruby = dll;
|
|
|
|
return TRUE;
|
|
|
|
}
|
2009-03-02 05:01:48 +03:00
|
|
|
|
|
|
|
HANDLE
|
|
|
|
rb_libruby_handle(void)
|
|
|
|
{
|
|
|
|
return libruby;
|
|
|
|
}
|
2014-11-29 10:53:17 +03:00
|
|
|
|
2014-11-29 18:02:25 +03:00
|
|
|
static inline void
|
|
|
|
translit_char_bin(char *p, int from, int to)
|
|
|
|
{
|
|
|
|
while (*p) {
|
|
|
|
if ((unsigned char)*p == from)
|
|
|
|
*p = to;
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
}
|
2016-04-23 03:03:37 +03:00
|
|
|
#endif
|
2014-11-29 18:02:25 +03:00
|
|
|
|
2016-04-23 03:03:37 +03:00
|
|
|
#ifdef _WIN32
|
2014-11-29 10:53:17 +03:00
|
|
|
# define UTF8_PATH 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef UTF8_PATH
|
|
|
|
# define UTF8_PATH 0
|
2007-05-18 06:11:42 +04:00
|
|
|
#endif
|
2016-06-02 11:05:21 +03:00
|
|
|
#if UTF8_PATH
|
|
|
|
# define IF_UTF8_PATH(t, f) t
|
|
|
|
#else
|
|
|
|
# define IF_UTF8_PATH(t, f) f
|
|
|
|
#endif
|
2007-05-18 06:11:42 +04:00
|
|
|
|
2014-11-29 18:02:58 +03:00
|
|
|
#if UTF8_PATH
|
|
|
|
static VALUE
|
|
|
|
str_conv_enc(VALUE str, rb_encoding *from, rb_encoding *to)
|
|
|
|
{
|
|
|
|
return rb_str_conv_enc_opts(str, from, to,
|
|
|
|
ECONV_UNDEF_REPLACE|ECONV_INVALID_REPLACE,
|
|
|
|
Qnil);
|
|
|
|
}
|
2017-05-17 07:47:05 +03:00
|
|
|
#else
|
|
|
|
# define str_conv_enc(str, from, to) (str)
|
2014-11-29 18:02:58 +03:00
|
|
|
#endif
|
|
|
|
|
2019-09-21 05:06:22 +03:00
|
|
|
void ruby_init_loadpath(void);
|
2008-10-31 02:16:16 +03:00
|
|
|
|
2018-05-21 15:24:47 +03:00
|
|
|
#if defined(LOAD_RELATIVE)
|
2015-01-24 15:24:27 +03:00
|
|
|
static VALUE
|
2018-05-21 15:24:47 +03:00
|
|
|
runtime_libruby_path(void)
|
2015-01-24 15:24:27 +03:00
|
|
|
{
|
2018-05-21 15:24:47 +03:00
|
|
|
#if defined _WIN32 || defined __CYGWIN__
|
|
|
|
DWORD len = RSTRING_EMBED_LEN_MAX, ret;
|
|
|
|
VALUE path;
|
|
|
|
VALUE wsopath = rb_str_new(0, len*sizeof(WCHAR));
|
|
|
|
WCHAR *wlibpath;
|
|
|
|
char *libpath;
|
|
|
|
|
|
|
|
while (wlibpath = (WCHAR *)RSTRING_PTR(wsopath),
|
|
|
|
ret = GetModuleFileNameW(libruby, wlibpath, len),
|
|
|
|
(ret == len))
|
|
|
|
{
|
|
|
|
rb_str_modify_expand(wsopath, len*sizeof(WCHAR));
|
|
|
|
rb_str_set_len(wsopath, (len += len)*sizeof(WCHAR));
|
|
|
|
}
|
|
|
|
if (!ret || ret > len) rb_fatal("failed to get module file name");
|
|
|
|
#if defined __CYGWIN__
|
|
|
|
{
|
|
|
|
const int win_to_posix = CCP_WIN_W_TO_POSIX | CCP_RELATIVE;
|
|
|
|
size_t newsize = cygwin_conv_path(win_to_posix, wlibpath, 0, 0);
|
|
|
|
if (!newsize) rb_fatal("failed to convert module path to cygwin");
|
|
|
|
path = rb_str_new(0, newsize);
|
|
|
|
libpath = RSTRING_PTR(path);
|
|
|
|
if (cygwin_conv_path(win_to_posix, wlibpath, libpath, newsize)) {
|
|
|
|
rb_str_resize(path, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
{
|
|
|
|
DWORD i;
|
|
|
|
for (len = ret, i = 0; i < len; ++i) {
|
|
|
|
if (wlibpath[i] == L'\\') {
|
|
|
|
wlibpath[i] = L'/';
|
|
|
|
ret = i+1; /* chop after the last separator */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
len = WideCharToMultiByte(CP_UTF8, 0, wlibpath, ret, NULL, 0, NULL, NULL);
|
|
|
|
path = rb_utf8_str_new(0, len);
|
|
|
|
libpath = RSTRING_PTR(path);
|
|
|
|
WideCharToMultiByte(CP_UTF8, 0, wlibpath, ret, libpath, len, NULL, NULL);
|
|
|
|
#endif
|
|
|
|
rb_str_resize(wsopath, 0);
|
|
|
|
return path;
|
|
|
|
#elif defined(HAVE_DLADDR)
|
2015-01-24 15:24:27 +03:00
|
|
|
Dl_info dli;
|
|
|
|
VALUE fname, path;
|
2018-05-21 15:24:47 +03:00
|
|
|
const void* addr = (void *)(VALUE)expand_include_path;
|
2015-01-24 15:24:27 +03:00
|
|
|
|
2018-07-26 12:34:30 +03:00
|
|
|
if (!dladdr((void *)addr, &dli)) {
|
2015-01-24 15:24:27 +03:00
|
|
|
return rb_str_new(0, 0);
|
|
|
|
}
|
|
|
|
#ifdef __linux__
|
2017-08-09 14:03:55 +03:00
|
|
|
else if (origarg.argc > 0 && origarg.argv && dli.dli_fname == origarg.argv[0]) {
|
2015-01-24 15:24:27 +03:00
|
|
|
fname = rb_str_new_cstr("/proc/self/exe");
|
2015-09-05 17:00:15 +03:00
|
|
|
path = rb_readlink(fname, NULL);
|
2015-01-24 15:24:27 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
else {
|
|
|
|
fname = rb_str_new_cstr(dli.dli_fname);
|
|
|
|
path = rb_realpath_internal(Qnil, fname, 1);
|
|
|
|
}
|
|
|
|
rb_str_resize(fname, 0);
|
|
|
|
return path;
|
2018-05-21 15:24:47 +03:00
|
|
|
#else
|
|
|
|
# error relative load path is not supported on this platform.
|
|
|
|
#endif
|
2015-01-24 15:24:27 +03:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2015-07-02 08:12:04 +03:00
|
|
|
#define INITIAL_LOAD_PATH_MARK rb_intern_const("@gem_prelude_index")
|
|
|
|
|
2018-04-27 05:02:29 +03:00
|
|
|
VALUE ruby_archlibdir_path, ruby_prefix_path;
|
|
|
|
|
2008-10-31 02:16:16 +03:00
|
|
|
void
|
2019-09-21 05:06:22 +03:00
|
|
|
ruby_init_loadpath(void)
|
2000-08-01 13:25:37 +04:00
|
|
|
{
|
2018-04-27 08:20:40 +03:00
|
|
|
VALUE load_path, archlibdir = 0;
|
|
|
|
ID id_initial_load_path_mark;
|
|
|
|
const char *paths = ruby_initial_load_paths;
|
|
|
|
#if defined LOAD_RELATIVE
|
2018-04-27 07:36:34 +03:00
|
|
|
#if !defined ENABLE_MULTIARCH
|
|
|
|
# define RUBY_ARCH_PATH ""
|
|
|
|
#elif defined RUBY_ARCH
|
|
|
|
# define RUBY_ARCH_PATH "/"RUBY_ARCH
|
|
|
|
#else
|
|
|
|
# define RUBY_ARCH_PATH "/"RUBY_PLATFORM
|
|
|
|
#endif
|
2009-05-17 04:02:58 +04:00
|
|
|
char *libpath;
|
|
|
|
VALUE sopath;
|
2009-10-18 13:32:02 +04:00
|
|
|
size_t baselen;
|
2018-04-26 15:36:26 +03:00
|
|
|
const char *p;
|
2007-05-18 06:11:42 +04:00
|
|
|
|
2018-05-21 15:24:47 +03:00
|
|
|
sopath = runtime_libruby_path();
|
2009-08-27 08:55:55 +04:00
|
|
|
libpath = RSTRING_PTR(sopath);
|
2001-02-09 17:11:23 +03:00
|
|
|
|
|
|
|
p = strrchr(libpath, '/');
|
2000-08-03 13:50:41 +04:00
|
|
|
if (p) {
|
2018-05-21 15:25:45 +03:00
|
|
|
static const char libdir[] = "/"
|
|
|
|
#ifdef LIBDIR_BASENAME
|
|
|
|
LIBDIR_BASENAME
|
|
|
|
#else
|
|
|
|
"lib"
|
|
|
|
#endif
|
|
|
|
RUBY_ARCH_PATH;
|
|
|
|
const ptrdiff_t libdir_len = (ptrdiff_t)sizeof(libdir)
|
|
|
|
- rb_strlen_lit(RUBY_ARCH_PATH) - 1;
|
2012-08-29 09:59:05 +04:00
|
|
|
static const char bindir[] = "/bin";
|
|
|
|
const ptrdiff_t bindir_len = (ptrdiff_t)sizeof(bindir) - 1;
|
2013-02-21 07:45:07 +04:00
|
|
|
|
2018-04-26 15:36:26 +03:00
|
|
|
const char *p2 = NULL;
|
2013-02-21 07:45:07 +04:00
|
|
|
|
2018-04-27 05:02:29 +03:00
|
|
|
#ifdef ENABLE_MULTIARCH
|
2013-02-21 07:45:07 +04:00
|
|
|
multiarch:
|
|
|
|
#endif
|
|
|
|
if (p - libpath >= bindir_len && !STRNCASECMP(p - bindir_len, bindir, bindir_len)) {
|
2012-08-29 09:59:05 +04:00
|
|
|
p -= bindir_len;
|
2018-04-27 05:02:29 +03:00
|
|
|
archlibdir = rb_str_subseq(sopath, 0, p - libpath);
|
|
|
|
rb_str_cat_cstr(archlibdir, libdir);
|
|
|
|
OBJ_FREEZE_RAW(archlibdir);
|
2012-08-29 09:59:05 +04:00
|
|
|
}
|
2013-02-21 07:45:07 +04:00
|
|
|
else if (p - libpath >= libdir_len && !strncmp(p - libdir_len, libdir, libdir_len)) {
|
2018-04-27 05:02:29 +03:00
|
|
|
archlibdir = rb_str_subseq(sopath, 0, (p2 ? p2 : p) - libpath);
|
|
|
|
OBJ_FREEZE_RAW(archlibdir);
|
2012-08-29 09:59:05 +04:00
|
|
|
p -= libdir_len;
|
2000-08-03 13:50:41 +04:00
|
|
|
}
|
2013-02-21 07:45:07 +04:00
|
|
|
#ifdef ENABLE_MULTIARCH
|
|
|
|
else if (p2) {
|
|
|
|
p = p2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
p2 = p;
|
|
|
|
p = rb_enc_path_last_separator(libpath, p, rb_ascii8bit_encoding());
|
|
|
|
if (p) goto multiarch;
|
|
|
|
p = p2;
|
|
|
|
}
|
|
|
|
#endif
|
2000-08-03 13:50:41 +04:00
|
|
|
}
|
2010-08-02 16:51:18 +04:00
|
|
|
baselen = p - libpath;
|
2010-08-05 09:12:50 +04:00
|
|
|
rb_str_resize(sopath, baselen);
|
2010-08-02 16:51:18 +04:00
|
|
|
libpath = RSTRING_PTR(sopath);
|
2010-03-12 01:15:11 +03:00
|
|
|
#define PREFIX_PATH() sopath
|
2009-10-18 13:32:02 +04:00
|
|
|
#define BASEPATH() rb_str_buf_cat(rb_str_buf_new(baselen+len), libpath, baselen)
|
2010-12-28 01:37:59 +03:00
|
|
|
#define RUBY_RELATIVE(path, len) rb_str_buf_cat(BASEPATH(), (path), (len))
|
2000-08-03 13:50:41 +04:00
|
|
|
#else
|
2013-02-18 05:11:58 +04:00
|
|
|
const size_t exec_prefix_len = strlen(ruby_exec_prefix);
|
2014-04-16 12:46:31 +04:00
|
|
|
#define RUBY_RELATIVE(path, len) rubylib_path_new((path), (len))
|
2013-02-18 05:11:58 +04:00
|
|
|
#define PREFIX_PATH() RUBY_RELATIVE(ruby_exec_prefix, exec_prefix_len)
|
2000-08-03 13:50:41 +04:00
|
|
|
#endif
|
2018-04-27 05:02:29 +03:00
|
|
|
rb_gc_register_address(&ruby_prefix_path);
|
|
|
|
ruby_prefix_path = PREFIX_PATH();
|
|
|
|
OBJ_FREEZE_RAW(ruby_prefix_path);
|
|
|
|
if (!archlibdir) archlibdir = ruby_prefix_path;
|
|
|
|
rb_gc_register_address(&ruby_archlibdir_path);
|
|
|
|
ruby_archlibdir_path = archlibdir;
|
|
|
|
|
2008-04-30 13:03:03 +04:00
|
|
|
load_path = GET_VM()->load_path;
|
2000-08-03 13:50:41 +04:00
|
|
|
|
2019-09-21 05:06:22 +03:00
|
|
|
ruby_push_include(getenv("RUBYLIB"), identical_path);
|
2000-08-01 13:25:37 +04:00
|
|
|
|
2015-07-02 08:12:04 +03:00
|
|
|
id_initial_load_path_mark = INITIAL_LOAD_PATH_MARK;
|
2009-02-05 05:21:37 +03:00
|
|
|
while (*paths) {
|
2009-05-17 04:02:58 +04:00
|
|
|
size_t len = strlen(paths);
|
2010-03-12 18:11:10 +03:00
|
|
|
VALUE path = RUBY_RELATIVE(paths, len);
|
|
|
|
rb_ivar_set(path, id_initial_load_path_mark, path);
|
|
|
|
rb_ary_push(load_path, path);
|
2009-03-09 22:56:46 +03:00
|
|
|
paths += len + 1;
|
2009-02-05 05:21:37 +03:00
|
|
|
}
|
2010-03-12 01:15:11 +03:00
|
|
|
|
2018-04-27 05:02:29 +03:00
|
|
|
rb_const_set(rb_cObject, rb_intern_const("TMP_RUBY_PREFIX"), ruby_prefix_path);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2009-05-17 04:47:49 +04:00
|
|
|
add_modules(VALUE *req_list, const char *mod)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2009-05-17 04:47:49 +04:00
|
|
|
VALUE list = *req_list;
|
2012-08-23 11:46:12 +04:00
|
|
|
VALUE feature;
|
2008-06-09 08:20:07 +04:00
|
|
|
|
|
|
|
if (!list) {
|
2018-06-12 02:33:35 +03:00
|
|
|
*req_list = list = rb_ary_tmp_new(0);
|
2008-06-09 08:20:07 +04:00
|
|
|
}
|
2018-06-12 02:33:35 +03:00
|
|
|
feature = rb_str_cat_cstr(rb_str_tmp_new(0), mod);
|
2012-08-23 11:46:12 +04:00
|
|
|
rb_ary_push(list, feature);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
* intern.h: add prototypes.
rb_gc_enable(), rb_gc_disable(), rb_gc_start(), rb_str_new5()
rb_str_buf_append(), rb_str_buf_cat(), rb_str_buf_cat2(),
rb_str_dup_frozen()
* ruby.h: added declaration.
rb_defout, rb_stdin, rb_stdout, rb_stderr, ruby_errinfo
* rubyio.h: changed double include guard macro to RUBYIO_H.
* array.c (inspect_call): make static.
* eval.c (dvar_asgn): ditto.
* io.c (rb_io_close_read): ditto.
* lex.c (rb_reserved_word): ditto.
* ruby.c: (req_list_head, req_list_last): ditto.
* ruby.c (require_libraries): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1915 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2001-12-17 10:52:35 +03:00
|
|
|
static void
|
2009-05-17 04:47:49 +04:00
|
|
|
require_libraries(VALUE *req_list)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2009-05-17 04:47:49 +04:00
|
|
|
VALUE list = *req_list;
|
2011-02-11 06:06:50 +03:00
|
|
|
VALUE self = rb_vm_top_self();
|
2011-03-23 02:05:53 +03:00
|
|
|
ID require;
|
2012-08-23 11:46:12 +04:00
|
|
|
rb_encoding *extenc = rb_default_external_encoding();
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2008-06-09 13:25:32 +04:00
|
|
|
CONST_ID(require, "require");
|
2008-06-09 10:40:02 +04:00
|
|
|
while (list && RARRAY_LEN(list) > 0) {
|
2008-06-09 08:20:07 +04:00
|
|
|
VALUE feature = rb_ary_shift(list);
|
2012-08-23 11:46:12 +04:00
|
|
|
rb_enc_associate(feature, extenc);
|
* 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_RAW(feature, rb_cString);
|
2012-08-23 11:46:12 +04:00
|
|
|
OBJ_FREEZE(feature);
|
2016-07-29 14:57:14 +03:00
|
|
|
rb_funcallv(self, require, 1, &feature);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2009-05-17 04:47:49 +04:00
|
|
|
*req_list = 0;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2016-07-28 14:02:30 +03:00
|
|
|
static const struct rb_block*
|
2016-03-29 00:39:24 +03:00
|
|
|
toplevel_context(rb_binding_t *bind)
|
2012-06-14 06:22:08 +04:00
|
|
|
{
|
2016-07-28 14:02:30 +03:00
|
|
|
return &bind->block;
|
2012-06-14 06:22:08 +04:00
|
|
|
}
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
static void
|
2009-05-17 04:47:49 +04:00
|
|
|
process_sflag(int *sflag)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2009-05-17 04:47:49 +04:00
|
|
|
if (*sflag > 0) {
|
2002-08-21 19:47:54 +04:00
|
|
|
long n;
|
2013-11-08 06:37:47 +04:00
|
|
|
const VALUE *args;
|
2008-03-01 11:59:04 +03:00
|
|
|
VALUE argv = rb_argv;
|
1999-10-15 12:52:18 +04:00
|
|
|
|
2008-03-01 11:59:04 +03:00
|
|
|
n = RARRAY_LEN(argv);
|
2013-11-08 06:37:47 +04:00
|
|
|
args = RARRAY_CONST_PTR(argv);
|
1999-12-02 09:58:52 +03:00
|
|
|
while (n > 0) {
|
2001-05-02 08:22:21 +04:00
|
|
|
VALUE v = *args++;
|
|
|
|
char *s = StringValuePtr(v);
|
1999-10-15 12:52:18 +04:00
|
|
|
char *p;
|
2009-09-13 15:18:51 +04:00
|
|
|
int hyphen = FALSE;
|
1999-10-15 12:52:18 +04:00
|
|
|
|
2006-12-31 18:02:22 +03:00
|
|
|
if (s[0] != '-')
|
|
|
|
break;
|
1999-12-02 09:58:52 +03:00
|
|
|
n--;
|
2006-12-31 18:02:22 +03:00
|
|
|
if (s[1] == '-' && s[2] == '\0')
|
|
|
|
break;
|
1999-10-15 12:52:18 +04:00
|
|
|
|
2005-05-01 04:13:48 +04:00
|
|
|
v = Qtrue;
|
|
|
|
/* check if valid name before replacing - with _ */
|
|
|
|
for (p = s + 1; *p; p++) {
|
|
|
|
if (*p == '=') {
|
|
|
|
*p++ = '\0';
|
|
|
|
v = rb_str_new2(p);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (*p == '-') {
|
2009-09-13 15:18:51 +04:00
|
|
|
hyphen = TRUE;
|
2005-05-01 04:13:48 +04:00
|
|
|
}
|
|
|
|
else if (*p != '_' && !ISALNUM(*p)) {
|
|
|
|
VALUE name_error[2];
|
2006-12-31 18:02:22 +03:00
|
|
|
name_error[0] =
|
|
|
|
rb_str_new2("invalid name for global variable - ");
|
2005-05-01 04:13:48 +04:00
|
|
|
if (!(p = strchr(p, '='))) {
|
|
|
|
rb_str_cat2(name_error[0], s);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rb_str_cat(name_error[0], s, p - s);
|
|
|
|
}
|
|
|
|
name_error[1] = args[-1];
|
2007-09-29 01:47:31 +04:00
|
|
|
rb_exc_raise(rb_class_new_instance(2, name_error, rb_eNameError));
|
2005-05-01 04:13:48 +04:00
|
|
|
}
|
1999-10-15 12:52:18 +04:00
|
|
|
}
|
2005-05-01 04:13:48 +04:00
|
|
|
s[0] = '$';
|
|
|
|
if (hyphen) {
|
|
|
|
for (p = s + 1; *p; ++p) {
|
2006-12-31 18:02:22 +03:00
|
|
|
if (*p == '-')
|
|
|
|
*p = '_';
|
2005-05-01 04:13:48 +04:00
|
|
|
}
|
1999-10-15 12:52:18 +04:00
|
|
|
}
|
2005-05-01 04:13:48 +04:00
|
|
|
rb_gv_set(s, v);
|
1999-10-15 12:52:18 +04:00
|
|
|
}
|
2008-03-01 11:59:04 +03:00
|
|
|
n = RARRAY_LEN(argv) - n;
|
1999-10-15 12:52:18 +04:00
|
|
|
while (n--) {
|
2008-03-01 11:59:04 +03:00
|
|
|
rb_ary_shift(argv);
|
1999-10-15 12:52:18 +04:00
|
|
|
}
|
2009-05-17 04:47:49 +04:00
|
|
|
*sflag = -1;
|
1999-10-15 12:52:18 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-19 13:44:53 +03:00
|
|
|
static long proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt);
|
1999-10-21 11:52:15 +04:00
|
|
|
|
2008-10-30 04:34:23 +03:00
|
|
|
static void
|
2016-08-19 13:44:53 +03:00
|
|
|
moreswitches(const char *s, ruby_cmdline_options_t *opt, int envopt)
|
1999-10-21 11:52:15 +04:00
|
|
|
{
|
2009-05-17 04:47:49 +04:00
|
|
|
long argc, i, len;
|
2008-10-30 04:34:23 +03:00
|
|
|
char **argv, *p;
|
|
|
|
const char *ap = 0;
|
|
|
|
VALUE argstr, argary;
|
2018-05-10 05:54:04 +03:00
|
|
|
void *ptr;
|
2008-10-30 04:34:23 +03:00
|
|
|
|
|
|
|
while (ISSPACE(*s)) s++;
|
|
|
|
if (!*s) return;
|
2017-08-10 08:54:56 +03:00
|
|
|
argstr = rb_str_tmp_new((len = strlen(s)) + (envopt!=0));
|
2008-10-30 04:34:23 +03:00
|
|
|
argary = rb_str_tmp_new(0);
|
|
|
|
|
|
|
|
p = RSTRING_PTR(argstr);
|
2017-08-10 08:54:56 +03:00
|
|
|
if (envopt) *p++ = ' ';
|
* dir.c, dln.c, parse.y, re.c, ruby.c, sprintf.c, strftime.c,
string.c, util.c, variable.c: use strlcpy, memcpy and snprintf
instead of strcpy, strncpy and sprintf.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22984 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2009-03-17 04:29:17 +03:00
|
|
|
memcpy(p, s, len + 1);
|
2008-10-30 04:34:23 +03:00
|
|
|
ap = 0;
|
|
|
|
rb_str_cat(argary, (char *)&ap, sizeof(ap));
|
|
|
|
while (*p) {
|
|
|
|
ap = p;
|
|
|
|
rb_str_cat(argary, (char *)&ap, sizeof(ap));
|
|
|
|
while (*p && !ISSPACE(*p)) ++p;
|
|
|
|
if (!*p) break;
|
|
|
|
*p++ = '\0';
|
2009-01-21 07:59:20 +03:00
|
|
|
while (ISSPACE(*p)) ++p;
|
2008-10-30 04:34:23 +03:00
|
|
|
}
|
|
|
|
argc = RSTRING_LEN(argary) / sizeof(ap);
|
|
|
|
ap = 0;
|
|
|
|
rb_str_cat(argary, (char *)&ap, sizeof(ap));
|
2018-05-10 05:54:04 +03:00
|
|
|
argv = ptr = ALLOC_N(char *, argc);
|
|
|
|
MEMMOVE(argv, RSTRING_PTR(argary), char *, argc);
|
2008-10-30 04:34:23 +03:00
|
|
|
|
2017-08-10 08:54:56 +03:00
|
|
|
while ((i = proc_options(argc, argv, opt, envopt)) > 1 && envopt && (argc -= i) > 0) {
|
2008-10-30 04:34:23 +03:00
|
|
|
argv += i;
|
|
|
|
if (**argv != '-') {
|
|
|
|
*--*argv = '-';
|
|
|
|
}
|
|
|
|
if ((*argv)[1]) {
|
|
|
|
++argc;
|
|
|
|
--argv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-10 05:54:04 +03:00
|
|
|
ruby_xfree(ptr);
|
2008-10-30 04:34:23 +03:00
|
|
|
/* get rid of GC */
|
|
|
|
rb_str_resize(argary, 0);
|
|
|
|
rb_str_resize(argstr, 0);
|
1999-10-21 11:52:15 +04:00
|
|
|
}
|
|
|
|
|
2015-09-27 08:47:24 +03:00
|
|
|
static int
|
|
|
|
name_match_p(const char *name, const char *str, size_t len)
|
|
|
|
{
|
|
|
|
if (len == 0) return 0;
|
2019-07-14 15:56:39 +03:00
|
|
|
while (1) {
|
2015-09-27 08:47:24 +03:00
|
|
|
while (TOLOWER(*str) == *name) {
|
|
|
|
if (!--len || !*++str) return 1;
|
|
|
|
++name;
|
|
|
|
}
|
|
|
|
if (*str != '-' && *str != '_') return 0;
|
|
|
|
while (ISALNUM(*name)) name++;
|
|
|
|
if (*name != '-' && *name != '_') return 0;
|
|
|
|
++name;
|
|
|
|
++str;
|
2019-07-14 15:56:39 +03:00
|
|
|
}
|
2015-09-27 08:47:24 +03:00
|
|
|
}
|
|
|
|
|
2008-02-24 00:49:15 +03:00
|
|
|
#define NAME_MATCH_P(name, str, len) \
|
2015-09-27 08:47:24 +03:00
|
|
|
((len) < (int)sizeof(name) && name_match_p((name), (str), (len)))
|
2008-02-24 00:49:15 +03:00
|
|
|
|
|
|
|
#define UNSET_WHEN(name, bit, str, len) \
|
2010-12-28 01:37:59 +03:00
|
|
|
if (NAME_MATCH_P((name), (str), (len))) { \
|
2008-02-24 00:49:15 +03:00
|
|
|
*(unsigned int *)arg &= ~(bit); \
|
|
|
|
return; \
|
2008-02-24 00:13:05 +03:00
|
|
|
}
|
|
|
|
|
2008-02-24 00:49:15 +03:00
|
|
|
#define SET_WHEN(name, bit, str, len) \
|
2010-12-28 01:37:59 +03:00
|
|
|
if (NAME_MATCH_P((name), (str), (len))) { \
|
2008-02-24 00:49:15 +03:00
|
|
|
*(unsigned int *)arg |= (bit); \
|
|
|
|
return; \
|
2008-02-24 00:13:05 +03:00
|
|
|
}
|
|
|
|
|
2016-03-08 18:21:22 +03:00
|
|
|
#define LITERAL_NAME_ELEMENT(name) #name
|
2016-02-09 11:32:20 +03:00
|
|
|
|
2008-02-24 00:13:05 +03:00
|
|
|
static void
|
2015-11-19 11:56:12 +03:00
|
|
|
feature_option(const char *str, int len, void *arg, const unsigned int enable)
|
2008-02-24 00:13:05 +03:00
|
|
|
{
|
2016-03-08 18:21:22 +03:00
|
|
|
static const char list[] = EACH_FEATURES(LITERAL_NAME_ELEMENT, ", ");
|
2019-03-30 17:31:35 +03:00
|
|
|
ruby_features_t *argp = arg;
|
2015-11-19 11:56:12 +03:00
|
|
|
unsigned int mask = ~0U;
|
2016-02-08 04:30:22 +03:00
|
|
|
unsigned int set = 0U;
|
2019-03-30 17:31:35 +03:00
|
|
|
#if AMBIGUOUS_FEATURE_NAMES
|
2016-02-08 04:30:22 +03:00
|
|
|
int matched = 0;
|
2019-03-30 17:31:35 +03:00
|
|
|
# define FEATURE_FOUND ++matched
|
2016-02-08 04:30:22 +03:00
|
|
|
#else
|
2019-03-30 17:31:35 +03:00
|
|
|
# define FEATURE_FOUND goto found
|
2016-02-08 04:30:22 +03:00
|
|
|
#endif
|
2019-03-30 17:31:35 +03:00
|
|
|
#define SET_FEATURE(bit) \
|
|
|
|
if (NAME_MATCH_P(#bit, str, len)) {set |= mask = FEATURE_BIT(bit); FEATURE_FOUND;}
|
2016-03-08 18:21:22 +03:00
|
|
|
EACH_FEATURES(SET_FEATURE, ;);
|
2008-02-24 00:49:15 +03:00
|
|
|
if (NAME_MATCH_P("all", str, len)) {
|
2015-11-19 11:56:12 +03:00
|
|
|
found:
|
2019-03-30 17:31:35 +03:00
|
|
|
FEATURE_SET_TO(*argp, mask, (mask & enable));
|
2008-02-24 00:49:15 +03:00
|
|
|
return;
|
|
|
|
}
|
2016-02-08 04:30:22 +03:00
|
|
|
#if AMBIGUOUS_FEATURE_NAMES
|
|
|
|
if (matched == 1) goto found;
|
|
|
|
if (matched > 1) {
|
|
|
|
VALUE mesg = rb_sprintf("ambiguous feature: `%.*s' (", len, str);
|
2016-02-09 08:47:12 +03:00
|
|
|
#define ADD_FEATURE_NAME(bit) \
|
2016-02-08 04:30:22 +03:00
|
|
|
if (FEATURE_BIT(bit) & set) { \
|
|
|
|
rb_str_cat_cstr(mesg, #bit); \
|
|
|
|
if (--matched) rb_str_cat_cstr(mesg, ", "); \
|
|
|
|
}
|
2016-03-08 18:21:22 +03:00
|
|
|
EACH_FEATURES(ADD_FEATURE_NAME, ;);
|
2016-02-08 04:30:22 +03:00
|
|
|
rb_str_cat_cstr(mesg, ")");
|
|
|
|
rb_exc_raise(rb_exc_new_str(rb_eRuntimeError, mesg));
|
2016-02-09 08:47:12 +03:00
|
|
|
#undef ADD_FEATURE_NAME
|
2016-02-08 04:30:22 +03:00
|
|
|
}
|
|
|
|
#endif
|
2015-11-19 11:56:12 +03:00
|
|
|
rb_warn("unknown argument for --%s: `%.*s'",
|
|
|
|
enable ? "enable" : "disable", len, str);
|
2016-03-08 18:21:22 +03:00
|
|
|
rb_warn("features are [%.*s].", (int)strlen(list), list);
|
2015-11-19 11:56:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
enable_option(const char *str, int len, void *arg)
|
|
|
|
{
|
|
|
|
feature_option(str, len, arg, ~0U);
|
2008-02-24 00:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
disable_option(const char *str, int len, void *arg)
|
|
|
|
{
|
2015-11-19 11:56:12 +03:00
|
|
|
feature_option(str, len, arg, 0U);
|
2008-02-24 00:13:05 +03:00
|
|
|
}
|
|
|
|
|
2017-06-21 05:44:23 +03:00
|
|
|
RUBY_EXTERN const int ruby_patchlevel;
|
|
|
|
int ruby_env_debug_option(const char *str, int len, void *arg);
|
|
|
|
|
2015-11-21 12:57:31 +03:00
|
|
|
static void
|
|
|
|
debug_option(const char *str, int len, void *arg)
|
|
|
|
{
|
2016-03-08 18:21:22 +03:00
|
|
|
static const char list[] = EACH_DEBUG_FEATURES(LITERAL_NAME_ELEMENT, ", ");
|
2019-03-30 17:31:35 +03:00
|
|
|
ruby_features_t *argp = arg;
|
|
|
|
#define SET_WHEN_DEBUG(bit) \
|
|
|
|
if (NAME_MATCH_P(#bit, str, len)) { \
|
|
|
|
FEATURE_SET(*argp, DEBUG_BIT(bit)); \
|
|
|
|
return; \
|
|
|
|
}
|
2016-03-08 18:21:22 +03:00
|
|
|
EACH_DEBUG_FEATURES(SET_WHEN_DEBUG, ;);
|
2017-06-21 07:34:25 +03:00
|
|
|
#ifdef RUBY_DEVEL
|
2017-06-21 05:44:23 +03:00
|
|
|
if (ruby_patchlevel < 0 && ruby_env_debug_option(str, len, 0)) return;
|
2017-06-21 07:34:25 +03:00
|
|
|
#endif
|
2015-11-21 12:57:31 +03:00
|
|
|
rb_warn("unknown argument for --debug: `%.*s'", len, str);
|
2016-03-08 18:21:22 +03:00
|
|
|
rb_warn("debug features are [%.*s].", (int)strlen(list), list);
|
2015-11-21 12:57:31 +03:00
|
|
|
}
|
|
|
|
|
2008-05-20 07:13:52 +04:00
|
|
|
static void
|
|
|
|
dump_option(const char *str, int len, void *arg)
|
|
|
|
{
|
2016-03-08 18:21:22 +03:00
|
|
|
static const char list[] = EACH_DUMPS(LITERAL_NAME_ELEMENT, ", ");
|
2008-05-20 07:13:52 +04:00
|
|
|
#define SET_WHEN_DUMP(bit) SET_WHEN(#bit, DUMP_BIT(bit), str, len)
|
2016-03-08 18:21:22 +03:00
|
|
|
EACH_DUMPS(SET_WHEN_DUMP, ;);
|
2008-12-08 05:28:17 +03:00
|
|
|
rb_warn("don't know how to dump `%.*s',", len, str);
|
2016-03-08 18:21:22 +03:00
|
|
|
rb_warn("but only [%.*s].", (int)strlen(list), list);
|
2008-05-20 07:13:52 +04:00
|
|
|
}
|
|
|
|
|
2008-10-14 04:41:09 +04:00
|
|
|
static void
|
2009-05-17 04:47:49 +04:00
|
|
|
set_option_encoding_once(const char *type, VALUE *name, const char *e, long elen)
|
2008-10-14 04:41:09 +04:00
|
|
|
{
|
|
|
|
VALUE ename;
|
|
|
|
|
|
|
|
if (!elen) elen = strlen(e);
|
|
|
|
ename = rb_str_new(e, elen);
|
|
|
|
|
2008-12-08 04:32:36 +03:00
|
|
|
if (*name &&
|
|
|
|
rb_funcall(ename, rb_intern("casecmp"), 1, *name) != INT2FIX(0)) {
|
2008-10-14 04:41:09 +04:00
|
|
|
rb_raise(rb_eRuntimeError,
|
2013-06-24 15:31:21 +04:00
|
|
|
"%s already set to %"PRIsVALUE, type, *name);
|
2008-10-14 04:41:09 +04:00
|
|
|
}
|
2008-12-08 04:32:36 +03:00
|
|
|
*name = ename;
|
2008-10-14 04:41:09 +04:00
|
|
|
}
|
|
|
|
|
2008-12-08 04:32:36 +03:00
|
|
|
#define set_internal_encoding_once(opt, e, elen) \
|
2010-12-28 01:37:59 +03:00
|
|
|
set_option_encoding_once("default_internal", &(opt)->intern.enc.name, (e), (elen))
|
2008-12-08 04:32:36 +03:00
|
|
|
#define set_external_encoding_once(opt, e, elen) \
|
2010-12-28 01:37:59 +03:00
|
|
|
set_option_encoding_once("default_external", &(opt)->ext.enc.name, (e), (elen))
|
2008-12-08 04:32:36 +03:00
|
|
|
#define set_source_encoding_once(opt, e, elen) \
|
2010-12-28 01:37:59 +03:00
|
|
|
set_option_encoding_once("source", &(opt)->src.enc.name, (e), (elen))
|
2008-10-14 04:41:09 +04:00
|
|
|
|
2018-10-20 09:53:00 +03:00
|
|
|
#if USE_MJIT
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
static void
|
|
|
|
setup_mjit_options(const char *s, struct mjit_options *mjit_opt)
|
|
|
|
{
|
|
|
|
if (*s == 0) return;
|
|
|
|
else if (strcmp(s, "-warnings") == 0) {
|
|
|
|
mjit_opt->warnings = 1;
|
|
|
|
}
|
2019-12-01 11:56:27 +03:00
|
|
|
else if (strncmp(s, "-debug=", 7) == 0) {
|
|
|
|
mjit_opt->debug_flags = strdup(s + 7);
|
|
|
|
}
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
else if (strcmp(s, "-debug") == 0) {
|
|
|
|
mjit_opt->debug = 1;
|
|
|
|
}
|
|
|
|
else if (strcmp(s, "-wait") == 0) {
|
|
|
|
mjit_opt->wait = 1;
|
|
|
|
}
|
|
|
|
else if (strcmp(s, "-save-temps") == 0) {
|
|
|
|
mjit_opt->save_temps = 1;
|
|
|
|
}
|
|
|
|
else if (strncmp(s, "-verbose=", 9) == 0) {
|
|
|
|
mjit_opt->verbose = atoi(s + 9);
|
|
|
|
}
|
|
|
|
else if (strncmp(s, "-max-cache=", 11) == 0) {
|
|
|
|
mjit_opt->max_cache_size = atoi(s + 11);
|
|
|
|
}
|
|
|
|
else if (strncmp(s, "-min-calls=", 11) == 0) {
|
|
|
|
mjit_opt->min_calls = atoi(s + 11);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rb_raise(rb_eRuntimeError,
|
|
|
|
"invalid MJIT option `%s' (--help will show valid MJIT options)", s + 1);
|
|
|
|
}
|
|
|
|
}
|
2018-10-20 09:53:00 +03:00
|
|
|
#endif
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
|
2009-05-17 04:47:49 +04:00
|
|
|
static long
|
2016-08-19 13:44:53 +03:00
|
|
|
proc_options(long argc, char **argv, ruby_cmdline_options_t *opt, int envopt)
|
1999-10-15 12:52:18 +04:00
|
|
|
{
|
2009-05-17 04:47:49 +04:00
|
|
|
long n, argc0 = argc;
|
2006-07-21 18:58:18 +04:00
|
|
|
const char *s;
|
2015-12-29 15:23:04 +03:00
|
|
|
int warning = opt->warning;
|
1999-10-16 14:33:06 +04:00
|
|
|
|
2017-08-09 14:03:55 +03:00
|
|
|
if (argc <= 0 || !argv)
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 12:12:18 +04:00
|
|
|
return 0;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2006-12-31 18:02:22 +03:00
|
|
|
for (argc--, argv++; argc > 0; argc--, argv++) {
|
2008-12-08 04:32:36 +03:00
|
|
|
const char *const arg = argv[0];
|
2012-11-23 19:00:55 +04:00
|
|
|
if (!arg || arg[0] != '-' || !arg[1])
|
2006-12-31 18:02:22 +03:00
|
|
|
break;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2008-12-08 04:32:36 +03:00
|
|
|
s = arg + 1;
|
1998-01-16 15:13:05 +03:00
|
|
|
reswitch:
|
|
|
|
switch (*s) {
|
|
|
|
case 'a':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
2009-09-13 15:18:51 +04:00
|
|
|
opt->do_split = TRUE;
|
1998-01-16 15:13:05 +03:00
|
|
|
s++;
|
|
|
|
goto reswitch;
|
|
|
|
|
|
|
|
case 'p':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
2009-09-13 15:18:51 +04:00
|
|
|
opt->do_print = TRUE;
|
1998-01-16 15:13:05 +03:00
|
|
|
/* through */
|
|
|
|
case 'n':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
2009-09-13 15:18:51 +04:00
|
|
|
opt->do_loop = TRUE;
|
1998-01-16 15:13:05 +03:00
|
|
|
s++;
|
|
|
|
goto reswitch;
|
|
|
|
|
|
|
|
case 'd':
|
1999-08-13 09:45:20 +04:00
|
|
|
ruby_debug = Qtrue;
|
1999-10-16 14:33:06 +04:00
|
|
|
ruby_verbose = Qtrue;
|
1998-01-16 15:13:05 +03:00
|
|
|
s++;
|
|
|
|
goto reswitch;
|
|
|
|
|
|
|
|
case 'y':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
2008-12-08 05:28:17 +03:00
|
|
|
opt->dump |= DUMP_BIT(yydebug);
|
1998-01-16 15:13:05 +03:00
|
|
|
s++;
|
|
|
|
goto reswitch;
|
|
|
|
|
|
|
|
case 'v':
|
2007-09-29 01:47:31 +04:00
|
|
|
if (opt->verbose) {
|
2001-02-27 10:52:11 +03:00
|
|
|
s++;
|
|
|
|
goto reswitch;
|
|
|
|
}
|
2012-08-09 13:33:49 +04:00
|
|
|
opt->dump |= DUMP_BIT(version_v);
|
2007-09-29 01:47:31 +04:00
|
|
|
opt->verbose = 1;
|
1998-01-16 15:13:05 +03:00
|
|
|
case 'w':
|
2015-12-29 13:12:48 +03:00
|
|
|
if (!opt->warning) {
|
2015-12-29 15:23:04 +03:00
|
|
|
warning = 1;
|
2015-12-29 13:12:48 +03:00
|
|
|
ruby_verbose = Qtrue;
|
|
|
|
}
|
1998-01-16 15:13:05 +03:00
|
|
|
s++;
|
|
|
|
goto reswitch;
|
|
|
|
|
2003-07-29 22:26:55 +04:00
|
|
|
case 'W':
|
2019-12-20 17:05:22 +03:00
|
|
|
if (s[1] == ':') {
|
|
|
|
unsigned int bits = 0;
|
|
|
|
static const char no_prefix[] = "no-";
|
|
|
|
int enable = strncmp(s += 2, no_prefix, sizeof(no_prefix)-1) != 0;
|
|
|
|
if (!enable) s += sizeof(no_prefix)-1;
|
|
|
|
size_t len = strlen(s);
|
|
|
|
if (NAME_MATCH_P("deprecated", s, len)) {
|
|
|
|
bits = 1U << RB_WARN_CATEGORY_DEPRECATED;
|
|
|
|
}
|
2019-12-20 17:51:17 +03:00
|
|
|
else if (NAME_MATCH_P("experimental", s, len)) {
|
|
|
|
bits = 1U << RB_WARN_CATEGORY_EXPERIMENTAL;
|
|
|
|
}
|
2019-12-20 17:05:22 +03:00
|
|
|
else {
|
|
|
|
rb_warn("unknown warning category: `%s'", s);
|
|
|
|
}
|
|
|
|
if (bits) FEATURE_SET_TO(opt->warn, bits, enable ? bits : 0);
|
|
|
|
break;
|
|
|
|
}
|
2015-12-29 13:39:53 +03:00
|
|
|
{
|
2009-03-14 12:25:20 +03:00
|
|
|
size_t numlen;
|
2003-07-29 22:26:55 +04:00
|
|
|
int v = 2; /* -W as -W2 */
|
|
|
|
|
|
|
|
if (*++s) {
|
|
|
|
v = scan_oct(s, 1, &numlen);
|
2006-12-31 18:02:22 +03:00
|
|
|
if (numlen == 0)
|
|
|
|
v = 1;
|
2003-07-29 22:26:55 +04:00
|
|
|
s += numlen;
|
|
|
|
}
|
2015-12-29 13:39:53 +03:00
|
|
|
if (!opt->warning) {
|
|
|
|
switch (v) {
|
|
|
|
case 0:
|
|
|
|
ruby_verbose = Qnil;
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
ruby_verbose = Qfalse;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ruby_verbose = Qtrue;
|
|
|
|
break;
|
|
|
|
}
|
2003-07-29 22:26:55 +04:00
|
|
|
}
|
2015-12-29 15:23:04 +03:00
|
|
|
warning = 1;
|
2003-07-29 22:26:55 +04:00
|
|
|
}
|
|
|
|
goto reswitch;
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
case 'c':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
2008-12-08 05:28:17 +03:00
|
|
|
opt->dump |= DUMP_BIT(syntax);
|
1998-01-16 15:13:05 +03:00
|
|
|
s++;
|
|
|
|
goto reswitch;
|
|
|
|
|
|
|
|
case 's':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
1998-01-16 15:13:05 +03:00
|
|
|
forbid_setid("-s");
|
2009-05-17 04:47:49 +04:00
|
|
|
if (!opt->sflag) opt->sflag = 1;
|
1998-01-16 15:13:05 +03:00
|
|
|
s++;
|
|
|
|
goto reswitch;
|
|
|
|
|
1999-08-13 09:45:20 +04:00
|
|
|
case 'h':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
2008-12-08 05:28:17 +03:00
|
|
|
opt->dump |= DUMP_BIT(usage);
|
|
|
|
goto switch_end;
|
1999-08-13 09:45:20 +04:00
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
case 'l':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
2009-09-13 15:18:51 +04:00
|
|
|
opt->do_line = TRUE;
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_output_rs = rb_rs;
|
1998-01-16 15:13:05 +03:00
|
|
|
s++;
|
|
|
|
goto reswitch;
|
|
|
|
|
|
|
|
case 'S':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
1998-01-16 15:13:05 +03:00
|
|
|
forbid_setid("-S");
|
2009-09-13 15:18:51 +04:00
|
|
|
opt->do_search = TRUE;
|
1998-01-16 15:13:05 +03:00
|
|
|
s++;
|
|
|
|
goto reswitch;
|
|
|
|
|
|
|
|
case 'e':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
1998-01-16 15:13:05 +03:00
|
|
|
forbid_setid("-e");
|
1999-08-13 09:45:20 +04:00
|
|
|
if (!*++s) {
|
2014-02-07 20:20:55 +04:00
|
|
|
if (!--argc)
|
|
|
|
rb_raise(rb_eRuntimeError, "no code specified for -e");
|
|
|
|
s = *++argv;
|
1999-08-13 09:45:20 +04:00
|
|
|
}
|
2007-09-29 01:47:31 +04:00
|
|
|
if (!opt->e_script) {
|
|
|
|
opt->e_script = rb_str_new(0, 0);
|
|
|
|
if (opt->script == 0)
|
|
|
|
opt->script = "-e";
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2007-09-29 01:47:31 +04:00
|
|
|
rb_str_cat2(opt->e_script, s);
|
|
|
|
rb_str_cat2(opt->e_script, "\n");
|
1998-01-16 15:13:05 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'r':
|
|
|
|
forbid_setid("-r");
|
|
|
|
if (*++s) {
|
2009-05-17 04:47:49 +04:00
|
|
|
add_modules(&opt->req_list, s);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2014-02-07 20:20:55 +04:00
|
|
|
else if (argc > 1) {
|
2009-05-17 04:47:49 +04:00
|
|
|
add_modules(&opt->req_list, argv[1]);
|
2006-12-31 18:02:22 +03:00
|
|
|
argc--, argv++;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'i':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
1998-01-16 15:13:05 +03:00
|
|
|
forbid_setid("-i");
|
2008-03-01 11:59:04 +03:00
|
|
|
ruby_set_inplace_mode(s + 1);
|
1998-01-16 15:13:05 +03:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 'x':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
2017-01-31 15:54:59 +03:00
|
|
|
forbid_setid("-x");
|
2009-09-13 15:18:51 +04:00
|
|
|
opt->xflag = TRUE;
|
1998-01-16 15:13:05 +03:00
|
|
|
s++;
|
|
|
|
if (*s && chdir(s) < 0) {
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_fatal("Can't chdir to %s", s);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2000-01-05 07:41:21 +03:00
|
|
|
case 'C':
|
1998-01-16 15:13:05 +03:00
|
|
|
case 'X':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
2014-02-07 20:20:55 +04:00
|
|
|
if (!*++s && (!--argc || !(s = *++argv) || !*s)) {
|
2000-01-05 07:41:21 +03:00
|
|
|
rb_fatal("Can't chdir");
|
|
|
|
}
|
|
|
|
if (chdir(s) < 0) {
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_fatal("Can't chdir to %s", s);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'F':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
1999-12-06 12:04:03 +03:00
|
|
|
if (*++s) {
|
2008-01-05 07:04:26 +03:00
|
|
|
rb_fs = rb_reg_new(s, strlen(s), 0);
|
1999-12-06 12:04:03 +03:00
|
|
|
}
|
1998-01-16 15:13:05 +03:00
|
|
|
break;
|
|
|
|
|
2007-10-17 00:07:20 +04:00
|
|
|
case 'E':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (!*++s && (!--argc || !(s = *++argv))) {
|
|
|
|
rb_raise(rb_eRuntimeError, "missing argument for -E");
|
|
|
|
}
|
2007-10-17 00:07:20 +04:00
|
|
|
goto encoding;
|
|
|
|
|
2008-10-13 03:03:17 +04:00
|
|
|
case 'U':
|
2008-10-14 04:41:09 +04:00
|
|
|
set_internal_encoding_once(opt, "UTF-8", 0);
|
2008-10-14 09:11:20 +04:00
|
|
|
++s;
|
|
|
|
goto reswitch;
|
2008-10-13 03:03:17 +04:00
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
case 'K':
|
1999-12-06 12:04:03 +03:00
|
|
|
if (*++s) {
|
2008-01-15 10:59:33 +03:00
|
|
|
const char *enc_name = 0;
|
2007-09-29 00:29:32 +04:00
|
|
|
switch (*s) {
|
|
|
|
case 'E': case 'e':
|
2008-01-15 10:59:33 +03:00
|
|
|
enc_name = "EUC-JP";
|
2007-09-29 00:29:32 +04:00
|
|
|
break;
|
|
|
|
case 'S': case 's':
|
2008-01-15 10:59:33 +03:00
|
|
|
enc_name = "Windows-31J";
|
2007-09-29 00:29:32 +04:00
|
|
|
break;
|
|
|
|
case 'U': case 'u':
|
2008-01-15 10:59:33 +03:00
|
|
|
enc_name = "UTF-8";
|
2007-09-29 00:29:32 +04:00
|
|
|
break;
|
|
|
|
case 'N': case 'n': case 'A': case 'a':
|
2008-01-23 19:08:04 +03:00
|
|
|
enc_name = "ASCII-8BIT";
|
2007-09-29 00:29:32 +04:00
|
|
|
break;
|
2007-10-16 09:48:40 +04:00
|
|
|
}
|
2008-01-15 10:59:33 +03:00
|
|
|
if (enc_name) {
|
2008-01-25 07:18:14 +03:00
|
|
|
opt->src.enc.name = rb_str_new2(enc_name);
|
2008-10-17 02:21:09 +04:00
|
|
|
if (!opt->ext.enc.name)
|
|
|
|
opt->ext.enc.name = opt->src.enc.name;
|
2007-09-29 00:29:32 +04:00
|
|
|
}
|
1999-12-06 12:04:03 +03:00
|
|
|
s++;
|
|
|
|
}
|
1998-01-16 15:13:05 +03:00
|
|
|
goto reswitch;
|
|
|
|
|
|
|
|
case 'T':
|
2019-09-21 05:06:22 +03:00
|
|
|
{
|
|
|
|
size_t numlen;
|
|
|
|
|
|
|
|
if (*++s) {
|
2019-11-18 06:00:19 +03:00
|
|
|
scan_oct(s, 2, &numlen);
|
2019-09-21 05:06:22 +03:00
|
|
|
s += numlen;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rb_warn("ruby -T will be removed in Ruby 3.0");
|
2002-05-22 16:32:15 +04:00
|
|
|
goto reswitch;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
|
|
|
case 'I':
|
|
|
|
forbid_setid("-I");
|
|
|
|
if (*++s)
|
2005-04-21 01:44:20 +04:00
|
|
|
ruby_incpush_expand(s);
|
2014-02-07 20:20:55 +04:00
|
|
|
else if (argc > 1) {
|
2005-04-21 01:44:20 +04:00
|
|
|
ruby_incpush_expand(argv[1]);
|
2006-12-31 18:02:22 +03:00
|
|
|
argc--, argv++;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2002-05-23 11:41:53 +04:00
|
|
|
break;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
|
|
|
case '0':
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt;
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2009-03-14 12:25:20 +03:00
|
|
|
size_t numlen;
|
1998-01-16 15:13:05 +03:00
|
|
|
int v;
|
|
|
|
char c;
|
|
|
|
|
|
|
|
v = scan_oct(s, 4, &numlen);
|
|
|
|
s += numlen;
|
2006-12-31 18:02:22 +03:00
|
|
|
if (v > 0377)
|
|
|
|
rb_rs = Qnil;
|
1998-01-16 15:13:05 +03:00
|
|
|
else if (v == 0 && numlen >= 2) {
|
2017-09-20 03:53:47 +03:00
|
|
|
rb_rs = rb_str_new2("");
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
c = v & 0xff;
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_rs = rb_str_new(&c, 1);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
goto reswitch;
|
|
|
|
|
|
|
|
case '-':
|
2003-01-16 10:38:40 +03:00
|
|
|
if (!s[1] || (s[1] == '\r' && !s[2])) {
|
2006-12-31 18:02:22 +03:00
|
|
|
argc--, argv++;
|
1998-01-16 15:13:05 +03:00
|
|
|
goto switch_end;
|
|
|
|
}
|
|
|
|
s++;
|
2008-10-30 04:34:23 +03:00
|
|
|
|
|
|
|
# define is_option_end(c, allow_hyphen) \
|
2010-12-28 01:37:59 +03:00
|
|
|
(!(c) || ((allow_hyphen) && (c) == '-') || (c) == '=')
|
2008-10-30 04:34:23 +03:00
|
|
|
# define check_envopt(name, allow_envopt) \
|
2010-12-28 01:37:59 +03:00
|
|
|
(((allow_envopt) || !envopt) ? (void)0 : \
|
2008-10-30 04:34:23 +03:00
|
|
|
rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --" name))
|
2015-11-21 12:57:31 +03:00
|
|
|
# define need_argument(name, s, needs_arg, next_arg) \
|
|
|
|
((*(s) ? !*++(s) : (next_arg) && (!argc || !((s) = argv[1]) || (--argc, ++argv, 0))) && (needs_arg) ? \
|
2008-10-30 04:34:23 +03:00
|
|
|
rb_raise(rb_eRuntimeError, "missing argument for --" name) \
|
|
|
|
: (void)0)
|
2013-02-27 12:08:10 +04:00
|
|
|
# define is_option_with_arg(name, allow_hyphen, allow_envopt) \
|
2015-11-21 12:57:31 +03:00
|
|
|
is_option_with_optarg(name, allow_hyphen, allow_envopt, Qtrue, Qtrue)
|
|
|
|
# define is_option_with_optarg(name, allow_hyphen, allow_envopt, needs_arg, next_arg) \
|
2010-12-28 01:37:59 +03:00
|
|
|
(strncmp((name), s, n = sizeof(name) - 1) == 0 && is_option_end(s[n], (allow_hyphen)) ? \
|
2013-02-27 12:08:10 +04:00
|
|
|
(check_envopt(name, (allow_envopt)), s += n, \
|
2015-11-21 12:57:31 +03:00
|
|
|
need_argument(name, s, needs_arg, next_arg), 1) : 0)
|
2008-10-30 04:34:23 +03:00
|
|
|
|
|
|
|
if (strcmp("copyright", s) == 0) {
|
|
|
|
if (envopt) goto noenvopt_long;
|
2008-12-08 05:28:17 +03:00
|
|
|
opt->dump |= DUMP_BIT(copyright);
|
2008-10-30 04:34:23 +03:00
|
|
|
}
|
2015-11-21 12:57:31 +03:00
|
|
|
else if (is_option_with_optarg("debug", Qtrue, Qtrue, Qfalse, Qfalse)) {
|
|
|
|
if (s && *s) {
|
|
|
|
ruby_each_words(s, debug_option, &opt->features);
|
|
|
|
}
|
2015-11-25 11:02:29 +03:00
|
|
|
else {
|
|
|
|
ruby_debug = Qtrue;
|
|
|
|
ruby_verbose = Qtrue;
|
|
|
|
}
|
2001-10-02 08:31:23 +04:00
|
|
|
}
|
2008-10-30 04:34:23 +03:00
|
|
|
else if (is_option_with_arg("enable", Qtrue, Qtrue)) {
|
2015-09-23 17:43:45 +03:00
|
|
|
ruby_each_words(s, enable_option, &opt->features);
|
2008-02-24 00:13:05 +03:00
|
|
|
}
|
2008-10-30 04:34:23 +03:00
|
|
|
else if (is_option_with_arg("disable", Qtrue, Qtrue)) {
|
2015-09-23 17:43:45 +03:00
|
|
|
ruby_each_words(s, disable_option, &opt->features);
|
2008-02-24 00:13:05 +03:00
|
|
|
}
|
2008-10-30 04:34:23 +03:00
|
|
|
else if (is_option_with_arg("encoding", Qfalse, Qtrue)) {
|
2008-10-07 21:39:44 +04:00
|
|
|
char *p;
|
2007-10-17 00:07:20 +04:00
|
|
|
encoding:
|
2008-12-08 04:32:36 +03:00
|
|
|
do {
|
|
|
|
# define set_encoding_part(type) \
|
|
|
|
if (!(p = strchr(s, ':'))) { \
|
|
|
|
set_##type##_encoding_once(opt, s, 0); \
|
|
|
|
break; \
|
|
|
|
} \
|
|
|
|
else if (p > s) { \
|
|
|
|
set_##type##_encoding_once(opt, s, p-s); \
|
|
|
|
}
|
|
|
|
set_encoding_part(external);
|
|
|
|
if (!*(s = ++p)) break;
|
|
|
|
set_encoding_part(internal);
|
|
|
|
if (!*(s = ++p)) break;
|
2011-04-15 18:42:36 +04:00
|
|
|
#if defined ALLOW_DEFAULT_SOURCE_ENCODING && ALLOW_DEFAULT_SOURCE_ENCODING
|
2008-12-08 05:15:47 +03:00
|
|
|
set_encoding_part(source);
|
|
|
|
if (!*(s = ++p)) break;
|
|
|
|
#endif
|
2008-12-08 04:32:36 +03:00
|
|
|
rb_raise(rb_eRuntimeError, "extra argument for %s: %s",
|
|
|
|
(arg[1] == '-' ? "--encoding" : "-E"), s);
|
|
|
|
# undef set_encoding_part
|
|
|
|
} while (0);
|
|
|
|
}
|
|
|
|
else if (is_option_with_arg("internal-encoding", Qfalse, Qtrue)) {
|
|
|
|
set_internal_encoding_once(opt, s, 0);
|
|
|
|
}
|
|
|
|
else if (is_option_with_arg("external-encoding", Qfalse, Qtrue)) {
|
|
|
|
set_external_encoding_once(opt, s, 0);
|
2007-10-17 00:07:20 +04:00
|
|
|
}
|
2011-04-15 18:42:36 +04:00
|
|
|
#if defined ALLOW_DEFAULT_SOURCE_ENCODING && ALLOW_DEFAULT_SOURCE_ENCODING
|
2008-12-08 05:15:47 +03:00
|
|
|
else if (is_option_with_arg("source-encoding", Qfalse, Qtrue)) {
|
|
|
|
set_source_encoding_once(opt, s, 0);
|
|
|
|
}
|
|
|
|
#endif
|
2008-10-30 04:34:23 +03:00
|
|
|
else if (strcmp("version", s) == 0) {
|
|
|
|
if (envopt) goto noenvopt_long;
|
2008-12-08 05:28:17 +03:00
|
|
|
opt->dump |= DUMP_BIT(version);
|
2008-10-30 04:34:23 +03:00
|
|
|
}
|
1999-10-16 14:33:06 +04:00
|
|
|
else if (strcmp("verbose", s) == 0) {
|
2007-09-29 01:47:31 +04:00
|
|
|
opt->verbose = 1;
|
1999-10-16 14:33:06 +04:00
|
|
|
ruby_verbose = Qtrue;
|
|
|
|
}
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
else if (strncmp("jit", s, 3) == 0) {
|
2018-10-20 09:53:00 +03:00
|
|
|
#if USE_MJIT
|
2019-03-30 17:31:35 +03:00
|
|
|
FEATURE_SET(opt->features, FEATURE_BIT(jit));
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
setup_mjit_options(s + 3, &opt->mjit);
|
2018-10-20 09:53:00 +03:00
|
|
|
#else
|
2018-10-21 05:38:26 +03:00
|
|
|
rb_warn("MJIT support is disabled.");
|
2018-10-20 09:53:00 +03:00
|
|
|
#endif
|
mjit.c: merge MJIT infrastructure
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-04 09:58:09 +03:00
|
|
|
}
|
2008-10-30 04:34:23 +03:00
|
|
|
else if (strcmp("yydebug", s) == 0) {
|
|
|
|
if (envopt) goto noenvopt_long;
|
2008-12-08 05:28:17 +03:00
|
|
|
opt->dump |= DUMP_BIT(yydebug);
|
2008-10-30 04:34:23 +03:00
|
|
|
}
|
|
|
|
else if (is_option_with_arg("dump", Qfalse, Qfalse)) {
|
2008-05-20 07:13:52 +04:00
|
|
|
ruby_each_words(s, dump_option, &opt->dump);
|
|
|
|
}
|
1999-08-13 09:45:20 +04:00
|
|
|
else if (strcmp("help", s) == 0) {
|
2008-10-30 04:34:23 +03:00
|
|
|
if (envopt) goto noenvopt_long;
|
2012-11-23 12:31:52 +04:00
|
|
|
opt->dump |= DUMP_BIT(help);
|
2008-12-08 05:28:17 +03:00
|
|
|
goto switch_end;
|
1999-08-13 09:45:20 +04:00
|
|
|
}
|
2020-05-14 19:22:56 +03:00
|
|
|
else if (is_option_with_arg("backtrace-limit", Qfalse, Qfalse)) {
|
|
|
|
char *e;
|
|
|
|
long n = strtol(s, &e, 10);
|
|
|
|
if (errno == ERANGE || n < 0 || *e) rb_raise(rb_eRuntimeError, "wrong limit for backtrace length");
|
|
|
|
rb_backtrace_length_limit = n;
|
|
|
|
}
|
1998-01-16 15:13:05 +03:00
|
|
|
else {
|
2007-09-29 01:47:31 +04:00
|
|
|
rb_raise(rb_eRuntimeError,
|
|
|
|
"invalid option --%s (-h will show valid options)", s);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2005-01-15 08:58:02 +03:00
|
|
|
case '\r':
|
2006-12-31 18:02:22 +03:00
|
|
|
if (!s[1])
|
|
|
|
break;
|
2005-01-15 08:58:02 +03:00
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
default:
|
2005-01-15 08:58:02 +03:00
|
|
|
{
|
2019-01-08 12:08:31 +03:00
|
|
|
rb_raise(rb_eRuntimeError,
|
2007-12-08 11:11:52 +03:00
|
|
|
"invalid option -%c (-h will show valid options)",
|
|
|
|
(int)(unsigned char)*s);
|
2005-01-15 08:58:02 +03:00
|
|
|
}
|
2007-09-29 01:47:31 +04:00
|
|
|
goto switch_end;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2008-10-30 04:34:23 +03:00
|
|
|
noenvopt:
|
|
|
|
/* "EIdvwWrKU" only */
|
|
|
|
rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: -%c", *s);
|
|
|
|
break;
|
|
|
|
|
|
|
|
noenvopt_long:
|
|
|
|
rb_raise(rb_eRuntimeError, "invalid switch in RUBYOPT: --%s", s);
|
|
|
|
break;
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
case 0:
|
|
|
|
break;
|
2008-10-30 04:34:23 +03:00
|
|
|
# undef is_option_end
|
|
|
|
# undef check_envopt
|
|
|
|
# undef need_argument
|
|
|
|
# undef is_option_with_arg
|
2013-02-27 12:08:10 +04:00
|
|
|
# undef is_option_with_optarg
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_end:
|
2015-12-29 15:23:04 +03:00
|
|
|
if (warning) opt->warning = warning;
|
2007-09-29 01:47:31 +04:00
|
|
|
return argc0 - argc;
|
|
|
|
}
|
|
|
|
|
2019-12-10 10:19:13 +03:00
|
|
|
void Init_builtin_features(void);
|
|
|
|
|
2007-11-10 12:22:59 +03:00
|
|
|
static void
|
2011-01-15 03:48:16 +03:00
|
|
|
ruby_init_prelude(void)
|
2007-11-10 12:22:59 +03:00
|
|
|
{
|
2019-12-10 10:19:13 +03:00
|
|
|
Init_builtin_features();
|
2010-03-12 01:15:11 +03:00
|
|
|
rb_const_remove(rb_cObject, rb_intern_const("TMP_RUBY_PREFIX"));
|
2007-11-10 12:22:59 +03:00
|
|
|
}
|
|
|
|
|
2020-05-16 11:37:28 +03:00
|
|
|
void rb_call_builtin_inits(void);
|
|
|
|
|
|
|
|
static void
|
|
|
|
ruby_opt_init(ruby_cmdline_options_t *opt)
|
|
|
|
{
|
|
|
|
if (opt->dump & dump_exit_bits) return;
|
|
|
|
|
|
|
|
if (opt->features.set & FEATURE_BIT(gems)) {
|
|
|
|
rb_define_module("Gem");
|
|
|
|
if (opt->features.set & FEATURE_BIT(did_you_mean)) {
|
|
|
|
rb_define_module("DidYouMean");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Init_ext(); /* load statically linked extensions before rubygems */
|
|
|
|
rb_call_builtin_inits();
|
|
|
|
ruby_init_prelude();
|
|
|
|
|
|
|
|
ruby_set_script_name(opt->script_name);
|
|
|
|
require_libraries(&opt->req_list);
|
|
|
|
}
|
|
|
|
|
2008-01-09 09:54:26 +03:00
|
|
|
static int
|
|
|
|
opt_enc_index(VALUE enc_name)
|
|
|
|
{
|
|
|
|
const char *s = RSTRING_PTR(enc_name);
|
|
|
|
int i = rb_enc_find_index(s);
|
|
|
|
|
|
|
|
if (i < 0) {
|
|
|
|
rb_raise(rb_eRuntimeError, "unknown encoding name - %s", s);
|
|
|
|
}
|
|
|
|
else if (rb_enc_dummy_p(rb_enc_from_index(i))) {
|
|
|
|
rb_raise(rb_eRuntimeError, "dummy encoding is not acceptable - %s ", s);
|
|
|
|
}
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
2013-08-07 18:12:08 +04:00
|
|
|
#define rb_progname (GET_VM()->progname)
|
|
|
|
#define rb_orig_progname (GET_VM()->orig_progname)
|
2008-06-10 06:25:18 +04:00
|
|
|
VALUE rb_argv0;
|
2018-11-10 14:43:02 +03:00
|
|
|
VALUE rb_e_script;
|
2008-01-25 10:11:18 +03:00
|
|
|
|
2008-12-08 05:28:17 +03:00
|
|
|
static VALUE
|
2019-08-27 05:16:52 +03:00
|
|
|
false_value(ID _x, VALUE *_y)
|
2008-12-08 05:28:17 +03:00
|
|
|
{
|
|
|
|
return Qfalse;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
2019-08-27 05:16:52 +03:00
|
|
|
true_value(ID _x, VALUE *_y)
|
2008-12-08 05:28:17 +03:00
|
|
|
{
|
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define rb_define_readonly_boolean(name, val) \
|
|
|
|
rb_define_virtual_variable((name), (val) ? true_value : false_value, 0)
|
|
|
|
|
2008-12-15 17:46:50 +03:00
|
|
|
static VALUE
|
* cont.c (rb_fiber_current), dln.c (dln_print_undef, dln_undefined),
eval.c (rb_iterator_p, rb_need_block), load.c: (Init_load), ruby.c
(uscore_get, rb_f_chop), st.c (stat_col), signal.c
(rb_signal_buff_size, ruby_sig_finalize), thread.c
(rb_thread_sleep_forever, rb_thread_sleep_deadly, rb_thread_alone):
protoized.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@21929 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2009-02-01 15:51:44 +03:00
|
|
|
uscore_get(void)
|
2008-12-15 17:46:50 +03:00
|
|
|
{
|
|
|
|
VALUE line;
|
|
|
|
|
|
|
|
line = rb_lastline_get();
|
2011-09-29 15:07:45 +04:00
|
|
|
if (!RB_TYPE_P(line, T_STRING)) {
|
2008-12-15 17:46:50 +03:00
|
|
|
rb_raise(rb_eTypeError, "$_ value need to be String (%s given)",
|
|
|
|
NIL_P(line) ? "nil" : rb_obj_classname(line));
|
|
|
|
}
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* sub(pattern, replacement) -> $_
|
2013-04-24 08:47:31 +04:00
|
|
|
* sub(pattern) {|...| block } -> $_
|
2009-01-21 07:59:20 +03:00
|
|
|
*
|
2008-12-15 17:46:50 +03:00
|
|
|
* Equivalent to <code>$_.sub(<i>args</i>)</code>, except that
|
|
|
|
* <code>$_</code> will be updated if substitution occurs.
|
|
|
|
* Available only when -p/-n command line option specified.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
2019-08-28 12:19:11 +03:00
|
|
|
rb_f_sub(int argc, VALUE *argv, VALUE _)
|
2008-12-15 17:46:50 +03:00
|
|
|
{
|
2012-10-14 07:30:50 +04:00
|
|
|
VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("sub"), argc, argv);
|
2008-12-15 17:46:50 +03:00
|
|
|
rb_lastline_set(str);
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2013-04-24 08:47:31 +04:00
|
|
|
* gsub(pattern, replacement) -> $_
|
|
|
|
* gsub(pattern) {|...| block } -> $_
|
2009-01-21 07:59:20 +03:00
|
|
|
*
|
2008-12-15 17:46:50 +03:00
|
|
|
* Equivalent to <code>$_.gsub...</code>, except that <code>$_</code>
|
2013-04-24 08:47:31 +04:00
|
|
|
* will be updated if substitution occurs.
|
2008-12-15 17:46:50 +03:00
|
|
|
* Available only when -p/-n command line option specified.
|
2009-01-21 07:59:20 +03:00
|
|
|
*
|
2008-12-15 17:46:50 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
2019-08-28 12:19:11 +03:00
|
|
|
rb_f_gsub(int argc, VALUE *argv, VALUE _)
|
2008-12-15 17:46:50 +03:00
|
|
|
{
|
2012-10-14 07:30:50 +04:00
|
|
|
VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("gsub"), argc, argv);
|
2008-12-15 17:46:50 +03:00
|
|
|
rb_lastline_set(str);
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2013-04-24 08:47:31 +04:00
|
|
|
* chop -> $_
|
2009-01-21 07:59:20 +03:00
|
|
|
*
|
2008-12-15 17:46:50 +03:00
|
|
|
* Equivalent to <code>($_.dup).chop!</code>, except <code>nil</code>
|
2019-03-28 06:33:35 +03:00
|
|
|
* is never returned. See String#chop!.
|
2008-12-15 17:46:50 +03:00
|
|
|
* Available only when -p/-n command line option specified.
|
2009-01-21 07:59:20 +03:00
|
|
|
*
|
2008-12-15 17:46:50 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
2019-08-28 12:19:11 +03:00
|
|
|
rb_f_chop(VALUE _)
|
2008-12-15 17:46:50 +03:00
|
|
|
{
|
2012-10-14 07:30:50 +04:00
|
|
|
VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("chop"), 0, 0);
|
2008-12-15 17:46:50 +03:00
|
|
|
rb_lastline_set(str);
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-05-18 01:07:33 +04:00
|
|
|
* chomp -> $_
|
|
|
|
* chomp(string) -> $_
|
2009-01-21 07:59:20 +03:00
|
|
|
*
|
2008-12-15 17:46:50 +03:00
|
|
|
* Equivalent to <code>$_ = $_.chomp(<em>string</em>)</code>. See
|
2019-03-28 06:33:35 +03:00
|
|
|
* String#chomp.
|
2008-12-15 17:46:50 +03:00
|
|
|
* Available only when -p/-n command line option specified.
|
2009-01-21 07:59:20 +03:00
|
|
|
*
|
2008-12-15 17:46:50 +03:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
2019-08-28 12:19:11 +03:00
|
|
|
rb_f_chomp(int argc, VALUE *argv, VALUE _)
|
2008-12-15 17:46:50 +03:00
|
|
|
{
|
2012-10-14 07:30:50 +04:00
|
|
|
VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("chomp"), argc, argv);
|
2008-12-15 17:46:50 +03:00
|
|
|
rb_lastline_set(str);
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2020-04-12 06:56:17 +03:00
|
|
|
static void
|
|
|
|
setup_pager_env(void)
|
|
|
|
{
|
|
|
|
if (!getenv("LESS")) ruby_setenv("LESS", "-R"); // Output "raw" control characters.
|
|
|
|
}
|
|
|
|
|
2007-10-03 05:06:57 +04:00
|
|
|
static VALUE
|
2016-08-19 13:44:53 +03:00
|
|
|
process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
|
2007-09-29 01:47:31 +04:00
|
|
|
{
|
2017-10-29 18:51:23 +03:00
|
|
|
rb_ast_t *ast = 0;
|
2007-09-29 01:47:31 +04:00
|
|
|
VALUE parser;
|
2017-06-08 05:07:42 +03:00
|
|
|
VALUE script_name;
|
2015-07-22 01:52:59 +03:00
|
|
|
const rb_iseq_t *iseq;
|
2016-04-24 06:42:25 +03:00
|
|
|
rb_encoding *enc, *lenc;
|
2016-04-26 17:35:24 +03:00
|
|
|
#if UTF8_PATH
|
|
|
|
rb_encoding *uenc, *ienc = 0;
|
|
|
|
#endif
|
2007-09-29 01:47:31 +04:00
|
|
|
const char *s;
|
2008-05-08 01:43:54 +04:00
|
|
|
char fbuf[MAXPATHLEN];
|
2009-06-22 09:35:51 +04:00
|
|
|
int i = (int)proc_options(argc, argv, opt, 0);
|
2016-12-07 17:39:24 +03:00
|
|
|
unsigned int dump = opt->dump & dump_exit_bits;
|
2007-09-29 01:47:31 +04:00
|
|
|
|
2012-11-23 12:31:52 +04:00
|
|
|
if (opt->dump & (DUMP_BIT(usage)|DUMP_BIT(help))) {
|
2020-03-27 17:18:42 +03:00
|
|
|
int tty = isatty(1);
|
2017-08-09 14:03:55 +03:00
|
|
|
const char *const progname =
|
|
|
|
(argc > 0 && argv && argv[0] ? argv[0] :
|
|
|
|
origarg.argc > 0 && origarg.argv && origarg.argv[0] ? origarg.argv[0] :
|
|
|
|
ruby_engine);
|
2020-04-12 07:00:27 +03:00
|
|
|
int columns = 0;
|
2020-03-27 17:18:42 +03:00
|
|
|
if ((opt->dump & DUMP_BIT(help)) && tty) {
|
2020-02-04 03:47:58 +03:00
|
|
|
const char *pager_env = getenv("RUBY_PAGER");
|
|
|
|
if (!pager_env) pager_env = getenv("PAGER");
|
2020-03-27 17:18:42 +03:00
|
|
|
if (pager_env && *pager_env && isatty(0)) {
|
2020-04-12 07:00:27 +03:00
|
|
|
const char *columns_env = getenv("COLUMNS");
|
|
|
|
if (columns_env) columns = atoi(columns_env);
|
2020-02-04 03:47:58 +03:00
|
|
|
VALUE pager = rb_str_new_cstr(pager_env);
|
2020-02-04 05:28:20 +03:00
|
|
|
#ifdef HAVE_WORKING_FORK
|
2020-02-04 03:47:58 +03:00
|
|
|
int fds[2];
|
|
|
|
if (rb_pipe(fds) == 0) {
|
2020-05-02 15:34:10 +03:00
|
|
|
rb_pid_t pid = rb_fork();
|
2020-02-04 03:47:58 +03:00
|
|
|
if (pid > 0) {
|
|
|
|
/* exec PAGER with reading from child */
|
|
|
|
dup2(fds[0], 0);
|
|
|
|
}
|
|
|
|
else if (pid == 0) {
|
|
|
|
/* send the help message to the parent PAGER */
|
|
|
|
dup2(fds[1], 1);
|
|
|
|
dup2(fds[1], 2);
|
|
|
|
}
|
|
|
|
close(fds[0]);
|
|
|
|
close(fds[1]);
|
|
|
|
if (pid > 0) {
|
2020-04-12 06:56:17 +03:00
|
|
|
setup_pager_env();
|
2020-02-04 03:47:58 +03:00
|
|
|
rb_f_exec(1, &pager);
|
|
|
|
kill(SIGTERM, pid);
|
|
|
|
rb_waitpid(pid, 0, 0);
|
|
|
|
}
|
|
|
|
}
|
2020-02-04 05:28:20 +03:00
|
|
|
#else
|
2020-04-12 06:56:17 +03:00
|
|
|
setup_pager_env();
|
2020-02-04 05:28:20 +03:00
|
|
|
VALUE port = rb_io_popen(pager, rb_str_new_lit("w"), Qnil, Qnil);
|
|
|
|
if (!NIL_P(port)) {
|
|
|
|
int oldout = dup(1);
|
|
|
|
int olderr = dup(2);
|
|
|
|
int fd = RFILE(port)->fptr->fd;
|
|
|
|
dup2(fd, 1);
|
|
|
|
dup2(fd, 2);
|
2020-03-27 17:18:42 +03:00
|
|
|
/* more.com doesn't support CSI sequence */
|
2020-04-12 07:00:27 +03:00
|
|
|
usage(progname, 1, 0, columns);
|
2020-02-04 05:28:20 +03:00
|
|
|
fflush(stdout);
|
|
|
|
dup2(oldout, 1);
|
|
|
|
dup2(olderr, 2);
|
|
|
|
rb_io_close(port);
|
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
#endif
|
2020-02-04 03:47:58 +03:00
|
|
|
}
|
|
|
|
}
|
2020-04-12 07:00:27 +03:00
|
|
|
usage(progname, (opt->dump & DUMP_BIT(help)), tty, columns);
|
2008-12-08 05:28:17 +03:00
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
|
2017-08-09 14:03:55 +03:00
|
|
|
argc -= i;
|
|
|
|
argv += i;
|
|
|
|
|
2019-09-21 05:06:22 +03:00
|
|
|
if ((opt->features.set & FEATURE_BIT(rubyopt)) && (s = getenv("RUBYOPT"))) {
|
2008-01-25 07:18:14 +03:00
|
|
|
VALUE src_enc_name = opt->src.enc.name;
|
|
|
|
VALUE ext_enc_name = opt->ext.enc.name;
|
2008-10-07 21:39:44 +04:00
|
|
|
VALUE int_enc_name = opt->intern.enc.name;
|
2019-03-30 17:31:35 +03:00
|
|
|
ruby_features_t feat = opt->features;
|
2019-12-20 17:05:22 +03:00
|
|
|
ruby_features_t warn = opt->warn;
|
2008-01-09 09:54:26 +03:00
|
|
|
|
2008-10-14 04:41:09 +04:00
|
|
|
opt->src.enc.name = opt->ext.enc.name = opt->intern.enc.name = 0;
|
2008-10-30 04:34:23 +03:00
|
|
|
moreswitches(s, opt, 1);
|
2008-01-25 07:18:14 +03:00
|
|
|
if (src_enc_name)
|
|
|
|
opt->src.enc.name = src_enc_name;
|
|
|
|
if (ext_enc_name)
|
|
|
|
opt->ext.enc.name = ext_enc_name;
|
2008-10-07 21:39:44 +04:00
|
|
|
if (int_enc_name)
|
|
|
|
opt->intern.enc.name = int_enc_name;
|
2019-12-20 16:50:46 +03:00
|
|
|
FEATURE_SET_RESTORE(opt->features, feat);
|
2019-12-20 17:05:22 +03:00
|
|
|
FEATURE_SET_RESTORE(opt->warn, warn);
|
1999-10-21 11:52:15 +04:00
|
|
|
}
|
|
|
|
|
2012-07-04 20:01:01 +04:00
|
|
|
if (opt->src.enc.name)
|
|
|
|
rb_warning("-K is specified; it is for 1.8 compatibility and may cause odd behavior");
|
|
|
|
|
2018-10-20 09:53:00 +03:00
|
|
|
#if USE_MJIT
|
2019-03-30 17:31:35 +03:00
|
|
|
if (opt->features.set & FEATURE_BIT(jit)) {
|
2018-07-18 15:45:54 +03:00
|
|
|
opt->mjit.on = TRUE; /* set mjit.on for ruby_show_version() API and check to call mjit_init() */
|
|
|
|
}
|
2018-10-20 09:53:00 +03:00
|
|
|
#endif
|
2012-08-09 13:33:49 +04:00
|
|
|
if (opt->dump & (DUMP_BIT(version) | DUMP_BIT(version_v))) {
|
2018-10-20 09:53:00 +03:00
|
|
|
#if USE_MJIT
|
2018-07-18 15:45:54 +03:00
|
|
|
mjit_opts.on = opt->mjit.on; /* used by ruby_show_version(). mjit_init() still can't be called here. */
|
2018-10-20 09:53:00 +03:00
|
|
|
#endif
|
1999-01-20 07:59:39 +03:00
|
|
|
ruby_show_version();
|
2012-08-09 13:33:49 +04:00
|
|
|
if (opt->dump & DUMP_BIT(version)) return Qtrue;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2008-12-08 05:28:17 +03:00
|
|
|
if (opt->dump & DUMP_BIT(copyright)) {
|
1999-01-20 07:59:39 +03:00
|
|
|
ruby_show_copyright();
|
2016-01-07 05:34:33 +03:00
|
|
|
return Qtrue;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2007-09-29 01:47:31 +04:00
|
|
|
if (!opt->e_script) {
|
2017-08-09 14:03:55 +03:00
|
|
|
if (argc <= 0) { /* no more args */
|
2007-09-29 01:47:31 +04:00
|
|
|
if (opt->verbose)
|
2007-10-03 05:06:57 +04:00
|
|
|
return Qtrue;
|
2007-09-29 01:47:31 +04:00
|
|
|
opt->script = "-";
|
2001-09-03 09:37:42 +04:00
|
|
|
}
|
1998-01-16 15:13:05 +03:00
|
|
|
else {
|
2007-09-29 01:47:31 +04:00
|
|
|
opt->script = argv[0];
|
2012-11-23 19:00:55 +04:00
|
|
|
if (!opt->script || opt->script[0] == '\0') {
|
2007-09-29 01:47:31 +04:00
|
|
|
opt->script = "-";
|
2003-02-13 06:02:19 +03:00
|
|
|
}
|
2007-09-29 01:47:31 +04:00
|
|
|
else if (opt->do_search) {
|
1999-10-15 12:52:18 +04:00
|
|
|
char *path = getenv("RUBYPATH");
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2007-09-29 01:47:31 +04:00
|
|
|
opt->script = 0;
|
1999-10-15 12:52:18 +04:00
|
|
|
if (path) {
|
2008-05-08 01:43:54 +04:00
|
|
|
opt->script = dln_find_file_r(argv[0], path, fbuf, sizeof(fbuf));
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2007-09-29 01:47:31 +04:00
|
|
|
if (!opt->script) {
|
2008-05-08 01:43:54 +04:00
|
|
|
opt->script = dln_find_file_r(argv[0], getenv(PATH_ENV), fbuf, sizeof(fbuf));
|
1999-10-15 12:52:18 +04:00
|
|
|
}
|
2007-09-29 01:47:31 +04:00
|
|
|
if (!opt->script)
|
|
|
|
opt->script = argv[0];
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2006-12-31 18:02:22 +03:00
|
|
|
argc--;
|
|
|
|
argv++;
|
2003-02-13 03:59:00 +03:00
|
|
|
}
|
2017-01-31 15:54:59 +03:00
|
|
|
if (opt->script[0] == '-' && !opt->script[1]) {
|
|
|
|
forbid_setid("program input from stdin");
|
|
|
|
}
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2008-12-15 05:32:21 +03:00
|
|
|
opt->script_name = rb_str_new_cstr(opt->script);
|
|
|
|
opt->script = RSTRING_PTR(opt->script_name);
|
2014-11-29 18:02:25 +03:00
|
|
|
|
|
|
|
#if _WIN32
|
|
|
|
translit_char_bin(RSTRING_PTR(opt->script_name), '\\', '/');
|
|
|
|
#elif defined DOSISH
|
2009-02-19 09:11:41 +03:00
|
|
|
translit_char(RSTRING_PTR(opt->script_name), '\\', '/');
|
2008-04-15 21:26:29 +04:00
|
|
|
#endif
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2019-09-21 05:06:22 +03:00
|
|
|
ruby_gc_set_params();
|
|
|
|
ruby_init_loadpath();
|
2018-02-05 19:51:12 +03:00
|
|
|
|
2018-10-20 09:53:00 +03:00
|
|
|
#if USE_MJIT
|
2018-02-05 19:51:12 +03:00
|
|
|
if (opt->mjit.on)
|
2019-09-21 05:06:22 +03:00
|
|
|
/* Using TMP_RUBY_PREFIX created by ruby_init_loadpath(). */
|
2018-02-05 19:51:12 +03:00
|
|
|
mjit_init(&opt->mjit);
|
2018-10-20 09:53:00 +03:00
|
|
|
#endif
|
2018-02-05 19:51:12 +03:00
|
|
|
|
2018-08-10 08:02:35 +03:00
|
|
|
Init_ruby_description();
|
2012-05-16 09:39:06 +04:00
|
|
|
Init_enc();
|
2008-05-07 15:25:23 +04:00
|
|
|
lenc = rb_locale_encoding();
|
2008-09-14 11:07:31 +04:00
|
|
|
rb_enc_associate(rb_progname, lenc);
|
2011-07-07 10:44:46 +04:00
|
|
|
rb_obj_freeze(rb_progname);
|
2007-09-29 00:29:32 +04:00
|
|
|
parser = rb_parser_new();
|
2008-12-08 05:28:17 +03:00
|
|
|
if (opt->dump & DUMP_BIT(yydebug)) {
|
|
|
|
rb_parser_set_yydebug(parser, Qtrue);
|
|
|
|
}
|
2008-01-25 07:18:14 +03:00
|
|
|
if (opt->ext.enc.name != 0) {
|
|
|
|
opt->ext.enc.index = opt_enc_index(opt->ext.enc.name);
|
2007-12-31 17:57:46 +03:00
|
|
|
}
|
2008-10-07 21:39:44 +04:00
|
|
|
if (opt->intern.enc.name != 0) {
|
|
|
|
opt->intern.enc.index = opt_enc_index(opt->intern.enc.name);
|
|
|
|
}
|
2008-01-25 07:18:14 +03:00
|
|
|
if (opt->src.enc.name != 0) {
|
|
|
|
opt->src.enc.index = opt_enc_index(opt->src.enc.name);
|
2008-01-25 10:11:18 +03:00
|
|
|
src_encoding_index = opt->src.enc.index;
|
2008-01-25 07:18:14 +03:00
|
|
|
}
|
2009-02-06 06:12:09 +03:00
|
|
|
if (opt->ext.enc.index >= 0) {
|
|
|
|
enc = rb_enc_from_index(opt->ext.enc.index);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
enc = lenc;
|
|
|
|
}
|
|
|
|
rb_enc_set_default_external(rb_enc_from_encoding(enc));
|
2008-10-07 21:39:44 +04:00
|
|
|
if (opt->intern.enc.index >= 0) {
|
|
|
|
enc = rb_enc_from_index(opt->intern.enc.index);
|
|
|
|
rb_enc_set_default_internal(rb_enc_from_encoding(enc));
|
|
|
|
opt->intern.enc.index = -1;
|
2016-04-26 17:35:24 +03:00
|
|
|
#if UTF8_PATH
|
|
|
|
ienc = enc;
|
|
|
|
#endif
|
2008-10-07 21:39:44 +04:00
|
|
|
}
|
2017-06-08 05:07:42 +03:00
|
|
|
script_name = opt->script_name;
|
|
|
|
rb_enc_associate(opt->script_name,
|
|
|
|
IF_UTF8_PATH(uenc = rb_utf8_encoding(), lenc));
|
|
|
|
#if UTF8_PATH
|
|
|
|
if (uenc != lenc) {
|
2017-05-17 07:47:05 +03:00
|
|
|
opt->script_name = str_conv_enc(opt->script_name, uenc, lenc);
|
|
|
|
opt->script = RSTRING_PTR(opt->script_name);
|
|
|
|
}
|
2017-06-08 05:07:42 +03:00
|
|
|
#endif
|
2011-07-07 10:44:46 +04:00
|
|
|
rb_obj_freeze(opt->script_name);
|
2017-05-17 07:47:05 +03:00
|
|
|
if (IF_UTF8_PATH(uenc != lenc, 1)) {
|
2008-12-15 05:32:21 +03:00
|
|
|
long i;
|
2019-05-20 12:10:35 +03:00
|
|
|
rb_vm_t *vm = GET_VM();
|
|
|
|
VALUE load_path = vm->load_path;
|
2015-07-02 08:12:04 +03:00
|
|
|
const ID id_initial_load_path_mark = INITIAL_LOAD_PATH_MARK;
|
2019-05-20 12:10:35 +03:00
|
|
|
int modifiable = FALSE;
|
|
|
|
|
|
|
|
rb_get_expanded_load_path();
|
2008-12-15 05:32:21 +03:00
|
|
|
for (i = 0; i < RARRAY_LEN(load_path); ++i) {
|
2014-08-23 06:52:23 +04:00
|
|
|
VALUE path = RARRAY_AREF(load_path, i);
|
2015-07-02 08:12:04 +03:00
|
|
|
int mark = rb_attr_get(path, id_initial_load_path_mark) == path;
|
2016-06-02 11:05:21 +03:00
|
|
|
#if UTF8_PATH
|
2016-06-03 15:27:24 +03:00
|
|
|
VALUE newpath = rb_str_conv_enc(path, uenc, lenc);
|
|
|
|
if (newpath == path) continue;
|
|
|
|
path = newpath;
|
2016-06-02 11:05:21 +03:00
|
|
|
#else
|
2014-08-23 06:52:23 +04:00
|
|
|
path = rb_enc_associate(rb_str_dup(path), lenc);
|
2016-06-02 11:05:21 +03:00
|
|
|
#endif
|
2015-07-02 08:12:04 +03:00
|
|
|
if (mark) rb_ivar_set(path, id_initial_load_path_mark, path);
|
2019-05-20 12:10:35 +03:00
|
|
|
if (!modifiable) {
|
|
|
|
rb_ary_modify(load_path);
|
|
|
|
modifiable = TRUE;
|
|
|
|
}
|
2014-08-23 06:52:23 +04:00
|
|
|
RARRAY_ASET(load_path, i, path);
|
2008-12-15 05:32:21 +03:00
|
|
|
}
|
2019-05-20 12:10:35 +03:00
|
|
|
if (modifiable) {
|
|
|
|
rb_ary_replace(vm->load_path_snapshot, load_path);
|
|
|
|
}
|
2008-12-15 05:32:21 +03:00
|
|
|
}
|
2020-05-16 11:37:28 +03:00
|
|
|
|
2019-03-30 17:31:35 +03:00
|
|
|
if (opt->features.mask & COMPILATION_FEATURES) {
|
2015-10-23 22:02:55 +03:00
|
|
|
VALUE option = rb_hash_new();
|
2015-11-19 08:58:31 +03:00
|
|
|
#define SET_COMPILE_OPTION(h, o, name) \
|
|
|
|
rb_hash_aset((h), ID2SYM(rb_intern_const(#name)), \
|
2019-03-30 17:31:35 +03:00
|
|
|
(FEATURE_SET_P(o->features, FEATURE_BIT(name)) ? Qtrue : Qfalse));
|
2015-11-19 08:58:31 +03:00
|
|
|
SET_COMPILE_OPTION(option, opt, frozen_string_literal);
|
2015-11-25 11:02:29 +03:00
|
|
|
SET_COMPILE_OPTION(option, opt, debug_frozen_string_literal);
|
2015-10-23 22:02:55 +03:00
|
|
|
rb_funcallv(rb_cISeq, rb_intern_const("compile_option="), 1, &option);
|
2015-11-19 08:58:31 +03:00
|
|
|
#undef SET_COMPILE_OPTION
|
2015-10-23 22:02:55 +03:00
|
|
|
}
|
2008-10-18 14:36:20 +04:00
|
|
|
ruby_set_argv(argc, argv);
|
2009-05-17 04:47:49 +04:00
|
|
|
process_sflag(&opt->sflag);
|
2008-02-16 02:03:22 +03:00
|
|
|
|
2019-10-03 19:29:21 +03:00
|
|
|
rb_parser_set_context(parser, 0, TRUE);
|
2017-10-24 10:41:48 +03:00
|
|
|
|
2007-09-29 01:47:31 +04:00
|
|
|
if (opt->e_script) {
|
2010-06-05 10:59:12 +04:00
|
|
|
VALUE progname = rb_progname;
|
2008-01-25 21:49:28 +03:00
|
|
|
rb_encoding *eenc;
|
|
|
|
if (opt->src.enc.index >= 0) {
|
|
|
|
eenc = rb_enc_from_index(opt->src.enc.index);
|
2008-01-25 09:12:44 +03:00
|
|
|
}
|
2008-01-25 09:56:50 +03:00
|
|
|
else {
|
2016-04-24 06:42:25 +03:00
|
|
|
eenc = lenc;
|
2016-04-26 17:35:24 +03:00
|
|
|
#if UTF8_PATH
|
|
|
|
if (ienc) eenc = ienc;
|
|
|
|
#endif
|
2008-01-25 09:56:50 +03:00
|
|
|
}
|
2016-04-26 17:35:24 +03:00
|
|
|
#if UTF8_PATH
|
|
|
|
if (eenc != uenc) {
|
|
|
|
opt->e_script = str_conv_enc(opt->e_script, uenc, eenc);
|
|
|
|
}
|
|
|
|
#endif
|
2008-01-25 09:12:44 +03:00
|
|
|
rb_enc_associate(opt->e_script, eenc);
|
2020-05-16 11:37:28 +03:00
|
|
|
ruby_opt_init(opt);
|
2012-06-14 06:22:08 +04:00
|
|
|
ruby_set_script_name(progname);
|
2017-10-24 14:09:41 +03:00
|
|
|
rb_parser_set_options(parser, opt->do_print, opt->do_loop,
|
|
|
|
opt->do_line, opt->do_split);
|
2019-12-20 17:05:22 +03:00
|
|
|
rb_warning_category_update(opt->warn.mask, opt->warn.set);
|
2017-10-27 19:44:57 +03:00
|
|
|
ast = rb_parser_compile_string(parser, opt->script, opt->e_script, 1);
|
1999-10-15 12:52:18 +04:00
|
|
|
}
|
|
|
|
else {
|
2017-05-28 12:49:30 +03:00
|
|
|
VALUE f;
|
2017-06-08 05:07:42 +03:00
|
|
|
f = open_load_file(script_name, &opt->xflag);
|
2017-10-27 19:44:57 +03:00
|
|
|
ast = load_file(parser, opt->script_name, f, 1, opt);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2012-06-14 06:22:08 +04:00
|
|
|
ruby_set_script_name(opt->script_name);
|
2016-12-07 17:39:24 +03:00
|
|
|
if (dump & DUMP_BIT(yydebug)) {
|
|
|
|
dump &= ~DUMP_BIT(yydebug);
|
|
|
|
if (!dump) return Qtrue;
|
|
|
|
}
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2009-02-06 06:05:27 +03:00
|
|
|
if (opt->ext.enc.index >= 0) {
|
|
|
|
enc = rb_enc_from_index(opt->ext.enc.index);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
enc = lenc;
|
|
|
|
}
|
|
|
|
rb_enc_set_default_external(rb_enc_from_encoding(enc));
|
2008-10-07 21:39:44 +04:00
|
|
|
if (opt->intern.enc.index >= 0) {
|
|
|
|
/* Set in the shebang line */
|
|
|
|
enc = rb_enc_from_index(opt->intern.enc.index);
|
|
|
|
rb_enc_set_default_internal(rb_enc_from_encoding(enc));
|
|
|
|
}
|
2008-12-13 09:58:58 +03:00
|
|
|
else if (!rb_default_internal_encoding())
|
2008-10-07 21:39:44 +04:00
|
|
|
/* Freeze default_internal */
|
|
|
|
rb_enc_set_default_internal(Qnil);
|
2009-07-31 11:37:02 +04:00
|
|
|
rb_stdio_set_default_encoding();
|
2008-10-07 21:39:44 +04:00
|
|
|
|
2018-01-05 11:59:20 +03:00
|
|
|
if (!ast->body.root) {
|
2017-10-27 19:44:57 +03:00
|
|
|
rb_ast_dispose(ast);
|
|
|
|
return Qfalse;
|
|
|
|
}
|
2007-09-29 01:47:31 +04:00
|
|
|
|
2009-05-17 04:47:49 +04:00
|
|
|
process_sflag(&opt->sflag);
|
2007-09-29 01:47:31 +04:00
|
|
|
opt->xflag = 0;
|
2001-05-30 13:12:34 +04:00
|
|
|
|
2016-12-07 17:39:24 +03:00
|
|
|
if (dump & DUMP_BIT(syntax)) {
|
2007-12-04 08:34:37 +03:00
|
|
|
printf("Syntax OK\n");
|
2016-12-07 17:39:24 +03:00
|
|
|
dump &= ~DUMP_BIT(syntax);
|
|
|
|
if (!dump) return Qtrue;
|
2007-12-04 08:34:37 +03:00
|
|
|
}
|
|
|
|
|
* eval.c (ruby_exec_node, ruby_run_node), ruby.c (process_options):
use iseq instead of NODE.
* gc.c (source_filenames): removed.
* include/ruby/intern.h, parse.y (yycompile, parser_mark, parser_free,
ripper_initialize): rb_source_filename() is no longer used.
* compile.c, compile.h (ERROR_ARGS), parse.y (node_newnode, fixpos,
parser_warn, e_option_supplied, warn_unless_e_option, range_op,
cond0): nd_file is no longer used.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15983 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-04-12 07:41:51 +04:00
|
|
|
if (opt->do_loop) {
|
2008-12-15 17:46:50 +03:00
|
|
|
rb_define_global_function("sub", rb_f_sub, -1);
|
|
|
|
rb_define_global_function("gsub", rb_f_gsub, -1);
|
|
|
|
rb_define_global_function("chop", rb_f_chop, 0);
|
|
|
|
rb_define_global_function("chomp", rb_f_chomp, -1);
|
2007-07-05 13:28:00 +04:00
|
|
|
}
|
|
|
|
|
2016-12-07 17:39:24 +03:00
|
|
|
if (dump & (DUMP_BIT(parsetree)|DUMP_BIT(parsetree_with_comment))) {
|
2018-01-05 11:59:20 +03:00
|
|
|
rb_io_write(rb_stdout, rb_parser_dump_tree(ast->body.root, dump & DUMP_BIT(parsetree_with_comment)));
|
2009-12-09 17:05:59 +03:00
|
|
|
rb_io_flush(rb_stdout);
|
2016-12-07 17:39:24 +03:00
|
|
|
dump &= ~DUMP_BIT(parsetree)&~DUMP_BIT(parsetree_with_comment);
|
2017-10-27 19:44:57 +03:00
|
|
|
if (!dump) {
|
|
|
|
rb_ast_dispose(ast);
|
|
|
|
return Qtrue;
|
|
|
|
}
|
2009-12-09 17:05:59 +03:00
|
|
|
}
|
|
|
|
|
2016-03-29 00:39:24 +03:00
|
|
|
{
|
2010-03-16 20:40:00 +03:00
|
|
|
VALUE path = Qnil;
|
2012-12-21 14:39:59 +04:00
|
|
|
if (!opt->e_script && strcmp(opt->script, "-")) {
|
2017-06-08 05:07:42 +03:00
|
|
|
path = rb_realpath_internal(Qnil, script_name, 1);
|
2017-10-21 18:43:05 +03:00
|
|
|
#if UTF8_PATH
|
|
|
|
if (uenc != lenc) {
|
|
|
|
path = str_conv_enc(path, uenc, lenc);
|
|
|
|
}
|
|
|
|
#endif
|
2017-12-16 16:25:11 +03:00
|
|
|
if (!ENCODING_GET(path)) { /* ASCII-8BIT */
|
|
|
|
rb_enc_copy(path, opt->script_name);
|
|
|
|
}
|
2012-12-21 14:39:59 +04:00
|
|
|
}
|
2019-10-03 19:29:21 +03:00
|
|
|
|
|
|
|
rb_binding_t *toplevel_binding;
|
|
|
|
GetBindingPtr(rb_const_get(rb_cObject, rb_intern("TOPLEVEL_BINDING")),
|
|
|
|
toplevel_binding);
|
|
|
|
const struct rb_block *base_block = toplevel_context(toplevel_binding);
|
2018-01-05 11:59:22 +03:00
|
|
|
iseq = rb_iseq_new_main(&ast->body, opt->script_name, path, vm_block_iseq(base_block));
|
2017-10-27 19:44:57 +03:00
|
|
|
rb_ast_dispose(ast);
|
2016-03-29 00:39:24 +03:00
|
|
|
}
|
2008-05-20 08:19:27 +04:00
|
|
|
|
2016-12-07 17:39:24 +03:00
|
|
|
if (dump & DUMP_BIT(insns)) {
|
2015-07-22 01:52:59 +03:00
|
|
|
rb_io_write(rb_stdout, rb_iseq_disasm((const rb_iseq_t *)iseq));
|
2008-05-20 07:13:52 +04:00
|
|
|
rb_io_flush(rb_stdout);
|
2016-12-07 17:39:24 +03:00
|
|
|
dump &= ~DUMP_BIT(insns);
|
|
|
|
if (!dump) return Qtrue;
|
2008-05-20 07:13:52 +04:00
|
|
|
}
|
2016-12-07 17:39:24 +03:00
|
|
|
if (opt->dump & dump_exit_bits) return Qtrue;
|
2008-05-20 07:13:52 +04:00
|
|
|
|
2008-12-08 05:28:17 +03:00
|
|
|
rb_define_readonly_boolean("$-p", opt->do_print);
|
|
|
|
rb_define_readonly_boolean("$-l", opt->do_line);
|
|
|
|
rb_define_readonly_boolean("$-a", opt->do_split);
|
|
|
|
|
2018-11-10 14:43:02 +03:00
|
|
|
if ((rb_e_script = opt->e_script) != 0) {
|
|
|
|
rb_gc_register_mark_object(opt->e_script);
|
|
|
|
}
|
|
|
|
|
2018-12-27 20:39:17 +03:00
|
|
|
{
|
|
|
|
rb_execution_context_t *ec = GET_EC();
|
|
|
|
|
|
|
|
if (opt->e_script) {
|
|
|
|
/* -e */
|
|
|
|
rb_exec_event_hook_script_compiled(ec, iseq, opt->e_script);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* file */
|
|
|
|
rb_exec_event_hook_script_compiled(ec, iseq, Qnil);
|
|
|
|
}
|
|
|
|
}
|
2015-07-22 01:52:59 +03:00
|
|
|
return (VALUE)iseq;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2016-03-07 18:44:34 +03:00
|
|
|
#ifndef DOSISH
|
2016-03-04 16:27:36 +03:00
|
|
|
static void
|
|
|
|
warn_cr_in_shebang(const char *str, long len)
|
|
|
|
{
|
|
|
|
if (str[len-1] == '\n' && str[len-2] == '\r') {
|
2017-06-01 07:38:03 +03:00
|
|
|
rb_warn("shebang line ending with \\r may cause problems");
|
2016-03-04 16:27:36 +03:00
|
|
|
}
|
|
|
|
}
|
2016-03-07 22:39:32 +03:00
|
|
|
#else
|
|
|
|
#define warn_cr_in_shebang(str, len) (void)0
|
2016-03-07 18:44:34 +03:00
|
|
|
#endif
|
2016-03-04 16:27:36 +03:00
|
|
|
|
2008-10-27 09:58:28 +03:00
|
|
|
struct load_file_arg {
|
|
|
|
VALUE parser;
|
2011-10-31 22:05:03 +04:00
|
|
|
VALUE fname;
|
2008-10-27 09:58:28 +03:00
|
|
|
int script;
|
2016-08-19 13:44:53 +03:00
|
|
|
ruby_cmdline_options_t *opt;
|
2014-06-03 18:33:51 +04:00
|
|
|
VALUE f;
|
2008-10-27 09:58:28 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
static VALUE
|
2015-10-17 07:19:12 +03:00
|
|
|
load_file_internal(VALUE argp_v)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2014-06-03 18:33:51 +04:00
|
|
|
struct load_file_arg *argp = (struct load_file_arg *)argp_v;
|
2008-10-27 09:58:28 +03:00
|
|
|
VALUE parser = argp->parser;
|
2013-08-09 17:20:58 +04:00
|
|
|
VALUE orig_fname = argp->fname;
|
2008-10-27 09:58:28 +03:00
|
|
|
int script = argp->script;
|
2016-08-19 13:44:53 +03:00
|
|
|
ruby_cmdline_options_t *opt = argp->opt;
|
2014-06-03 18:33:51 +04:00
|
|
|
VALUE f = argp->f;
|
1998-01-16 15:13:05 +03:00
|
|
|
int line_start = 1;
|
2017-10-29 18:51:23 +03:00
|
|
|
rb_ast_t *ast = 0;
|
2008-01-19 02:35:38 +03:00
|
|
|
rb_encoding *enc;
|
2008-10-29 03:23:04 +03:00
|
|
|
ID set_encoding;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2008-10-29 03:23:04 +03:00
|
|
|
CONST_ID(set_encoding, "set_encoding");
|
1998-01-16 15:13:05 +03:00
|
|
|
if (script) {
|
2001-07-14 19:17:19 +04:00
|
|
|
VALUE c = 1; /* something not nil */
|
1998-01-16 15:13:05 +03:00
|
|
|
VALUE line;
|
2016-03-04 08:19:12 +03:00
|
|
|
char *p, *str;
|
|
|
|
long len;
|
2008-01-25 07:18:14 +03:00
|
|
|
int no_src_enc = !opt->src.enc.name;
|
|
|
|
int no_ext_enc = !opt->ext.enc.name;
|
2008-10-07 21:39:44 +04:00
|
|
|
int no_int_enc = !opt->intern.enc.name;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2008-10-29 03:30:09 +03:00
|
|
|
enc = rb_ascii8bit_encoding();
|
2008-10-29 03:23:04 +03:00
|
|
|
rb_funcall(f, set_encoding, 1, rb_enc_from_encoding(enc));
|
2008-03-02 04:13:15 +03:00
|
|
|
|
2017-05-28 12:49:30 +03:00
|
|
|
if (opt->xflag) {
|
2010-12-05 05:27:13 +03:00
|
|
|
line_start--;
|
2009-08-05 14:19:18 +04:00
|
|
|
search_shebang:
|
1999-01-20 07:59:39 +03:00
|
|
|
while (!NIL_P(line = rb_io_gets(f))) {
|
1998-01-16 15:13:05 +03:00
|
|
|
line_start++;
|
2016-03-04 08:19:12 +03:00
|
|
|
RSTRING_GETMEM(line, str, len);
|
|
|
|
if (len > 2 && str[0] == '#' && str[1] == '!') {
|
2016-03-04 16:27:36 +03:00
|
|
|
if (line_start == 1) warn_cr_in_shebang(str, len);
|
2016-03-04 08:19:12 +03:00
|
|
|
if ((p = strstr(str+2, ruby_engine)) != 0) {
|
1998-01-16 15:13:05 +03:00
|
|
|
goto start_read;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-03-07 03:38:33 +04:00
|
|
|
rb_loaderror("no Ruby script found in input");
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
* 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
|
|
|
c = rb_io_getbyte(f);
|
1998-01-16 15:13:05 +03:00
|
|
|
if (c == INT2FIX('#')) {
|
* 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
|
|
|
c = rb_io_getbyte(f);
|
2018-10-02 21:51:21 +03:00
|
|
|
if (c == INT2FIX('!') && !NIL_P(line = rb_io_gets(f))) {
|
2016-03-04 08:19:12 +03:00
|
|
|
RSTRING_GETMEM(line, str, len);
|
2016-03-04 16:27:36 +03:00
|
|
|
warn_cr_in_shebang(str, len);
|
2016-03-04 08:19:12 +03:00
|
|
|
if ((p = strstr(str, ruby_engine)) == 0) {
|
2009-08-05 14:19:18 +04:00
|
|
|
/* not ruby script, assume -x flag */
|
|
|
|
goto search_shebang;
|
1998-01-16 15:19:22 +03:00
|
|
|
}
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
start_read:
|
2016-03-04 08:19:12 +03:00
|
|
|
str += len - 1;
|
|
|
|
if (*str == '\n') *str-- = '\0';
|
|
|
|
if (*str == '\r') *str-- = '\0';
|
2016-03-04 06:53:43 +03:00
|
|
|
/* ruby_engine should not contain a space */
|
2005-05-01 04:13:48 +04:00
|
|
|
if ((p = strstr(p, " -")) != 0) {
|
2015-12-29 13:12:48 +03:00
|
|
|
opt->warning = 0;
|
2008-10-30 04:34:23 +03:00
|
|
|
moreswitches(p + 1, opt, 0);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2005-05-14 06:48:07 +04:00
|
|
|
|
|
|
|
/* push back shebang for pragma may exist in next line */
|
2008-08-25 12:36:46 +04:00
|
|
|
rb_io_ungetbyte(f, rb_str_new2("!\n"));
|
2005-05-14 06:48:07 +04:00
|
|
|
}
|
|
|
|
else if (!NIL_P(c)) {
|
2008-08-25 12:36:46 +04:00
|
|
|
rb_io_ungetbyte(f, c);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2008-08-25 12:36:46 +04:00
|
|
|
rb_io_ungetbyte(f, INT2FIX('#'));
|
2008-01-25 07:18:14 +03:00
|
|
|
if (no_src_enc && opt->src.enc.name) {
|
|
|
|
opt->src.enc.index = opt_enc_index(opt->src.enc.name);
|
2008-01-25 10:11:18 +03:00
|
|
|
src_encoding_index = opt->src.enc.index;
|
2008-01-25 07:18:14 +03:00
|
|
|
}
|
|
|
|
if (no_ext_enc && opt->ext.enc.name) {
|
|
|
|
opt->ext.enc.index = opt_enc_index(opt->ext.enc.name);
|
2008-01-09 09:54:26 +03:00
|
|
|
}
|
2008-10-07 21:39:44 +04:00
|
|
|
if (no_int_enc && opt->intern.enc.name) {
|
|
|
|
opt->intern.enc.index = opt_enc_index(opt->intern.enc.name);
|
|
|
|
}
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2000-06-28 12:31:35 +04:00
|
|
|
else if (!NIL_P(c)) {
|
2008-08-25 12:36:46 +04:00
|
|
|
rb_io_ungetbyte(f, c);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2019-06-04 03:36:32 +03:00
|
|
|
if (NIL_P(c)) {
|
2017-01-31 15:55:00 +03:00
|
|
|
argp->f = f = Qnil;
|
2010-06-27 18:31:19 +04:00
|
|
|
}
|
2020-05-16 11:37:28 +03:00
|
|
|
ruby_opt_init(opt);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2008-01-25 07:18:14 +03:00
|
|
|
if (opt->src.enc.index >= 0) {
|
|
|
|
enc = rb_enc_from_index(opt->src.enc.index);
|
2008-01-13 07:50:48 +03:00
|
|
|
}
|
|
|
|
else if (f == rb_stdin) {
|
2008-01-25 21:49:28 +03:00
|
|
|
enc = rb_locale_encoding();
|
2008-01-19 02:35:38 +03:00
|
|
|
}
|
|
|
|
else {
|
2012-11-06 04:49:57 +04:00
|
|
|
enc = rb_utf8_encoding();
|
2008-01-13 07:50:48 +03:00
|
|
|
}
|
2017-10-24 14:09:41 +03:00
|
|
|
rb_parser_set_options(parser, opt->do_print, opt->do_loop,
|
|
|
|
opt->do_line, opt->do_split);
|
2019-12-20 17:05:22 +03:00
|
|
|
rb_warning_category_update(opt->warn.mask, opt->warn.set);
|
2010-06-27 18:31:19 +04:00
|
|
|
if (NIL_P(f)) {
|
|
|
|
f = rb_str_new(0, 0);
|
|
|
|
rb_enc_associate(f, enc);
|
2013-08-09 17:20:58 +04:00
|
|
|
return (VALUE)rb_parser_compile_string_path(parser, orig_fname, f, line_start);
|
2010-06-27 18:31:19 +04:00
|
|
|
}
|
2008-10-30 12:17:49 +03:00
|
|
|
rb_funcall(f, set_encoding, 2, rb_enc_from_encoding(enc), rb_str_new_cstr("-"));
|
2017-10-27 19:44:57 +03:00
|
|
|
ast = rb_parser_compile_file_path(parser, orig_fname, f, line_start);
|
2008-10-29 03:23:04 +03:00
|
|
|
rb_funcall(f, set_encoding, 1, rb_parser_encoding(parser));
|
2017-01-31 15:55:00 +03:00
|
|
|
if (script && rb_parser_end_seen_p(parser)) {
|
|
|
|
/*
|
|
|
|
* DATA is a File that contains the data section of the executed file.
|
|
|
|
* To create a data section use <tt>__END__</tt>:
|
|
|
|
*
|
|
|
|
* $ cat t.rb
|
|
|
|
* puts DATA.gets
|
|
|
|
* __END__
|
|
|
|
* hello world!
|
|
|
|
*
|
|
|
|
* $ ruby t.rb
|
|
|
|
* hello world!
|
|
|
|
*/
|
|
|
|
rb_define_global_const("DATA", f);
|
|
|
|
argp->f = Qnil;
|
|
|
|
}
|
2017-10-27 19:44:57 +03:00
|
|
|
return (VALUE)ast;
|
2014-06-03 18:33:51 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
2015-10-17 07:19:12 +03:00
|
|
|
open_load_file(VALUE fname_v, int *xflag)
|
2014-06-03 18:33:51 +04:00
|
|
|
{
|
2017-05-28 12:49:30 +03:00
|
|
|
const char *fname = (fname_v = rb_str_encode_ospath(fname_v),
|
|
|
|
StringValueCStr(fname_v));
|
2016-10-10 06:40:56 +03:00
|
|
|
long flen = RSTRING_LEN(fname_v);
|
2014-06-03 18:33:51 +04:00
|
|
|
VALUE f;
|
2015-10-18 00:09:10 +03:00
|
|
|
int e;
|
2014-06-03 18:33:51 +04:00
|
|
|
|
2016-10-10 06:40:56 +03:00
|
|
|
if (flen == 1 && fname[0] == '-') {
|
2014-06-03 18:33:51 +04:00
|
|
|
f = rb_stdin;
|
|
|
|
}
|
|
|
|
else {
|
2015-10-18 00:09:10 +03:00
|
|
|
int fd;
|
|
|
|
/* open(2) may block if fname is point to FIFO and it's empty. Let's
|
|
|
|
use O_NONBLOCK. */
|
|
|
|
#if defined O_NONBLOCK && HAVE_FCNTL && !(O_NONBLOCK & O_ACCMODE)
|
2015-10-17 07:03:23 +03:00
|
|
|
/* TODO: fix conflicting O_NONBLOCK in ruby/win32.h */
|
2016-10-12 15:07:16 +03:00
|
|
|
# define MODE_TO_LOAD (O_RDONLY | O_NONBLOCK)
|
2015-10-18 00:09:10 +03:00
|
|
|
#elif defined O_NDELAY && HAVE_FCNTL && !(O_NDELAY & O_ACCMODE)
|
2016-10-12 15:07:16 +03:00
|
|
|
# define MODE_TO_LOAD (O_RDONLY | O_NDELAY)
|
2015-10-18 07:22:44 +03:00
|
|
|
#else
|
2016-10-12 15:07:16 +03:00
|
|
|
# define MODE_TO_LOAD (O_RDONLY)
|
2015-10-16 09:54:38 +03:00
|
|
|
#endif
|
2016-10-12 15:07:16 +03:00
|
|
|
int mode = MODE_TO_LOAD;
|
2014-06-03 18:33:51 +04:00
|
|
|
#if defined DOSISH || defined __CYGWIN__
|
2016-10-12 11:24:36 +03:00
|
|
|
# define isdirsep(x) ((x) == '/' || (x) == '\\')
|
2014-06-03 18:33:51 +04:00
|
|
|
{
|
2016-10-12 11:24:36 +03:00
|
|
|
static const char exeext[] = ".exe";
|
2016-10-10 06:40:56 +03:00
|
|
|
enum {extlen = sizeof(exeext)-1};
|
|
|
|
if (flen > extlen && !isdirsep(fname[flen-extlen-1]) &&
|
|
|
|
STRNCASECMP(fname+flen-extlen, exeext, extlen) == 0) {
|
2016-10-12 15:07:16 +03:00
|
|
|
mode |= O_BINARY;
|
2015-10-17 07:19:12 +03:00
|
|
|
*xflag = 1;
|
2014-06-03 18:33:51 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2015-10-18 00:09:10 +03:00
|
|
|
|
2014-06-03 18:33:51 +04:00
|
|
|
if ((fd = rb_cloexec_open(fname, mode, 0)) < 0) {
|
2018-01-24 23:50:29 +03:00
|
|
|
e = errno;
|
2016-10-21 10:06:27 +03:00
|
|
|
if (!rb_gc_for_fd(e)) {
|
|
|
|
rb_load_fail(fname_v, strerror(e));
|
|
|
|
}
|
|
|
|
if ((fd = rb_cloexec_open(fname, mode, 0)) < 0) {
|
|
|
|
rb_load_fail(fname_v, strerror(errno));
|
|
|
|
}
|
2014-06-03 18:33:51 +04:00
|
|
|
}
|
2015-10-18 00:09:10 +03:00
|
|
|
rb_update_max_fd(fd);
|
|
|
|
|
2016-10-12 15:07:16 +03:00
|
|
|
#if defined HAVE_FCNTL && MODE_TO_LOAD != O_RDONLY
|
2015-10-18 00:09:10 +03:00
|
|
|
/* disabling O_NONBLOCK */
|
|
|
|
if (fcntl(fd, F_SETFL, 0) < 0) {
|
|
|
|
e = errno;
|
2015-10-18 02:38:18 +03:00
|
|
|
(void)close(fd);
|
2015-10-18 00:09:10 +03:00
|
|
|
rb_load_fail(fname_v, strerror(e));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-03-14 10:03:01 +03:00
|
|
|
e = ruby_is_fd_loadable(fd);
|
2016-10-10 09:22:30 +03:00
|
|
|
if (!e) {
|
|
|
|
e = errno;
|
|
|
|
(void)close(fd);
|
|
|
|
rb_load_fail(fname_v, strerror(e));
|
2014-06-03 18:33:51 +04:00
|
|
|
}
|
2015-10-18 00:09:10 +03:00
|
|
|
|
2014-06-03 18:33:51 +04:00
|
|
|
f = rb_io_fdopen(fd, mode, fname);
|
2016-10-10 09:22:30 +03:00
|
|
|
if (e < 0) {
|
|
|
|
/*
|
|
|
|
We need to wait if FIFO is empty. It's FIFO's semantics.
|
|
|
|
rb_thread_wait_fd() release GVL. So, it's safe.
|
|
|
|
*/
|
|
|
|
rb_thread_wait_fd(fd);
|
|
|
|
}
|
2014-06-03 18:33:51 +04:00
|
|
|
}
|
2015-10-17 07:19:12 +03:00
|
|
|
return f;
|
|
|
|
}
|
2014-06-03 18:33:51 +04:00
|
|
|
|
2015-10-17 07:19:12 +03:00
|
|
|
static VALUE
|
|
|
|
restore_load_file(VALUE arg)
|
|
|
|
{
|
|
|
|
struct load_file_arg *argp = (struct load_file_arg *)arg;
|
|
|
|
VALUE f = argp->f;
|
2014-06-03 18:33:51 +04:00
|
|
|
|
2017-01-31 15:55:00 +03:00
|
|
|
if (!NIL_P(f) && f != rb_stdin) {
|
1999-01-20 07:59:39 +03:00
|
|
|
rb_io_close(f);
|
|
|
|
}
|
2016-02-24 11:21:04 +03:00
|
|
|
return Qnil;
|
2008-10-27 09:58:28 +03:00
|
|
|
}
|
|
|
|
|
2017-10-29 18:51:23 +03:00
|
|
|
static rb_ast_t *
|
2017-05-28 12:49:30 +03:00
|
|
|
load_file(VALUE parser, VALUE fname, VALUE f, int script, ruby_cmdline_options_t *opt)
|
2008-10-27 09:58:28 +03:00
|
|
|
{
|
|
|
|
struct load_file_arg arg;
|
|
|
|
arg.parser = parser;
|
|
|
|
arg.fname = fname;
|
|
|
|
arg.script = script;
|
|
|
|
arg.opt = opt;
|
2017-05-28 12:49:30 +03:00
|
|
|
arg.f = f;
|
2017-10-29 18:51:23 +03:00
|
|
|
return (rb_ast_t *)rb_ensure(load_file_internal, (VALUE)&arg,
|
2017-10-27 19:44:57 +03:00
|
|
|
restore_load_file, (VALUE)&arg);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2006-12-31 18:02:22 +03:00
|
|
|
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
|
|
|
rb_load_file(const char *fname)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2011-10-31 22:05:03 +04:00
|
|
|
VALUE fname_v = rb_str_new_cstr(fname);
|
2013-07-26 08:04:23 +04:00
|
|
|
return rb_load_file_str(fname_v);
|
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
|
|
|
rb_load_file_str(VALUE fname_v)
|
|
|
|
{
|
2017-05-28 12:49:30 +03:00
|
|
|
return rb_parser_load_file(rb_parser_new(), fname_v);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2016-03-19 08:46:20 +03:00
|
|
|
void *
|
|
|
|
rb_parser_load_file(VALUE parser, VALUE fname_v)
|
|
|
|
{
|
2016-08-19 13:44:53 +03:00
|
|
|
ruby_cmdline_options_t opt;
|
2017-05-28 12:49:30 +03:00
|
|
|
VALUE f = open_load_file(fname_v, &cmdline_options_init(&opt)->xflag);
|
|
|
|
return load_file(parser, fname_v, f, 0, &opt);
|
2016-03-19 08:46:20 +03:00
|
|
|
}
|
|
|
|
|
2013-08-07 18:12:04 +04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* Process.argv0 -> frozen_string
|
|
|
|
*
|
|
|
|
* Returns the name of the script being executed. The value is not
|
|
|
|
* affected by assigning a new value to $0.
|
2013-09-02 09:42:02 +04:00
|
|
|
*
|
|
|
|
* This method first appeared in Ruby 2.1 to serve as a global
|
|
|
|
* variable free means to get the script name.
|
2013-08-07 18:12:04 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
proc_argv0(VALUE process)
|
|
|
|
{
|
|
|
|
return rb_orig_progname;
|
|
|
|
}
|
|
|
|
|
2017-10-19 14:24:03 +03:00
|
|
|
static VALUE ruby_setproctitle(VALUE title);
|
|
|
|
|
2013-08-07 18:12:04 +04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* Process.setproctitle(string) -> string
|
|
|
|
*
|
2013-09-02 09:42:02 +04:00
|
|
|
* Sets the process title that appears on the ps(1) command. Not
|
|
|
|
* necessarily effective on all platforms. No exception will be
|
|
|
|
* raised regardless of the result, nor will NotImplementedError be
|
|
|
|
* raised even if the platform does not support the feature.
|
2013-08-07 18:12:04 +04:00
|
|
|
*
|
|
|
|
* Calling this method does not affect the value of $0.
|
|
|
|
*
|
|
|
|
* Process.setproctitle('myapp: worker #%d' % worker_id)
|
2013-09-02 09:42:02 +04:00
|
|
|
*
|
|
|
|
* This method first appeared in Ruby 2.1 to serve as a global
|
|
|
|
* variable free means to change the process title.
|
2013-08-07 18:12:04 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
proc_setproctitle(VALUE process, VALUE title)
|
|
|
|
{
|
2017-10-19 14:24:03 +03:00
|
|
|
return ruby_setproctitle(title);
|
|
|
|
}
|
2013-08-07 18:12:04 +04:00
|
|
|
|
2017-10-19 14:24:03 +03:00
|
|
|
static VALUE
|
|
|
|
ruby_setproctitle(VALUE title)
|
|
|
|
{
|
|
|
|
const char *ptr = StringValueCStr(title);
|
|
|
|
setproctitle("%.*s", RSTRING_LENINT(title), ptr);
|
2013-08-07 18:12:04 +04:00
|
|
|
return title;
|
|
|
|
}
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
static void
|
2019-08-27 05:16:52 +03:00
|
|
|
set_arg0(VALUE val, ID id, VALUE *_)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2007-09-29 01:47:31 +04:00
|
|
|
if (origarg.argv == 0)
|
2006-12-31 18:02:22 +03:00
|
|
|
rb_raise(rb_eRuntimeError, "$0 not initialized");
|
2008-06-01 22:23:10 +04:00
|
|
|
|
2017-10-19 14:24:03 +03:00
|
|
|
rb_progname = rb_str_new_frozen(ruby_setproctitle(val));
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2014-11-29 10:53:17 +03:00
|
|
|
static inline VALUE
|
|
|
|
external_str_new_cstr(const char *p)
|
|
|
|
{
|
|
|
|
#if UTF8_PATH
|
|
|
|
VALUE str = rb_utf8_str_new_cstr(p);
|
2018-07-27 08:42:56 +03:00
|
|
|
str = str_conv_enc(str, NULL, rb_default_external_encoding());
|
|
|
|
return str;
|
2014-11-29 10:53:17 +03:00
|
|
|
#else
|
|
|
|
return rb_external_str_new_cstr(p);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2012-06-14 06:21:51 +04:00
|
|
|
/*! Sets the current script name to this value.
|
|
|
|
*
|
2013-05-19 07:10:21 +04:00
|
|
|
* This is similar to <code>$0 = name</code> in Ruby level but also affects
|
2012-06-14 06:21:51 +04:00
|
|
|
* <code>Method#location</code> and others.
|
|
|
|
*/
|
1998-01-16 15:13:05 +03:00
|
|
|
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
|
|
|
ruby_script(const char *name)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
|
|
|
if (name) {
|
2014-11-29 18:02:58 +03:00
|
|
|
rb_orig_progname = rb_progname = external_str_new_cstr(name);
|
2009-05-17 09:02:58 +04:00
|
|
|
rb_vm_set_progname(rb_progname);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-06-14 06:22:08 +04:00
|
|
|
/*! Sets the current script name to this value.
|
|
|
|
*
|
|
|
|
* Same as ruby_script() but accepts a VALUE.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
ruby_set_script_name(VALUE name)
|
|
|
|
{
|
2013-08-07 18:12:08 +04:00
|
|
|
rb_orig_progname = rb_progname = rb_str_dup(name);
|
2012-06-14 06:22:08 +04:00
|
|
|
rb_vm_set_progname(rb_progname);
|
|
|
|
}
|
|
|
|
|
1998-01-16 15:13:05 +03:00
|
|
|
static void
|
2016-08-19 13:44:53 +03:00
|
|
|
init_ids(ruby_cmdline_options_t *opt)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2008-06-09 08:20:07 +04:00
|
|
|
rb_uid_t uid = getuid();
|
|
|
|
rb_uid_t euid = geteuid();
|
|
|
|
rb_gid_t gid = getgid();
|
|
|
|
rb_gid_t egid = getegid();
|
|
|
|
|
|
|
|
if (uid != euid) opt->setids |= 1;
|
|
|
|
if (egid != gid) opt->setids |= 2;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2008-06-09 08:20:07 +04:00
|
|
|
#undef forbid_setid
|
1998-01-16 15:13:05 +03:00
|
|
|
static void
|
2017-01-31 15:54:59 +03:00
|
|
|
forbid_setid(const char *s, const ruby_cmdline_options_t *opt)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2008-06-09 08:20:07 +04:00
|
|
|
if (opt->setids & 1)
|
* 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
|
|
|
rb_raise(rb_eSecurityError, "no %s allowed while running setuid", s);
|
2008-06-09 08:20:07 +04:00
|
|
|
if (opt->setids & 2)
|
* 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
|
|
|
rb_raise(rb_eSecurityError, "no %s allowed while running setgid", s);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
2003-07-29 22:26:55 +04:00
|
|
|
static void
|
2019-08-27 05:16:52 +03:00
|
|
|
verbose_setter(VALUE val, ID id, VALUE *variable)
|
2003-07-29 22:26:55 +04:00
|
|
|
{
|
2008-06-18 16:08:16 +04:00
|
|
|
*variable = RTEST(val) ? Qtrue : val;
|
2003-07-29 22:26:55 +04:00
|
|
|
}
|
|
|
|
|
2004-03-03 07:55:35 +03:00
|
|
|
static VALUE
|
2019-08-27 05:16:52 +03:00
|
|
|
opt_W_getter(ID id, VALUE *variable)
|
2004-03-03 07:55:35 +03:00
|
|
|
{
|
2008-06-18 16:08:16 +04:00
|
|
|
switch (*variable) {
|
2008-06-17 18:02:20 +04:00
|
|
|
case Qnil:
|
2006-12-31 18:02:22 +03:00
|
|
|
return INT2FIX(0);
|
2008-06-17 18:02:20 +04:00
|
|
|
case Qfalse:
|
2006-12-31 18:02:22 +03:00
|
|
|
return INT2FIX(1);
|
2008-06-17 18:02:20 +04:00
|
|
|
case Qtrue:
|
2006-12-31 18:02:22 +03:00
|
|
|
return INT2FIX(2);
|
2012-04-15 04:06:13 +04:00
|
|
|
default:
|
|
|
|
return Qnil;
|
2008-06-17 18:02:20 +04:00
|
|
|
}
|
2004-03-03 07:55:35 +03:00
|
|
|
}
|
|
|
|
|
2012-06-14 06:21:51 +04:00
|
|
|
/*! Defines built-in variables */
|
1998-01-16 15:13:05 +03:00
|
|
|
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
|
|
|
ruby_prog_init(void)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2003-07-29 22:26:55 +04:00
|
|
|
rb_define_hooked_variable("$VERBOSE", &ruby_verbose, 0, verbose_setter);
|
|
|
|
rb_define_hooked_variable("$-v", &ruby_verbose, 0, verbose_setter);
|
|
|
|
rb_define_hooked_variable("$-w", &ruby_verbose, 0, verbose_setter);
|
2009-06-21 17:35:41 +04:00
|
|
|
rb_define_hooked_variable("$-W", &ruby_verbose, opt_W_getter, rb_gvar_readonly_setter);
|
1999-08-13 09:45:20 +04:00
|
|
|
rb_define_variable("$DEBUG", &ruby_debug);
|
|
|
|
rb_define_variable("$-d", &ruby_debug);
|
1998-01-16 15:13:05 +03:00
|
|
|
|
1998-01-16 15:19:22 +03:00
|
|
|
rb_define_hooked_variable("$0", &rb_progname, 0, set_arg0);
|
2004-04-02 06:36:48 +04:00
|
|
|
rb_define_hooked_variable("$PROGRAM_NAME", &rb_progname, 0, set_arg0);
|
1998-01-16 15:13:05 +03:00
|
|
|
|
2013-08-07 18:12:08 +04:00
|
|
|
rb_define_module_function(rb_mProcess, "argv0", proc_argv0, 0);
|
2013-08-07 18:12:04 +04:00
|
|
|
rb_define_module_function(rb_mProcess, "setproctitle", proc_setproctitle, 1);
|
|
|
|
|
2011-06-29 07:09:34 +04:00
|
|
|
/*
|
2015-11-19 13:45:04 +03:00
|
|
|
* ARGV contains the command line arguments used to run ruby.
|
2011-06-29 07:09:34 +04:00
|
|
|
*
|
|
|
|
* A library like OptionParser can be used to process command-line
|
|
|
|
* arguments.
|
|
|
|
*/
|
1998-01-16 15:19:22 +03:00
|
|
|
rb_define_global_const("ARGV", rb_argv);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
ruby_set_argv(int argc, char **argv)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
|
|
|
int i;
|
2008-03-01 11:59:04 +03:00
|
|
|
VALUE av = rb_argv;
|
1998-01-16 15:13:05 +03:00
|
|
|
|
|
|
|
#if defined(USE_DLN_A_OUT)
|
2017-08-09 14:03:55 +03:00
|
|
|
if (origarg.argc > 0 && origarg.argv)
|
2007-09-29 01:47:31 +04:00
|
|
|
dln_argv0 = origarg.argv[0];
|
2017-08-09 14:03:55 +03:00
|
|
|
else if (argc > 0 && argv)
|
2006-12-31 18:02:22 +03:00
|
|
|
dln_argv0 = argv[0];
|
1998-01-16 15:13:05 +03:00
|
|
|
#endif
|
2008-03-01 11:59:04 +03:00
|
|
|
rb_ary_clear(av);
|
2006-12-31 18:02:22 +03:00
|
|
|
for (i = 0; i < argc; i++) {
|
2014-11-29 10:53:17 +03:00
|
|
|
VALUE arg = external_str_new_cstr(argv[i]);
|
2003-03-25 11:26:08 +03:00
|
|
|
|
|
|
|
OBJ_FREEZE(arg);
|
2008-03-01 11:59:04 +03:00
|
|
|
rb_ary_push(av, arg);
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 12:12:18 +04:00
|
|
|
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
|
|
|
ruby_process_options(int argc, char **argv)
|
1998-01-16 15:13:05 +03:00
|
|
|
{
|
2016-08-19 13:44:53 +03:00
|
|
|
ruby_cmdline_options_t opt;
|
2009-02-22 07:04:31 +03:00
|
|
|
VALUE iseq;
|
2015-11-29 05:25:12 +03:00
|
|
|
const char *script_name = (argc > 0 && argv[0]) ? argv[0] : ruby_engine;
|
* include/ruby/{intern,ruby}.h, compile.[ch], error.c, eval.c,
eval_load.c, gc.c, iseq.c, main.c, parse.y, re.c, ruby.c,
yarvcore.[ch] (ruby_eval_tree, ruby_sourcefile, ruby_sourceline,
ruby_nerrs): purge global variables.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12700 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-07-05 12:12:18 +04:00
|
|
|
|
2017-08-09 14:03:55 +03:00
|
|
|
if (!origarg.argv || origarg.argc <= 0) {
|
|
|
|
origarg.argc = argc;
|
|
|
|
origarg.argv = argv;
|
|
|
|
}
|
2012-11-23 19:00:55 +04:00
|
|
|
ruby_script(script_name); /* for the time being */
|
2008-06-10 06:25:18 +04:00
|
|
|
rb_argv0 = rb_str_new4(rb_progname);
|
* gc.c, include/ruby/ruby.h: rename rb_register_mark_object()
to rb_gc_register_mark_object().
* eval.c, vm.c: initialize vm->mark_object_ary at
Init_top_self().
* bignum.c, complex.c, encoding.c, ext/win32ole/win32ole.c,
io.c, load.c, marshal.c, rational.c, ruby.c, vm.c:
use rb_gc_register_mark_object() instead of
rb_global_variable() or rb_gc_register_address().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@19365 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-09-15 18:59:14 +04:00
|
|
|
rb_gc_register_mark_object(rb_argv0);
|
2009-05-17 09:02:58 +04:00
|
|
|
iseq = process_options(argc, argv, cmdline_options_init(&opt));
|
2011-05-14 14:49:47 +04:00
|
|
|
|
|
|
|
#ifndef HAVE_SETPROCTITLE
|
2014-11-19 18:57:31 +03:00
|
|
|
ruby_init_setproctitle(argc, argv);
|
2011-05-14 14:49:47 +04:00
|
|
|
#endif
|
|
|
|
|
2009-02-22 07:04:31 +03:00
|
|
|
return (void*)(struct RData*)iseq;
|
1998-01-16 15:13:05 +03:00
|
|
|
}
|
2007-09-29 12:45:24 +04:00
|
|
|
|
2011-10-30 13:46:56 +04:00
|
|
|
static void
|
|
|
|
fill_standard_fds(void)
|
|
|
|
{
|
|
|
|
int f0, f1, f2, fds[2];
|
2011-10-30 17:34:04 +04:00
|
|
|
struct stat buf;
|
|
|
|
f0 = fstat(0, &buf) == -1 && errno == EBADF;
|
|
|
|
f1 = fstat(1, &buf) == -1 && errno == EBADF;
|
|
|
|
f2 = fstat(2, &buf) == -1 && errno == EBADF;
|
2011-10-30 13:46:56 +04:00
|
|
|
if (f0) {
|
|
|
|
if (pipe(fds) == 0) {
|
|
|
|
close(fds[1]);
|
|
|
|
if (fds[0] != 0) {
|
|
|
|
dup2(fds[0], 0);
|
|
|
|
close(fds[0]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (f1 || f2) {
|
|
|
|
if (pipe(fds) == 0) {
|
|
|
|
close(fds[0]);
|
|
|
|
if (f1 && fds[1] != 1)
|
|
|
|
dup2(fds[1], 1);
|
|
|
|
if (f2 && fds[1] != 2)
|
|
|
|
dup2(fds[1], 2);
|
|
|
|
if (fds[1] != 1 && fds[1] != 2)
|
|
|
|
close(fds[1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-09 14:03:55 +03:00
|
|
|
/*! Initializes the process for libruby.
|
2012-06-14 06:21:51 +04:00
|
|
|
*
|
|
|
|
* This function assumes this process is ruby(1) and it has just started.
|
2017-08-09 14:03:55 +03:00
|
|
|
* Usually programs that embed CRuby interpreter may not call this function,
|
|
|
|
* and may do their own initialization.
|
|
|
|
* argc and argv cannot be NULL.
|
2012-06-14 06:21:51 +04:00
|
|
|
*/
|
2007-09-29 12:45:24 +04:00
|
|
|
void
|
|
|
|
ruby_sysinit(int *argc, char ***argv)
|
|
|
|
{
|
2009-05-17 03:55:46 +04:00
|
|
|
#if defined(_WIN32)
|
2007-09-29 12:45:24 +04:00
|
|
|
rb_w32_sysinit(argc, argv);
|
|
|
|
#endif
|
2017-08-09 14:03:55 +03:00
|
|
|
if (*argc >= 0 && *argv) {
|
|
|
|
origarg.argc = *argc;
|
|
|
|
origarg.argv = *argv;
|
2007-10-03 05:06:57 +04:00
|
|
|
#if defined(USE_DLN_A_OUT)
|
2017-08-09 14:03:55 +03:00
|
|
|
dln_argv0 = origarg.argv[0];
|
2007-10-03 05:06:57 +04:00
|
|
|
#endif
|
2017-08-09 14:03:55 +03:00
|
|
|
}
|
2011-10-30 13:46:56 +04:00
|
|
|
fill_standard_fds();
|
2007-09-29 12:45:24 +04:00
|
|
|
}
|