Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into 1.8.7
Browse files Browse the repository at this point in the history
Conflicts:
	Gemfile.lock
	kernel/common/module.rb
	spec/ruby/core/module/const_defined_spec.rb
	spec/ruby/core/module/prepend_spec.rb
	vm/symbol_table.cpp
	vm/symbol_table.hpp
  • Loading branch information
brixen committed Apr 30, 2015
2 parents a393c94 + 91cf758 commit 89422b6
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 29 deletions.
5 changes: 5 additions & 0 deletions kernel/bootstrap/variable_scope.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ def self.current
raise PrimitiveFailure, "Rubinius::VariableScope.current primitive failed"
end

def self.allocate
Rubinius.primitive :variable_scope_allocate
raise PrimitiveFailure, "Rubinius::VariableScope.allocate primitive failed"
end

def self.synthesize(method, module_, parent, self_, block, locals)
Rubinius.primitive :variable_scope_synthesize
raise PrimitiveFailure, "Rubinius::VariableScope.synthesize primitive failed"
Expand Down
48 changes: 48 additions & 0 deletions spec/jit/call_site_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
require File.expand_path("../spec_helper", __FILE__)

describe "JIT compiling a call site" do
context "to m()" do
before :each do
klass = Class.new do
def m() :m end
def call() m() end
end

@o = klass.new

jit(@o, :call) { @o.call }
end

it "compiles" do
@o.method(:call).executable.jitted?.should be_true
end

it "returns the result of calling the method" do
@o.call.should equal(:m)
end
end

context "to m() defined in an included module" do
before :each do
mod = Module.new do
def m() :m end
end
klass = Class.new do
def call() m() end
include mod
end

@o = klass.new

jit(@o, :call) { @o.call }
end

it "compiles" do
@o.method(:call).executable.jitted?.should be_true
end

it "returns the result of calling the included method" do
@o.call.should equal(:m)
end
end
end
6 changes: 3 additions & 3 deletions vm/builtin/symbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ namespace rubinius {
}

Object* Symbol::is_ivar_p(STATE) {
return RBOOL(state->shared().symbols.kind(state, this) == SymbolTable::IVar);
return RBOOL(state->shared().symbols.kind(state, this) == SymbolTable::eIVar);
}

Object* Symbol::is_cvar_p(STATE) {
return RBOOL(state->shared().symbols.kind(state, this) == SymbolTable::CVar);
return RBOOL(state->shared().symbols.kind(state, this) == SymbolTable::eCVar);
}

Object* Symbol::is_constant_p(STATE) {
return RBOOL(state->shared().symbols.kind(state, this) == SymbolTable::Constant);
return RBOOL(state->shared().symbols.kind(state, this) == SymbolTable::eConstant);
}

