Changeset 34372 in webkit for trunk/JavaScriptCore
- Timestamp:
- Jun 4, 2008, 10:36:55 PM (17 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 32 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r34371 r34372 1 2008-06-04 Sam Weinig <[email protected]> 2 3 Reviewed by Maciej Stachowiak. 4 5 Big cleanup of formatting and whitespace. 6 1 7 2008-06-04 Cameron Zwarich <[email protected]> 2 8 -
trunk/JavaScriptCore/VM/CodeBlock.cpp
r34351 r34372 98 98 NEVER_INLINE static const char* debugHookName(int debugHookID) 99 99 { 100 switch ((DebugHookID)debugHookID) {101 case DidEnterCallFrame:102 return "didEnterCallFrame";103 case WillLeaveCallFrame:104 return "willLeaveCallFrame";105 case WillExecuteStatement:106 return "willExecuteStatement";107 case WillExecuteProgram:108 return "willExecuteProgram";109 case DidExecuteProgram:110 return "didExecuteProgram";111 case DidReachBreakpoint:112 return "didReachBreakpoint";113 } 114 100 switch (static_cast<DebugHookID>(debugHookID)) { 101 case DidEnterCallFrame: 102 return "didEnterCallFrame"; 103 case WillLeaveCallFrame: 104 return "willLeaveCallFrame"; 105 case WillExecuteStatement: 106 return "willExecuteStatement"; 107 case WillExecuteProgram: 108 return "willExecuteProgram"; 109 case DidExecuteProgram: 110 return "didExecuteProgram"; 111 case DidReachBreakpoint: 112 return "didReachBreakpoint"; 113 } 114 115 115 ASSERT_NOT_REACHED(); 116 116 return ""; -
trunk/JavaScriptCore/VM/CodeBlock.h
r34319 r34372 27 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 28 */ 29 29 30 30 #ifndef CodeBlock_h 31 31 #define CodeBlock_h … … 90 90 Vector<RefPtr<FuncExprNode> > functionExpressions; 91 91 Vector<JSValue*> jsValues; 92 Vector<RefPtr<RegExp> > regexps; 92 Vector<RefPtr<RegExp> > regexps; 93 93 Vector<HandlerInfo> exceptionHandlers; 94 94 Vector<LineInfo> lineInfo; -
trunk/JavaScriptCore/VM/CodeGenerator.cpp
r34319 r34372 40 40 /* 41 41 The layout of a register frame looks like this: 42 43 For 44 42 43 For 44 45 45 function f(x, y) { 46 46 var v1; … … 49 49 return (x) * (y); 50 50 } 51 51 52 52 assuming (x) and (y) generated temporaries t1 and t2, you would have 53 53 … … 58 58 ------------------------------------ 59 59 | params->|<-locals | temps-> 60 60 61 61 Because temporary registers are allocated in a stack-like fashion, we 62 62 can reclaim them with a simple popping algorithm. The same goes for labels. 63 63 (We never reclaim parameter or local registers, because parameters and 64 64 locals are DontDelete.) 65 65 66 66 The register layout before a function call looks like this: 67 67 68 68 For 69 69 70 70 function f(x, y) 71 71 { 72 72 } 73 73 74 74 f(1); 75 75 76 76 > <------------------------------ 77 77 < > reserved: call frame | 1 | <-- value held … … 79 79 < > +0 | +1 | +2 | +3 | +4 | +5 | <-- register index 80 80 > <------------------------------ 81 | params->|<-locals | temps-> 82 81 | params->|<-locals | temps-> 82 83 83 The call instruction fills in the "call frame" registers. It also pads 84 84 missing arguments at the end of the call: 85 85 86 86 > <----------------------------------- 87 87 < > reserved: call frame | 1 | ? | <-- value held ("?" stands for "undefined") … … 90 90 > <----------------------------------- 91 91 | params->|<-locals | temps-> 92 92 93 93 After filling in missing arguments, the call instruction sets up the new 94 94 stack frame to overlap the end of the old stack frame: … … 100 100 |----------------------------------> < 101 101 | | params->|<-locals | temps-> 102 102 103 103 That way, arguments are "copied" into the callee's stack frame for free. 104 104 105 105 If the caller supplies too many arguments, this trick doesn't work. The 106 106 extra arguments protrude into space reserved for locals and temporaries. … … 111 111 This copying strategy ensures that all named values will be at the indices 112 112 expected by the callee. 113 114 113 */ 115 114 … … 133 132 if (m_shouldEmitDebugHooks) 134 133 m_codeBlock->needsFullScopeChain = true; 135 134 136 135 m_scopeNode->emitCode(*this); 137 136 … … 196 195 197 196 JSGlobalObject* globalObject = scopeChain.globalObject(); 198 197 199 198 ExecState* exec = globalObject->globalExec(); 200 199 … … 207 206 emitNewFunction(addVar(funcDecl->m_ident, false), funcDecl); 208 207 } 209 208 210 209 for (size_t i = 0; i < varStack.size(); ++i) { 211 210 if (!globalObject->hasProperty(exec, varStack[i].first)) … … 245 244 FuncDeclNode* funcDecl = functionStack[i].get(); 246 245 const Identifier& ident = funcDecl->m_ident; 247 246 248 247 m_functions.add(ident.ustring().rep()); 249 248 emitNewFunction(addVar(ident, false), funcDecl); … … 255 254 if (ident == m_propertyNames->arguments) 256 255 continue; 257 256 258 257 RegisterID* r0; 259 258 if (addVar(ident, r0, varStack[i].second & DeclarationStacks::IsConstant)) … … 306 305 result = &(m_locals[localsIndex(m_nextParameter)]); 307 306 } 308 307 309 308 // To maintain the calling convention, we have to allocate unique space for 310 309 // each parameter, even if the parameter doesn't make it into the symbol table. … … 336 335 if (m_codeType == EvalCode) 337 336 return 0; 338 337 339 338 SymbolTableEntry entry = symbolTable().get(ident.ustring().rep()); 340 339 ASSERT(!entry.isEmpty()); 341 340 342 341 return &m_locals[localsIndex(entry.getIndex())]; 343 342 } … … 430 429 if (result.second) // new entry 431 430 m_codeBlock->identifiers.append(rep); 432 431 433 432 return result.first->second; 434 433 } … … 439 438 if (result.second) // new entry 440 439 m_codeBlock->jsValues.append(v); 441 440 442 441 return result.first->second; 443 442 } … … 752 751 for (; iter != end; ++iter, ++depth) { 753 752 JSObject* currentScope = *iter; 754 if (!currentScope->isVariableObject()) 753 if (!currentScope->isVariableObject()) 755 754 break; 756 755 JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope); … … 798 797 return emitGetScopedVar(dst, depth, index); 799 798 } 800 799 801 800 RegisterID* CodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index) 802 801 { … … 807 806 return dst; 808 807 } 809 808 810 809 RegisterID* CodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value) 811 810 { … … 824 823 return dst; 825 824 } 826 825 827 826 RegisterID* CodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property) 828 827 { … … 965 964 RefPtr<RegisterID> refFunc = func; 966 965 RefPtr<RegisterID> refBase = base; 967 966 968 967 // Reserve space for call frame. 969 968 Vector<RefPtr<RegisterID>, Machine::CallFrameHeaderSize> callFrame; … … 1107 1106 return 0; 1108 1107 } 1109 1108 1110 1109 for (int i = m_jumpContextStack.size() - 1; i >= 0; i--) { 1111 1110 JumpContext* scope = &m_jumpContextStack[i]; … … 1129 1128 return 0; 1130 1129 } 1131 1130 1132 1131 for (int i = m_jumpContextStack.size() - 1; i >= 0; i--) { 1133 1132 JumpContext* scope = &m_jumpContextStack[i]; … … 1152 1151 1153 1152 if (nNormalScopes) { 1154 // We need to remove a number of dynamic scopes to get to the next 1153 // We need to remove a number of dynamic scopes to get to the next 1155 1154 // finally block 1156 1155 instructions().append(machine().getOpcode(op_jmp_scopes)); 1157 1156 instructions().append(nNormalScopes); 1158 1157 1159 1158 // If topScope == bottomScope then there isn't actually a finally block 1160 1159 // left to emit, so make the jmp_scopes jump directly to the target label … … 1164 1163 } 1165 1164 1166 // Otherwise we just use jmp_scopes to pop a group of scopes and go 1165 // Otherwise we just use jmp_scopes to pop a group of scopes and go 1167 1166 // to the next instruction 1168 1167 RefPtr<LabelID> nextInsn = newLabel(); … … 1226 1225 return targetRegister; 1227 1226 } 1228 1227 1229 1228 void CodeGenerator::emitThrow(RegisterID* exception) 1230 1229 { -
trunk/JavaScriptCore/VM/CodeGenerator.h
r34319 r34372 38 38 #include "Machine.h" 39 39 #include "RegisterID.h" 40 #include "SegmentedVector.h" 40 41 #include "SymbolTable.h" 41 #include "SegmentedVector.h"42 42 #include "debugger.h" 43 43 #include "nodes.h" … … 64 64 RegisterID* retAddrDst; 65 65 }; 66 66 67 67 struct ControlFlowContext { 68 68 bool isFinallyBlock; 69 69 FinallyContext finallyContext; 70 70 }; 71 71 72 72 class CodeGenerator { 73 73 public: 74 74 typedef DeclarationStacks::VarStack VarStack; 75 75 typedef DeclarationStacks::FunctionStack FunctionStack; 76 76 77 77 static void setDumpsGeneratedCode(bool dumpsGeneratedCode); 78 78 79 79 CodeGenerator(ProgramNode*, const Debugger*, const ScopeChain&, SymbolTable*, CodeBlock*, VarStack&, FunctionStack&, bool canCreateGlobals); 80 80 CodeGenerator(FunctionBodyNode*, const Debugger*, const ScopeChain&, SymbolTable*, CodeBlock*); … … 96 96 97 97 // Searches the scope chain in an attempt to statically locate the requested 98 // property. Returns false if for any reason the property cannot be safely 98 // property. Returns false if for any reason the property cannot be safely 99 99 // optimised at all. Otherwise it will return the index and depth of the 100 // VariableObject that defines the property. If the property cannot be found 100 // VariableObject that defines the property. If the property cannot be found 101 101 // statically, depth will contain the depth of the scope chain where dynamic 102 102 // lookup must begin. … … 133 133 134 134 // Returns the place to write the final output of an operation. 135 RegisterID* finalDestination(RegisterID* originalDst, RegisterID* tempDst = 0) 136 { 135 RegisterID* finalDestination(RegisterID* originalDst, RegisterID* tempDst = 0) 136 { 137 137 if (originalDst) 138 138 return originalDst; 139 139 if (tempDst && tempDst->isTemporary()) 140 140 return tempDst; 141 return newTemporary(); 142 } 143 144 RegisterID* destinationForAssignResult(RegisterID* dst) { 145 if (dst && m_codeBlock->needsFullScopeChain) 141 return newTemporary(); 142 } 143 144 RegisterID* destinationForAssignResult(RegisterID* dst) 145 { 146 if (dst && m_codeBlock->needsFullScopeChain) 146 147 return dst->isTemporary() ? dst : newTemporary(); 147 148 return 0; … … 151 152 RegisterID* moveToDestinationIfNeeded(RegisterID* dst, RegisterID* src) { return (dst && dst != src) ? emitMove(dst, src) : src; } 152 153 153 154 154 PassRefPtr<LabelID> newLabel(); 155 155 156 156 // The emitNode functions are just syntactic sugar for calling 157 157 // Node::emitCode. They're the only functions that accept a NULL register. 158 RegisterID* emitNode(RegisterID* dst, Node* n) { 158 RegisterID* emitNode(RegisterID* dst, Node* n) 159 { 159 160 // Node::emitCode assumes that dst, if provided, is either a local or a referenced temporary. 160 161 ASSERT(!dst || !dst->isTemporary() || dst->refCount()); … … 183 184 return dst; 184 185 } 185 186 186 187 return PassRefPtr<RegisterID>(emitNode(n)); 187 188 } … … 190 191 RegisterID* emitLoad(RegisterID* dst, double); 191 192 RegisterID* emitLoad(RegisterID* dst, JSValue*); 192 193 193 194 RegisterID* emitNewObject(RegisterID* dst); 194 195 RegisterID* emitNewArray(RegisterID* dst); … … 266 267 PassRefPtr<LabelID> emitJumpSubroutine(RegisterID* retAddrDst, LabelID*); 267 268 void emitSubroutineReturn(RegisterID* retAddrSrc); 268 269 269 270 RegisterID* emitGetPropertyNames(RegisterID* dst, RegisterID* base); 270 271 RegisterID* emitNextPropertyName(RegisterID* dst, RegisterID* iter, LabelID* target); … … 273 274 void emitThrow(RegisterID*); 274 275 RegisterID* emitNewError(RegisterID* dst, ErrorType type, JSValue* message); 275 276 276 277 RegisterID* emitPushScope(RegisterID* scope); 277 278 void emitPopScope(); 278 279 279 280 void emitDebugHook(DebugHookID, int firstLine, int lastLine); 280 281 281 282 int scopeDepth() { return m_dynamicScopeDepth + m_finallyDepth; } 282 283 283 284 void pushFinallyContext(LabelID* target, RegisterID* returnAddrDst); 284 285 void popFinallyContext(); … … 290 291 JumpContext* jumpContextForBreak(const Identifier&); 291 292 292 293 293 CodeType codeType() const { return m_codeType; } 294 294 295 private: 295 296 PassRefPtr<LabelID> emitComplexJumpScopes(LabelID* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope); … … 300 301 301 302 typedef HashMap<JSValue*, unsigned, DefaultHash<JSValue*>::Hash, JSValueHashTraits> JSValueMap; 302 303 303 304 struct IdentifierMapIndexHashTraits { 304 305 typedef int TraitType; … … 316 317 // Maps a register index in the symbol table to a RegisterID index in m_locals. 317 318 int localsIndex(int registerIndex) { return -registerIndex - 1; } 318 319 319 320 // Returns the RegisterID corresponding to ident. 320 321 RegisterID* addVar(const Identifier& ident, bool isConstant) … … 335 336 unsigned addConstant(JSValue*); 336 337 unsigned addRegExp(RegExp* r); 337 338 338 339 Vector<Instruction>& instructions() { return m_codeBlock->instructions; } 339 340 SymbolTable& symbolTable() { return *m_symbolTable; } 340 341 Vector<HandlerInfo>& exceptionHandlers() { return m_codeBlock->exceptionHandlers; } 341 342 342 343 bool shouldOptimizeLocals() { return (m_codeType != EvalCode) && !m_dynamicScopeDepth; } 343 344 bool canOptimizeNonLocals() { return (m_codeType == FunctionCode) && !m_dynamicScopeDepth && !m_codeBlock->usesEval; } 344 345 345 346 bool m_shouldEmitDebugHooks; 346 347 347 348 const ScopeChain* m_scopeChain; 348 349 SymbolTable* m_symbolTable; 349 350 350 351 ScopeNode* m_scopeNode; 351 352 CodeBlock* m_codeBlock; 352 353 353 354 HashSet<RefPtr<UString::Rep>, IdentifierRepHash> m_functions; 354 355 RegisterID m_thisRegister; … … 359 360 int m_dynamicScopeDepth; 360 361 CodeType m_codeType; 361 362 362 363 Vector<JumpContext> m_jumpContextStack; 363 364 int m_continueDepth; … … 373 374 CommonIdentifiers* m_propertyNames; 374 375 375 #ifndef NDEBUG 376 #ifndef NDEBUG 376 377 static bool s_dumpsGeneratedCode; 377 378 #endif -
trunk/JavaScriptCore/VM/ExceptionHelpers.cpp
r34075 r34372 45 45 string = newString; 46 46 } 47 47 48 48 JSValue* createError(ExecState* exec, ErrorType e, const char* msg) 49 49 { … … 83 83 return createError(exec, ReferenceError, "Can't find variable: %s", ident); 84 84 } 85 85 86 86 JSValue* createInvalidParamError(ExecState* exec, const char* op, JSValue* v) 87 87 { … … 106 106 } 107 107 108 } 108 } // namespace KJS -
trunk/JavaScriptCore/VM/ExceptionHelpers.h
r34075 r34372 33 33 34 34 namespace KJS { 35 35 36 class Node; 37 36 38 JSValue* createStackOverflowError(ExecState*); 37 39 JSValue* createUndefinedVariableError(ExecState*, const Identifier&); 38 40 JSValue* createInvalidParamError(ExecState*, const char* op, JSValue*); 39 JSValue* createNotAConstructorError(ExecState* exec, JSValue* value, Node* expr); 40 JSValue* createNotAFunctionError(ExecState* exec, JSValue* value, Node* expr); 41 } 41 JSValue* createNotAConstructorError(ExecState*, JSValue*, Node* expr); 42 JSValue* createNotAFunctionError(ExecState*, JSValue*, Node* expr); 42 43 43 #endif 44 } // namespace KJS 45 46 #endif // ExceptionHelpers_h -
trunk/JavaScriptCore/VM/Instruction.h
r33979 r34372 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 29 #ifndef Instruction_h 30 30 #define Instruction_h … … 37 37 Instruction(Opcode opcode) { u.opcode = opcode; } 38 38 Instruction(int operand) { u.operand = operand; } 39 39 40 40 union { 41 41 Opcode opcode; … … 43 43 } u; 44 44 }; 45 45 46 46 } // namespace KJS 47 47 -
trunk/JavaScriptCore/VM/JSPropertyNameIterator.cpp
r33979 r34372 34 34 #include "PropertyNameArray.h" 35 35 36 namespace KJS {36 namespace KJS { 37 37 38 38 COMPILE_ASSERT(sizeof(JSPropertyNameIterator) <= CellSize<sizeof(void*)>::m_value, JSPropertyNameIteratorSizeASSERT); 39 39 40 JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue* v) 41 { 42 if (v->isUndefinedOrNull()) 43 return new JSPropertyNameIterator(0, 0, 0); 44 45 JSObject* o = v->toObject(exec); 46 PropertyNameArray propertyNames; 47 o->getPropertyNames(exec, propertyNames); 48 size_t numProperties = propertyNames.size(); 49 return new JSPropertyNameIterator(o, propertyNames.releaseIdentifiers(), numProperties); 50 } 51 40 52 JSPropertyNameIterator::JSPropertyNameIterator(JSObject* object, Identifier* propertyNames, size_t numProperties) 41 53 : m_object(object) … … 45 57 { 46 58 } 47 48 JSType JSPropertyNameIterator::type() const { 49 return UnspecifiedType; 59 60 JSPropertyNameIterator::~JSPropertyNameIterator() 61 { 62 delete m_propertyNames; 50 63 } 51 64 52 JSValue *JSPropertyNameIterator::toPrimitive(ExecState *, JSType) const 65 JSType JSPropertyNameIterator::type() const 66 { 67 return UnspecifiedType; 68 } 69 70 JSValue* JSPropertyNameIterator::toPrimitive(ExecState*, JSType) const 53 71 { 54 72 ASSERT_NOT_REACHED(); 55 return 0; 73 return 0; 56 74 } 57 75 58 bool JSPropertyNameIterator::getPrimitiveNumber(ExecState*, double&, JSValue*&) { 59 ASSERT_NOT_REACHED(); 76 bool JSPropertyNameIterator::getPrimitiveNumber(ExecState*, double&, JSValue*&) 77 { 78 ASSERT_NOT_REACHED(); 60 79 return false; 61 80 } 62 81 63 bool JSPropertyNameIterator::toBoolean(ExecState *) const { 64 ASSERT_NOT_REACHED(); 82 bool JSPropertyNameIterator::toBoolean(ExecState*) const 83 { 84 ASSERT_NOT_REACHED(); 65 85 return false; 66 86 } 67 87 68 double JSPropertyNameIterator::toNumber(ExecState *) const88 double JSPropertyNameIterator::toNumber(ExecState*) const 69 89 { 70 90 ASSERT_NOT_REACHED(); 71 return 0; 91 return 0; 72 92 } 73 93 74 UString JSPropertyNameIterator::toString(ExecState *) const94 UString JSPropertyNameIterator::toString(ExecState*) const 75 95 { 76 96 ASSERT_NOT_REACHED(); 77 return ""; 97 return ""; 78 98 } 79 99 80 JSObject *JSPropertyNameIterator::toObject(ExecState *) const100 JSObject* JSPropertyNameIterator::toObject(ExecState*) const 81 101 { 82 102 ASSERT_NOT_REACHED(); 83 return 0; 103 return 0; 84 104 } 85 105 86 void JSPropertyNameIterator::mark() { 106 void JSPropertyNameIterator::mark() 107 { 87 108 JSCell::mark(); 88 109 if (m_object && !m_object->marked()) … … 91 112 92 113 JSValue* JSPropertyNameIterator::next(ExecState* exec) 93 { 114 { 94 115 while (m_position != m_end) { 95 116 if (m_object->hasProperty(exec, *m_position)) … … 101 122 } 102 123 103 void JSPropertyNameIterator::invalidate() 104 { 105 delete m_propertyNames; 124 void JSPropertyNameIterator::invalidate() 125 { 126 delete m_propertyNames; 106 127 m_object = 0; 107 128 m_propertyNames = 0; 108 129 } 109 130 110 JSPropertyNameIterator::~JSPropertyNameIterator() 111 { 112 delete m_propertyNames; 113 } 114 115 116 JSPropertyNameIterator* JSPropertyNameIterator::create(ExecState* exec, JSValue* v) 117 { 118 if (v->isUndefinedOrNull()) 119 return new JSPropertyNameIterator(0, 0, 0); 120 121 JSObject* o = v->toObject(exec); 122 PropertyNameArray propertyNames; 123 o->getPropertyNames(exec, propertyNames); 124 size_t numProperties = propertyNames.size(); 125 return new JSPropertyNameIterator(o, propertyNames.releaseIdentifiers(), numProperties); 126 } 127 128 } 131 } // namespace KJS -
trunk/JavaScriptCore/VM/JSPropertyNameIterator.h
r33979 r34372 33 33 34 34 namespace KJS { 35 36 class Identifier; 35 37 class JSObject; 36 class Identifier;37 38 38 39 class JSPropertyNameIterator : public JSCell { 39 40 public: 41 static JSPropertyNameIterator* create(ExecState*, JSValue*); 42 43 virtual ~JSPropertyNameIterator(); 44 40 45 virtual JSType type() const; 41 virtual JSValue *toPrimitive(ExecState*, JSType) const;46 virtual JSValue* toPrimitive(ExecState*, JSType) const; 42 47 virtual bool getPrimitiveNumber(ExecState*, double&, JSValue*&); 43 virtual bool toBoolean(ExecState 44 virtual double toNumber(ExecState 45 virtual UString toString(ExecState 46 virtual JSObject *toObject(ExecState*) const;47 48 virtual bool toBoolean(ExecState*) const; 49 virtual double toNumber(ExecState*) const; 50 virtual UString toString(ExecState*) const; 51 virtual JSObject* toObject(ExecState*) const; 52 48 53 virtual void mark(); 49 50 JSValue* next(ExecState* exec);54 55 JSValue* next(ExecState*); 51 56 void invalidate(); 52 53 virtual ~JSPropertyNameIterator(); 54 55 static JSPropertyNameIterator* create(ExecState*, JSValue*); 57 56 58 private: 57 JSPropertyNameIterator(JSObject* object, Identifier* propertyNames, size_t numProperties); 59 JSPropertyNameIterator(JSObject*, Identifier* propertyNames, size_t numProperties); 60 58 61 JSObject* m_object; 59 62 Identifier* m_propertyNames; … … 61 64 Identifier* m_end; 62 65 }; 63 }64 66 65 #endif 67 } // namespace KJS 68 69 #endif // JSPropertyNameIterator_h -
trunk/JavaScriptCore/VM/LabelID.h
r34021 r34372 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 29 #ifndef LabelID_h 30 30 #define LabelID_h … … 101 101 private: 102 102 typedef Vector<int, 8> JumpVector; 103 103 104 104 static const unsigned invalidLocation = UINT_MAX; 105 105 106 106 int m_refCount; 107 107 unsigned m_location; … … 109 109 mutable JumpVector m_unresolvedJumps; 110 110 }; 111 111 112 112 } // namespace KJS 113 113 -
trunk/JavaScriptCore/VM/Machine.cpp
r34371 r34372 81 81 { 82 82 int scopeDepth = 0; 83 ScopeChainIterator iter = sc.begin(); 84 ScopeChainIterator end = sc.end(); 83 ScopeChainIterator iter = sc.begin(); 84 ScopeChainIterator end = sc.end(); 85 85 while (!(*iter)->isVariableObject()) { 86 86 ++iter; … … 89 89 return scopeDepth; 90 90 } 91 91 92 92 static inline bool jsLess(ExecState* exec, JSValue* v1, JSValue* v2) 93 93 { … … 219 219 return false; 220 220 } 221 221 222 222 static bool NEVER_INLINE resolve_skip(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock, JSValue*& exceptionValue) 223 223 { … … 225 225 int property = (vPC + 2)->u.operand; 226 226 int skip = (vPC + 3)->u.operand + codeBlock->needsFullScopeChain; 227 227 228 228 ScopeChainIterator iter = scopeChain->begin(); 229 229 ScopeChainIterator end = scopeChain->end(); … … 280 280 int propDst = (vPC + 2)->u.operand; 281 281 int property = (vPC + 3)->u.operand; 282 282 283 283 ScopeChainIterator iter = scopeChain->begin(); 284 284 ScopeChainIterator end = scopeChain->end(); 285 285 286 286 // FIXME: add scopeDepthIsZero optimization 287 287 288 288 ASSERT(iter != end); 289 289 290 290 Identifier& ident = codeBlock->identifiers[property]; 291 291 JSObject* base; … … 298 298 if (exceptionValue) 299 299 return false; 300 r[propDst].u.jsValue = result; 300 r[propDst].u.jsValue = result; 301 301 r[baseDst].u.jsValue = base; 302 302 return true; … … 304 304 ++iter; 305 305 } while (iter != end); 306 306 307 307 exceptionValue = createUndefinedVariableError(exec, ident); 308 308 return false; … … 317 317 ScopeChainIterator iter = scopeChain->begin(); 318 318 ScopeChainIterator end = scopeChain->end(); 319 319 320 320 // FIXME: add scopeDepthIsZero optimization 321 321 322 322 ASSERT(iter != end); 323 323 324 324 Identifier& ident = codeBlock->identifiers[property]; 325 325 JSObject* base; … … 340 340 if (exceptionValue) 341 341 return false; 342 342 343 343 r[baseDst].u.jsValue = thisObj; 344 344 r[funcDst].u.jsValue = result; … … 385 385 } 386 386 r = (*registerBase) + registerOffset; 387 387 388 388 int omittedArgCount = newCodeBlock->numParameters - argc; 389 389 Register* endOfParams = r - newCodeBlock->numVars; … … 400 400 } 401 401 r = (*registerBase) + registerOffset; 402 402 403 403 Register* it = r - newCodeBlock->numLocals - Machine::CallFrameHeaderSize - shift; 404 404 Register* end = it + Machine::CallFrameHeaderSize + newCodeBlock->numParameters; … … 436 436 437 437 JSValue* program = r[argv + 1].u.jsValue; 438 438 439 439 if (!program->isString()) 440 440 return program; 441 441 442 442 Profiler** profiler = Profiler::enabledProfilerReference(); 443 443 if (*profiler) … … 448 448 UString errMsg; 449 449 RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(exec, UString(), 1, UStringSourceProvider::create(static_cast<StringImp*>(program)->value()), &sourceId, &errLine, &errMsg); 450 450 451 451 if (!evalNode) { 452 452 exceptionValue = Error::create(exec, SyntaxError, errMsg, errLine, sourceId, NULL); … … 491 491 printf(" use | address | value \n"); 492 492 printf("----------------------------------------\n"); 493 493 494 494 const Register* it; 495 495 const Register* end; 496 496 497 497 if (isGlobalCallFrame(registerFile->basePointer(), r)) { 498 498 it = r - registerFile->numGlobalSlots(); … … 515 515 printf("----------------------------------------\n"); 516 516 } 517 517 518 518 end = it + codeBlock->numParameters; 519 519 if (it != end) { … … 559 559 CodeBlock* oldCodeBlock = codeBlock; 560 560 Register* callFrame = r - oldCodeBlock->numLocals - CallFrameHeaderSize; 561 561 562 562 if (Debugger* debugger = exec->dynamicGlobalObject()->debugger()) { 563 563 DebuggerCallFrame debuggerCallFrame(this, exec->dynamicGlobalObject(), codeBlock, scopeChain, exceptionValue, registerBase, r - *registerBase); … … 577 577 if (oldCodeBlock->needsFullScopeChain) 578 578 scopeChain->deref(); 579 579 580 580 if (isGlobalCallFrame(registerBase, r)) 581 581 return false; … … 620 620 // Calculate an exception handler vPC, unwinding call frames as necessary. 621 621 622 int scopeDepth; 622 int scopeDepth; 623 623 Instruction* handlerVPC; 624 624 625 while (!codeBlock->getHandlerForVPC(vPC, handlerVPC, scopeDepth)) 625 while (!codeBlock->getHandlerForVPC(vPC, handlerVPC, scopeDepth)) { 626 626 if (!unwindCallFrame(exec, exceptionValue, registerBase, vPC, codeBlock, k, scopeChain, r)) 627 627 return 0; 628 } 628 629 629 630 // Now unwind the scope chain within the exception handler's call frame. 630 631 631 632 ScopeChain sc(scopeChain); 632 633 int scopeDelta = depth(sc) - scopeDepth; … … 659 660 660 661 r[ProgramCodeThisRegister].u.jsValue = thisObj; 661 662 662 663 if (codeBlock->needsFullScopeChain) 663 664 scopeChain = scopeChain->copy(); … … 692 693 int argv = CallFrameHeaderSize; 693 694 int argc = args.size() + 1; // implicit "this" parameter 694 695 695 696 size_t oldSize = registerFile->size(); 696 697 if (!registerFile->grow(oldSize + CallFrameHeaderSize + argc)) { … … 698 699 return 0; 699 700 } 700 701 701 702 Register** registerBase = registerFile->basePointer(); 702 703 int registerOffset = oldSize; 703 704 int callFrameOffset = registerOffset; 704 705 Register* callFrame = (*registerBase) + callFrameOffset; 705 706 706 707 // put args in place, including "this" 707 708 Register* dst = callFrame + CallFrameHeaderSize; 708 709 (*dst).u.jsValue = thisObj; 709 710 710 711 List::const_iterator end = args.end(); 711 712 for (List::const_iterator it = args.begin(); it != end; ++it) … … 722 723 } 723 724 724 scopeChain = scopeChainForCall(functionBodyNode, newCodeBlock, scopeChain, registerBase, r); 725 scopeChain = scopeChainForCall(functionBodyNode, newCodeBlock, scopeChain, registerBase, r); 725 726 726 727 ExecState newExec(exec, this, registerFile, scopeChain, callFrameOffset); 727 728 728 729 Profiler** profiler = Profiler::enabledProfilerReference(); 729 730 if (*profiler) … … 746 747 747 748 EvalCodeBlock* codeBlock = &evalNode->code(scopeChain); 748 749 749 750 JSVariableObject* variableObject; 750 751 for (ScopeChainNode* node = scopeChain; ; node = node->next) { … … 755 756 } 756 757 } 757 758 758 759 const Node::VarStack& varStack = codeBlock->ownerNode->varStack(); 759 760 Node::VarStack::const_iterator varStackEnd = varStack.end(); … … 763 764 variableObject->put(exec, ident, jsUndefined()); 764 765 } 765 766 766 767 const Node::FunctionStack& functionStack = codeBlock->ownerNode->functionStack(); 767 768 Node::FunctionStack::const_iterator functionStackEnd = functionStack.end(); 768 769 for (Node::FunctionStack::const_iterator it = functionStack.begin(); it != functionStackEnd; ++it) 769 770 variableObject->put(exec, (*it)->m_ident, (*it)->makeFunction(exec, scopeChain)); 770 771 771 772 size_t oldSize = registerFile->size(); 772 773 size_t newSize = registerOffset + codeBlock->numVars + codeBlock->numTemporaries + CallFrameHeaderSize; … … 777 778 778 779 Register* callFrame = *registerFile->basePointer() + registerOffset; 779 780 780 781 // put call frame in place, using a 0 codeBlock to indicate a built-in caller 781 782 initializeCallFrame(callFrame, 0, 0, 0, registerOffset, 0, 0, 0, 0, 0); … … 889 890 JSValue** k = codeBlock->jsValues.data(); 890 891 Profiler** enabledProfilerReference = Profiler::enabledProfilerReference(); 891 892 892 893 #if HAVE(COMPUTED_GOTO) 893 894 // Yet another hack around GCC's various foibles, in this case fetching the … … 922 923 #define BEGIN_OPCODE(opcode) case opcode: 923 924 #endif 924 while (1) // iterator loop begins925 while (1) // iterator loop begins 925 926 switch (vPC->u.opcode) 926 927 #endif … … 934 935 int src = (++vPC)->u.operand; 935 936 r[dst].u.jsValue = k[src]; 936 937 937 938 ++vPC; 938 939 NEXT_OPCODE; … … 946 947 int dst = (++vPC)->u.operand; 947 948 r[dst].u.jsValue = scopeChain->globalObject()->objectConstructor()->construct(exec, exec->emptyList()); 948 949 949 950 ++vPC; 950 951 NEXT_OPCODE; … … 958 959 int dst = (++vPC)->u.operand; 959 960 r[dst].u.jsValue = scopeChain->globalObject()->arrayConstructor()->construct(exec, exec->emptyList()); 960 961 961 962 ++vPC; 962 963 NEXT_OPCODE; … … 1046 1047 else 1047 1048 dst = jsBoolean(strictEqual(src1, src2)); 1048 1049 1049 1050 ++vPC; 1050 1051 NEXT_OPCODE; … … 1117 1118 VM_CHECK_EXCEPTION(); 1118 1119 r[srcDst].u.jsValue = result; 1119 1120 1120 1121 ++vPC; 1121 1122 NEXT_OPCODE; … … 1281 1282 /* mod dst(r) dividend(r) divisor(r) 1282 1283 1283 Divides register dividend (converted to number) by 1284 Divides register dividend (converted to number) by 1284 1285 register divisor (converted to number), and puts the 1285 1286 remainder in register dst. … … 1334 1335 } 1335 1336 dst = result; 1336 1337 1337 1338 ++vPC; 1338 1339 NEXT_OPCODE; … … 1356 1357 } 1357 1358 dst = result; 1358 1359 1359 1360 ++vPC; 1360 1361 NEXT_OPCODE; … … 1378 1379 } 1379 1380 dst = result; 1380 1381 1381 1382 ++vPC; 1382 1383 NEXT_OPCODE; … … 1400 1401 } 1401 1402 dst = result; 1402 1403 1403 1404 ++vPC; 1404 1405 NEXT_OPCODE; … … 1422 1423 } 1423 1424 dst = result; 1424 1425 1425 1426 ++vPC; 1426 1427 NEXT_OPCODE; … … 1444 1445 } 1445 1446 dst = result; 1446 1447 1447 1448 ++vPC; 1448 1449 NEXT_OPCODE; … … 1483 1484 Tests whether register value is an instance of register 1484 1485 constructor, and puts the boolean result in register dst. 1485 1486 1486 1487 Raises an exception if register constructor is not an 1487 1488 object. … … 1520 1521 Tests whether register base has a property named register 1521 1522 property, and puts the boolean result in register dst. 1522 1523 1523 1524 Raises an exception if register constructor is not an 1524 1525 object. … … 1563 1564 BEGIN_OPCODE(op_resolve_skip) { 1564 1565 /* resolve_skip dst(r) property(id) skip(n) 1565 1566 1566 1567 Looks up the property named by identifier property in the 1567 1568 scope chain skipping the top 'skip' levels, and writes the resulting … … 1570 1571 if (UNLIKELY(!resolve_skip(exec, vPC, r, scopeChain, codeBlock, exceptionValue))) 1571 1572 goto vm_throw; 1572 1573 1573 1574 vPC += 4; 1574 1575 1575 1576 NEXT_OPCODE; 1576 1577 } 1577 1578 BEGIN_OPCODE(op_get_scoped_var) { 1578 1579 /* get_scoped_var dst(r) index(n) skip(n) 1579 1580 1580 1581 Loads the contents of the index-th local from the scope skip nodes from 1581 1582 the top of the scope chain, and places it in register dst … … 1584 1585 int index = (++vPC)->u.operand; 1585 1586 int skip = (++vPC)->u.operand + codeBlock->needsFullScopeChain; 1586 1587 1587 1588 ScopeChainIterator iter = scopeChain->begin(); 1588 1589 ScopeChainIterator end = scopeChain->end(); … … 1592 1593 ASSERT(iter != end); 1593 1594 } 1594 1595 1595 1596 ASSERT((*iter)->isVariableObject()); 1596 1597 JSVariableObject* scope = static_cast<JSVariableObject*>(*iter); … … 1606 1607 int skip = (++vPC)->u.operand + codeBlock->needsFullScopeChain; 1607 1608 int value = (++vPC)->u.operand; 1608 1609 1609 1610 ScopeChainIterator iter = scopeChain->begin(); 1610 1611 ScopeChainIterator end = scopeChain->end(); … … 1614 1615 ASSERT(iter != end); 1615 1616 } 1616 1617 1617 1618 ASSERT((*iter)->isVariableObject()); 1618 1619 JSVariableObject* scope = static_cast<JSVariableObject*>(*iter); … … 1700 1701 Sets register value on register base as the property named 1701 1702 by identifier property. Base is converted to object first. 1702 1703 1703 1704 Unlike many opcodes, this one does not write any output to 1704 1705 the register file. … … 1710 1711 int registerOffset = r - (*registerBase); 1711 1712 #endif 1712 1713 1713 1714 Identifier& ident = codeBlock->identifiers[property]; 1714 1715 r[base].u.jsValue->put(exec, ident, r[value].u.jsValue); 1715 1716 ASSERT(registerOffset == (r - (*registerBase))); 1716 1717 1717 1718 VM_CHECK_EXCEPTION(); 1718 1719 ++vPC; … … 1732 1733 1733 1734 JSObject* baseObj = r[base].u.jsValue->toObject(exec); 1734 1735 1735 1736 Identifier& ident = codeBlock->identifiers[property]; 1736 1737 JSValue* result = jsBoolean(baseObj->deleteProperty(exec, ident)); … … 1753 1754 1754 1755 JSValue* baseValue = r[base].u.jsValue; 1755 1756 1756 1757 JSValue* subscript = r[property].u.jsValue; 1757 1758 JSValue* result; … … 1772 1773 result = baseObj->get(exec, property); 1773 1774 } 1774 1775 1775 1776 VM_CHECK_EXCEPTION(); 1776 1777 r[dst].u.jsValue = result; … … 1785 1786 first. register property is nominally converted to string 1786 1787 but numbers are treated more efficiently. 1787 1788 1788 1789 Unlike many opcodes, this one does not write any output to 1789 1790 the register file. … … 1794 1795 1795 1796 JSValue* baseValue = r[base].u.jsValue; 1796 1797 1797 1798 JSValue* subscript = r[property].u.jsValue; 1798 1799 … … 1813 1814 baseObj->put(exec, property, r[value].u.jsValue); 1814 1815 } 1815 1816 1816 1817 VM_CHECK_EXCEPTION(); 1817 1818 ++vPC; … … 1843 1844 result = jsBoolean(baseObj->deleteProperty(exec, property)); 1844 1845 } 1845 1846 1846 1847 VM_CHECK_EXCEPTION(); 1847 1848 r[dst].u.jsValue = result; … … 1856 1857 object first. register property is nominally converted to 1857 1858 string but numbers are treated more efficiently. 1858 1859 1859 1860 Unlike many opcodes, this one does not write any output to 1860 1861 the register file. … … 1873 1874 BEGIN_OPCODE(op_jmp) { 1874 1875 /* jmp target(offset) 1875 1876 1876 1877 Jumps unconditionally to offset target from the current 1877 1878 instruction. … … 1884 1885 BEGIN_OPCODE(op_jtrue) { 1885 1886 /* jtrue cond(r) target(offset) 1886 1887 1887 1888 Jumps to offset target from the current instruction, if and 1888 1889 only if register cond converts to boolean as true. … … 1900 1901 BEGIN_OPCODE(op_jfalse) { 1901 1902 /* jfalse cond(r) target(offset) 1902 1903 1903 1904 Jumps to offset target from the current instruction, if and 1904 1905 only if register cond converts to boolean as false. … … 1966 1967 JSValue* funcVal = r[func].u.jsValue; 1967 1968 JSValue* baseVal = r[thisVal].u.jsValue; 1968 1969 1969 1970 if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) { 1970 1971 int registerOffset = r - (*registerBase); … … 1983 1984 1984 1985 r[dst].u.jsValue = result; 1985 1986 1986 1987 ++vPC; 1987 1988 NEXT_OPCODE; 1988 1989 } 1989 1990 1990 1991 // We didn't find the blessed version of eval, so reset vPC and process 1991 1992 // this instruction as a normal function call, supplying the proper 'this' … … 2044 2045 int firstArg = (++vPC)->u.operand; 2045 2046 int argCount = (++vPC)->u.operand; 2046 2047 2047 2048 JSValue* v = r[func].u.jsValue; 2048 2049 2049 2050 CallData callData; 2050 2051 CallType callType = v->getCallData(callData); 2051 2052 2052 2053 if (callType == CallTypeJS) { 2053 2054 if (*enabledProfilerReference) … … 2140 2141 returnValue = thisObject; 2141 2142 } 2142 2143 2143 2144 codeBlock = callFrame[CallerCodeBlock].u.codeBlock; 2144 2145 if (!codeBlock) 2145 2146 return returnValue; 2146 2147 2147 2148 k = codeBlock->jsValues.data(); 2148 2149 vPC = callFrame[ReturnVPC].u.vPC; … … 2254 2255 JSObject* o = v->toObject(exec); 2255 2256 VM_CHECK_EXCEPTION(); 2256 2257 2257 2258 setScopeChain(exec, scopeChain, scopeChain->push(o)); 2258 2259 … … 2318 2319 int count = (++vPC)->u.operand; 2319 2320 int target = (++vPC)->u.operand; 2320 2321 2321 2322 ScopeChainNode* tmp = scopeChain; 2322 2323 while (count--) 2323 2324 tmp = tmp->pop(); 2324 2325 setScopeChain(exec, scopeChain, tmp); 2325 2326 2326 2327 vPC += target; 2327 2328 NEXT_OPCODE; … … 2385 2386 int type = (++vPC)->u.operand; 2386 2387 int message = (++vPC)->u.operand; 2387 2388 2388 2389 r[dst].u.jsValue = Error::create(exec, (ErrorType)type, k[message]->toString(exec), codeBlock->lineNumberForVPC(vPC), codeBlock->ownerNode->sourceId(), codeBlock->ownerNode->sourceURL()); 2389 2390 2390 2391 ++vPC; 2391 2392 NEXT_OPCODE; … … 2407 2408 BEGIN_OPCODE(op_put_getter) { 2408 2409 /* put_getter base(r) property(id) function(r) 2409 2410 2410 2411 Sets register function on register base as the getter named 2411 2412 by identifier property. Base and function are assumed to be 2412 2413 objects as this op should only be used for getters defined 2413 2414 in object literal form. 2414 2415 2415 2416 Unlike many opcodes, this one does not write any output to 2416 2417 the register file. … … 2419 2420 int property = (++vPC)->u.operand; 2420 2421 int function = (++vPC)->u.operand; 2421 2422 2422 2423 ASSERT(r[base].u.jsValue->isObject()); 2423 2424 JSObject* baseObj = static_cast<JSObject*>(r[base].u.jsValue); … … 2431 2432 BEGIN_OPCODE(op_put_setter) { 2432 2433 /* put_setter base(r) property(id) function(r) 2433 2434 2434 2435 Sets register function on register base as the setter named 2435 2436 by identifier property. Base and function are assumed to be 2436 2437 objects as this op should only be used for setters defined 2437 2438 in object literal form. 2438 2439 2439 2440 Unlike many opcodes, this one does not write any output to 2440 2441 the register file. … … 2443 2444 int property = (++vPC)->u.operand; 2444 2445 int function = (++vPC)->u.operand; 2445 2446 2446 2447 ASSERT(r[base].u.jsValue->isObject()); 2447 2448 JSObject* baseObj = static_cast<JSObject*>(r[base].u.jsValue); … … 2449 2450 ASSERT(r[function].u.jsValue->isObject()); 2450 2451 baseObj->defineSetter(exec, ident, static_cast<JSObject* >(r[function].u.jsValue)); 2451 2452 2452 2453 ++vPC; 2453 2454 NEXT_OPCODE; … … 2455 2456 BEGIN_OPCODE(op_jsr) { 2456 2457 /* jsr retAddrDst(r) target(offset) 2457 2458 2458 2459 Places the address of the next instruction into the retAddrDst 2459 2460 register and jumps to offset target from the current instruction. … … 2468 2469 BEGIN_OPCODE(op_sret) { 2469 2470 /* sret retAddrSrc(r) 2470 2471 2471 2472 Jumps to the address stored in the retAddrSrc register. This 2472 2473 differs from op_jmp because the target address is stored in a … … 2479 2480 BEGIN_OPCODE(op_debug) { 2480 2481 /* debug debugHookID(n) firstLine(n) lastLine(n) 2481 2482 2482 2483 Notifies the debugger of the current state of execution. This opcode 2483 2484 is only generated while the debugger is attached. … … 2502 2503 vPC = handlerVPC; 2503 2504 NEXT_OPCODE; 2504 } 2505 } 2505 2506 } 2506 2507 #undef NEXT_OPCODE -
trunk/JavaScriptCore/VM/Machine.h
r34351 r34372 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 29 #ifndef Machine_h 30 30 #define Machine_h … … 32 32 #include "Opcode.h" 33 33 #include "RegisterFileStack.h" 34 #include <kjs/list.h> 34 35 #include <wtf/HashMap.h> 35 #include <kjs/list.h>36 36 37 37 namespace KJS { … … 46 46 class RegisterFileStack; 47 47 class ScopeChainNode; 48 48 49 49 enum DebugHookID { 50 50 WillExecuteProgram, … … 60 60 class Machine { 61 61 public: 62 enum { CallerCodeBlock = 0, 63 ReturnVPC, 64 CallerScopeChain, 65 CallerRegisterOffset, 66 ReturnValueRegister, 67 ArgumentStartRegister, 68 ArgumentCount, 69 CalledAsConstructor, 70 Callee, 71 OptionalCalleeActivation, 72 CallFrameHeaderSize}; 73 62 enum { 63 CallerCodeBlock = 0, 64 ReturnVPC, 65 CallerScopeChain, 66 CallerRegisterOffset, 67 ReturnValueRegister, 68 ArgumentStartRegister, 69 ArgumentCount, 70 CalledAsConstructor, 71 Callee, 72 OptionalCalleeActivation, 73 CallFrameHeaderSize 74 }; 75 74 76 enum { ProgramCodeThisRegister = -1 }; 75 77 76 78 Machine(); 77 78 Opcode getOpcode(OpcodeID id) { 79 80 Opcode getOpcode(OpcodeID id) 81 { 79 82 #if HAVE(COMPUTED_GOTO) 80 return m_opcodeTable[id]; 83 return m_opcodeTable[id]; 81 84 #else 82 85 return id; … … 84 87 } 85 88 86 OpcodeID getOpcodeID(Opcode opcode) { 89 OpcodeID getOpcodeID(Opcode opcode) 90 { 87 91 #if HAVE(COMPUTED_GOTO) 88 92 ASSERT(isOpcode(opcode)); … … 94 98 95 99 bool isOpcode(Opcode opcode); 96 100 97 101 JSValue* execute(ProgramNode*, ExecState*, ScopeChainNode*, JSObject* thisObj, RegisterFileStack*, JSValue** exception); 98 102 JSValue* execute(FunctionBodyNode*, ExecState*, FunctionImp*, JSObject* thisObj, const List& args, RegisterFileStack*, ScopeChainNode*, JSValue** exception); 99 103 JSValue* execute(EvalNode*, ExecState*, JSObject* thisObj, RegisterFile*, int registerOffset, ScopeChainNode*, JSValue** exception); 100 104 JSValue* execute(EvalNode*, ExecState*, JSObject* thisObj, RegisterFileStack*, ScopeChainNode*, JSValue** exception); 101 105 102 106 JSValue* retrieveArguments(ExecState*, FunctionImp*) const; 103 107 JSValue* retrieveCaller(ExecState*, FunctionImp*) const; 104 108 105 109 void getFunctionAndArguments(Register** registerBase, Register* callFrame, FunctionImp*&, Register*& argv, int& argc); 106 110 107 111 private: 108 typedef enum { Normal, InitializeAndReturn } ExecutionFlag;112 enum ExecutionFlag { Normal, InitializeAndReturn }; 109 113 110 114 ALWAYS_INLINE void setScopeChain(ExecState* exec, ScopeChainNode*&, ScopeChainNode*); … … 113 117 NEVER_INLINE bool unwindCallFrame(ExecState*, JSValue*, Register**, const Instruction*&, CodeBlock*&, JSValue**&, ScopeChainNode*&, Register*&); 114 118 NEVER_INLINE Instruction* throwException(ExecState*, JSValue*, Register**, const Instruction*, CodeBlock*&, JSValue**&, ScopeChainNode*&, Register*&); 115 119 116 120 bool getCallFrame(ExecState*, FunctionImp*, Register**& registerBase, int& callFrameOffset) const; 117 121 … … 120 124 void dumpCallFrame(const CodeBlock*, ScopeChainNode*, RegisterFile*, const Register*); 121 125 void dumpRegisters(const CodeBlock*, RegisterFile*, const Register*); 122 126 123 127 bool isGlobalCallFrame(Register** registerBase, const Register* r) const { return (*registerBase) == r; } 124 128 125 129 int m_reentryDepth; 126 #if HAVE(COMPUTED_GOTO) 130 #if HAVE(COMPUTED_GOTO) 127 131 Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling 128 132 HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling 129 133 #endif 130 134 }; 131 135 132 136 Machine& machine(); 133 137 -
trunk/JavaScriptCore/VM/Opcode.h
r34371 r34372 122 122 \ 123 123 macro(op_end) // end must be the last opcode in the list 124 124 125 125 #define OPCODE_ID_ENUM(opcode) opcode, 126 126 typedef enum { FOR_EACH_OPCODE_ID(OPCODE_ID_ENUM) } OpcodeID; -
trunk/JavaScriptCore/VM/Register.h
r33979 r34372 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 29 #ifndef Register_h 30 30 #define Register_h … … 36 36 class CodeBlock; 37 37 class FunctionImp; 38 struct Instruction;39 38 class JSObject; 40 39 class JSPropertyNameIterator; 41 40 class JSValue; 42 41 class ScopeChainNode; 43 42 struct Instruction; 43 44 44 struct Register { 45 45 union { … … 54 54 } u; 55 55 }; 56 56 57 57 } // namespace KJS 58 58 -
trunk/JavaScriptCore/VM/RegisterFile.cpp
r33979 r34372 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 29 #include "config.h" 30 30 #include "RegisterFile.h" 31 31 32 #include "RegisterFileStack.h" 32 33 33 #include "Register.h" 34 34 35 using namespace std; 36 35 37 namespace KJS { 36 37 using namespace std;38 38 39 39 size_t RegisterFile::newBuffer(size_t size, size_t capacity, size_t minCapacity, size_t maxSize, size_t offset) … … 58 58 size_t capacity = m_capacity + numGlobalSlots; 59 59 minCapacity += numGlobalSlots; 60 60 61 61 capacity = newBuffer(size, capacity, minCapacity, maxSize, 0); 62 62 … … 75 75 size_t capacity = m_capacity + numGlobalSlots; 76 76 size_t minCapacity = size + count; 77 77 78 78 if (minCapacity < capacity) 79 79 memmove(m_buffer + count, m_buffer, size * sizeof(Register)); -
trunk/JavaScriptCore/VM/RegisterFile.h
r34069 r34372 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 29 #ifndef RegisterFile_h 30 30 #define RegisterFile_h … … 40 40 frame by its offset from "base", the logical first entry in the register 41 41 file. The bottom-most register frame's offset from base is 0. 42 42 43 43 In a program where function "a" calls function "b" (global code -> a -> b), 44 44 the register file might look like this: … … 54 54 | | | | 55 55 buffer base (frame 0) frame 1 frame 2 56 56 57 57 Since all variables, including globals, are accessed by negative offsets 58 58 from their register frame pointers, to keep old global offsets correct, new 59 59 globals must appear at the beginning of the register file, shifting base 60 60 to the right. 61 61 62 62 If we added one global variable to the register file depicted above, it 63 63 would look like this: … … 70 70 -------------------------------> < 71 71 | <-globals | temps-> | 72 ^ ^ 73 | | 72 ^ ^ 73 | | 74 74 buffer base (frame 0) 75 75 … … 78 78 clients keep an indirect pointer, so their calculations update 79 79 automatically when base changes. 80 80 81 81 For client simplicity, the RegisterFile measures size and capacity from 82 82 "base", not "buffer". … … 84 84 85 85 class RegisterFileStack; 86 86 87 87 class RegisterFile : Noncopyable { 88 88 public: 89 89 enum { DefaultRegisterFileSize = 2 * 1024 * 1024 }; 90 90 91 RegisterFile(size_t maxSize, RegisterFileStack* m_baseObserver) 91 92 : m_safeForReentry(true) … … 98 99 { 99 100 } 100 101 101 102 ~RegisterFile() 102 103 { 103 104 setBuffer(0); 104 105 } 105 106 106 107 // Pointer to a value that holds the base of this register file. 107 108 Register** basePointer() { return &m_base; } 108 109 109 110 void shrink(size_t size) 110 111 { … … 128 129 size_t size() { return m_size; } 129 130 size_t maxSize() { return m_maxSize; } 130 131 131 132 void clear(); 132 133 … … 145 146 bool safeForReentry() { return m_safeForReentry; } 146 147 void setSafeForReentry(bool safeForReentry) { m_safeForReentry = safeForReentry; } 148 147 149 private: 148 150 size_t newBuffer(size_t size, size_t capacity, size_t minCapacity, size_t maxSize, size_t offset); … … 155 157 m_buffer = buffer; 156 158 } 157 159 158 160 void setBase(Register*); 161 159 162 bool m_safeForReentry; 160 163 size_t m_size; … … 165 168 RegisterFileStack* m_baseObserver; 166 169 }; 167 170 168 171 } // namespace KJS 169 172 -
trunk/JavaScriptCore/VM/RegisterFileStack.cpp
r33979 r34372 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 29 #include "config.h" 30 30 #include "RegisterFileStack.h" … … 70 70 } 71 71 72 // Slow case: This is a nested register file: pop this register file and 72 // Slow case: This is a nested register file: pop this register file and 73 73 // copy its globals to the previous register file. 74 74 RegisterFile* tmp = m_stack.last(); -
trunk/JavaScriptCore/VM/RegisterFileStack.h
r33979 r34372 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 29 #ifndef RegisterFileStack_h 30 30 #define RegisterFileStack_h … … 44 44 45 45 ~RegisterFileStack(); 46 46 47 47 RegisterFile* pushGlobalRegisterFile(); 48 48 void popGlobalRegisterFile(); … … 51 51 52 52 RegisterFile* current() { return m_stack.last(); } 53 53 54 54 void mark() 55 55 { 56 56 Stack::iterator end = m_stack.end(); 57 for (Stack::iterator it = m_stack.begin(); it != end; ++it) {57 for (Stack::iterator it = m_stack.begin(); it != end; ++it) 58 58 (*it)->mark(); 59 }60 59 } 61 60 … … 69 68 } 70 69 71 bool inImplicitCall() { 72 for (size_t i = 0; i < m_stack.size(); ++i) { 70 bool inImplicitCall() 71 { 72 for (size_t i = 0; i < m_stack.size(); ++i) { 73 73 if (!m_stack[i]->safeForReentry()) 74 74 return true; … … 80 80 typedef Vector<RegisterFile*, 4> Stack; 81 81 82 RegisterFile* lastGlobal() { 82 RegisterFile* lastGlobal() 83 { 83 84 ASSERT(m_stack.size()); 84 85 for (size_t i = m_stack.size() - 1; i > 0; --i) { -
trunk/JavaScriptCore/VM/RegisterID.h
r33979 r34372 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 29 #ifndef RegisterID_h 30 30 #define RegisterID_h … … 63 63 m_index = index; 64 64 } 65 65 66 66 int index() const 67 67 { … … 69 69 return m_index; 70 70 } 71 71 72 72 bool isTemporary() 73 73 { … … 92 92 93 93 private: 94 94 95 95 int m_refCount; 96 96 int m_index; … … 99 99 #endif 100 100 }; 101 101 102 102 } // namespace KJS 103 103 … … 111 111 112 112 } // namespace WTF 113 113 114 114 #endif // RegisterID_h -
trunk/JavaScriptCore/VM/SegmentedVector.h
r33979 r34372 33 33 34 34 namespace KJS { 35 35 36 36 template <typename T, size_t SegmentSize> class SegmentedVector { 37 37 public: 38 SegmentedVector() 38 SegmentedVector() 39 39 : m_size(0) 40 40 { … … 48 48 } 49 49 50 T& last() 50 T& last() 51 51 { 52 52 ASSERT(m_size); … … 61 61 m_size++; 62 62 } 63 63 64 64 void removeLast() 65 65 { … … 73 73 } 74 74 75 size_t size() const 75 size_t size() const 76 76 { 77 return m_size; 77 return m_size; 78 78 } 79 79 80 T& operator[](size_t index) 80 T& operator[](size_t index) 81 81 { 82 82 ASSERT(index < m_size); … … 133 133 numSegments++; 134 134 size_t oldSize = m_segments.size(); 135 135 136 136 if (numSegments == oldSize) { 137 137 m_segments.last()->resize(extra); … … 143 143 144 144 m_segments.resize(numSegments); 145 145 146 146 ASSERT(oldSize < m_segments.size()); 147 147 for (size_t i = oldSize - 1; i < (numSegments - 1); i++) { -
trunk/JavaScriptCore/kjs/CallData.h
r33979 r34372 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 29 #ifndef CallData_h 30 30 #define CallData_h -
trunk/JavaScriptCore/kjs/JSNotAnObject.cpp
r33979 r34372 34 34 35 35 namespace KJS { 36 // JSValue methods37 JSValue *JSNotAnObject::toPrimitive(ExecState* exec, JSType) const38 {39 UNUSED_PARAM(exec);40 ASSERT(exec->hadException() && exec->exception() == m_exception);41 return m_exception;42 }43 44 bool JSNotAnObject::getPrimitiveNumber(ExecState* exec, double&, JSValue*&)45 {46 UNUSED_PARAM(exec);47 ASSERT(exec->hadException() && exec->exception() == m_exception);48 return false;49 }50 51 bool JSNotAnObject::toBoolean(ExecState* exec) const52 {53 UNUSED_PARAM(exec);54 ASSERT(exec->hadException() && exec->exception() == m_exception);55 return false;56 }57 58 double JSNotAnObject::toNumber(ExecState* exec) const59 {60 UNUSED_PARAM(exec);61 ASSERT(exec->hadException() && exec->exception() == m_exception);62 return NaN;63 }64 36 65 UString JSNotAnObject::toString(ExecState* exec) const 66 { 67 UNUSED_PARAM(exec); 68 ASSERT(exec->hadException() && exec->exception() == m_exception); 69 return ""; 70 } 71 72 JSObject *JSNotAnObject::toObject(ExecState* exec) const 73 { 74 UNUSED_PARAM(exec); 75 ASSERT(exec->hadException() && exec->exception() == m_exception); 76 return m_exception; 77 } 78 79 // marking 80 void JSNotAnObject::mark() 81 { 82 JSCell::mark(); 83 if (!m_exception->marked()) 84 m_exception->mark(); 85 } 86 87 bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, const Identifier&, PropertySlot&) 88 { 89 UNUSED_PARAM(exec); 90 ASSERT(exec->hadException() && exec->exception() == m_exception); 91 return false; 92 } 93 94 bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, unsigned, PropertySlot&) 95 { 96 UNUSED_PARAM(exec); 97 ASSERT(exec->hadException() && exec->exception() == m_exception); 98 return false; 99 } 100 101 void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue*) 102 { 103 UNUSED_PARAM(exec); 104 ASSERT(exec->hadException() && exec->exception() == m_exception); 105 } 106 107 void JSNotAnObject::put(ExecState* exec, unsigned, JSValue*) 108 { 109 UNUSED_PARAM(exec); 110 ASSERT(exec->hadException() && exec->exception() == m_exception); 111 } 112 113 bool JSNotAnObject::deleteProperty(ExecState* exec, const Identifier &) 114 { 115 UNUSED_PARAM(exec); 116 ASSERT(exec->hadException() && exec->exception() == m_exception); 117 return false; 118 } 119 120 bool JSNotAnObject::deleteProperty(ExecState* exec, unsigned) 121 { 122 UNUSED_PARAM(exec); 123 ASSERT(exec->hadException() && exec->exception() == m_exception); 124 return false; 125 } 126 127 JSValue *JSNotAnObject::defaultValue(ExecState* exec, JSType) const 128 { 129 UNUSED_PARAM(exec); 130 ASSERT(exec->hadException() && exec->exception() == m_exception); 131 return m_exception; 132 } 133 134 JSObject* JSNotAnObject::construct(ExecState* exec, const List&) 135 { 136 UNUSED_PARAM(exec); 137 ASSERT(exec->hadException() && exec->exception() == m_exception); 138 return m_exception; 139 } 140 141 JSObject* JSNotAnObject::construct(ExecState* exec, const List&, const Identifier&, const UString&, int) 142 { 143 UNUSED_PARAM(exec); 144 ASSERT(exec->hadException() && exec->exception() == m_exception); 145 return m_exception; 146 } 147 148 JSValue* JSNotAnObject::callAsFunction(ExecState* exec, JSObject *, const List &) 149 { 150 UNUSED_PARAM(exec); 151 ASSERT(exec->hadException() && exec->exception() == m_exception); 152 return m_exception; 153 } 154 155 void JSNotAnObject::getPropertyNames(ExecState* exec, PropertyNameArray&) 156 { 157 UNUSED_PARAM(exec); 158 ASSERT(exec->hadException() && exec->exception() == m_exception); 159 } 160 37 // JSValue methods 38 JSValue* JSNotAnObject::toPrimitive(ExecState* exec, JSType) const 39 { 40 UNUSED_PARAM(exec); 41 ASSERT(exec->hadException() && exec->exception() == m_exception); 42 return m_exception; 161 43 } 44 45 bool JSNotAnObject::getPrimitiveNumber(ExecState* exec, double&, JSValue*&) 46 { 47 UNUSED_PARAM(exec); 48 ASSERT(exec->hadException() && exec->exception() == m_exception); 49 return false; 50 } 51 52 bool JSNotAnObject::toBoolean(ExecState* exec) const 53 { 54 UNUSED_PARAM(exec); 55 ASSERT(exec->hadException() && exec->exception() == m_exception); 56 return false; 57 } 58 59 double JSNotAnObject::toNumber(ExecState* exec) const 60 { 61 UNUSED_PARAM(exec); 62 ASSERT(exec->hadException() && exec->exception() == m_exception); 63 return NaN; 64 } 65 66 UString JSNotAnObject::toString(ExecState* exec) const 67 { 68 UNUSED_PARAM(exec); 69 ASSERT(exec->hadException() && exec->exception() == m_exception); 70 return ""; 71 } 72 73 JSObject* JSNotAnObject::toObject(ExecState* exec) const 74 { 75 UNUSED_PARAM(exec); 76 ASSERT(exec->hadException() && exec->exception() == m_exception); 77 return m_exception; 78 } 79 80 // Marking 81 void JSNotAnObject::mark() 82 { 83 JSCell::mark(); 84 if (!m_exception->marked()) 85 m_exception->mark(); 86 } 87 88 // JSObject methods 89 bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, const Identifier&, PropertySlot&) 90 { 91 UNUSED_PARAM(exec); 92 ASSERT(exec->hadException() && exec->exception() == m_exception); 93 return false; 94 } 95 96 bool JSNotAnObject::getOwnPropertySlot(ExecState* exec, unsigned, PropertySlot&) 97 { 98 UNUSED_PARAM(exec); 99 ASSERT(exec->hadException() && exec->exception() == m_exception); 100 return false; 101 } 102 103 void JSNotAnObject::put(ExecState* exec, const Identifier& , JSValue*) 104 { 105 UNUSED_PARAM(exec); 106 ASSERT(exec->hadException() && exec->exception() == m_exception); 107 } 108 109 void JSNotAnObject::put(ExecState* exec, unsigned, JSValue*) 110 { 111 UNUSED_PARAM(exec); 112 ASSERT(exec->hadException() && exec->exception() == m_exception); 113 } 114 115 bool JSNotAnObject::deleteProperty(ExecState* exec, const Identifier&) 116 { 117 UNUSED_PARAM(exec); 118 ASSERT(exec->hadException() && exec->exception() == m_exception); 119 return false; 120 } 121 122 bool JSNotAnObject::deleteProperty(ExecState* exec, unsigned) 123 { 124 UNUSED_PARAM(exec); 125 ASSERT(exec->hadException() && exec->exception() == m_exception); 126 return false; 127 } 128 129 JSValue* JSNotAnObject::defaultValue(ExecState* exec, JSType) const 130 { 131 UNUSED_PARAM(exec); 132 ASSERT(exec->hadException() && exec->exception() == m_exception); 133 return m_exception; 134 } 135 136 JSObject* JSNotAnObject::construct(ExecState* exec, const List&) 137 { 138 UNUSED_PARAM(exec); 139 ASSERT(exec->hadException() && exec->exception() == m_exception); 140 return m_exception; 141 } 142 143 JSObject* JSNotAnObject::construct(ExecState* exec, const List&, const Identifier&, const UString&, int) 144 { 145 UNUSED_PARAM(exec); 146 ASSERT(exec->hadException() && exec->exception() == m_exception); 147 return m_exception; 148 } 149 150 JSValue* JSNotAnObject::callAsFunction(ExecState* exec, JSObject*, const List&) 151 { 152 UNUSED_PARAM(exec); 153 ASSERT(exec->hadException() && exec->exception() == m_exception); 154 return m_exception; 155 } 156 157 void JSNotAnObject::getPropertyNames(ExecState* exec, PropertyNameArray&) 158 { 159 UNUSED_PARAM(exec); 160 ASSERT(exec->hadException() && exec->exception() == m_exception); 161 } 162 163 } // namespace KJS -
trunk/JavaScriptCore/kjs/JSNotAnObject.h
r33979 r34372 33 33 34 34 namespace KJS { 35 35 36 36 // This unholy class is used to allow us to avoid multiple exception checks 37 37 // in certain SquirrelFish opcodes -- effectively it just silently consumes … … 45 45 46 46 // JSValue methods 47 virtual JSValue *toPrimitive(ExecState* exec, JSType preferredType = UnspecifiedType) const;48 virtual bool getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value);49 virtual bool toBoolean(ExecState* exec) const;50 virtual double toNumber(ExecState* exec) const;51 virtual UString toString(ExecState* exec) const;52 virtual JSObject *toObject(ExecState* exec) const;53 54 // marking47 virtual JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const; 48 virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*&); 49 virtual bool toBoolean(ExecState*) const; 50 virtual double toNumber(ExecState*) const; 51 virtual UString toString(ExecState*) const; 52 virtual JSObject* toObject(ExecState*) const; 53 54 // Marking 55 55 virtual void mark(); 56 56 57 virtual bool getOwnPropertySlot(ExecState* , const Identifier&, PropertySlot&); 58 virtual bool getOwnPropertySlot(ExecState* , unsigned index, PropertySlot&); 57 // JSObject methods 58 virtual bool getOwnPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&); 59 virtual bool getOwnPropertySlot(ExecState*, unsigned propertyName, PropertySlot&); 59 60 60 virtual void put(ExecState*, const Identifier& propertyName, JSValue* value);61 virtual void put(ExecState*, unsigned propertyName, JSValue* value);61 virtual void put(ExecState*, const Identifier& propertyName, JSValue*); 62 virtual void put(ExecState*, unsigned propertyName, JSValue*); 62 63 63 virtual bool deleteProperty(ExecState* exec, const Identifier &propertyName);64 virtual bool deleteProperty(ExecState* exec, unsigned propertyName);64 virtual bool deleteProperty(ExecState*, const Identifier& propertyName); 65 virtual bool deleteProperty(ExecState*, unsigned propertyName); 65 66 66 virtual JSValue *defaultValue(ExecState* exec, JSType hint) const;67 virtual JSValue* defaultValue(ExecState*, JSType hint) const; 67 68 68 virtual JSObject* construct(ExecState* exec, const List& args);69 virtual JSObject* construct(ExecState* exec, const List& args, const Identifier& functionName, const UString& sourceURL, int lineNumber);70 71 virtual JSValue *callAsFunction(ExecState* exec, JSObject *thisObj, const List &args);69 virtual JSObject* construct(ExecState*, const List&); 70 virtual JSObject* construct(ExecState*, const List&, const Identifier& functionName, const UString& sourceURL, int lineNumber); 71 72 virtual JSValue* callAsFunction(ExecState*, JSObject* thisObj, const List&); 72 73 73 74 virtual void getPropertyNames(ExecState*, PropertyNameArray&); … … 76 77 JSObject* m_exception; 77 78 }; 78 }79 79 80 #endif 80 } // namespace KJS 81 82 #endif // JSNotAnObject_h -
trunk/JavaScriptCore/kjs/JSVariableObject.h
r34355 r34372 55 55 56 56 JSValue*& valueAt(int index) const { return registers()[index].u.jsValue; } 57 57 58 protected: 58 59 // Subclasses of JSVariableObject can subclass this struct to add data -
trunk/JavaScriptCore/kjs/LocalStorageEntry.h
r32259 r34372 23 23 */ 24 24 25 #ifndef KJS_LOCAL_STORAGE_H26 #define KJS_LOCAL_STORAGE_H25 #ifndef LocalStorageEntry_h 26 #define LocalStorageEntry_h 27 27 28 28 #include <wtf/Forward.h> … … 30 30 31 31 namespace KJS { 32 32 33 class JSValue; 33 34 … … 48 49 49 50 typedef Vector<LocalStorageEntry, 32> LocalStorage; 50 } 51 52 } // namespace KJS 51 53 52 54 namespace WTF { 55 53 56 template<> struct VectorTraits<KJS::LocalStorageEntry> : VectorTraitsBase<true, KJS::LocalStorageEntry> { }; 54 }55 57 56 #endif // KJS_LOCAL_STORAGE_H 58 } // namespace WTF 59 60 #endif // LocalStorageEntry_h -
trunk/JavaScriptCore/kjs/PropertyNameArray.h
r33979 r34372 20 20 */ 21 21 22 #ifndef KJS_PROPERTY_NAME_ARRAY_H23 #define KJS_PROPERTY_NAME_ARRAY_H22 #ifndef PropertyNameArray_h 23 #define PropertyNameArray_h 24 24 25 25 #include "identifier.h" … … 37 37 void add(UString::Rep*); 38 38 void addKnownUnique(UString::Rep* identifier) { m_vector.append(identifier); } 39 39 40 const_iterator begin() const { return m_vector.begin(); } 40 41 const_iterator end() const { return m_vector.end(); } 42 41 43 size_t size() const { return m_vector.size(); } 42 44 … … 45 47 46 48 Identifier* releaseIdentifiers() { return size() ? m_vector.releaseBuffer() : 0; } 49 47 50 private: 48 51 typedef HashSet<UString::Rep*, PtrHash<UString::Rep*> > IdentifierSet; … … 54 57 } // namespace KJS 55 58 56 57 #endif // KJS_PROPERTY_NAME_ARRAY_H 59 #endif // PropertyNameArray_h -
trunk/JavaScriptCore/kjs/SourceProvider.h
r33979 r34372 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 29 #ifndef SourceProvider_h 30 30 #define SourceProvider_h … … 37 37 class SourceProvider : public RefCounted<SourceProvider> { 38 38 public: 39 virtual ~SourceProvider() { }39 virtual ~SourceProvider() { } 40 40 virtual UString getRange(int start, int end) const = 0; 41 41 virtual const UChar* data() const = 0; … … 52 52 53 53 private: 54 UStringSourceProvider(const UString& source) : m_source(source) {} 54 UStringSourceProvider(const UString& source) 55 : m_source(source) 56 { 57 } 58 55 59 UString m_source; 56 60 }; 57 61 58 } 62 } // namespace KJS 59 63 60 64 #endif // SourceProvider_h -
trunk/JavaScriptCore/kjs/SourceRange.h
r33979 r34372 26 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 27 */ 28 28 29 29 #ifndef SourceRange_h 30 30 #define SourceRange_h … … 37 37 class SourceRange { 38 38 public: 39 SourceRange(PassRefPtr<SourceProvider> provider, int start, int end) 39 SourceRange(PassRefPtr<SourceProvider> provider, int start, int end) 40 40 : m_sourceProvider(provider) 41 41 , m_startChar(start) … … 43 43 { 44 44 } 45 SourceRange() {}46 45 47 UString toString() const { if (!m_sourceProvider) return UString(); return m_sourceProvider->getRange(m_startChar, m_endChar); } 46 SourceRange() 47 { 48 } 49 50 UString toString() const 51 { 52 if (!m_sourceProvider) 53 return UString(); 54 return m_sourceProvider->getRange(m_startChar, m_endChar); 55 } 48 56 49 57 private: … … 53 61 }; 54 62 55 } 63 } // namespace KJS 56 64 57 65 #endif // SourceRange_h -
trunk/JavaScriptCore/kjs/scope_chain.h
r34007 r34372 45 45 JSObject* globalThis; 46 46 int refCount; 47 47 48 48 void deref() { if (--refCount == 0) release(); } 49 49 void ref() { ++refCount; } … … 119 119 class ScopeChainIterator { 120 120 public: 121 ScopeChainIterator(const ScopeChainNode* node) : m_node(node) {} 121 ScopeChainIterator(const ScopeChainNode* node) 122 : m_node(node) 123 { 124 } 122 125 123 126 JSObject* const & operator*() const { return m_node->object; } … … 188 191 void print() const { _node->print(); } 189 192 #endif 190 193 191 194 private: 192 195 ScopeChainNode* _node; -
trunk/JavaScriptCore/kjs/value.cpp
r34355 r34372 81 81 static const double D32 = 4294967296.0; 82 82 83 void *JSCell::operator new(size_t size)83 void* JSCell::operator new(size_t size) 84 84 { 85 85 return Collector::allocate(size); … … 102 102 103 103 // ECMA 9.4 104 double JSValue::toInteger(ExecState *exec) const104 double JSValue::toInteger(ExecState* exec) const 105 105 { 106 106 int32_t i; … … 111 111 } 112 112 113 double JSValue::toIntegerPreserveNaN(ExecState *exec) const113 double JSValue::toIntegerPreserveNaN(ExecState* exec) const 114 114 { 115 115 int32_t i; … … 172 172 } 173 173 174 bool JSCell::getNumber(double &numericValue) const174 bool JSCell::getNumber(double& numericValue) const 175 175 { 176 176 if (!isNumber()) 177 177 return false; 178 numericValue = static_cast<const NumberImp 178 numericValue = static_cast<const NumberImp*>(this)->value(); 179 179 return true; 180 180 } … … 182 182 double JSCell::getNumber() const 183 183 { 184 return isNumber() ? static_cast<const NumberImp 185 } 186 187 bool JSCell::getString(UString 184 return isNumber() ? static_cast<const NumberImp*>(this)->value() : NaN; 185 } 186 187 bool JSCell::getString(UString&stringValue) const 188 188 { 189 189 if (!isString()) 190 190 return false; 191 stringValue = static_cast<const StringImp 191 stringValue = static_cast<const StringImp*>(this)->value(); 192 192 return true; 193 193 } … … 195 195 UString JSCell::getString() const 196 196 { 197 return isString() ? static_cast<const StringImp 198 } 199 200 JSObject 201 { 202 return isObject() ? static_cast<JSObject 203 } 204 205 const JSObject *JSCell::getObject() const206 { 207 return isObject() ? static_cast<const JSObject 197 return isString() ? static_cast<const StringImp*>(this)->value() : UString(); 198 } 199 200 JSObject*JSCell::getObject() 201 { 202 return isObject() ? static_cast<JSObject*>(this) : 0; 203 } 204 205 const JSObject* JSCell::getObject() const 206 { 207 return isObject() ? static_cast<const JSObject*>(this) : 0; 208 208 } 209 209 -
trunk/JavaScriptCore/kjs/value.h
r34355 r34372 53 53 friend class JSCell; // so it can derive from this class 54 54 friend class Collector; // so it can call asCell() 55 56 55 private: 57 56 JSValue(); … … 68 67 bool isString() const; 69 68 bool isObject() const; 70 bool isObject(const ClassInfo 69 bool isObject(const ClassInfo*) const; 71 70 72 71 // Extracting the value. … … 78 77 bool getString(UString&) const; 79 78 UString getString() const; // null string if not a string 80 JSObject *getObject(); // NULL if not an object81 const JSObject *getObject() const; // NULL if not an object79 JSObject* getObject(); // NULL if not an object 80 const JSObject* getObject() const; // NULL if not an object 82 81 83 82 CallType getCallData(CallData&); … … 90 89 91 90 // Basic conversions. 92 JSValue* toPrimitive(ExecState* exec, JSType preferredType = UnspecifiedType) const;93 bool getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value);94 95 bool toBoolean(ExecState *exec) const;91 JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const; 92 bool getPrimitiveNumber(ExecState*, double& number, JSValue*&); 93 94 bool toBoolean(ExecState*) const; 96 95 97 96 // toNumber conversion is expected to be side effect free if an exception has 98 97 // been set in the ExecState already. 99 double toNumber(ExecState *exec) const;98 double toNumber(ExecState*) const; 100 99 JSValue* toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number. 101 UString toString(ExecState *exec) const;102 JSObject* toObject(ExecState *exec) const;100 UString toString(ExecState*) const; 101 JSObject* toObject(ExecState*) const; 103 102 104 103 // Integer conversions. … … 138 137 139 138 // Implementation details. 140 JSCell *asCell();141 const JSCell *asCell() const;139 JSCell* asCell(); 140 const JSCell* asCell() const; 142 141 }; 143 142 … … 152 151 JSCell(); 153 152 virtual ~JSCell(); 153 154 154 public: 155 155 // Querying the type. … … 158 158 bool isString() const; 159 159 bool isObject() const; 160 bool isObject(const ClassInfo 160 bool isObject(const ClassInfo*) const; 161 161 162 162 // Extracting the value. … … 165 165 bool getString(UString&) const; 166 166 UString getString() const; // null string if not a string 167 JSObject *getObject(); // NULL if not an object168 const JSObject *getObject() const; // NULL if not an object167 JSObject* getObject(); // NULL if not an object 168 const JSObject* getObject() const; // NULL if not an object 169 169 170 170 virtual CallType getCallData(CallData&); … … 177 177 178 178 // Basic conversions. 179 virtual JSValue *toPrimitive(ExecState *exec, JSType preferredType = UnspecifiedType) const = 0;180 virtual bool getPrimitiveNumber(ExecState* exec, double& number, JSValue*& value) = 0;181 virtual bool toBoolean(ExecState *exec) const = 0;182 virtual double toNumber(ExecState *exec) const = 0;183 virtual UString toString(ExecState *exec) const = 0;184 virtual JSObject *toObject(ExecState *exec) const = 0;179 virtual JSValue* toPrimitive(ExecState*, JSType preferredType = UnspecifiedType) const = 0; 180 virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*&) = 0; 181 virtual bool toBoolean(ExecState*) const = 0; 182 virtual double toNumber(ExecState*) const = 0; 183 virtual UString toString(ExecState*) const = 0; 184 virtual JSObject* toObject(ExecState*) const = 0; 185 185 186 186 // Garbage collection. 187 void *operator new(size_t);187 void* operator new(size_t); 188 188 virtual void mark(); 189 189 bool marked() const; … … 200 200 201 201 class NumberImp : public JSCell { 202 friend JSValue* jsNumberCell(double); 203 202 friend JSValue* jsNumberCell(double); 204 203 public: 205 double value() const { return val; }206 207 virtual JSType type() const;208 209 virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const;210 virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value);211 virtual bool toBoolean(ExecState* exec) const;212 virtual double toNumber(ExecState* exec) const;213 virtual UString toString(ExecState* exec) const;214 virtual JSObject* toObject(ExecState* exec) const;204 double value() const { return val; } 205 206 virtual JSType type() const; 207 208 virtual JSValue* toPrimitive(ExecState*, JSType preferred = UnspecifiedType) const; 209 virtual bool getPrimitiveNumber(ExecState*, double& number, JSValue*& value); 210 virtual bool toBoolean(ExecState*) const; 211 virtual double toNumber(ExecState*) const; 212 virtual UString toString(ExecState*) const; 213 virtual JSObject* toObject(ExecState*) const; 215 214 virtual JSObject* toThisObject(ExecState*) const; 216 215 217 void* operator new(size_t size)218 {216 void* operator new(size_t size) 217 { 219 218 #ifdef JAVASCRIPTCORE_BUILDING_ALL_IN_ONE_FILE 220 return Collector::inlineAllocateNumber(size);219 return Collector::inlineAllocateNumber(size); 221 220 #else 222 return Collector::allocateNumber(size);221 return Collector::allocateNumber(size); 223 222 #endif 224 }223 } 225 224 226 225 private: 227 NumberImp(double v) : val(v) { } 228 229 virtual bool getUInt32(uint32_t&) const; 230 virtual bool getTruncatedInt32(int32_t&) const; 231 virtual bool getTruncatedUInt32(uint32_t&) const; 232 233 double val; 226 NumberImp(double v) 227 : val(v) 228 { 229 } 230 231 virtual bool getUInt32(uint32_t&) const; 232 virtual bool getTruncatedInt32(int32_t&) const; 233 virtual bool getTruncatedUInt32(uint32_t&) const; 234 235 double val; 234 236 }; 235 237 236 JSCell *jsString(const UString&); // returns empty string if passed null string237 JSCell *jsString(const char* = ""); // returns empty string if passed 0238 JSCell* jsString(const UString&); // returns empty string if passed null string 239 JSCell* jsString(const char* = ""); // returns empty string if passed 0 238 240 239 241 // should be used for strings that are owned by an object that will 240 242 // likely outlive the JSValue this makes, such as the parse tree or a 241 243 // DOM object that contains a UString 242 JSCell *jsOwnedString(const UString&);244 JSCell* jsOwnedString(const UString&); 243 245 244 246 extern const double NaN; … … 252 254 } 253 255 254 ALWAYS_INLINE JSValue *jsUndefined()256 ALWAYS_INLINE JSValue* jsUndefined() 255 257 { 256 258 return JSImmediate::undefinedImmediate(); 257 259 } 258 260 259 inline JSValue *jsNull()261 inline JSValue* jsNull() 260 262 { 261 263 return JSImmediate::nullImmediate(); 262 264 } 263 265 264 inline JSValue *jsNaN()266 inline JSValue* jsNaN() 265 267 { 266 268 return jsNumberCell(NaN); 267 269 } 268 270 269 inline JSValue *jsBoolean(bool b)271 inline JSValue* jsBoolean(bool b) 270 272 { 271 273 return b ? JSImmediate::trueImmediate() : JSImmediate::falseImmediate(); … … 608 610 } 609 611 610 } // namespace 612 } // namespace KJS 611 613 612 614 #endif // KJS_VALUE_H
Note:
See TracChangeset
for help on using the changeset viewer.