diff options
Diffstat (limited to 'template/prelude.c.tmpl')
-rw-r--r-- | template/prelude.c.tmpl | 144 |
1 files changed, 45 insertions, 99 deletions
diff --git a/template/prelude.c.tmpl b/template/prelude.c.tmpl index a36e572a41..386511f20c 100644 --- a/template/prelude.c.tmpl +++ b/template/prelude.c.tmpl @@ -20,7 +20,6 @@ class Prelude def initialize(output, preludes, vpath) @output = output - @have_sublib = false @vpath = vpath @prelude_count = 0 @builtin_count = 0 @@ -44,11 +43,14 @@ class Prelude lineno = 0 result = [@preludes.size, @vpath.strip(filename), lines, sub] @vpath.foreach(filename) do |line| - line.force_encoding("ASCII-8BIT") if line.respond_to?(:force_encoding) + if line.respond_to?(:force_encoding) + enc = line.encoding + line.force_encoding("ASCII-8BIT") + end line.rstrip! lineno += 1 @preludes[filename] ||= result - comment = ($1 || '' if line.sub!(/(?:^|\s+)\#(?:$|[#\s](.*))/, '')) + comment = ($1 || '' if line.sub!(/(?:^|\s+)\#(?!\{)(?:$|(?:[#\s]|(?=\W))(.*))/, '')) if !line.empty? or start_line line << "\n" start_line ||= lineno @@ -64,12 +66,15 @@ class Prelude end path = translate("#{path}.rb", true) rescue nil if path - @have_sublib = true - "TMP_RUBY_PREFIX.require(#{path[0]})" + # This library will be loaded before this, + # the order cannot be preserved + comment = "#{orig} #{comment}".rstrip + "" else orig end end + comment.force_encoding(enc) if enc and comment lines << [line, comment] end result << (start_line || 1) @@ -85,6 +90,7 @@ Prelude.new(output, ARGV, vpath).instance_eval do */ %unless @preludes.empty? #include "internal.h" +#include "internal/ruby_parser.h" #include "internal/warnings.h" #include "iseq.h" #include "ruby/ruby.h" @@ -131,59 +137,43 @@ static const struct { COMPILER_WARNING_POP -% if @have_sublib -#define PRELUDE_COUNT <%=preludes.size%> - -struct prelude_env { - volatile VALUE prefix_path; -#if PRELUDE_COUNT > 0 - char loaded[PRELUDE_COUNT]; -#endif -}; - -static VALUE -prelude_prefix_path(VALUE self) -{ - struct prelude_env *ptr = DATA_PTR(self); - return ptr->prefix_path; -} - -% end % unless preludes.empty? #define PRELUDE_NAME(n) rb_usascii_str_new_static(prelude_name##n, sizeof(prelude_name##n)-1) #define PRELUDE_CODE(n) rb_utf8_str_new_static(prelude_code##n.L0, sizeof(prelude_code##n)) -static rb_ast_t * -prelude_ast(VALUE name, VALUE code, int line) +static VALUE +prelude_vast(VALUE name, VALUE code, int line) { - rb_ast_t *ast = rb_parser_compile_string_path(rb_parser_new(), name, code, line); - if (!ast->body.root) { - rb_ast_dispose(ast); - rb_exc_raise(rb_errinfo()); + rb_ast_t *ast; + VALUE vast = rb_parser_compile_string_path(rb_parser_new(), name, code, line); + ast = rb_ruby_ast_data_get(vast); + if (!ast || !ast->body.root) { + if (ast) rb_ast_dispose(ast); + rb_exc_raise(rb_errinfo()); } - return ast; + return vast; } % end % if @builtin_count > 0 -#define PRELUDE_AST(n, name_str, start_line) \ +#define PRELUDE_VAST(n, name_str, start_line) \ (((sizeof(prelude_name<%='##'%><%=%>n) - prefix_len - 2) == namelen) && \ (strncmp(prelude_name<%='##'%><%=%>n + prefix_len, feature_name, namelen) == 0) ? \ - prelude_ast((name_str) = PRELUDE_NAME(n), PRELUDE_CODE(n), start_line) : 0) + prelude_vast((name_str) = PRELUDE_NAME(n), PRELUDE_CODE(n), start_line) : Qnil) -rb_ast_t * -rb_builtin_ast(const char *feature_name, VALUE *name_str) +VALUE +rb_builtin_vast(const char *feature_name, VALUE *name_str) { const size_t prefix_len = rb_strlen_lit("<internal:"); size_t namelen = strlen(feature_name); - rb_ast_t *ast = 0; + VALUE vast = Qnil; % @preludes.each_value do |i, prelude, lines, sub, start_line| -% if sub and sub != true - if ((ast = PRELUDE_AST(<%=i%><%=%>, *name_str, <%=start_line%>)) != 0) return ast; +% if sub + if (!NIL_P(vast = PRELUDE_VAST(<%=i%><%=%>, *name_str, <%=start_line%>))) return vast; % end % end - return ast; + return vast; } % end @@ -196,82 +186,38 @@ static void prelude_eval(VALUE code, VALUE name, int line) { static const rb_compile_option_t optimization = { - TRUE, /* int inline_const_cache; */ - TRUE, /* int peephole_optimization; */ - FALSE,/* int tailcall_optimization; */ - TRUE, /* int specialized_instruction; */ - TRUE, /* int operands_unification; */ - TRUE, /* int instructions_unification; */ - TRUE, /* int stack_caching; */ - TRUE, /* int frozen_string_literal; */ - FALSE, /* int debug_frozen_string_literal; */ - FALSE, /* unsigned int coverage_enabled; */ - 0, /* int debug_level; */ + TRUE, /* unsigned int inline_const_cache; */ + TRUE, /* unsigned int peephole_optimization; */ + FALSE,/* unsigned int tailcall_optimization; */ + TRUE, /* unsigned int specialized_instruction; */ + TRUE, /* unsigned int operands_unification; */ + TRUE, /* unsigned int instructions_unification; */ + TRUE, /* unsigned int frozen_string_literal; */ + FALSE, /* unsigned int debug_frozen_string_literal; */ + FALSE, /* unsigned int coverage_enabled; */ + 0, /* int debug_level; */ }; - rb_ast_t *ast = prelude_ast(name, code, line); - rb_iseq_eval(rb_iseq_new_with_opt(&ast->body, name, name, Qnil, INT2FIX(line), - NULL, 0, ISEQ_TYPE_TOP, &optimization)); + rb_ast_t *ast; + VALUE vast = prelude_vast(name, code, line); + ast = rb_ruby_ast_data_get(vast); + rb_iseq_eval(rb_iseq_new_with_opt(vast, name, name, Qnil, line, + NULL, 0, ISEQ_TYPE_TOP, &optimization, + Qnil)); rb_ast_dispose(ast); } COMPILER_WARNING_POP % end -% if @have_sublib -static VALUE -prelude_require(VALUE self, VALUE nth) -{ - struct prelude_env *ptr = DATA_PTR(self); - VALUE code, name; - int n = FIX2INT(nth); - int start_line; - - if (n > PRELUDE_COUNT) return Qfalse; - if (ptr->loaded[n]) return Qfalse; - ptr->loaded[n] = 1; - switch (n) { -% @preludes.each_value do |i, prelude, lines, sub, start_line| -% if sub == true - case <%=i%><%=%>: - code = PRELUDE_CODE(<%=i%><%=%>); - name = PRELUDE_NAME(<%=i%><%=%>); - start_line = <%=start_line%>; - break; -% end -% end - default: - return Qfalse; - } - prelude_eval(code, name, start_line); - return Qtrue; -} - -% end %end % init_name = @output && @output[/\w+(?=_prelude.c\b)/] || 'prelude' void Init_<%=init_name%><%=%>(void) { %unless @prelude_count.zero? -% if @have_sublib - struct prelude_env memo; - ID name = rb_intern("TMP_RUBY_PREFIX"); - VALUE prelude = Data_Wrap_Struct(rb_cData, 0, 0, &memo); - - memo.prefix_path = rb_const_remove(rb_cObject, name); - rb_const_set(rb_cObject, name, prelude); - rb_define_singleton_method(prelude, "to_s", prelude_prefix_path, 0); -% end -% if @have_sublib - memset(memo.loaded, 0, sizeof(memo.loaded)); - rb_define_singleton_method(prelude, "require", prelude_require, 1); -% end % preludes.each do |i, prelude, lines, sub, start_line| % next if sub - prelude_eval(PRELUDE_CODE(<%=i%><%=%>), PRELUDE_NAME(<%=i%><%=%>), <%=start_line%>); -% end -% if @have_sublib - rb_gc_force_recycle(prelude); + prelude_eval(PRELUDE_CODE(<%=i%><%=%>), PRELUDE_NAME(<%=i%><%=%>), <%=start_line%><%=%>); % end #if 0 |