void Symbol::Info::show(STATE, Object* self, int level) {
Expand Down
13 changes: 13 additions & 0 deletions vm/builtin/variable_scope.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@ namespace rubinius {
return call_frame->promote_scope(state);
}

VariableScope* VariableScope::allocate(STATE)
{
VariableScope* scope = state->new_object<VariableScope>(G(variable_scope));

scope->number_of_locals_ = 0;
scope->isolated_ = 1;
scope->locals_ = 0;
scope->flags_ = 0;
scope->lock_.init();

return scope;
}

VariableScope* VariableScope::synthesize(STATE, CompiledCode* method,
Module* module, Object* parent,
Object* self, Object* block,
Expand Down
3 changes: 3 additions & 0 deletions vm/builtin/variable_scope.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ namespace rubinius {
// Rubinius.primitive+ :variable_scope_current
static VariableScope* current(STATE, CallFrame* calling_environment);

// Rubinius.primitive :variable_scope_allocate
static VariableScope* allocate(STATE);

// Rubinius.primitive :variable_scope_synthesize
static VariableScope* synthesize(STATE, CompiledCode* method, Module* module, Object* parent, Object* self, Object* block, Tuple* locals);

Expand Down
46 changes: 28 additions & 18 deletions vm/symbol_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,53 +12,63 @@

namespace rubinius {

SymbolTable::Kind SymbolTable::detect_kind(const char* str, size_t size) {
const char one = str[0];
SymbolTable::Kind SymbolTable::detect_kind(STATE, const Symbol* sym) {
std::string str = strings[sym->index()];
size_t size = str.size();
uint8_t* p = reinterpret_cast<uint8_t*>(const_cast<char*>(str.c_str()));

// A constant begins with an uppercase letter.
if(one >= 'A' && one <= 'Z') {
// Make sure that the rest of it is only alphanumerics
// Constants start with A-Z, followed by alphanumeric characters or '_'.
if(isupper(*p)) {
for(size_t i = 1; i < size; i++) {
if((isalnum(str[i]) || str[i] == '_') == false)
return SymbolTable::Normal;
if(!isalnum(p[i]) && p[i] != '_') {
return SymbolTable::eNormal;
}
}
return SymbolTable::Constant;

return SymbolTable::eConstant;
}

if(one == '@') {
if(p[0] == '@') {
// A class variable begins with @@
if(size > 1 && str[1] == '@') {
return SymbolTable::CVar;
if(size > 1 && p[1] == '@') {
return SymbolTable::eCVar;
}

// An instance variable can't start with a digit
if(size > 1 && ISDIGIT(str[1])) {
return SymbolTable::Normal;
return SymbolTable::eNormal;
}

// An instance variable begins with @
return SymbolTable::IVar;
return SymbolTable::eIVar;
}

// A system variable begins with __
if(size > 2 && one == '_' && str[1] == '_') {
return SymbolTable::System;
if(size > 2 && p[0] == '_' && p[1] == '_') {
return SymbolTable::eSystem;
}

// Everything else is normal
return SymbolTable::Normal;
return SymbolTable::eNormal;
}

SymbolTable::Kind SymbolTable::kind(STATE, const Symbol* sym) {
utilities::thread::SpinLock::LockGuard guard(lock_);
return kinds[sym->index()];

Kind k = kinds[sym->index()];

if(k == eUnknown) {
k = kinds[sym->index()] = detect_kind(state, sym);
}

return k;
}

size_t SymbolTable::add(std::string str) {
bytes_used_ += (str.size() + sizeof(std::string) + sizeof(Kind));

strings.push_back(str);
kinds.push_back(detect_kind(str.data(), str.size()));
kinds.push_back(eUnknown);
return strings.size() - 1;
}

Expand Down
16 changes: 8 additions & 8 deletions vm/symbol_table.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ namespace rubinius {
// easily about it without having to get the string representation
// and perform comparisons against the char data.
enum Kind {
Normal,
Constant,
IVar,
CVar,
System
eUnknown,
eNormal,
eConstant,
eIVar,
eCVar,
eSystem
};

typedef std::vector<Kind> SymbolKinds;
Expand All @@ -60,8 +61,6 @@ namespace rubinius {
utilities::thread::SpinLock lock_;
size_t bytes_used_;

Symbol* lookup(const char* str, size_t length, uint32_t seed);

public:

SymbolTable()
Expand All @@ -77,6 +76,7 @@ namespace rubinius {
Symbol* lookup(SharedState* shared, const std::string& str);
Symbol* lookup(STATE, const std::string& str);
Symbol* lookup(STATE, const char* str, size_t length);
Symbol* lookup(const char* str, size_t length, uint32_t seed);
Symbol* lookup(STATE, String* str);
String* lookup_string(STATE, const Symbol* sym);

Expand All @@ -88,7 +88,7 @@ namespace rubinius {
Kind kind(STATE, const Symbol* sym);

size_t add(std::string str);
static Kind detect_kind(const char* str, size_t size);
Kind detect_kind(STATE, const Symbol* sym);
};
};

Expand Down

0 comments on commit 89422b6

Please sign in to comment.