Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed Rubinius loading stale runtime.

  • Loading branch information...
commit 3ce0d8a6725689a1203a627f7e10aaa6c54a054e 1 parent c23def8
@brixen brixen authored
View
50 rakelib/kernel.rake
@@ -106,6 +106,9 @@ end
# Compile all compiler files during build stage
opcodes = "lib/compiler/opcodes.rb"
+# Generate a digest of the Rubinius runtime files
+signature_file = "kernel/signature.rb"
+
compiler_files = FileList[
"lib/compiler.rb",
"lib/compiler/**/*.rb",
@@ -124,16 +127,25 @@ parser_files = FileList[
"lib/ext/melbourne/lex.c.blt"
]
+kernel_files = FileList[
+ "kernel/**/*.txt",
+ "kernel/**/*.rb"
+].exclude(signature_file)
+
+config_files = FileList[
+ "Rakefile",
+ "config.rb",
+ "rakelib/*.rb",
+ "rakelib/*.rake"
+]
-# Generate a sha1 of all parser and compiler files to use as
-# as signature in the .rbc files.
-compiler_signature = "kernel/signature.rb"
+signature_files = compiler_files + parser_files + kernel_files + config_files
-file compiler_signature => compiler_files + parser_files do |t|
+file signature_file => signature_files do
require 'digest/sha1'
digest = Digest::SHA1.new
- (compiler_files + parser_files).each do |name|
+ signature_files.each do |name|
File.open name, "r" do |file|
while chunk = file.read(1024)
digest << chunk
@@ -143,13 +155,21 @@ file compiler_signature => compiler_files + parser_files do |t|
# Collapse the digest to a 64bit quantity
hd = digest.hexdigest
- signature_hash = hd[0, 16].to_i(16) ^ hd[16,16].to_i(16) ^ hd[32,8].to_i(16)
+ SIGNATURE_HASH = hd[0, 16].to_i(16) ^ hd[16,16].to_i(16) ^ hd[32,8].to_i(16)
- File.open compiler_signature, "wb" do |file|
+ File.open signature_file, "wb" do |file|
file.puts "# This file is generated by rakelib/kernel.rake. The signature"
- file.puts "# is used to ensure that only current .rbc files are loaded."
+ file.puts "# is used to ensure that the runtime files and VM are in sync."
file.puts "#"
- file.puts "Rubinius::Signature = #{signature_hash}"
+ file.puts "Rubinius::Signature = #{SIGNATURE_HASH}"
+ end
+end
+
+SIGNATURE_HEADER = "vm/gen/signature.h"
+
+file SIGNATURE_HEADER => signature_file do |t|
+ File.open t.name, "wb" do |file|
+ file.puts "#define RBX_SIGNATURE #{SIGNATURE_HASH}ULL"
end
end
@@ -168,7 +188,7 @@ BUILD_CONFIG[:version_list].each do |ver|
end
signature = "runtime/#{ver}/signature"
- file signature => compiler_signature do |t|
+ file signature => signature_file do |t|
File.open t.name, "wb" do |file|
puts "GEN #{t.name}"
file.puts Rubinius::Signature
@@ -196,15 +216,15 @@ BUILD_CONFIG[:version_list].each do |ver|
IO.foreach kernel_load_order do |name|
rbc = runtime_dir + name.chomp!
rb = kernel_dir + name.chop
- kernel_file_task runtime, compiler_signature, ver, rb, rbc
+ kernel_file_task runtime, signature_file, ver, rb, rbc
end
end
- [ compiler_signature,
+ [ signature_file,
"kernel/alpha.rb",
"kernel/loader.rb"
].each do |name|
- kernel_file_task runtime, compiler_signature, ver, name
+ kernel_file_task runtime, signature_file, ver, name
end
compiler_files.map { |f| File.dirname f }.uniq.each do |dir|
@@ -212,7 +232,7 @@ BUILD_CONFIG[:version_list].each do |ver|
end
compiler_files.each do |name|
- compiler_file_task runtime, compiler_signature, ver, name
+ compiler_file_task runtime, signature_file, ver, name
end
end
@@ -239,7 +259,7 @@ namespace :compiler do
require signature_path
end
- task :generate => [compiler_signature]
+ task :generate => [signature_file]
end
desc "Build all kernel files (alias for kernel:build)"
View
1  rakelib/vm.rake
@@ -49,6 +49,7 @@ GENERATED = %W[ vm/gen/revision.h
vm/gen/config_variables.h
#{encoding_database}
#{transcoders_database}
+ #{SIGNATURE_HEADER}
] + TYPE_GEN + INSN_GEN
# Files are in order based on dependencies. For example,
View
1  vm/config.h
@@ -2,6 +2,7 @@
#define RBX_CONFIG
#include "gen/config.h"
+#include "gen/signature.h"
#include "detection.hpp"
#endif
View
60 vm/environment.cpp
@@ -654,21 +654,6 @@ namespace rubinius {
throw std::runtime_error(error);
}
- // Pull in the signature file; this helps control when .rbc files need to
- // be discarded and recompiled due to changes to the compiler since the
- // .rbc files were created.
- std::string sig_path = root + "/signature";
- std::ifstream sig_stream(sig_path.c_str());
- if(sig_stream) {
- sig_stream >> signature_;
- G(rubinius)->set_const(state, "Signature",
- Integer::from(state, signature_));
- sig_stream.close();
- } else {
- std::string error = "Unable to load compiler signature file: " + sig_path;
- throw std::runtime_error(error);
- }
-
version_ = as<Fixnum>(G(rubinius)->get_const(
state, state->symbol("RUBY_LIB_VERSION")))->to_native();
@@ -767,12 +752,47 @@ namespace rubinius {
return argv_[0];
}
- static bool verify_and_set_paths(STATE, std::string prefix) {
+ bool Environment::load_signature(std::string runtime) {
+ std::string path = runtime;
+
+ // TODO: Fix this
+ if(LANGUAGE_20_ENABLED(state)) {
+ path += "/20";
+ } else if(LANGUAGE_19_ENABLED(state)) {
+ path += "/19";
+ } else {
+ path += "/18";
+ }
+
+ path += "/signature";
+
+ std::ifstream signature(path.c_str());
+ if(signature) {
+ signature >> signature_;
+
+ if(signature_ != RBX_SIGNATURE) return false;
+
+ signature.close();
+
+ return true;
+ }
+
+ /*
+ } else {
+ std::string error = "Unable to load compiler signature file: " + sig_path;
+ throw std::runtime_error(error);
+ */
+ return false;
+ }
+
+ bool Environment::verify_paths(std::string prefix) {
struct stat st;
std::string dir = prefix + RBX_RUNTIME_PATH;
if(stat(dir.c_str(), &st) == -1 || !S_ISDIR(st.st_mode)) return false;
+ if(!load_signature(dir)) return false;
+
dir = prefix + RBX_BIN_PATH;
if(stat(dir.c_str(), &st) == -1 || !S_ISDIR(st.st_mode)) return false;
@@ -790,14 +810,14 @@ namespace rubinius {
// 1. Check if our configure prefix is overridden by the environment.
const char* path = getenv("RBX_PREFIX_PATH");
- if(path && verify_and_set_paths(state, path)) {
+ if(path && verify_paths(path)) {
system_prefix_ = path;
return path;
}
// 2. Check if our configure prefix is valid.
path = RBX_PREFIX_PATH;
- if(verify_and_set_paths(state, path)) {
+ if(verify_paths(path)) {
system_prefix_ = path;
return path;
}
@@ -809,7 +829,7 @@ namespace rubinius {
if(exe != std::string::npos) {
std::string prefix = name.substr(0, exe - strlen(RBX_BIN_PATH));
- if(verify_and_set_paths(state, prefix)) {
+ if(verify_paths(prefix)) {
system_prefix_ = prefix;
return prefix;
}
@@ -838,6 +858,8 @@ namespace rubinius {
load_tool();
+ G(rubinius)->set_const(state, "Signature", Integer::from(state, signature_));
+
if(LANGUAGE_20_ENABLED(state)) {
runtime += "/20";
} else if(LANGUAGE_19_ENABLED(state)) {
View
9 vm/environment.hpp
@@ -47,9 +47,10 @@ namespace rubinius {
int argc_;
char** argv_;
- /// Signature to be used to verify the validity of .rbc files.
- /// If the signature in a .rbc file does not match this value, the file
- /// needs to be recompiled.
+ /**
+ * Digest of the runtime and configuration files to keep the runtime
+ * and VM in sync.
+ */
uint64_t signature_;
// The Ruby library version with which the .rbc file is compatible.
@@ -88,6 +89,8 @@ namespace rubinius {
std::string executable_name();
std::string system_prefix();
+ bool verify_paths(std::string prefix);
+ bool load_signature(std::string dir);
void load_vm_options(int argc, char** argv);
void load_argv(int argc, char** argv);
void load_kernel(std::string root);
Please sign in to comment.
Something went wrong with that request. Please try again.