Title: [89392] trunk/Source/_javascript_Core
Revision
89392
Author
gga...@apple.com
Date
2011-06-21 16:39:28 -0700 (Tue, 21 Jun 2011)

Log Message

2011-06-21  Geoffrey Garen  <gga...@apple.com>

        Reviewed by Oliver Hunt.

        Moved 'const' off the global-variable-as-local-variable crack pipe
        https://bugs.webkit.org/show_bug.cgi?id=63105
        
        This is necessary for moving the rest of the code off of same.
        
        Many problems remain in our handling of const. I have fixed none of them.

        * bytecompiler/BytecodeGenerator.h:
        (JSC::BytecodeGenerator::scopeChain): New accessor, needed to enable
        const to directly implement its unique scoping rules.

        * bytecompiler/NodesCodegen.cpp:
        (JSC::PrefixResolveNode::emitBytecode): Do specify that our resolve is
        for writing, so we don't overwrite const variables.

        (JSC::ConstDeclNode::emitCodeSingle): Don't assume that all declared const
        variables are available as local variables, since this won't be the case
        once global variables are not available as local variables. Instead, use
        put_scoped_var in the case where there is no local variable. Like a local
        variable, put_scoped_var succeeds even though const properties are
        read-only, since put_scoped_var skips read-only checks. (Yay?)

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (89391 => 89392)


--- trunk/Source/_javascript_Core/ChangeLog	2011-06-21 23:12:19 UTC (rev 89391)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-06-21 23:39:28 UTC (rev 89392)
@@ -1,3 +1,29 @@
+2011-06-21  Geoffrey Garen  <gga...@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        Moved 'const' off the global-variable-as-local-variable crack pipe
+        https://bugs.webkit.org/show_bug.cgi?id=63105
+        
+        This is necessary for moving the rest of the code off of same.
+        
+        Many problems remain in our handling of const. I have fixed none of them.
+
+        * bytecompiler/BytecodeGenerator.h:
+        (JSC::BytecodeGenerator::scopeChain): New accessor, needed to enable
+        const to directly implement its unique scoping rules.
+
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::PrefixResolveNode::emitBytecode): Do specify that our resolve is
+        for writing, so we don't overwrite const variables.
+
+        (JSC::ConstDeclNode::emitCodeSingle): Don't assume that all declared const
+        variables are available as local variables, since this won't be the case
+        once global variables are not available as local variables. Instead, use
+        put_scoped_var in the case where there is no local variable. Like a local
+        variable, put_scoped_var succeeds even though const properties are
+        read-only, since put_scoped_var skips read-only checks. (Yay?)
+
 2011-06-21  Oliver Hunt  <oli...@apple.com>
 
         Reviewed by Alexey Proskuryakov.

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (89391 => 89392)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2011-06-21 23:12:19 UTC (rev 89391)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2011-06-21 23:39:28 UTC (rev 89392)
@@ -399,6 +399,8 @@
         bool shouldEmitProfileHooks() { return m_shouldEmitProfileHooks; }
         
         bool isStrictMode() const { return m_codeBlock->isStrictMode(); }
+        
+        ScopeChainNode* scopeChain() const { return m_scopeChain.get(); }
 
     private:
         void emitOpcode(OpcodeID);

Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (89391 => 89392)


--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2011-06-21 23:12:19 UTC (rev 89391)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2011-06-21 23:39:28 UTC (rev 89392)
@@ -744,7 +744,7 @@
     size_t depth = 0;
     JSObject* globalObject = 0;
     bool requiresDynamicChecks = false;
-    if (generator.findScopedProperty(m_ident, index, depth, false, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
+    if (generator.findScopedProperty(m_ident, index, depth, true, requiresDynamicChecks, globalObject) && index != missingSymbolMarker() && !requiresDynamicChecks) {
         RefPtr<RegisterID> propDst = generator.emitGetScopedVar(generator.tempDestination(dst), depth, index, globalObject);
         emitPreIncOrDec(generator, propDst.get(), m_operator);
         generator.emitPutScopedVar(depth, index, propDst.get(), globalObject);
@@ -1293,6 +1293,7 @@
 
 RegisterID* ConstDeclNode::emitCodeSingle(BytecodeGenerator& generator)
 {
+    // FIXME: This code does not match the behavior of const in Firefox.
     if (RegisterID* local = generator.constRegisterFor(m_ident)) {
         if (!m_init)
             return local;
@@ -1300,17 +1301,30 @@
         return generator.emitNode(local, m_init);
     }
 
-    if (generator.codeType() != EvalCode) {
-        if (m_init)
-            return generator.emitNode(m_init);
-        else
-            return generator.emitResolve(generator.newTemporary(), m_ident);
+    RefPtr<RegisterID> value = m_init ? generator.emitNode(m_init) : generator.emitLoad(0, jsUndefined());
+
+    ScopeChainIterator iter = generator.scopeChain()->begin();
+    ScopeChainIterator end = generator.scopeChain()->end();
+    size_t depth = 0;
+    for (; iter != end; ++iter, ++depth) {
+        JSObject* currentScope = iter->get();
+        if (!currentScope->isVariableObject())
+            continue;
+        JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope);
+        SymbolTableEntry entry = currentVariableObject->symbolTable().get(m_ident.impl());
+        if (entry.isNull())
+            continue;
+
+        return generator.emitPutScopedVar(depth, entry.getIndex(), value.get(), currentVariableObject->isGlobalObject() ? currentVariableObject : 0);
     }
-    // FIXME: While this code should only be hit in eval code, it will potentially
-    // assign to the wrong base if m_ident exists in an intervening dynamic scope.
+
+    if (generator.codeType() != EvalCode)
+        return value.get();
+
+    // FIXME: While this code should only be hit in an eval block, it will assign
+    // to the wrong base if m_ident exists in an intervening with scope.
     RefPtr<RegisterID> base = generator.emitResolveBase(generator.newTemporary(), m_ident);
-    RegisterID* value = m_init ? generator.emitNode(m_init) : generator.emitLoad(0, jsUndefined());
-    return generator.emitPutById(base.get(), m_ident, value);
+    return generator.emitPutById(base.get(), m_ident, value.get());
 }
 
 RegisterID* ConstDeclNode::emitBytecode(BytecodeGenerator& generator, RegisterID*)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to