summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/bytecode
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2010-10-22 13:02:20 +0100
committerBen Murdoch <benm@google.com>2010-10-26 15:21:41 +0100
commita94275402997c11dd2e778633dacf4b7e630a35d (patch)
treee66f56c67e3b01f22c9c23cd932271ee9ac558ed /JavaScriptCore/bytecode
parent09e26c78506587b3f5d930d7bc72a23287ffbec0 (diff)
downloadexternal_webkit-a94275402997c11dd2e778633dacf4b7e630a35d.zip
external_webkit-a94275402997c11dd2e778633dacf4b7e630a35d.tar.gz
external_webkit-a94275402997c11dd2e778633dacf4b7e630a35d.tar.bz2
Merge WebKit at r70209: Initial merge by Git
Change-Id: Id23a68efa36e9d1126bcce0b137872db00892c8e
Diffstat (limited to 'JavaScriptCore/bytecode')
-rw-r--r--JavaScriptCore/bytecode/CodeBlock.cpp64
-rw-r--r--JavaScriptCore/bytecode/CodeBlock.h17
-rw-r--r--JavaScriptCore/bytecode/EvalCodeCache.h8
-rw-r--r--JavaScriptCore/bytecode/Opcode.h6
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) \