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;
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()));
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()) {
}
size_t depth = 0;
-
+ requiresDynamicChecks = false;
ScopeChainIterator iter = m_scopeChain->begin();
ScopeChainIterator end = m_scopeChain->end();
for (; iter != end; ++iter, ++depth) {
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();
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());
#endif
}
- if (index != missingSymbolMarker() && !forceGlobalResolve) {
+ if (index != missingSymbolMarker() && !forceGlobalResolve && !requiresDynamicChecks) {
// Directly index the property lookup across multiple scopes.
return emitGetScopedVar(dst, depth, index, globalObject);
}
#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;
}
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());
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());
#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;
}
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;
}
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);
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;