X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/9dae56ea45a0f5f8136a5c93d6f3a7f99399ca73..b80e619319b1def83d1e8b4f84042b661be1be7f:/bytecompiler/BytecodeGenerator.h?ds=inline diff --git a/bytecompiler/BytecodeGenerator.h b/bytecompiler/BytecodeGenerator.h index 194aabd..3667198 100644 --- a/bytecompiler/BytecodeGenerator.h +++ b/bytecompiler/BytecodeGenerator.h @@ -37,11 +37,12 @@ #include "LabelScope.h" #include "Interpreter.h" #include "RegisterID.h" -#include "SegmentedVector.h" #include "SymbolTable.h" #include "Debugger.h" #include "Nodes.h" +#include #include +#include #include namespace JSC { @@ -60,7 +61,14 @@ namespace JSC { FinallyContext finallyContext; }; - class BytecodeGenerator { + struct ForInContext { + RefPtr expectedSubscriptRegister; + RefPtr iterRegister; + RefPtr indexRegister; + RefPtr propertyRegister; + }; + + class BytecodeGenerator : public FastAllocBase { public: typedef DeclarationStacks::VarStack VarStack; typedef DeclarationStacks::FunctionStack FunctionStack; @@ -81,6 +89,9 @@ namespace JSC { // 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 @@ -95,7 +106,7 @@ namespace JSC { // // NB: depth does _not_ include the local scope. eg. a depth of 0 refers // to the scope containing this codeblock. - bool findScopedProperty(const Identifier&, int& index, size_t& depth, bool forWriting, JSObject*& globalObject); + bool findScopedProperty(const Identifier&, int& index, size_t& depth, bool forWriting, bool& includesDynamicScopes, JSObject*& globalObject); // Returns the register storing "this" RegisterID* thisRegister() { return &m_thisRegister; } @@ -181,6 +192,19 @@ namespace JSC { return emitNode(0, n); } + void emitNodeInConditionContext(ExpressionNode* n, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue) + { + if (!m_codeBlock->numberOfLineInfos() || m_codeBlock->lastLineInfo().lineNumber != n->lineNo()) { + LineInfo info = { instructions().size(), n->lineNo() }; + m_codeBlock->addLineInfo(info); + } + if (m_emitNodeDepth >= s_maxEmitNodeDepth) + emitThrowExpressionTooDeepException(); + ++m_emitNodeDepth; + n->emitBytecodeInConditionContext(*this, trueTarget, falseTarget, fallThroughMeansTrue); + --m_emitNodeDepth; + } + void emitExpressionInfo(unsigned divot, unsigned startOffset, unsigned endOffset) { divot -= m_codeBlock->sourceOffset(); @@ -240,9 +264,7 @@ namespace JSC { 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); @@ -252,7 +274,7 @@ namespace JSC { RegisterID* emitNewObject(RegisterID* dst); RegisterID* emitNewArray(RegisterID* dst, ElementNode*); // stops at first elision - RegisterID* emitNewFunction(RegisterID* dst, FuncDeclNode* func); + RegisterID* emitNewFunction(RegisterID* dst, FunctionBodyNode* body); RegisterID* emitNewFunctionExpression(RegisterID* dst, FuncExprNode* func); RegisterID* emitNewRegExp(RegisterID* dst, RegExp* regExp); @@ -269,15 +291,17 @@ namespace JSC { 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* emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value); RegisterID* emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier&); RegisterID* emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property); RegisterID* emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value); @@ -288,28 +312,34 @@ namespace JSC { 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