Project

General

Profile

Feature #6251 ยป magic-comments-for-compile-options.diff

shugo (Shugo Maeda), 04/03/2012 06:20 PM

View differences:

include/ruby/intern.h
#define rb_argv rb_get_argv()
RUBY_EXTERN VALUE rb_argv0;
VALUE rb_get_argv(void);
void *rb_load_file(const char*);
void *rb_load_file(VALUE, const char*);
void ruby_script(const char*);
void ruby_prog_init(void);
void ruby_set_argv(int, char**);
internal.h
/* iseq.c */
VALUE rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE filepath, VALUE line, VALUE opt);
VALUE rb_iseq_clone(VALUE iseqval, VALUE newcbase);
void rb_compile_option_set(VALUE opt);
/* load.c */
VALUE rb_get_load_path(void);
......
/* parse.y */
VALUE rb_parser_get_yydebug(VALUE);
VALUE rb_parser_set_yydebug(VALUE, VALUE);
VALUE rb_parser_compile_option(VALUE);
int rb_is_const_name(VALUE name);
int rb_is_class_name(VALUE name);
int rb_is_global_name(VALUE name);
iseq.c
}
VALUE
rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE parent)
rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE filepath,
VALUE parent, VALUE compile_option)
{
return rb_iseq_new_with_opt(node, name, filename, filepath, INT2FIX(0), parent, ISEQ_TYPE_TOP,
&COMPILE_OPTION_DEFAULT);
rb_compile_option_t option;
make_compile_option(&option, compile_option);
return rb_iseq_new_with_opt(node, name, filename, filepath, INT2FIX(0),
parent, ISEQ_TYPE_TOP, &option);
}
VALUE
......
return opt;
}
void
rb_compile_option_set(VALUE opt)
{
iseq_s_compile_option_set(Qnil, opt);
}
static VALUE
iseq_s_compile_option_get(VALUE self)
{
load.c
state = EXEC_TAG();
if (state == 0) {
NODE *node;
VALUE iseq;
VALUE parser, iseq;
th->mild_compile_error++;
node = (NODE *)rb_load_file(RSTRING_PTR(fname));
parser = rb_parser_new();
node = (NODE *)rb_load_file(parser, RSTRING_PTR(fname));
loaded = TRUE;
iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, rb_realpath_internal(Qnil, fname, 1), Qfalse);
iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"),
fname, rb_realpath_internal(Qnil, fname, 1),
Qfalse, rb_parser_compile_option(parser));
th->mild_compile_error--;
rb_iseq_eval(iseq);
}
parse.y
int parser_ruby_sourceline; /* current line no. */
rb_encoding *enc;
rb_encoding *utf8;
VALUE compile_option;
int parser_yydebug;
......
rb_compile_warning(ruby_sourcefile, ruby_sourceline, "invalid value for %s: %s", name, val);
}
static void
parser_set_compile_option(struct parser_params *parser,
const char *name, const char *val)
{
switch (*val) {
case 't': case 'T':
if (strcasecmp(val, "true") == 0) {
rb_hash_aset(parser->compile_option, ID2SYM(rb_intern(name)),
Qtrue);
return;
}
break;
case 'f': case 'F':
if (strcasecmp(val, "false") == 0) {
rb_hash_aset(parser->compile_option, ID2SYM(rb_intern(name)),
Qfalse);
return;
}
break;
}
rb_compile_warning(ruby_sourcefile, ruby_sourceline,
"invalid value for %s: %s", name, val);
}
static void
parser_set_compile_option_num(struct parser_params *parser,
const char *name, const char *val)
{
rb_hash_aset(parser->compile_option, ID2SYM(rb_intern(name)),
rb_cstr_to_inum(val, 10, 0));
}
struct magic_comment {
const char *name;
rb_magic_comment_setter_t func;
......
{"coding", magic_comment_encoding, parser_encode_length},
{"encoding", magic_comment_encoding, parser_encode_length},
{"warn_indent", parser_set_token_info},
{"inline_const_cache", parser_set_compile_option},
{"peephole_optimization", parser_set_compile_option},
{"tailcall_optimization", parser_set_compile_option},
{"specialized_instruction", parser_set_compile_option},
{"operands_unification", parser_set_compile_option},
{"instructions_unification", parser_set_compile_option},
{"stack_caching", parser_set_compile_option},
{"trace_instruction", parser_set_compile_option},
{"debug_level", parser_set_compile_option_num},
};
#endif
......
parser->parser_lvtbl = 0;
parser->parser_ruby__end__seen = 0;
parser->parser_ruby_sourcefile = 0;
parser->compile_option = rb_hash_new();
#ifndef RIPPER
parser->is_ripper = 0;
parser->parser_eval_tree_begin = 0;
......
rb_gc_mark(p->parser_lex_input);
rb_gc_mark(p->parser_lex_lastline);
rb_gc_mark(p->parser_lex_nextline);
rb_gc_mark(p->compile_option);
#ifndef RIPPER
rb_gc_mark((VALUE)p->parser_eval_tree_begin) ;
rb_gc_mark((VALUE)p->parser_eval_tree) ;
......
return flag;
}
VALUE
rb_parser_compile_option(VALUE self)
{
struct parser_params *parser;
TypedData_Get_Struct(self, struct parser_params, &parser_data_type,
parser);
return parser->compile_option;
}
#ifdef YYMALLOC
#define HEAPCNT(n, size) ((n) * (size) / sizeof(YYSTYPE))
#define NEWHEAP() rb_node_newnode(NODE_ALLOCA, 0, (VALUE)parser->heap, 0)
ruby.c
tree = load_file(parser, opt->script_name, 1, opt);
});
}
rb_compile_option_set(rb_parser_compile_option(parser));
rb_progname = opt->script_name;
rb_vm_set_progname(rb_progname);
if (opt->dump & DUMP_BIT(yydebug)) return Qtrue;
......
}
void *
rb_load_file(const char *fname)
rb_load_file(VALUE parser, const char *fname)
{
struct cmdline_options opt;
VALUE fname_v = rb_str_new_cstr(fname);
return load_file(rb_parser_new(), fname_v, 0, cmdline_options_init(&opt));
return load_file(parser, fname_v, 0, cmdline_options_init(&opt));
}
static void
vm_core.h
#pragma GCC visibility push(default)
#endif
VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE, enum iseq_type);
VALUE rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE parent);
VALUE rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE parent, VALUE compile_option);
VALUE rb_iseq_new_main(NODE *node, VALUE filename, VALUE filepath);
VALUE rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, enum iseq_type, VALUE);
VALUE rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, enum iseq_type, const rb_compile_option_t*);
    (1-1/1)