Skip to content

Commit

Permalink
Showing 4 changed files with 47 additions and 12 deletions.
14 changes: 14 additions & 0 deletions lib/opal/nodes/helpers.rb
Original file line number Diff line number Diff line change
@@ -11,6 +11,12 @@ module Helpers
# ES3 reserved words that aren’t ES5.1 reserved words
ES3_RESERVED_WORD_EXCLUSIVE = /#{REGEXP_START}(?:int|byte|char|goto|long|final|float|short|double|native|throws|boolean|abstract|volatile|transient|synchronized)#{REGEXP_END}/

# Prototype special properties.
PROTO_SPECIAL_PROPS = /#{REGEXP_START}(?:constructor|__proto__|__parent__|__noSuchMethod__|__count__)#{REGEXP_END}/

# Prototype special methods.
PROTO_SPECIAL_METHODS = /#{REGEXP_START}(?:hasOwnProperty|valueOf)#{REGEXP_END}/

# Immutable properties of the global object
IMMUTABLE_PROPS = /#{REGEXP_START}(?:NaN|Infinity|undefined)#{REGEXP_END}/

@@ -34,6 +40,14 @@ def variable(name)
valid_name?(name.to_s) ? name : "#{name}$"
end

def valid_ivar_name?(name)
not (PROTO_SPECIAL_PROPS =~ name or PROTO_SPECIAL_METHODS =~ name)
end

def ivar(name)
valid_ivar_name?(name.to_s) ? name : "#{name}$"
end

# Converts a ruby lvar/arg name to a js identifier. Not all ruby names
# are valid in javascript. A $ suffix is added to non-valid names.
# varibales
4 changes: 2 additions & 2 deletions lib/opal/nodes/variables.rb
Original file line number Diff line number Diff line change
@@ -55,7 +55,7 @@ def var_name
end

def compile
name = property var_name
name = property ivar(var_name)
add_ivar name
push "self#{name}"
end
@@ -71,7 +71,7 @@ def var_name
end

def compile
name = property var_name
name = property ivar(var_name)
push "self#{name} = "
push expr(value)
end
22 changes: 12 additions & 10 deletions opal/corelib/module.rb
Original file line number Diff line number Diff line change
@@ -100,18 +100,19 @@ def attr_reader(*names)
for (var i = names.length - 1; i >= 0; i--) {
var name = names[i],
id = '$' + name;
id = '$' + name,
ivar = Opal.ivar(name);
// the closure here is needed because name will change at the next
// cycle, I wish we could use let.
var body = (function(name) {
var body = (function(ivar) {
return function() {
return this[name];
return this[ivar];
};
})(name);
})(ivar);
// initialize the instance variable as nil
proto[name] = nil;
proto[ivar] = nil;
if (self.$$is_singleton) {
proto.constructor.prototype[id] = body;
@@ -131,18 +132,19 @@ def attr_writer(*names)
for (var i = names.length - 1; i >= 0; i--) {
var name = names[i],
id = '$' + name + '=';
id = '$' + name + '=',
ivar = Opal.ivar(name);
// the closure here is needed because name will change at the next
// cycle, I wish we could use let.
var body = (function(name){
var body = (function(ivar){
return function(value) {
return this[name] = value;
return this[ivar] = value;
}
})(name);
})(ivar);
// initialize the instance variable as nil
proto[name] = nil;
proto[ivar] = nil;
if (self.$$is_singleton) {
proto.constructor.prototype[id] = body;
19 changes: 19 additions & 0 deletions opal/corelib/runtime.js
Original file line number Diff line number Diff line change
@@ -1455,6 +1455,25 @@
}
};

Opal.ivar = function(name) {
if (name == "constructor" ||
name == "__proto__" ||
name == "__parent__" ||
name == "__noSuchMethod__" ||
name == "__count__")
{
return name + "$";
}

if (name == "hasOwnProperty" ||
name == "valueOf")
{
return name + "$";
}

return name;
};

// Require system
// --------------
(function(Opal) {

1 comment on commit 73ce13e

@vais
Copy link
Contributor

@vais vais commented on 73ce13e Aug 11, 2015

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👏 you rock, @meh, thanks for taking care of this!

Please sign in to comment.