Created
August 26, 2009 16:52
-
-
Save pbevin/175639 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/kernel/common/compiled_method.rb b/kernel/common/compiled_method.rb | |
index df80cc9..338c18a 100644 | |
--- a/kernel/common/compiled_method.rb | |
+++ b/kernel/common/compiled_method.rb | |
@@ -198,6 +198,8 @@ module Rubinius | |
class Script | |
attr_accessor :path | |
+ def root_script=(value); @root_script = value; end | |
+ def root_script?; @root_script; end | |
end | |
def as_script(script=nil) | |
diff --git a/kernel/common/data.rb b/kernel/common/data.rb | |
new file mode 100644 | |
index 0000000..56901c5 | |
--- /dev/null | |
+++ b/kernel/common/data.rb | |
@@ -0,0 +1,6 @@ | |
+module Rubinius | |
+ def self.set_data(str) | |
+ require 'stringio' | |
+ Object.const_set :DATA, StringIO.new(str) | |
+ end | |
+end | |
diff --git a/kernel/common/load_order.txt b/kernel/common/load_order.txt | |
index cf063c3..f521835 100644 | |
--- a/kernel/common/load_order.txt | |
+++ b/kernel/common/load_order.txt | |
@@ -37,6 +37,7 @@ compiled_method.rbc | |
continuation.rbc | |
delegated_method.rbc | |
fixnum.rbc | |
+data.rbc | |
dir.rbc | |
dir_186.rbc | |
dir_glob.rbc | |
diff --git a/kernel/common/static_scope.rb b/kernel/common/static_scope.rb | |
index e4003b1..299c20e 100644 | |
--- a/kernel/common/static_scope.rb | |
+++ b/kernel/common/static_scope.rb | |
@@ -74,12 +74,8 @@ module Rubinius | |
end | |
def active_path | |
- scope = self | |
- while scope and !scope.script | |
- scope = scope.parent | |
- end | |
- | |
- if scope and script = scope.script | |
+ script = current_script | |
+ if script | |
if path = script.path | |
return path.dup | |
end | |
@@ -88,6 +84,19 @@ module Rubinius | |
return "__unknown__.rb" | |
end | |
+ def root_script? | |
+ script = current_script | |
+ return script && script.root_script? | |
+ end | |
+ | |
+ def current_script | |
+ scope = self | |
+ while scope and !scope.script | |
+ scope = scope.parent | |
+ end | |
+ return scope && scope.script | |
+ end | |
+ | |
def const_defined?(name) | |
scope = self | |
while scope and scope.module != Object | |
diff --git a/kernel/compiler/bytecode.rb b/kernel/compiler/bytecode.rb | |
index 13e40fb..143ad55 100644 | |
--- a/kernel/compiler/bytecode.rb | |
+++ b/kernel/compiler/bytecode.rb | |
@@ -1052,6 +1052,27 @@ class Compiler | |
end | |
end | |
+ class EndData | |
+ def bytecode(g) | |
+ # if (scope.root_script?) | |
+ # Rubinius.set_data(...) | |
+ # end | |
+ not_root = g.new_label | |
+ done = g.new_label | |
+ | |
+ g.push_scope | |
+ g.send :root_script?, 0 | |
+ g.gif not_root | |
+ g.push_const(:Rubinius) | |
+ g.push_literal(data) | |
+ g.send :set_data, 1 | |
+ g.goto done | |
+ not_root.set! | |
+ g.push_nil | |
+ done.set! | |
+ end | |
+ end | |
+ | |
class Ensure | |
def bytecode(g) | |
pos(g) | |
diff --git a/kernel/compiler/compile.rb b/kernel/compiler/compile.rb | |
index a9b47f2..e5ffb86 100644 | |
--- a/kernel/compiler/compile.rb | |
+++ b/kernel/compiler/compile.rb | |
@@ -243,6 +243,7 @@ class Compiler | |
end | |
cm.as_script do |script| | |
script.path = rb_path | |
+ script.root_script = options[:root_script] | |
end | |
rescue Exception => e | |
$LOADED_FEATURES.delete(rb) if requiring | |
diff --git a/kernel/compiler/nodes.rb b/kernel/compiler/nodes.rb | |
index 97839e1..805a3ed 100644 | |
--- a/kernel/compiler/nodes.rb | |
+++ b/kernel/compiler/nodes.rb | |
@@ -989,6 +989,16 @@ raise "no" | |
kind :zarray | |
end | |
+ class EndData < Node | |
+ kind :end_data | |
+ | |
+ def args(data) | |
+ @data = data | |
+ end | |
+ | |
+ attr_accessor :data | |
+ end | |
+ | |
class Ensure < Node | |
kind :ensure | |
diff --git a/kernel/loader.rb b/kernel/loader.rb | |
index ab74f73..d45b303 100644 | |
--- a/kernel/loader.rb | |
+++ b/kernel/loader.rb | |
@@ -317,7 +317,8 @@ module Rubinius | |
if File.exist?(@script) | |
$0 = @script | |
Compiler::Utils.debug_script! if @debugging | |
- Compiler::Utils.load_from_extension @script, :no_rbc => @no_rbc | |
+ Compiler::Utils.load_from_extension @script, | |
+ :no_rbc => @no_rbc, :root_script => true | |
else | |
if @script.suffix?(".rb") | |
puts "Unable to find '#{@script}'" | |
diff --git a/vm/codegen/node_types.rb b/vm/codegen/node_types.rb | |
new file mode 100644 | |
index 0000000..5022267 | |
--- /dev/null | |
+++ b/vm/codegen/node_types.rb | |
@@ -0,0 +1,191 @@ | |
+node_types = %w{ | |
+ method | |
+ fbody | |
+ cfunc | |
+ scope | |
+ block | |
+ if | |
+ case | |
+ when | |
+ opt_n | |
+ while | |
+ until | |
+ iter | |
+ for | |
+ break | |
+ next | |
+ redo | |
+ retry | |
+ begin | |
+ rescue | |
+ resbody | |
+ ensure | |
+ and | |
+ or | |
+ not | |
+ masgn | |
+ lasgn | |
+ dasgn | |
+ dasgn_curr | |
+ gasgn | |
+ iasgn | |
+ cdecl | |
+ cvasgn | |
+ cvdecl | |
+ op_asgn1 | |
+ op_asgn2 | |
+ op_asgn_and | |
+ op_asgn_or | |
+ call | |
+ fcall | |
+ vcall | |
+ super | |
+ zsuper | |
+ array | |
+ zarray | |
+ hash | |
+ return | |
+ yield | |
+ lvar | |
+ dvar | |
+ gvar | |
+ ivar | |
+ const | |
+ cvar | |
+ nth_ref | |
+ back_ref | |
+ match | |
+ match2 | |
+ match3 | |
+ lit | |
+ str | |
+ dstr | |
+ xstr | |
+ dxstr | |
+ evstr | |
+ dregx | |
+ dregx_once | |
+ args | |
+ argscat | |
+ argspush | |
+ splat | |
+ to_ary | |
+ svalue | |
+ block_arg | |
+ block_pass | |
+ defn | |
+ defs | |
+ alias | |
+ valias | |
+ undef | |
+ class | |
+ module | |
+ sclass | |
+ colon2 | |
+ colon3 | |
+ cref | |
+ dot2 | |
+ dot3 | |
+ flip2 | |
+ flip3 | |
+ attrset | |
+ self | |
+ nil | |
+ true | |
+ false | |
+ defined | |
+ newline | |
+ postexe | |
+ dmethod | |
+ bmethod | |
+ memo | |
+ ifunc | |
+ dsym | |
+ attrasgn | |
+ regex | |
+ fixnum | |
+ number | |
+ hexnum | |
+ binnum | |
+ octnum | |
+ float | |
+ negate | |
+ last | |
+ file | |
+ end_data | |
+} | |
+ | |
+File.open("vm/parser/node_types.cpp", "w") do |f| | |
+ f.puts <<EOF | |
+/* This file is generated by node_types.rb. Do not edit. */ | |
+ | |
+#include "node_types.hpp" | |
+ | |
+namespace rubinius { | |
+ namespace parser { | |
+ | |
+ static const char node_types[] = { | |
+EOF | |
+ | |
+ node_types.each do |type| | |
+ f.puts(" \"#{type}\\0\"") | |
+ end | |
+ | |
+ f.puts(" };") | |
+ f.puts | |
+ | |
+ f.puts(" static const unsigned short node_types_offsets[] = {") | |
+ offset = 0 | |
+ | |
+ node_types.each_with_index do |type, index| | |
+ f.puts(",") if index > 0 | |
+ f.write(" #{offset}") | |
+ offset += node_types[index].length + 1 | |
+ end | |
+ | |
+ f.puts <<EOF | |
+ | |
+ }; | |
+ | |
+ const char *get_node_type_string(enum node_type nt) { | |
+ return node_types + node_types_offsets[nt]; | |
+ } | |
+ | |
+ }; // namespace parser | |
+}; // namespace rubinius | |
+EOF | |
+end | |
+ | |
+File.open("vm/parser/node_types.hpp", "w") do |f| | |
+ f.puts <<EOF | |
+/* This file is generated by node_types.rb. Do not edit. */ | |
+ | |
+#ifdef __cplusplus | |
+extern "C" { | |
+#endif | |
+ | |
+namespace rubinius { | |
+ namespace parser { | |
+ | |
+ enum node_type { | |
+EOF | |
+ | |
+ node_types.each_with_index do |type, index| | |
+ f.puts(",") if index > 0 | |
+ f.write(" NODE_#{type.upcase}") | |
+ end | |
+ | |
+ f.puts <<EOF | |
+ | |
+ }; | |
+ | |
+ const char *get_node_type_string(enum node_type nt); | |
+ | |
+ }; // namespace parser | |
+}; // namespace rubinius | |
+ | |
+#ifdef __cplusplus | |
+} | |
+#endif | |
+EOF | |
+end | |
diff --git a/vm/parser/grammar.y b/vm/parser/grammar.y | |
index c746b1e..455052d 100644 | |
--- a/vm/parser/grammar.y | |
+++ b/vm/parser/grammar.y | |
@@ -337,16 +337,17 @@ static NODE *extract_block_vars(rb_parse_state *parse_state, NODE* node, var_tab | |
klEND | |
k__LINE__ | |
k__FILE__ | |
+ k__END__ | |
%token <id> tIDENTIFIER tFID tGVAR tIVAR tCONSTANT tCVAR tXSTRING_BEG | |
-%token <node> tINTEGER tFLOAT tSTRING_CONTENT | |
+%token <node> tINTEGER tFLOAT tSTRING_CONTENT tEND_DATA | |
%token <node> tNTH_REF tBACK_REF | |
%token <num> tREGEXP_END | |
%type <node> singleton strings string string1 xstring regexp | |
%type <node> string_contents xstring_contents string_content | |
%type <node> words qwords word_list qword_list word | |
%type <node> literal numeric dsym cpath | |
-%type <node> bodystmt compstmt stmts stmt expr arg primary command command_call method_call | |
+%type <node> bodystmt compstmt opt_end_data stmts stmt expr arg primary command command_call method_call | |
%type <node> expr_value arg_value primary_value | |
%type <node> if_tail opt_else case_body cases opt_rescue exc_list exc_var opt_ensure | |
%type <node> args when_args call_args call_args2 open_args paren_args opt_paren_args | |
@@ -425,7 +426,7 @@ program : { | |
vps->variables = new LocalState(0); | |
class_nest = 0; | |
} | |
- compstmt | |
+ compstmt opt_end_data | |
{ | |
if ($2 && !compile_for_eval) { | |
/* last expression should not be void */ | |
@@ -439,6 +440,8 @@ program : { | |
} | |
} | |
vps->top = block_append(vps, vps->top, $2); | |
+ if ($3) | |
+ vps->top = block_append(vps, $3, vps->top); | |
class_nest = 0; | |
} | |
; | |
@@ -470,6 +473,12 @@ compstmt : stmts opt_terms | |
} | |
; | |
+opt_end_data : none | |
+ | k__END__ tEND_DATA | |
+ { | |
+ $$ = $2; | |
+ } | |
+ | |
stmts : none | |
| stmt | |
{ | |
@@ -1033,7 +1042,7 @@ op : '|' { $$ = '|'; } | |
| '`' { $$ = '`'; } | |
; | |
-reswords : k__LINE__ | k__FILE__ | klBEGIN | klEND | |
+reswords : k__LINE__ | k__FILE__ | klBEGIN | klEND | k__END__ | |
| kALIAS | kAND | kBEGIN | kBREAK | kCASE | kCLASS | kDEF | |
| kDEFINED | kDO | kELSE | kELSIF | kEND | kENSURE | kFALSE | |
| kFOR | kIN | kMODULE | kNEXT | kNIL | kNOT | |
@@ -2569,6 +2578,7 @@ yycompile(rb_parse_state *parse_state, char *f, int line) | |
/* Setup an initial empty scope. */ | |
heredoc_end = 0; | |
lex_strterm = 0; | |
+ parse_state->end_seen = 0; | |
ruby_sourcefile = f; | |
n = yyparse(parse_state); | |
ruby_debug_lines = 0; | |
@@ -3475,6 +3485,18 @@ yylex(void *yylval_v, void *vstate) | |
} | |
return token; | |
} | |
+ | |
+ if (parse_state->end_seen) { /* After __END__ */ | |
+ newtok(parse_state); | |
+ while ((c = nextc()) != -1) { | |
+ tokadd(c, parse_state); | |
+ } | |
+ tokfix(); | |
+ pslval->node = NEW_END_DATA(string_new(tok(), toklen())); | |
+ parse_state->end_seen = 0; | |
+ return tEND_DATA; | |
+ } | |
+ | |
cmd_state = command_start; | |
command_start = FALSE; | |
retry: | |
@@ -4493,7 +4515,9 @@ yylex(void *yylval_v, void *vstate) | |
case '_': | |
if (was_bol() && whole_match_p("__END__", 7, 0, parse_state)) { | |
parse_state->lex_lastline = 0; | |
- return -1; | |
+ parse_state->end_seen = 1; | |
+ parse_state->lex_p = parse_state->lex_pend; | |
+ return k__END__; | |
} | |
newtok(parse_state); | |
break; | |
diff --git a/vm/parser/grammar_node.hpp b/vm/parser/grammar_node.hpp | |
index c1f7f9b..3c25b0b 100644 | |
--- a/vm/parser/grammar_node.hpp | |
+++ b/vm/parser/grammar_node.hpp | |
@@ -248,6 +248,7 @@ namespace rubinius { | |
#define NEW_NEGATE(l) NEW_NODE(NODE_NEGATE,l,0,0) | |
#define NEW_REGEX(l,o) NEW_NODE(NODE_REGEX,l,0,o) | |
#define NEW_FILE() NEW_NODE(NODE_FILE,0,0,0) | |
+#define NEW_END_DATA(s) NEW_NODE(NODE_END_DATA,s,0,0) | |
#define NOEX_PUBLIC 0 | |
#define NOEX_NOSUPER 1 | |
#define NOEX_PRIVATE 2 | |
diff --git a/vm/parser/grammar_runtime.cpp b/vm/parser/grammar_runtime.cpp | |
index 2659cc6..1872618 100644 | |
--- a/vm/parser/grammar_runtime.cpp | |
+++ b/vm/parser/grammar_runtime.cpp | |
@@ -813,6 +813,7 @@ namespace rubinius { | |
case NODE_XSTR: /* u1 (%x{ls}) */ | |
case NODE_STR: /* u1 */ | |
+ case NODE_END_DATA: | |
array_push(state, current, string_newfrombstr(state, node->nd_str)); | |
bdestroy(node->nd_str); | |
break; | |
diff --git a/vm/parser/node_types.cpp b/vm/parser/node_types.cpp | |
index 5bf7819..79e3d02 100644 | |
--- a/vm/parser/node_types.cpp | |
+++ b/vm/parser/node_types.cpp | |
@@ -119,6 +119,7 @@ namespace rubinius { | |
"negate\0" | |
"last\0" | |
"file\0" | |
+ "end_data\0" | |
}; | |
static const unsigned short node_types_offsets[] = { | |
@@ -234,7 +235,8 @@ namespace rubinius { | |
697, | |
703, | |
710, | |
- 715 | |
+ 715, | |
+ 720 | |
}; | |
const char *get_node_type_string(enum node_type nt) { | |
diff --git a/vm/parser/node_types.hpp b/vm/parser/node_types.hpp | |
index f00eaf2..513c4de 100644 | |
--- a/vm/parser/node_types.hpp | |
+++ b/vm/parser/node_types.hpp | |
@@ -120,7 +120,8 @@ namespace rubinius { | |
NODE_FLOAT, | |
NODE_NEGATE, | |
NODE_LAST, | |
- NODE_FILE | |
+ NODE_FILE, | |
+ NODE_END_DATA | |
}; | |
const char *get_node_type_string(enum node_type nt); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment