diff options
Diffstat (limited to 'JavaScriptCore/bytecode')
-rw-r--r-- | JavaScriptCore/bytecode/CodeBlock.cpp | 64 | ||||
-rw-r--r-- | JavaScriptCore/bytecode/CodeBlock.h | 17 | ||||
-rw-r--r-- | JavaScriptCore/bytecode/EvalCodeCache.h | 8 | ||||
-rw-r--r-- | JavaScriptCore/bytecode/Opcode.h | 6 |
4 files changed, 71 insertions, 24 deletions
diff --git a/JavaScriptCore/bytecode/CodeBlock.cpp b/JavaScriptCore/bytecode/CodeBlock.cpp index 6c0696e..55101d4 100644 --- a/JavaScriptCore/bytecode/CodeBlock.cpp +++ b/JavaScriptCore/bytecode/CodeBlock.cpp @@ -34,10 +34,11 @@ #include "Debugger.h" #include "Interpreter.h" #include "JIT.h" +#include "JSActivation.h" #include "JSFunction.h" #include "JSStaticScopeObject.h" #include "JSValue.h" -#include "StringConcatenate.h" +#include "UStringConcatenate.h" #include <stdio.h> #include <wtf/StringExtras.h> @@ -52,7 +53,7 @@ static UString escapeQuotes(const UString& str) UString result = str; size_t pos = 0; while ((pos = result.find('\"', pos)) != notFound) { - result = makeString(result.substringSharingImpl(0, pos), "\"\\\"\"", result.substringSharingImpl(pos + 1)); + result = makeUString(result.substringSharingImpl(0, pos), "\"\\\"\"", result.substringSharingImpl(pos + 1)); pos += 4; } return result; @@ -64,19 +65,19 @@ static UString valueToSourceString(ExecState* exec, JSValue val) return "0"; if (val.isString()) - return makeString("\"", escapeQuotes(val.toString(exec)), "\""); + return makeUString("\"", escapeQuotes(val.toString(exec)), "\""); return val.toString(exec); } static CString constantName(ExecState* exec, int k, JSValue value) { - return makeString(valueToSourceString(exec, value), "(@k", UString::number(k - FirstConstantRegisterIndex), ")").utf8(); + return makeUString(valueToSourceString(exec, value), "(@k", UString::number(k - FirstConstantRegisterIndex), ")").utf8(); } static CString idName(int id0, const Identifier& ident) { - return makeString(ident.ustring(), "(@id", UString::number(id0), ")").utf8(); + return makeUString(ident.ustring(), "(@id", UString::number(id0), ")").utf8(); } CString CodeBlock::registerName(ExecState* exec, int r) const @@ -87,7 +88,7 @@ CString CodeBlock::registerName(ExecState* exec, int r) const if (isConstantRegisterIndex(r)) return constantName(exec, r, getConstant(r)); - return makeString("r", UString::number(r)).utf8(); + return makeUString("r", UString::number(r)).utf8(); } static UString regexpToSourceString(RegExp* regExp) @@ -101,12 +102,12 @@ static UString regexpToSourceString(RegExp* regExp) if (regExp->multiline()) postfix[index] = 'm'; - return makeString("/", regExp->pattern(), postfix); + return makeUString("/", regExp->pattern(), postfix); } static CString regexpName(int re, RegExp* regexp) { - return makeString(regexpToSourceString(regexp), "(@re", UString::number(re), ")").utf8(); + return makeUString(regexpToSourceString(regexp), "(@re", UString::number(re), ")").utf8(); } static UString pointerToSourceString(void* p) @@ -485,9 +486,9 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& printf("[%4d] enter\n", location); break; } - case op_enter_with_activation: { + case op_create_activation: { int r0 = (++it)->u.operand; - printf("[%4d] enter_with_activation %s\n", location, registerName(exec, r0).data()); + printf("[%4d] create_activation %s\n", location, registerName(exec, r0).data()); break; } case op_create_arguments: { @@ -516,6 +517,11 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& printf("[%4d] convert_this %s\n", location, registerName(exec, r0).data()); break; } + case op_convert_this_strict: { + int r0 = (++it)->u.operand; + printf("[%4d] convert_this_strict %s\n", location, registerName(exec, r0).data()); + break; + } case op_new_object: { int r0 = (++it)->u.operand; printf("[%4d] new_object\t %s\n", location, registerName(exec, r0).data()); @@ -722,9 +728,8 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& int id0 = (++it)->u.operand; JSValue scope = JSValue((++it)->u.jsCell); ++it; - int depth = it[2].u.operand; + int depth = (++it)->u.operand; printf("[%4d] resolve_global_dynamic\t %s, %s, %s, %d\n", location, registerName(exec, r0).data(), valueToSourceString(exec, scope).utf8().data(), idName(id0, m_identifiers[id0]).data(), depth); - it += 3; break; } case op_get_scoped_var: { @@ -756,7 +761,14 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& case op_resolve_base: { int r0 = (++it)->u.operand; int id0 = (++it)->u.operand; - printf("[%4d] resolve_base\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); + int isStrict = (++it)->u.operand; + printf("[%4d] resolve_base%s\t %s, %s\n", location, isStrict ? "_strict" : "", registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); + break; + } + case op_ensure_property_exists: { + int r0 = (++it)->u.operand; + int id0 = (++it)->u.operand; + printf("[%4d] ensure_property_exists\t %s, %s\n", location, registerName(exec, r0).data(), idName(id0, m_identifiers[id0]).data()); break; } case op_resolve_with_base: { @@ -1134,9 +1146,12 @@ void CodeBlock::dump(ExecState* exec, const Vector<Instruction>::const_iterator& } case op_next_pname: { int dest = it[1].u.operand; - int iter = it[4].u.operand; - int offset = it[5].u.operand; - printf("[%4d] next_pname\t %s, %s, %d(->%d)\n", location, registerName(exec, dest).data(), registerName(exec, iter).data(), offset, location + offset); + int base = it[2].u.operand; + int i = it[3].u.operand; + int size = it[4].u.operand; + int iter = it[5].u.operand; + int offset = it[6].u.operand; + printf("[%4d] next_pname\t %s, %s, %s, %s, %s, %d(->%d)\n", location, registerName(exec, dest).data(), registerName(exec, base).data(), registerName(exec, i).data(), registerName(exec, size).data(), registerName(exec, iter).data(), offset, location + offset); it += OPCODE_LENGTH(op_next_pname) - 1; break; } @@ -1371,6 +1386,7 @@ CodeBlock::CodeBlock(ScriptExecutable* ownerExecutable, CodeType codeType, JSGlo , m_needsFullScopeChain(ownerExecutable->needsActivation()) , m_usesEval(ownerExecutable->usesEval()) , m_isNumericCompareFunction(false) + , m_isStrictMode(ownerExecutable->isStrictMode()) , m_codeType(codeType) , m_source(sourceProvider) , m_sourceOffset(sourceOffset) @@ -1542,6 +1558,10 @@ bool CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame) ASSERT(!m_rareData || !m_rareData->m_exceptionHandlers.size()); ScopeChainNode* scopeChain = callFrame->scopeChain(); if (m_needsFullScopeChain) { + if (codeType() == FunctionCode && !callFrame->r(activationRegister()).jsValue()) { + createActivation(callFrame); + scopeChain = callFrame->scopeChain(); + } ScopeChain sc(scopeChain); int scopeDelta = sc.localDepth(); if (m_codeType == EvalCode) @@ -1553,7 +1573,7 @@ bool CodeBlock::reparseForExceptionInfoIfNecessary(CallFrame* callFrame) scopeChain = scopeChain->next; } - m_exceptionInfo = m_ownerExecutable->reparseExceptionInfo(m_globalData, scopeChain, this); + m_exceptionInfo = m_ownerExecutable->reparseExceptionInfo(scopeChain, this); return m_exceptionInfo; } @@ -1765,4 +1785,14 @@ void CodeBlock::shrinkToFit() } } +void CodeBlock::createActivation(CallFrame* callFrame) +{ + ASSERT(codeType() == FunctionCode); + ASSERT(needsFullScopeChain()); + ASSERT(!callFrame->r(activationRegister()).jsValue()); + JSActivation* activation = new (callFrame) JSActivation(callFrame, static_cast<FunctionExecutable*>(ownerExecutable())); + callFrame->r(activationRegister()) = JSValue(activation); + callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation)); +} + } // namespace JSC diff --git a/JavaScriptCore/bytecode/CodeBlock.h b/JavaScriptCore/bytecode/CodeBlock.h index cda4530..e4ebeb8 100644 --- a/JavaScriptCore/bytecode/CodeBlock.h +++ b/JavaScriptCore/bytecode/CodeBlock.h @@ -297,9 +297,11 @@ namespace JSC { void printStructure(const char* name, const Instruction*, int operand) const; #endif + bool isStrictMode() const { return m_isStrictMode; } + inline bool isKnownNotImmediate(int index) { - if (index == m_thisRegister) + if (index == m_thisRegister && !m_isStrictMode) return true; if (isConstantRegisterIndex(index)) @@ -408,6 +410,15 @@ namespace JSC { ASSERT(usesArguments()); return m_argumentsRegister; } + void setActivationRegister(int activationRegister) + { + m_activationRegister = activationRegister; + } + int activationRegister() + { + ASSERT(needsFullScopeChain()); + return m_activationRegister; + } bool usesArguments() const { return m_argumentsRegister != -1; } CodeType codeType() const { return m_codeType; } @@ -420,6 +431,8 @@ namespace JSC { unsigned jumpTarget(int index) const { return m_jumpTargets[index]; } unsigned lastJumpTarget() const { return m_jumpTargets.last(); } + void createActivation(CallFrame*); + #if ENABLE(INTERPRETER) void addPropertyAccessInstruction(unsigned propertyAccessInstruction) { m_propertyAccessInstructions.append(propertyAccessInstruction); } void addGlobalResolveInstruction(unsigned globalResolveInstruction) { m_globalResolveInstructions.append(globalResolveInstruction); } @@ -548,10 +561,12 @@ namespace JSC { int m_thisRegister; int m_argumentsRegister; + int m_activationRegister; bool m_needsFullScopeChain; bool m_usesEval; bool m_isNumericCompareFunction; + bool m_isStrictMode; CodeType m_codeType; diff --git a/JavaScriptCore/bytecode/EvalCodeCache.h b/JavaScriptCore/bytecode/EvalCodeCache.h index 7c4cb33..edd575f 100644 --- a/JavaScriptCore/bytecode/EvalCodeCache.h +++ b/JavaScriptCore/bytecode/EvalCodeCache.h @@ -43,20 +43,20 @@ namespace JSC { class EvalCodeCache { public: - PassRefPtr<EvalExecutable> get(ExecState* exec, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue) + PassRefPtr<EvalExecutable> get(ExecState* exec, bool inStrictContext, const UString& evalSource, ScopeChainNode* scopeChain, JSValue& exceptionValue) { RefPtr<EvalExecutable> evalExecutable; - if (evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject()) + if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject()) evalExecutable = m_cacheMap.get(evalSource.impl()); if (!evalExecutable) { - evalExecutable = EvalExecutable::create(exec, makeSource(evalSource)); + evalExecutable = EvalExecutable::create(exec, makeSource(evalSource), inStrictContext); exceptionValue = evalExecutable->compile(exec, scopeChain); if (exceptionValue) return 0; - if (evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries) + if (!inStrictContext && evalSource.length() < maxCacheableSourceLength && (*scopeChain->begin())->isVariableObject() && m_cacheMap.size() < maxCacheEntries) m_cacheMap.set(evalSource.impl(), evalExecutable); } diff --git a/JavaScriptCore/bytecode/Opcode.h b/JavaScriptCore/bytecode/Opcode.h index 03f6573..e1ef01e 100644 --- a/JavaScriptCore/bytecode/Opcode.h +++ b/JavaScriptCore/bytecode/Opcode.h @@ -39,12 +39,13 @@ namespace JSC { #define FOR_EACH_OPCODE_ID(macro) \ macro(op_enter, 1) \ - macro(op_enter_with_activation, 2) \ + macro(op_create_activation, 2) \ macro(op_init_lazy_reg, 2) \ macro(op_create_arguments, 2) \ macro(op_create_this, 3) \ macro(op_get_callee, 2) \ macro(op_convert_this, 2) \ + macro(op_convert_this_strict, 2) \ \ macro(op_new_object, 2) \ macro(op_new_array, 4) \ @@ -99,7 +100,8 @@ namespace JSC { macro(op_put_scoped_var, 4) \ macro(op_get_global_var, 3) \ macro(op_put_global_var, 3) \ - macro(op_resolve_base, 3) \ + macro(op_resolve_base, 4) \ + macro(op_ensure_property_exists, 3) \ macro(op_resolve_with_base, 4) \ macro(op_get_by_id, 8) \ macro(op_get_by_id_self, 8) \ |