Skip to content

Commit

Permalink
Merge branch 'scoped_const_lookups' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
Adam Beynon committed Dec 23, 2011
2 parents c19aa88 + b9ac3fe commit 2fcd223
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 53 deletions.
17 changes: 11 additions & 6 deletions lib/opal/parser/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,12 @@ class Parser
"$klass" => "klass",
"$defn" => "defn",
"$defs" => "defs",
"$const_get" => "const_get",
"$range" => "range",
"$hash" => "hash",
"$slice" => "slice",
"$send" => "send",
"$arg_error" => "arg_error"
"$arg_error" => "arg_error",
"$const" => "constants"
}

# Type info for flags of objects. This helps identify the type of object
Expand Down Expand Up @@ -573,7 +573,7 @@ def class(sexp, level)

in_scope(:class) do
code = process body, :statement

vars << "$const = self.$const"
@scope.locals.each { |t| vars << t }
@scope.temps.each { |t| vars << t }

Expand Down Expand Up @@ -619,6 +619,7 @@ def module(sexp, level)
in_scope(:class) do
code = process body, :statement

vars << "$const = self.$const"
@scope.locals.each { |t| vars << t }
@scope.temps.each { |t| vars << t }

Expand Down Expand Up @@ -911,7 +912,11 @@ def gasgn(sexp, level)

# s(:const, :const)
def const(sexp, level)
"$const_get(self, #{sexp.shift.to_s.inspect})"
if @debug
"$opal.const_get($const, #{sexp.shift.to_s.inspect})"
else
"$const[#{sexp.shift.to_s.inspect}]"
end
end

# s(:cdecl, :const, rhs)
Expand Down Expand Up @@ -1190,11 +1195,11 @@ def cvdecl exp, level
# s(:colon2, base, :NAME)
def colon2(sexp, level)
base, name = sexp
"$const_get(#{process base, :expression}, #{name.to_s.inspect})"
"$opal.const_get((#{process base, :expression}).$const, #{name.to_s.inspect})"
end

def colon3(exp, level)
"$const_get($opal.Object, #{exp.shift.to_s.inspect})"
"$opal.const_get($opal.Object, #{exp.shift.to_s.inspect})"
end

# super a, b, c
Expand Down
31 changes: 10 additions & 21 deletions runtime/kernel/class.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,7 @@ function boot_makemeta(id, klass, superklass) {
proto.$s = superklass;
proto.constructor = meta;

// constants
if (superklass.prototype.$constants_alloc) {
proto.$c = new superklass.prototype.$constants_alloc();
proto.$constants_alloc = function() {};
proto.$constants_alloc.prototype = proto.$c;
}
else {
proto.$constants_alloc = function() {};
proto.$c = proto.$constants_alloc.prototype;
}

var result = new meta();

klass.prototype.$k = result;

return result;
Expand Down Expand Up @@ -112,12 +100,8 @@ function boot_class(superklass) {
proto.$methods = [];
proto.constructor = meta;
proto.$s = superklass;
proto.$c = new superklass.$constants_alloc();
proto.$constants_alloc = function() {};
proto.$constants_alloc.prototype = proto.$c;

var result = new meta();

cls.prototype.$k = result;

return result;
Expand Down Expand Up @@ -150,7 +134,7 @@ function make_metaclass(klass, superklass) {

klass.$k = meta;

meta.$c = klass.$c;
meta.$const = klass.$const;
meta.__attached__ = klass;

return meta;
Expand Down Expand Up @@ -199,8 +183,8 @@ function bridge_class(constructor, flags, id) {
function define_class(base, id, superklass) {
var klass;

if (base.$c.hasOwnProperty(id)) {
return base.$c[id];
if (base.$const.hasOwnProperty(id)) {
return base.$const[id];
}

var class_id = (base === RubyObject ? id : base.__classid__ + '::' + id);
Expand All @@ -210,8 +194,13 @@ function define_class(base, id, superklass) {

make_metaclass(klass, superklass.$k);

base.$c[id] = klass;
klass.$parent = base;
var const_alloc = function() {};
var const_scope = const_alloc.prototype = new base.$const.alloc();
klass.$const = const_scope;
const_scope.alloc = const_alloc;

base.$const[id] = klass;
klass.$parent = base;

if (superklass.m$inherited) {
superklass.m$inherited(null, klass);
Expand Down
29 changes: 24 additions & 5 deletions runtime/kernel/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,31 @@ RubyObject.$s = null;
RubyModule.$s = RubyObject;
RubyClass.$s = RubyModule;

RubyObject.$c.BasicObject = RubyObject;
RubyObject.$c.Object = RubyObject;
RubyObject.$c.Module = RubyModule;
RubyObject.$c.Class = RubyClass;

opal.Object = RubyObject;
opal.Module = RubyModule;
opal.Class = RubyClass;

// Top level Object scope (used by object and top_self).
var top_const_alloc = function(){};
var top_const_scope = top_const_alloc.prototype;
top_const_scope.alloc = top_const_alloc;

RubyObject.$const = opal.constants = top_const_scope;

var module_const_alloc = function(){};
var module_const_scope = new top_const_alloc();
module_const_scope.alloc = module_const_alloc;
RubyModule.$const = module_const_scope;

var class_const_alloc = function(){};
var class_const_scope = new top_const_alloc();
class_const_scope.alloc = class_const_alloc;
RubyClass.$const = class_const_scope;

RubyObject.$const.BasicObject = RubyObject;
RubyObject.$const.Object = RubyObject;
RubyObject.$const.Module = RubyModule;
RubyObject.$const.Class = RubyClass;

This comment has been minimized.

Copy link
@peter-leonov

peter-leonov Jul 28, 2013

Contributor

Nice trick with prototype chain. It helps a lot with all kinds of scopes as far as it is essentially naked scopes done natively :)
Today we, finally, may use Object.create() which allows us avoid extra closures creation.


var top_self = opal.top = new RubyObject.$a();

Expand Down
33 changes: 12 additions & 21 deletions runtime/kernel/runtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,23 +104,9 @@ opal.jump = function(value, func) {
};

// Get constant with given id
opal.const_get = function(base, id) {
if (base.$f & T_OBJECT) {
base = class_real(base.$k);
}

if (base.$c[id]) {
return base.$c[id];
}

var parent = base.$parent;

while (parent) {
if (parent.$c[id] !== undefined) {
return parent.$c[id];
}

parent = parent.$parent;
opal.const_get = function(const_table, id) {
if (const_table[id]) {
return const_table[id];
}

raise(RubyNameError, 'uninitialized constant ' + id);
Expand All @@ -132,7 +118,7 @@ opal.const_set = function(base, id, val) {
base = class_real(base.$k);
}

return base.$c[id] = val;
return base.$const[id] = val;
};

// Table holds all class variables
Expand Down Expand Up @@ -262,8 +248,8 @@ opal.range = function(beg, end, exc) {
function define_module(base, id) {
var module;

if (base.$c.hasOwnProperty(id)) {
return base.$c[id];
if (base.$const.hasOwnProperty(id)) {
return base.$const[id];
}

module = boot_class(RubyModule);
Expand All @@ -274,7 +260,12 @@ function define_module(base, id) {
module.$f = T_MODULE;
module.$included_in = [];

base.$c[id] = module;
var const_alloc = function() {};
var const_scope = const_alloc.prototype = new base.$const.alloc();
module.$const = const_scope;
const_scope.alloc = const_alloc;

base.$const[id] = module;
module.$parent = base;

return module;
Expand Down

0 comments on commit 2fcd223

Please sign in to comment.