Modified: trunk/Source/_javascript_Core/ChangeLog (236433 => 236434)
--- trunk/Source/_javascript_Core/ChangeLog 2018-09-24 22:55:56 UTC (rev 236433)
+++ trunk/Source/_javascript_Core/ChangeLog 2018-09-24 22:59:23 UTC (rev 236434)
@@ -1,5 +1,32 @@
2018-09-24 Tadeu Zagallo <[email protected]>
+ offlineasm: fix macro scoping
+ https://bugs.webkit.org/show_bug.cgi?id=189902
+
+ Reviewed by Mark Lam.
+
+ In the code below, the reference to `f` in `g`, which should refer to
+ the outer macro definition will instead refer to the f argument of the
+ anonymous macro passed to `g`. That leads to this code failing to
+ compile (f expected 0 args but got 1).
+
+ ```
+ macro f(x)
+ move x, t0
+ end
+
+ macro g(fn)
+ fn(macro () f(42) end)
+ end
+
+ g(macro(f) f() end)
+ ```
+
+ * offlineasm/ast.rb:
+ * offlineasm/transform.rb:
+
+2018-09-24 Tadeu Zagallo <[email protected]>
+
Add forEach method for iterating CodeBlock's ValueProfiles
https://bugs.webkit.org/show_bug.cgi?id=189897
Modified: trunk/Source/_javascript_Core/offlineasm/ast.rb (236433 => 236434)
--- trunk/Source/_javascript_Core/offlineasm/ast.rb 2018-09-24 22:55:56 UTC (rev 236433)
+++ trunk/Source/_javascript_Core/offlineasm/ast.rb 2018-09-24 22:59:23 UTC (rev 236434)
@@ -727,26 +727,31 @@
class Variable < NoChildren
attr_reader :name
- def initialize(codeOrigin, name)
+ def initialize(codeOrigin, name, originalName = nil)
super(codeOrigin)
@name = name
+ @originalName = originalName
end
@@mapping = {}
- def self.forName(codeOrigin, name)
+ def self.forName(codeOrigin, name, originalName = nil)
unless @@mapping[name]
- @@mapping[name] = Variable.new(codeOrigin, name)
+ @@mapping[name] = Variable.new(codeOrigin, name, originalName)
end
@@mapping[name]
end
+
+ def originalName
+ @originalName || name
+ end
def dump
- name
+ originalName
end
def inspect
- "<variable #{name} at #{codeOriginString}>"
+ "<variable #{originalName} at #{codeOriginString}>"
end
end
@@ -1455,7 +1460,7 @@
class MacroCall < Node
attr_reader :name, :operands, :annotation
- def initialize(codeOrigin, name, operands, annotation)
+ def initialize(codeOrigin, name, operands, annotation, originalName = nil)
super(codeOrigin)
@name = name
@operands = operands
@@ -1462,7 +1467,12 @@
raise unless @operands
@operands.each{|v| raise unless v}
@annotation = annotation
+ @originalName = originalName
end
+
+ def originalName
+ @originalName || name
+ end
def children
@operands
@@ -1469,11 +1479,11 @@
end
def mapChildren(&proc)
- MacroCall.new(codeOrigin, @name, @operands.map(&proc), @annotation)
+ MacroCall.new(codeOrigin, @name, @operands.map(&proc), @annotation, @originalName)
end
def dump
- "\t#{name}(" + operands.collect{|v| v.dump}.join(", ") + ")"
+ "\t#{originalName}(" + operands.collect{|v| v.dump}.join(", ") + ")"
end
end
Modified: trunk/Source/_javascript_Core/offlineasm/transform.rb (236433 => 236434)
--- trunk/Source/_javascript_Core/offlineasm/transform.rb 2018-09-24 22:55:56 UTC (rev 236433)
+++ trunk/Source/_javascript_Core/offlineasm/transform.rb 2018-09-24 22:59:23 UTC (rev 236434)
@@ -134,7 +134,20 @@
end
end
+$uniqueMacroVarID = 0
class Macro
+ def capture
+ mapping = {}
+ newVars = []
+ variables.each do |var|
+ $uniqueMacroVarID += 1
+ newVar = Variable.forName(var.codeOrigin, "_var#{$uniqueMacroVarID}", var.originalName)
+ newVars << newVar
+ mapping[var] = newVar
+ end
+ Macro.new(codeOrigin, name, newVars, body.substitute(mapping))
+ end
+
def substitute(mapping)
myMapping = {}
mapping.each_pair {
@@ -150,6 +163,17 @@
end
end
+class MacroCall
+ def substitute(mapping)
+ newName = Variable.forName(codeOrigin, name)
+ if mapping[newName]
+ newName = mapping[newName]
+ end
+ newOperands = operands.map { |operand| operand.substitute(mapping) }
+ MacroCall.new(codeOrigin, newName.name, newOperands, annotation, originalName)
+ end
+end
+
class Variable
def substitute(mapping)
if mapping[self]
@@ -203,7 +227,7 @@
@list.each {
| item |
if item.is_a? Macro
- myMacros[item.name] = item
+ myMacros[item.name] = item.capture
end
}
newList = []
@@ -214,8 +238,8 @@
elsif item.is_a? MacroCall
mapping = {}
myMyMacros = myMacros.dup
- raise "Could not find macro #{item.name} at #{item.codeOriginString}" unless myMacros[item.name]
- raise "Argument count mismatch for call to #{item.name} at #{item.codeOriginString}" unless item.operands.size == myMacros[item.name].variables.size
+ raise "Could not find macro #{item.originalName} at #{item.codeOriginString}" unless myMacros[item.name]
+ raise "Argument count mismatch for call to #{item.originalName} at #{item.codeOriginString}" unless item.operands.size == myMacros[item.name].variables.size
item.operands.size.times {
| idx |
if item.operands[idx].is_a? Variable and myMacros[item.operands[idx].name]
@@ -222,7 +246,7 @@
myMyMacros[myMacros[item.name].variables[idx].name] = myMacros[item.operands[idx].name]
mapping[myMacros[item.name].variables[idx].name] = nil
elsif item.operands[idx].is_a? Macro
- myMyMacros[myMacros[item.name].variables[idx].name] = item.operands[idx]
+ myMyMacros[myMacros[item.name].variables[idx].name] = item.operands[idx].capture
mapping[myMacros[item.name].variables[idx].name] = nil
else
myMyMacros[myMacros[item.name].variables[idx]] = nil
@@ -232,7 +256,7 @@
if item.annotation
newList << Instruction.new(item.codeOrigin, "localAnnotation", [], item.annotation)
end
- newList += myMacros[item.name].body.substitute(mapping).demacroify(myMyMacros).renameLabels(item.name).list
+ newList += myMacros[item.name].body.substitute(mapping).demacroify(myMyMacros).renameLabels(item.originalName).list
else
newList << item.demacroify(myMacros)
end