Skip to content

Commit

Permalink
Added language version tagging to .rbc files.
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Ford committed Jun 3, 2011
1 parent 65e33c3 commit b8b06c3
Show file tree
Hide file tree
Showing 16 changed files with 65 additions and 42 deletions.
9 changes: 5 additions & 4 deletions kernel/delta/codeloader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,10 +122,11 @@ def save_compiled?
# TODO: Make the compiled version checking logic available as a Compiler
# convenience method.
def load_file(wrap=false)
version = CodeLoader.check_version ? Signature : 0
signature = CodeLoader.check_version ? Signature : 0
version = Rubinius::RUBY_LIB_VERSION

if CodeLoader.load_compiled
cm = load_compiled_file @load_path, version
cm = load_compiled_file @load_path, signature, version
else
compiled_name = Compiler.compiled_name @load_path

Expand All @@ -134,7 +135,7 @@ def load_file(wrap=false)
cm = compile_file @load_path, compiled_name
else
begin
cm = load_compiled_file compiled_name, version
cm = load_compiled_file compiled_name, signature, version
rescue TypeError, InvalidRBC
cm = compile_file @load_path, compiled_name
end
Expand Down Expand Up @@ -165,7 +166,7 @@ def compile_file(file, compiled)
end

# Load a compiled version of a Ruby source file.
def load_compiled_file(path, version)
def load_compiled_file(path, signature, version)
Ruby.primitive :compiledfile_load

raise InvalidRBC, path
Expand Down
1 change: 1 addition & 0 deletions lib/bin/compile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ def set_printers(compiler)
def set_output(compiler, name)
if writer = compiler.writer
writer.name = name
writer.version = @use_19 ? 19 : 18
end
end

Expand Down
23 changes: 12 additions & 11 deletions lib/compiler/compiled_file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,20 @@ module Rubinius

class CompiledFile
##
# Create a CompiledFile with +magic+ magic bytes, of version +ver+,
# data containing a SHA1 sum of +sum+. The optional +stream+ is used
# to lazy load the body.
# Create a CompiledFile with +magic+ bytes, +signature+, and +version+.
# The optional +stream+ is used to lazy load the body.

def initialize(magic, ver, sum, stream=nil)
@magic, @version, @sum = magic, ver, sum
def initialize(magic, signature, version, stream=nil)
@magic = magic
@signature = signature
@version = version
@stream = stream
@data = nil
end

attr_reader :magic
attr_reader :signature
attr_reader :version
attr_reader :sum
attr_reader :stream

##
Expand All @@ -27,17 +28,17 @@ def self.load(stream)
raise IOError, "attempted to load nil stream" unless stream

magic = stream.gets.strip
signature = Integer(stream.gets.strip)
version = Integer(stream.gets.strip)
sum = stream.gets.strip

return new(magic, version, sum, stream)
return new(magic, signature, version, stream)
end

##
# Writes the CompiledFile +cm+ to +file+.
def self.dump(cm, file)
def self.dump(cm, file, signature, version)
File.open(file, "wb") do |f|
new("!RBIX", Rubinius::Signature, "x").encode_to(f, cm)
new("!RBIX", signature, version).encode_to(f, cm)
end
rescue SystemCallError
# just skip writing the compiled file if we don't have permissions
Expand All @@ -49,8 +50,8 @@ def self.dump(cm, file)

def encode_to(stream, body)
stream.puts @magic
stream.puts @signature.to_s
stream.puts @version.to_s
stream.puts @sum.to_s

mar = CompiledFile::Marshal.new
stream << mar.marshal(body)
Expand Down
1 change: 1 addition & 0 deletions lib/compiler/compiler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def self.compile(file, output=nil, line=1, transforms=:default)
parser.input file, line

writer = compiler.writer
writer.version = Rubinius::RUBY_LIB_VERSION
writer.name = output ? output : compiled_name(file)

begin
Expand Down
6 changes: 4 additions & 2 deletions lib/compiler/stages.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,13 @@ def run_next
class Writer < Stage
stage :compiled_file

attr_accessor :name
attr_accessor :name, :version

def initialize(compiler, last)
super
compiler.writer = self

@version = 0
@processor = Rubinius::CompiledFile
end

Expand All @@ -84,7 +86,7 @@ def run
end
end

@processor.dump @input, @name
@processor.dump @input, @name, Signature, @version
@input
end
end
Expand Down
5 changes: 5 additions & 0 deletions rakelib/kernel.rake
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,19 @@ class KernelCompiler
parser = compiler.parser
parser.root Rubinius::AST::Script

writer = compiler.writer

# Not ready to enable them yet
case version
when "18"
parser.processor Rubinius::Melbourne
writer.version = 18
when "19"
parser.processor Rubinius::Melbourne
writer.version = 19
when "20"
parser.processor Rubinius::Melbourne
writer.version = 20
end

if transforms.kind_of? Array
Expand Down
4 changes: 2 additions & 2 deletions spec/core/kernel/fixtures/classes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ def self.cache_file(name, cache)
code = File.read name

be = Rubinius::Compiler.construct_block code, empty_binding, name
Rubinius::CompiledFile.dump be.code, cache
Rubinius::CompiledFile.dump be.code, cache, 0, 0
end

def self.run_cache(cache)
cl = Rubinius::CodeLoader.new cache
cm = cl.load_compiled_file cache, Rubinius::Signature
cm = cl.load_compiled_file cache, 0, 0

