#include "LabelScope.h"
#include "Interpreter.h"
#include "RegisterID.h"
-#include "SegmentedVector.h"
#include "SymbolTable.h"
#include "Debugger.h"
#include "Nodes.h"
+#include <wtf/FastAllocBase.h>
#include <wtf/PassRefPtr.h>
+#include <wtf/SegmentedVector.h>
#include <wtf/Vector.h>
namespace JSC {
FinallyContext finallyContext;
};
- class BytecodeGenerator {
+ class BytecodeGenerator : public WTF::FastAllocBase {
public:
typedef DeclarationStacks::VarStack VarStack;
typedef DeclarationStacks::FunctionStack FunctionStack;
// such register exists. Registers returned by registerFor do not
// require explicit reference counting.
RegisterID* registerFor(const Identifier&);
+
+ bool willResolveToArguments(const Identifier&);
+ RegisterID* uncheckedRegisterForArguments();
// Behaves as registerFor does, but ignores dynamic scope as
// dynamic scope should not interfere with const initialisation
RegisterID* emitLoad(RegisterID* dst, bool);
RegisterID* emitLoad(RegisterID* dst, double);
RegisterID* emitLoad(RegisterID* dst, const Identifier&);
- RegisterID* emitLoad(RegisterID* dst, JSValuePtr);
- RegisterID* emitUnexpectedLoad(RegisterID* dst, bool);
- RegisterID* emitUnexpectedLoad(RegisterID* dst, double);
+ RegisterID* emitLoad(RegisterID* dst, JSValue);
RegisterID* emitUnaryOp(OpcodeID, RegisterID* dst, RegisterID* src);
RegisterID* emitBinaryOp(OpcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes);
RegisterID* emitIn(RegisterID* dst, RegisterID* property, RegisterID* base) { return emitBinaryOp(op_in, dst, property, base, OperandTypes()); }
RegisterID* emitResolve(RegisterID* dst, const Identifier& property);
- RegisterID* emitGetScopedVar(RegisterID* dst, size_t skip, int index, JSValuePtr globalObject);
- RegisterID* emitPutScopedVar(size_t skip, int index, RegisterID* value, JSValuePtr globalObject);
+ RegisterID* emitGetScopedVar(RegisterID* dst, size_t skip, int index, JSValue globalObject);
+ RegisterID* emitPutScopedVar(size_t skip, int index, RegisterID* value, JSValue globalObject);
RegisterID* emitResolveBase(RegisterID* dst, const Identifier& property);
RegisterID* emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property);
- RegisterID* emitResolveFunction(RegisterID* baseDst, RegisterID* funcDst, const Identifier& property);
+
+ void emitMethodCheck();
RegisterID* emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property);
RegisterID* emitPutById(RegisterID* base, const Identifier& property, RegisterID* value);
RegisterID* emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
RegisterID* emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ RegisterID* emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* argCount, unsigned divot, unsigned startOffset, unsigned endOffset);
+ RegisterID* emitLoadVarargs(RegisterID* argCountDst, RegisterID* args);
RegisterID* emitReturn(RegisterID* src);
RegisterID* emitEnd(RegisterID* src) { return emitUnaryNoDstOp(op_end, src); }
RegisterID* emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+ RegisterID* emitStrcat(RegisterID* dst, RegisterID* src, int count);
+ void emitToPrimitive(RegisterID* dst, RegisterID* src);
PassRefPtr<Label> emitLabel(Label*);
PassRefPtr<Label> emitJump(Label* target);
PassRefPtr<Label> emitJumpIfTrue(RegisterID* cond, Label* target);
PassRefPtr<Label> emitJumpIfFalse(RegisterID* cond, Label* target);
+ PassRefPtr<Label> emitJumpIfNotFunctionCall(RegisterID* cond, Label* target);
+ PassRefPtr<Label> emitJumpIfNotFunctionApply(RegisterID* cond, Label* target);
PassRefPtr<Label> emitJumpScopes(Label* target, int targetScopeDepth);
PassRefPtr<Label> emitJumpSubroutine(RegisterID* retAddrDst, Label*);
RegisterID* emitCatch(RegisterID*, Label* start, Label* end);
void emitThrow(RegisterID* exc) { emitUnaryNoDstOp(op_throw, exc); }
- RegisterID* emitNewError(RegisterID* dst, ErrorType type, JSValuePtr message);
+ RegisterID* emitNewError(RegisterID* dst, ErrorType type, JSValue message);
void emitPushNewScope(RegisterID* dst, Identifier& property, RegisterID* value);
RegisterID* emitPushScope(RegisterID* scope);
PassRefPtr<Label> emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope);
- struct JSValueHashTraits : HashTraits<JSValueEncodedAsPointer*> {
- static void constructDeletedValue(JSValueEncodedAsPointer*& slot) { slot = JSValuePtr::encode(jsImpossibleValue()); }
- static bool isDeletedValue(JSValueEncodedAsPointer* value) { return value == JSValuePtr::encode(jsImpossibleValue()); }
- };
-
- typedef HashMap<JSValueEncodedAsPointer*, unsigned, PtrHash<JSValueEncodedAsPointer*>, JSValueHashTraits> JSValueMap;
+ typedef HashMap<EncodedJSValue, unsigned, EncodedJSValueHash, EncodedJSValueHashTraits> JSValueMap;
struct IdentifierMapIndexHashTraits {
typedef int TraitType;
};
typedef HashMap<RefPtr<UString::Rep>, int, IdentifierRepHash, HashTraits<RefPtr<UString::Rep> >, IdentifierMapIndexHashTraits> IdentifierMap;
- typedef HashMap<double, JSValuePtr> NumberMap;
+ typedef HashMap<double, JSValue> NumberMap;
typedef HashMap<UString::Rep*, JSString*, IdentifierRepHash> IdentifierStringMap;
-
+
RegisterID* emitCall(OpcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
RegisterID* newRegister();
RegisterID* addParameter(const Identifier&);
- void allocateConstants(size_t);
+ void preserveLastVar();
RegisterID& registerFor(int index)
{
unsigned addConstant(FuncDeclNode*);
unsigned addConstant(FuncExprNode*);
unsigned addConstant(const Identifier&);
- RegisterID* addConstant(JSValuePtr);
- unsigned addUnexpectedConstant(JSValuePtr);
+ RegisterID* addConstantValue(JSValue);
unsigned addRegExp(RegExp*);
Vector<Instruction>& instructions() { return m_codeBlock->instructions(); }
RegisterID* emitThrowExpressionTooDeepException();
+ void createArgumentsIfNecessary();
+
bool m_shouldEmitDebugHooks;
bool m_shouldEmitProfileHooks;
ScopeNode* m_scopeNode;
CodeBlock* m_codeBlock;
+ // Some of these objects keep pointers to one another. They are arranged
+ // to ensure a sane destruction order that avoids references to freed memory.
HashSet<RefPtr<UString::Rep>, IdentifierRepHash> m_functions;
RegisterID m_ignoredResultRegister;
RegisterID m_thisRegister;
RegisterID m_argumentsRegister;
int m_activationRegisterIndex;
- SegmentedVector<RegisterID, 512> m_calleeRegisters;
- SegmentedVector<RegisterID, 512> m_parameters;
- SegmentedVector<RegisterID, 512> m_globals;
- SegmentedVector<LabelScope, 256> m_labelScopes;
- SegmentedVector<Label, 256> m_labels;
- RefPtr<RegisterID> m_lastConstant;
+ WTF::SegmentedVector<RegisterID, 32> m_constantPoolRegisters;
+ WTF::SegmentedVector<RegisterID, 32> m_calleeRegisters;
+ WTF::SegmentedVector<RegisterID, 32> m_parameters;
+ WTF::SegmentedVector<RegisterID, 32> m_globals;
+ WTF::SegmentedVector<Label, 32> m_labels;
+ WTF::SegmentedVector<LabelScope, 8> m_labelScopes;
+ RefPtr<RegisterID> m_lastVar;
int m_finallyDepth;
int m_dynamicScopeDepth;
int m_baseScopeDepth;
int m_nextGlobalIndex;
int m_nextParameterIndex;
- int m_nextConstantIndex;
+ int m_firstConstantIndex;
+ int m_nextConstantOffset;
+ unsigned m_globalConstantIndex;
int m_globalVarStorageOffset;
bool m_regeneratingForExceptionInfo;
CodeBlock* m_codeBlockBeingRegeneratedFrom;
- static const unsigned s_maxEmitNodeDepth = 10000;
+ static const unsigned s_maxEmitNodeDepth = 5000;
};
}