Commit a963b966 authored by weinig@apple.com's avatar weinig@apple.com

2008-06-04 Sam Weinig <sam@webkit.org>

        Reviewed by Maciej Stachowiak.

        Big cleanup of formatting and whitespace.



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@34372 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent b7a96101
2008-06-04 Sam Weinig <sam@webkit.org>
Reviewed by Maciej Stachowiak.
Big cleanup of formatting and whitespace.
2008-06-04 Cameron Zwarich <cwzwarich@uwaterloo.ca>
Reviewed by Oliver.
......
......@@ -97,21 +97,21 @@ static CString regexpName(int re, RegExp* regexp)
NEVER_INLINE static const char* debugHookName(int debugHookID)
{
switch((DebugHookID)debugHookID) {
case DidEnterCallFrame:
return "didEnterCallFrame";
case WillLeaveCallFrame:
return "willLeaveCallFrame";
case WillExecuteStatement:
return "willExecuteStatement";
case WillExecuteProgram:
return "willExecuteProgram";
case DidExecuteProgram:
return "didExecuteProgram";
case DidReachBreakpoint:
return "didReachBreakpoint";
switch (static_cast<DebugHookID>(debugHookID)) {
case DidEnterCallFrame:
return "didEnterCallFrame";
case WillLeaveCallFrame:
return "willLeaveCallFrame";
case WillExecuteStatement:
return "willExecuteStatement";
case WillExecuteProgram:
return "willExecuteProgram";
case DidExecuteProgram:
return "didExecuteProgram";
case DidReachBreakpoint:
return "didReachBreakpoint";
}
ASSERT_NOT_REACHED();
return "";
}
......
......@@ -26,7 +26,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CodeBlock_h
#define CodeBlock_h
......@@ -89,7 +89,7 @@ namespace KJS {
Vector<RefPtr<FuncDeclNode> > functions;
Vector<RefPtr<FuncExprNode> > functionExpressions;
Vector<JSValue*> jsValues;
Vector<RefPtr<RegExp> > regexps;
Vector<RefPtr<RegExp> > regexps;
Vector<HandlerInfo> exceptionHandlers;
Vector<LineInfo> lineInfo;
......
......@@ -39,16 +39,16 @@ namespace KJS {
/*
The layout of a register frame looks like this:
For
For
function f(x, y) {
var v1;
function g() { }
var v2;
return (x) * (y);
}
assuming (x) and (y) generated temporaries t1 and t2, you would have
------------------------------------
......@@ -57,39 +57,39 @@ namespace KJS {
| -5 | -4 | -3 | -2 | -1 | +0 | +1 | <-- register index
------------------------------------
| params->|<-locals | temps->
Because temporary registers are allocated in a stack-like fashion, we
can reclaim them with a simple popping algorithm. The same goes for labels.
(We never reclaim parameter or local registers, because parameters and
locals are DontDelete.)
The register layout before a function call looks like this:
For
function f(x, y)
{
}
f(1);
> <------------------------------
< > reserved: call frame | 1 | <-- value held
> >snip< <------------------------------
< > +0 | +1 | +2 | +3 | +4 | +5 | <-- register index
> <------------------------------
| params->|<-locals | temps->
| params->|<-locals | temps->
The call instruction fills in the "call frame" registers. It also pads
missing arguments at the end of the call:
> <-----------------------------------
< > reserved: call frame | 1 | ? | <-- value held ("?" stands for "undefined")
> >snip< <-----------------------------------
< > +0 | +1 | +2 | +3 | +4 | +5 | +6 | <-- register index
> <-----------------------------------
| params->|<-locals | temps->
After filling in missing arguments, the call instruction sets up the new
stack frame to overlap the end of the old stack frame:
......@@ -99,9 +99,9 @@ namespace KJS {
| -7 | -6 | -5 | -4 | -3 | -2 | -1 < > <-- register index
|----------------------------------> <
| | params->|<-locals | temps->
That way, arguments are "copied" into the callee's stack frame for free.
If the caller supplies too many arguments, this trick doesn't work. The
extra arguments protrude into space reserved for locals and temporaries.
In that case, the call instruction makes a real copy of the call frame header,
......@@ -110,7 +110,6 @@ namespace KJS {
extra arguments, because the "arguments" object may access them later.)
This copying strategy ensures that all named values will be at the indices
expected by the callee.
*/
#ifndef NDEBUG
......@@ -132,7 +131,7 @@ void CodeGenerator::generate()
m_codeBlock->thisRegister = m_thisRegister.index();
if (m_shouldEmitDebugHooks)
m_codeBlock->needsFullScopeChain = true;
m_scopeNode->emitCode(*this);
#ifndef NDEBUG
......@@ -195,7 +194,7 @@ CodeGenerator::CodeGenerator(ProgramNode* programNode, const Debugger* debugger,
m_nextVar -= size;
JSGlobalObject* globalObject = scopeChain.globalObject();
ExecState* exec = globalObject->globalExec();
// FIXME: Move the execution-related parts of this code to Machine::execute.
......@@ -206,7 +205,7 @@ CodeGenerator::CodeGenerator(ProgramNode* programNode, const Debugger* debugger,
globalObject->removeDirect(funcDecl->m_ident); // Make sure our new function is not shadowed by an old property.
emitNewFunction(addVar(funcDecl->m_ident, false), funcDecl);
}
for (size_t i = 0; i < varStack.size(); ++i) {
if (!globalObject->hasProperty(exec, varStack[i].first))
emitLoad(addVar(varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant), jsUndefined());
......@@ -244,7 +243,7 @@ CodeGenerator::CodeGenerator(FunctionBodyNode* functionBody, const Debugger* deb
for (size_t i = 0; i < functionStack.size(); ++i) {
FuncDeclNode* funcDecl = functionStack[i].get();
const Identifier& ident = funcDecl->m_ident;
m_functions.add(ident.ustring().rep());
emitNewFunction(addVar(ident, false), funcDecl);
}
......@@ -254,7 +253,7 @@ CodeGenerator::CodeGenerator(FunctionBodyNode* functionBody, const Debugger* deb
const Identifier& ident = varStack[i].first;
if (ident == m_propertyNames->arguments)
continue;
RegisterID* r0;
if (addVar(ident, r0, varStack[i].second & DeclarationStacks::IsConstant))
emitLoad(r0, jsUndefined());
......@@ -305,7 +304,7 @@ RegisterID* CodeGenerator::addParameter(const Identifier& ident)
m_locals[localsIndex(m_nextParameter)].setIndex(m_nextParameter);
result = &(m_locals[localsIndex(m_nextParameter)]);
}
// To maintain the calling convention, we have to allocate unique space for
// each parameter, even if the parameter doesn't make it into the symbol table.
++m_nextParameter;
......@@ -335,10 +334,10 @@ RegisterID* CodeGenerator::registerForLocalConstInit(const Identifier& ident)
{
if (m_codeType == EvalCode)
return 0;
SymbolTableEntry entry = symbolTable().get(ident.ustring().rep());
ASSERT(!entry.isEmpty());
return &m_locals[localsIndex(entry.getIndex())];
}
......@@ -429,7 +428,7 @@ unsigned CodeGenerator::addConstant(const Identifier& ident)
pair<IdentifierMap::iterator, bool> result = m_identifierMap.add(rep, m_codeBlock->identifiers.size());
if (result.second) // new entry
m_codeBlock->identifiers.append(rep);
return result.first->second;
}
......@@ -438,7 +437,7 @@ unsigned CodeGenerator::addConstant(JSValue* v)
pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(v, m_codeBlock->jsValues.size());
if (result.second) // new entry
m_codeBlock->jsValues.append(v);
return result.first->second;
}
......@@ -751,7 +750,7 @@ bool CodeGenerator::findScopedProperty(const Identifier& property, int& index, s
for (; iter != end; ++iter, ++depth) {
JSObject* currentScope = *iter;
if (!currentScope->isVariableObject())
if (!currentScope->isVariableObject())
break;
JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope);
SymbolTableEntry entry = currentVariableObject->symbolTable().get(property.ustring().rep());
......@@ -797,7 +796,7 @@ RegisterID* CodeGenerator::emitResolve(RegisterID* dst, const Identifier& proper
// Directly index the property lookup across multiple scopes. Yay!
return emitGetScopedVar(dst, depth, index);
}
RegisterID* CodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index)
{
instructions().append(machine().getOpcode(op_get_scoped_var));
......@@ -806,7 +805,7 @@ RegisterID* CodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int i
instructions().append(depth);
return dst;
}
RegisterID* CodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value)
{
instructions().append(machine().getOpcode(op_put_scoped_var));
......@@ -823,7 +822,7 @@ RegisterID* CodeGenerator::emitResolveBase(RegisterID* dst, const Identifier& pr
instructions().append(addConstant(property));
return dst;
}
RegisterID* CodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property)
{
instructions().append(machine().getOpcode(op_resolve_with_base));
......@@ -964,7 +963,7 @@ RegisterID* CodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, Register
RefPtr<RegisterID> refFunc = func;
RefPtr<RegisterID> refBase = base;
// Reserve space for call frame.
Vector<RefPtr<RegisterID>, Machine::CallFrameHeaderSize> callFrame;
for (int i = 0; i < Machine::CallFrameHeaderSize; ++i)
......@@ -1106,7 +1105,7 @@ JumpContext* CodeGenerator::jumpContextForContinue(const Identifier& label)
}
return 0;
}
for (int i = m_jumpContextStack.size() - 1; i >= 0; i--) {
JumpContext* scope = &m_jumpContextStack[i];
if (scope->labels->contains(label))
......@@ -1128,7 +1127,7 @@ JumpContext* CodeGenerator::jumpContextForBreak(const Identifier& label)
}
return 0;
}
for (int i = m_jumpContextStack.size() - 1; i >= 0; i--) {
JumpContext* scope = &m_jumpContextStack[i];
if (scope->labels->contains(label))
......@@ -1151,11 +1150,11 @@ PassRefPtr<LabelID> CodeGenerator::emitComplexJumpScopes(LabelID* target, Contro
}
if (nNormalScopes) {
// We need to remove a number of dynamic scopes to get to the next
// We need to remove a number of dynamic scopes to get to the next
// finally block
instructions().append(machine().getOpcode(op_jmp_scopes));
instructions().append(nNormalScopes);
// If topScope == bottomScope then there isn't actually a finally block
// left to emit, so make the jmp_scopes jump directly to the target label
if (topScope == bottomScope) {
......@@ -1163,7 +1162,7 @@ PassRefPtr<LabelID> CodeGenerator::emitComplexJumpScopes(LabelID* target, Contro
return target;
}
// Otherwise we just use jmp_scopes to pop a group of scopes and go
// Otherwise we just use jmp_scopes to pop a group of scopes and go
// to the next instruction
RefPtr<LabelID> nextInsn = newLabel();
instructions().append(nextInsn->offsetFrom(instructions().size()));
......@@ -1225,7 +1224,7 @@ RegisterID* CodeGenerator::emitCatch(RegisterID* targetRegister, LabelID* start,
instructions().append(targetRegister->index());
return targetRegister;
}
void CodeGenerator::emitThrow(RegisterID* exception)
{
instructions().append(machine().getOpcode(op_throw));
......
......@@ -37,8 +37,8 @@
#include "LabelID.h"
#include "Machine.h"
#include "RegisterID.h"
#include "SymbolTable.h"
#include "SegmentedVector.h"
#include "SymbolTable.h"
#include "debugger.h"
#include "nodes.h"
#include <wtf/PassRefPtr.h>
......@@ -63,19 +63,19 @@ namespace KJS {
LabelID* finallyAddr;
RegisterID* retAddrDst;
};
struct ControlFlowContext {
bool isFinallyBlock;
FinallyContext finallyContext;
};
class CodeGenerator {
public:
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
static void setDumpsGeneratedCode(bool dumpsGeneratedCode);
CodeGenerator(ProgramNode*, const Debugger*, const ScopeChain&, SymbolTable*, CodeBlock*, VarStack&, FunctionStack&, bool canCreateGlobals);
CodeGenerator(FunctionBodyNode*, const Debugger*, const ScopeChain&, SymbolTable*, CodeBlock*);
CodeGenerator(EvalNode*, const Debugger*, const ScopeChain&, SymbolTable*, EvalCodeBlock*);
......@@ -95,9 +95,9 @@ namespace KJS {
RegisterID* registerForLocalConstInit(const Identifier&);
// Searches the scope chain in an attempt to statically locate the requested
// property. Returns false if for any reason the property cannot be safely
// property. Returns false if for any reason the property cannot be safely
// optimised at all. Otherwise it will return the index and depth of the
// VariableObject that defines the property. If the property cannot be found
// VariableObject that defines the property. If the property cannot be found
// statically, depth will contain the depth of the scope chain where dynamic
// lookup must begin.
//
......@@ -132,17 +132,18 @@ namespace KJS {
RegisterID* tempDestination(RegisterID* dst) { return (dst && dst->isTemporary()) ? dst : newTemporary(); }
// Returns the place to write the final output of an operation.
RegisterID* finalDestination(RegisterID* originalDst, RegisterID* tempDst = 0)
{
RegisterID* finalDestination(RegisterID* originalDst, RegisterID* tempDst = 0)
{
if (originalDst)
return originalDst;
if (tempDst && tempDst->isTemporary())
return tempDst;
return newTemporary();
return newTemporary();
}
RegisterID* destinationForAssignResult(RegisterID* dst) {
if (dst && m_codeBlock->needsFullScopeChain)
RegisterID* destinationForAssignResult(RegisterID* dst)
{
if (dst && m_codeBlock->needsFullScopeChain)
return dst->isTemporary() ? dst : newTemporary();
return 0;
}
......@@ -150,12 +151,12 @@ namespace KJS {
// moves src to dst if dst is not null and is different from src, otherwise just returns src
RegisterID* moveToDestinationIfNeeded(RegisterID* dst, RegisterID* src) { return (dst && dst != src) ? emitMove(dst, src) : src; }
PassRefPtr<LabelID> newLabel();
// The emitNode functions are just syntactic sugar for calling
// Node::emitCode. They're the only functions that accept a NULL register.
RegisterID* emitNode(RegisterID* dst, Node* n) {
RegisterID* emitNode(RegisterID* dst, Node* n)
{
// Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary.
ASSERT(!dst || !dst->isTemporary() || dst->refCount());
if (!m_codeBlock->lineInfo.size() || m_codeBlock->lineInfo.last().lineNumber != n->lineNo()) {
......@@ -182,14 +183,14 @@ namespace KJS {
emitNode(dst.get(), n);
return dst;
}
return PassRefPtr<RegisterID>(emitNode(n));
}
RegisterID* emitLoad(RegisterID* dst, bool);
RegisterID* emitLoad(RegisterID* dst, double);
RegisterID* emitLoad(RegisterID* dst, JSValue*);
RegisterID* emitNewObject(RegisterID* dst);
RegisterID* emitNewArray(RegisterID* dst);
......@@ -265,21 +266,21 @@ namespace KJS {
PassRefPtr<LabelID> emitJumpSubroutine(RegisterID* retAddrDst, LabelID*);
void emitSubroutineReturn(RegisterID* retAddrSrc);
RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base);
RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* iter, LabelID* target);
RegisterID* emitCatch(RegisterID*, LabelID* start, LabelID* end);
void emitThrow(RegisterID*);
RegisterID* emitNewError(RegisterID* dst, ErrorType type, JSValue* message);
RegisterID* emitPushScope(RegisterID* scope);
void emitPopScope();
void emitDebugHook(DebugHookID, int firstLine, int lastLine);
int scopeDepth() { return m_dynamicScopeDepth + m_finallyDepth; }
void pushFinallyContext(LabelID* target, RegisterID* returnAddrDst);
void popFinallyContext();
bool inContinueContext() { return m_continueDepth > 0; };
......@@ -289,8 +290,8 @@ namespace KJS {
JumpContext* jumpContextForContinue(const Identifier&);
JumpContext* jumpContextForBreak(const Identifier&);
CodeType codeType() const { return m_codeType; }
private:
PassRefPtr<LabelID> emitComplexJumpScopes(LabelID* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
struct JSValueHashTraits : HashTraits<JSValue*> {
......@@ -299,7 +300,7 @@ namespace KJS {
};
typedef HashMap<JSValue*, unsigned, DefaultHash<JSValue*>::Hash, JSValueHashTraits> JSValueMap;
struct IdentifierMapIndexHashTraits {
typedef int TraitType;
typedef IdentifierMapIndexHashTraits StorageTraits;
......@@ -315,7 +316,7 @@ namespace KJS {
// Maps a register index in the symbol table to a RegisterID index in m_locals.
int localsIndex(int registerIndex) { return -registerIndex - 1; }
// Returns the RegisterID corresponding to ident.
RegisterID* addVar(const Identifier& ident, bool isConstant)
{
......@@ -334,22 +335,22 @@ namespace KJS {
unsigned addConstant(const Identifier&);
unsigned addConstant(JSValue*);
unsigned addRegExp(RegExp* r);
Vector<Instruction>& instructions() { return m_codeBlock->instructions; }
SymbolTable& symbolTable() { return *m_symbolTable; }
Vector<HandlerInfo>& exceptionHandlers() { return m_codeBlock->exceptionHandlers; }
bool shouldOptimizeLocals() { return (m_codeType != EvalCode) && !m_dynamicScopeDepth; }
bool canOptimizeNonLocals() { return (m_codeType == FunctionCode) && !m_dynamicScopeDepth && !m_codeBlock->usesEval; }
bool m_shouldEmitDebugHooks;
const ScopeChain* m_scopeChain;
SymbolTable* m_symbolTable;
ScopeNode* m_scopeNode;
CodeBlock* m_codeBlock;
HashSet<RefPtr<UString::Rep>, IdentifierRepHash> m_functions;
RegisterID m_thisRegister;
SegmentedVector<RegisterID, 512> m_locals;
......@@ -358,7 +359,7 @@ namespace KJS {
int m_finallyDepth;
int m_dynamicScopeDepth;
CodeType m_codeType;
Vector<JumpContext> m_jumpContextStack;
int m_continueDepth;
Vector<ControlFlowContext> m_scopeContextStack;
......@@ -372,7 +373,7 @@ namespace KJS {
CommonIdentifiers* m_propertyNames;
#ifndef NDEBUG
#ifndef NDEBUG
static bool s_dumpsGeneratedCode;
#endif
};
......
......@@ -44,7 +44,7 @@ static void substitute(UString& string, const UString& substring)
newString.append(string.substr(position + 2));
string = newString;
}
JSValue* createError(ExecState* exec, ErrorType e, const char* msg)
{
return Error::create(exec, e, msg, -1, -1, 0);
......@@ -82,7 +82,7 @@ JSValue* createUndefinedVariableError(ExecState* exec, const Identifier& ident)
{
return createError(exec, ReferenceError, "Can't find variable: %s", ident);
}
JSValue* createInvalidParamError(ExecState* exec, const char* op, JSValue* v)
{
UString message = "'%s' is not a valid argument for '%s'";
......@@ -105,4 +105,4 @@ JSValue* createNotAFunctionError(ExecState* exec, JSValue* value, Node* expr)
return createError(exec, TypeError, "Value %s does not allow function calls.", value);
}
}
} // namespace KJS
......@@ -32,12 +32,15 @@
#include "object.h"
namespace KJS {
class Node;
JSValue* createStackOverflowError(ExecState*);
JSValue* createUndefinedVariableError(ExecState*, const Identifier&);
JSValue* createInvalidParamError(ExecState*, const char* op, JSValue*);
JSValue* createNotAConstructorError(ExecState* exec, JSValue* value, Node* expr);
JSValue* createNotAFunctionError(ExecState* exec, JSValue* value, Node* expr);
}
JSValue* createNotAConstructorError(ExecState*, JSValue*, Node* expr);
JSValue* createNotAFunctionError(ExecState*, JSValue*, Node* expr);
} // namespace KJS
#endif
#endif // ExceptionHelpers_h
......@@ -25,7 +25,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef Instruction_h
#define Instruction_h
......@@ -36,13 +36,13 @@ namespace KJS {
struct Instruction {
Instruction(Opcode opcode) { u.opcode = opcode; }
Instruction(int operand) { u.operand = operand; }
union {
Opcode opcode;
int operand;
} u;
};
} // namespace KJS
#endif // Instruction_h
......@@ -33,10 +33,22 @@
#include "object.h"
#include "PropertyNameArray.h"
namespace KJS{
namespace KJS {
COMPILE_ASSERT(sizeof(JSPropertyNameIterator) <= CellSize<sizeof(void*)>::m_value, JSPropertyNameIteratorSizeASSERT);
JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue* v)
{
if (v->isUndefinedOrNull())
return new JSPropertyNameIterator(0, 0, 0);
JSObject* o = v->toObject(exec);
PropertyNameArray propertyNames;
o->getPropertyNames(exec, propertyNames);
size_t numProperties = propertyNames.size();
return new JSPropertyNameIterator(o, propertyNames.releaseIdentifiers(), numProperties);
}
JSPropertyNameIterator::JSPropertyNameIterator(JSObject* object, Identifier* propertyNames, size_t numProperties)
: m_object(object)
, m_propertyNames(propertyNames)
......@@ -44,53 +56,62 @@ JSPropertyNameIterator::JSPropertyNameIterator(JSObject* object, Identifier* pro
, m_end(propertyNames + numProperties)
{
}
JSType JSPropertyNameIterator::type() const {
return UnspecifiedType;
JSPropertyNameIterator::~JSPropertyNameIterator()
{
delete m_propertyNames;
}
JSType JSPropertyNameIterator::type() const
{
return UnspecifiedType;
}
JSValue *JSPropertyNameIterator::toPrimitive(ExecState *, JSType) const
JSValue* JSPropertyNameIterator::toPrimitive(ExecState*,