Only setup prototypes on constructors which are the direct target of new operations.
This is a simple change to removes the need to install a prototype on constructors which are merely used as targets of super()/this() calls.
http://gwt-code-reviews.appspot.com/176802/show
Review by: spoon
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7775 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
index 7722d4a..dae6575 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GenerateJavaScriptAST.java
@@ -350,8 +350,7 @@
*/
if (!stripStack || !polymorphicNames.containsKey(x) || x.isNative()) {
globalName = topScope.declareName(mangleName, name);
- x.getSourceInfo().addCorrelation(
- program.getCorrelator().by(globalName));
+ x.getSourceInfo().addCorrelation(program.getCorrelator().by(globalName));
names.put(x, globalName);
recordSymbol(x, globalName);
}
@@ -366,13 +365,13 @@
SourceInfo sourceInfo = x.getSourceInfo().makeChild(
CreateNamesAndScopesVisitor.class, "Translated JS function");
/*
- * It would be more correct here to check for an inline assignment,
- * such as var foo = function blah() {} and introduce a separate scope
- * for the function's name according to EcmaScript-262, but this would
- * mess up stack traces by allowing two inner scope function names to
- * onfuscate to the same identifier, making function names no longer
- * a 1:1 mapping to obfuscated symbols. Leaving them in global scope
- * causes no harm.
+ * It would be more correct here to check for an inline assignment, such
+ * as var foo = function blah() {} and introduce a separate scope for
+ * the function's name according to EcmaScript-262, but this would mess
+ * up stack traces by allowing two inner scope function names to
+ * onfuscate to the same identifier, making function names no longer a
+ * 1:1 mapping to obfuscated symbols. Leaving them in global scope
+ * causes no harm.
*/
jsFunction = new JsFunction(sourceInfo, topScope, globalName, true);
}
@@ -1573,14 +1572,14 @@
// Add it first, so that script-tag chunking in IFrameLinker works
globalStatements.add(0, nullFunc.makeStmt());
}
-
+
private void generateSeedFuncAndPrototype(JClassType x,
List<JsStatement> globalStmts) {
SourceInfo sourceInfo = x.getSourceInfo().makeChild(
GenerateJavaScriptVisitor.class, "Seed and function prototype");
if (x != program.getTypeJavaLangString()) {
JsName seedFuncName = names.get(x);
-
+
// seed function
// function com_example_foo_Foo() { }
JsFunction seedFunc = new JsFunction(sourceInfo, topScope,
@@ -1609,7 +1608,7 @@
// Chain assign the same prototype to every live constructor.
for (JMethod method : x.getMethods()) {
- if (method instanceof JConstructor) {
+ if (liveCtors.contains(method)) {
JsNameRef protoRef = prototype.makeRef(sourceInfo);
protoRef.setQualifier(names.get(method).makeRef(sourceInfo));
protoAsg = createAssignment(protoRef, protoAsg);
@@ -1731,8 +1730,8 @@
JsNameRef lhs = polymorphicNames.get(method).makeRef(sourceInfo);
lhs.setQualifier(globalTemp.makeRef(sourceInfo));
/*
- * Inline JsFunction rather than reference, e.g.
- * _.vtableName = function functionName() { ... }
+ * Inline JsFunction rather than reference, e.g. _.vtableName =
+ * function functionName() { ... }
*/
JsExpression rhs = methodBodyMap.get(method.getBody());
JsExpression asg = createAssignment(lhs, rhs);
@@ -1876,8 +1875,14 @@
}
@Override
+ public void endVisit(JNewInstance x, Context ctx) {
+ super.endVisit(x, ctx);
+ liveCtors.add(x.getTarget());
+ }
+
+ @Override
public void endVisit(JProgram x, Context ctx) {
- // Entry methods can be called externally, so they must run clinit.
+ // Entry methods can be called externally, so they must run clinit.
crossClassTargets.addAll(x.getAllEntryMethods());
}
@@ -1952,6 +1957,8 @@
private final JsProgram jsProgram;
+ private final Set<JConstructor> liveCtors = new IdentityHashSet<JConstructor>();
+
/**
* Sorted to avoid nondeterministic iteration.
*/
@@ -1967,10 +1974,10 @@
*/
private final JsScope objectScope;
private final JsOutputOption output;
- private final Map<JMethod, JsName> polymorphicNames = new IdentityHashMap<JMethod, JsName>();
private final Set<JsFunction> polymorphicJsFunctions = new IdentityHashSet<JsFunction>();
+ private final Map<JMethod, JsName> polymorphicNames = new IdentityHashMap<JMethod, JsName>();
private final JProgram program;
-
+
/**
* All of the fields and polymorphic methods in String.
*
@@ -1992,7 +1999,7 @@
* not assigned topScope identifiers.
*/
private boolean stripStack;
-
+
/**
* Maps JsNames to machine-usable identifiers.
*/
@@ -2021,8 +2028,7 @@
this.output = output;
this.symbolTable = symbolTable;
- this.stripStack = JsStackEmulator.getStackMode(propertyOracles) ==
- JsStackEmulator.StackMode.STRIP;
+ this.stripStack = JsStackEmulator.getStackMode(propertyOracles) == JsStackEmulator.StackMode.STRIP;
/*
* Because we modify String's prototype, all fields and polymorphic methods
* on String's super types need special handling.