]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - bytecompiler/BytecodeGenerator.cpp
JavaScriptCore-621.1.tar.gz
[apple/javascriptcore.git] / bytecompiler / BytecodeGenerator.cpp
index b0a0877c15ba83b47b4dff470e37e487c99f3d1d..c4b3cab912b1b69897d4c886c45863048c50d999 100644 (file)
@@ -633,7 +633,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar
             instructions().append(target->bind(begin, instructions().size()));
             return target;
         }
-    } else if (m_lastOpcodeID == op_lesseq && !target->isForward()) {
+    } else if (m_lastOpcodeID == op_lesseq) {
         int dstIndex;
         int src1Index;
         int src2Index;
@@ -644,7 +644,7 @@ PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* tar
             rewindBinaryOp();
 
             size_t begin = instructions().size();
-            emitOpcode(op_loop_if_lesseq);
+            emitOpcode(target->isForward() ? op_jlesseq : op_loop_if_lesseq);
             instructions().append(src1Index);
             instructions().append(src2Index);
             instructions().append(target->bind(begin, instructions().size()));
@@ -990,7 +990,7 @@ RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v)
     return constantID;
 }
 
-bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, JSObject*& globalObject)
+bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, bool& requiresDynamicChecks, JSObject*& globalObject)
 {
     // Cases where we cannot statically optimize the lookup.
     if (property == propertyNames().arguments || !canOptimizeNonLocals()) {
@@ -1006,7 +1006,7 @@ bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& inde
     }
 
     size_t depth = 0;
-    
+    requiresDynamicChecks = false;
     ScopeChainIterator iter = m_scopeChain->begin();
     ScopeChainIterator end = m_scopeChain->end();
     for (; iter != end; ++iter, ++depth) {
@@ -1031,10 +1031,11 @@ bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& inde
                 globalObject = currentVariableObject;
             return true;
         }
-        if (currentVariableObject->isDynamicScope())
+        bool scopeRequiresDynamicChecks = false;
+        if (currentVariableObject->isDynamicScope(scopeRequiresDynamicChecks))
             break;
+        requiresDynamicChecks |= scopeRequiresDynamicChecks;
     }
-
     // Can't locate the property but we're able to avoid a few lookups.
     stackDepth = depth;
     index = missingSymbolMarker();
@@ -1059,7 +1060,8 @@ RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& pr
     size_t depth = 0;
     int index = 0;
     JSObject* globalObject = 0;
-    if (!findScopedProperty(property, index, depth, false, globalObject) && !globalObject) {
+    bool requiresDynamicChecks = false;
+    if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) && !globalObject) {
         // We can't optimise at all :-(
         emitOpcode(op_resolve);
         instructions().append(dst->index());
@@ -1077,7 +1079,7 @@ RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& pr
 #endif
         }
 
-        if (index != missingSymbolMarker() && !forceGlobalResolve) {
+        if (index != missingSymbolMarker() && !forceGlobalResolve && !requiresDynamicChecks) {
             // Directly index the property lookup across multiple scopes.
             return emitGetScopedVar(dst, depth, index, globalObject);
         }
@@ -1087,12 +1089,22 @@ RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& pr
 #else
         m_codeBlock->addGlobalResolveInstruction(instructions().size());
 #endif
-        emitOpcode(op_resolve_global);
+        emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
         instructions().append(dst->index());
         instructions().append(globalObject);
         instructions().append(addConstant(property));
         instructions().append(0);
         instructions().append(0);
+        if (requiresDynamicChecks)
+            instructions().append(depth);
+        return dst;
+    }
+
+    if (requiresDynamicChecks) {
+        // If we get here we have eval nested inside a |with| just give up
+        emitOpcode(op_resolve);
+        instructions().append(dst->index());
+        instructions().append(addConstant(property));
         return dst;
     }
 
@@ -1148,8 +1160,9 @@ RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const Identifier
     size_t depth = 0;
     int index = 0;
     JSObject* globalObject = 0;
-    findScopedProperty(property, index, depth, false, globalObject);
-    if (!globalObject) {
+    bool requiresDynamicChecks = false;
+    findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject);
+    if (!globalObject || requiresDynamicChecks) {
         // We can't optimise at all :-(
         emitOpcode(op_resolve_base);
         instructions().append(dst->index());
@@ -1166,7 +1179,8 @@ RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, Register
     size_t depth = 0;
     int index = 0;
     JSObject* globalObject = 0;
-    if (!findScopedProperty(property, index, depth, false, globalObject) || !globalObject) {
+    bool requiresDynamicChecks = false;
+    if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) || !globalObject || requiresDynamicChecks) {
         // We can't optimise at all :-(
         emitOpcode(op_resolve_with_base);
         instructions().append(baseDst->index());
@@ -1198,12 +1212,14 @@ RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, Register
 #else
     m_codeBlock->addGlobalResolveInstruction(instructions().size());
 #endif
-    emitOpcode(op_resolve_global);
+    emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
     instructions().append(propDst->index());
     instructions().append(globalObject);
     instructions().append(addConstant(property));
     instructions().append(0);
     instructions().append(0);
+    if (requiresDynamicChecks)
+        instructions().append(depth);
     return baseDst;
 }
 
@@ -1247,6 +1263,27 @@ RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& p
     instructions().append(0);
     instructions().append(0);
     instructions().append(0);
+    instructions().append(0);
+    return value;
+}
+
+RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
+{
+#if ENABLE(JIT)
+    m_codeBlock->addStructureStubInfo(StructureStubInfo(access_put_by_id));
+#else
+    m_codeBlock->addPropertyAccessInstruction(instructions().size());
+#endif
+    
+    emitOpcode(op_put_by_id);
+    instructions().append(base->index());
+    instructions().append(addConstant(property));
+    instructions().append(value->index());
+    instructions().append(0);
+    instructions().append(0);
+    instructions().append(0);
+    instructions().append(0);
+    instructions().append(property != m_globalData->propertyNames->underscoreProto);
     return value;
 }
 
@@ -1637,8 +1674,13 @@ void BytecodeGenerator::emitPopScope()
 
 void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine)
 {
+#if ENABLE(DEBUG_WITH_BREAKPOINT)
+    if (debugHookID != DidReachBreakpoint)
+        return;
+#else
     if (!m_shouldEmitDebugHooks)
         return;
+#endif
     emitOpcode(op_debug);
     instructions().append(debugHookID);
     instructions().append(firstLine);
@@ -1940,9 +1982,9 @@ static int32_t keyForCharacterSwitch(ExpressionNode* node, int32_t min, int32_t
     UNUSED_PARAM(max);
     ASSERT(node->isString());
     UString::Rep* clause = static_cast<StringNode*>(node)->value().ustring().rep();
-    ASSERT(clause->size() == 1);
+    ASSERT(clause->length() == 1);
     
-    int32_t key = clause->data()[0];
+    int32_t key = clause->characters()[0];
     ASSERT(key >= min);
     ASSERT(key <= max);
     return key - min;