script = cm.create_script
MAIN.__send__ :__script__
Expand Down
9 changes: 6 additions & 3 deletions vm/builtin/system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ namespace rubinius {
//
// HACK: remove this when performance is better and compiled_file.rb
// unmarshal_data method works.
Object* System::compiledfile_load(STATE, String* path, Integer* version) {
Object* System::compiledfile_load(STATE, String* path,
Integer* signature, Integer* version)
{
std::ifstream stream(path->c_str(state));
if(!stream) {
return Primitives::failure();
Expand All @@ -150,8 +152,9 @@ namespace rubinius {
return Primitives::failure();
}

uint64_t ver = version->to_ulong_long();
if((ver > 0 && cf->version != ver) || cf->sum != "x") {
uint64_t sig = signature->to_ulong_long();
if((sig > 0 && cf->signature != sig)
|| cf->version != version->to_native()) {
return Primitives::failure();
}

Expand Down
2 changes: 1 addition & 1 deletion vm/builtin/system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ namespace rubinius {

/** Load a compiled file. */
// Ruby.primitive :compiledfile_load
static Object* compiledfile_load(STATE, String* path, Integer* version);
static Object* compiledfile_load(STATE, String* path, Integer* signature, Integer* version);

/**
* When running under GDB, stop here.
Expand Down
11 changes: 6 additions & 5 deletions vm/compiled_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@

namespace rubinius {
CompiledFile* CompiledFile::load(std::istream& stream) {
std::string magic, sum;
uint64_t ver;
std::string magic;
uint64_t signature;
int version;

stream >> magic;
stream >> ver;
stream >> sum;
stream >> signature;
stream >> version;
stream.get(); // eat the \n

return new CompiledFile(magic, ver, sum, &stream);
return new CompiledFile(magic, signature, version, &stream);
}

Object* CompiledFile::body(STATE) {
Expand Down
8 changes: 4 additions & 4 deletions vm/compiled_file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,18 @@ namespace rubinius {
class CompiledFile {
public:
std::string magic;
uint64_t version;
std::string sum;
uint64_t signature;
int version;

private:
std::istream* stream;

public:
CompiledFile(std::string magic, uint64_t version, std::string sum,
CompiledFile(std::string magic, uint64_t signature, int version,
std::istream* stream)
: magic(magic)
, signature(signature)
, version(version)
, sum(sum)
, stream(stream)
{}

Expand Down
7 changes: 6 additions & 1 deletion vm/environment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ namespace rubinius {
: argc_(argc)
, argv_(argv)
, signature_(0)
, version_(0)
, agent(0)
{
#ifdef ENABLE_LLVM
Expand Down Expand Up @@ -480,7 +481,8 @@ namespace rubinius {

CompiledFile* cf = CompiledFile::load(stream);
if(cf->magic != "!RBIX") throw std::runtime_error("Invalid file");
if((signature_ > 0 && cf->version != signature_) || cf->sum != "x") {
if((signature_ > 0 && cf->signature != signature_)
|| cf->version != version_) {
throw BadKernelFile(file);
}

Expand Down Expand Up @@ -609,6 +611,9 @@ namespace rubinius {
throw std::runtime_error(error);
}

version_ = as<Fixnum>(G(rubinius)->get_const(
state, state->symbol("RUBY_LIB_VERSION")))->to_native();

// Load alpha
run_file(root + "/alpha.rbc");

Expand Down
3 changes: 3 additions & 0 deletions vm/environment.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ namespace rubinius {
/// needs to be recompiled.
uint64_t signature_;

// The Ruby library version with which the .rbc file is compatible.
int version_;

public:
SharedState* shared;
VM* state;
Expand Down
6 changes: 3 additions & 3 deletions vm/ontology.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,11 +401,11 @@ namespace rubinius {
G(rubinius)->set_const(state, "OS", String::create(state, RBX_OS));

if(LANGUAGE_20_ENABLED(state)) {
G(rubinius)->set_const(state, "RUBY_LIB_VERSION", String::create(state, "20"));
G(rubinius)->set_const(state, "RUBY_LIB_VERSION", Fixnum::from(20));
} else if(LANGUAGE_19_ENABLED(state)) {
G(rubinius)->set_const(state, "RUBY_LIB_VERSION", String::create(state, "19"));
G(rubinius)->set_const(state, "RUBY_LIB_VERSION", Fixnum::from(19));
} else {
G(rubinius)->set_const(state, "RUBY_LIB_VERSION", String::create(state, "18"));
G(rubinius)->set_const(state, "RUBY_LIB_VERSION", Fixnum::from(18));
}

#ifdef RBX_LITTLE_ENDIAN
Expand Down
2 changes: 1 addition & 1 deletion vm/test/fixture.rbc_
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
!RBIX
0
x
0
M
1
n
Expand Down
10 changes: 5 additions & 5 deletions vm/test/test_compiled_file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,18 @@ class TestCompiledFile : public CxxTest::TestSuite, public VMTest {

void test_load() {
std::istringstream stream;
stream.str("!RBIX\n1\naoeu\nt");
stream.str("!RBIX\n1\n42\nt");

CompiledFile* cf = CompiledFile::load(stream);
TS_ASSERT_EQUALS(cf->magic, std::string("!RBIX"));
TS_ASSERT_EQUALS(cf->version, 1ULL);
TS_ASSERT_EQUALS(cf->sum, std::string("aoeu"));
TS_ASSERT_EQUALS((long)stream.tellg(), 13);
TS_ASSERT_EQUALS(cf->signature, 1ULL);
TS_ASSERT_EQUALS(cf->version, 42);
TS_ASSERT_EQUALS((long)stream.tellg(), 11);
}

void test_body() {
std::istringstream stream;
stream.str("!RBIX\n1\naoeu\nt");
stream.str("!RBIX\n1\n42\nt");

CompiledFile* cf = CompiledFile::load(stream);
TS_ASSERT_EQUALS(cf->body(state), Qtrue);
Expand Down

0 comments on commit b8b06c3

Please sign in to comment.