]> git.saurik.com Git - apple/javascriptcore.git/blame - bytecode/CodeBlock.h
JavaScriptCore-554.1.tar.gz
[apple/javascriptcore.git] / bytecode / CodeBlock.h
CommitLineData
9dae56ea
A
1/*
2 * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 * its contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#ifndef CodeBlock_h
31#define CodeBlock_h
32
33#include "EvalCodeCache.h"
34#include "Instruction.h"
ba379fdc 35#include "JITCode.h"
9dae56ea
A
36#include "JSGlobalObject.h"
37#include "JumpTable.h"
38#include "Nodes.h"
39#include "RegExp.h"
40#include "UString.h"
ba379fdc 41#include <wtf/FastAllocBase.h>
9dae56ea
A
42#include <wtf/RefPtr.h>
43#include <wtf/Vector.h>
44
45#if ENABLE(JIT)
46#include "StructureStubInfo.h"
47#endif
48
ba379fdc
A
49// Register numbers used in bytecode operations have different meaning accoring to their ranges:
50// 0x80000000-0xFFFFFFFF Negative indicies from the CallFrame pointer are entries in the call frame, see RegisterFile.h.
51// 0x00000000-0x3FFFFFFF Forwards indices from the CallFrame pointer are local vars and temporaries with the function's callframe.
52// 0x40000000-0x7FFFFFFF Positive indices from 0x40000000 specify entries in the constant pool on the CodeBlock.
53static const int FirstConstantRegisterIndex = 0x40000000;
54
9dae56ea
A
55namespace JSC {
56
57 class ExecState;
58
ba379fdc 59 enum CodeType { GlobalCode, EvalCode, FunctionCode, NativeCode };
9dae56ea
A
60
61 static ALWAYS_INLINE int missingThisObjectMarker() { return std::numeric_limits<int>::max(); }
62
63 struct HandlerInfo {
64 uint32_t start;
65 uint32_t end;
66 uint32_t target;
67 uint32_t scopeDepth;
68#if ENABLE(JIT)
ba379fdc 69 CodeLocationLabel nativeCode;
9dae56ea
A
70#endif
71 };
72
9dae56ea
A
73 struct ExpressionRangeInfo {
74 enum {
75 MaxOffset = (1 << 7) - 1,
76 MaxDivot = (1 << 25) - 1
77 };
78 uint32_t instructionOffset : 25;
79 uint32_t divotPoint : 25;
80 uint32_t startOffset : 7;
81 uint32_t endOffset : 7;
82 };
83
84 struct LineInfo {
85 uint32_t instructionOffset;
86 int32_t lineNumber;
87 };
88
89 // Both op_construct and op_instanceof require a use of op_get_by_id to get
90 // the prototype property from an object. The exception messages for exceptions
91 // thrown by these instances op_get_by_id need to reflect this.
92 struct GetByIdExceptionInfo {
93 unsigned bytecodeOffset : 31;
94 bool isOpConstruct : 1;
95 };
96
97#if ENABLE(JIT)
98 struct CallLinkInfo {
99 CallLinkInfo()
ba379fdc 100 : callee(0)
9dae56ea
A
101 {
102 }
103
104 unsigned bytecodeIndex;
ba379fdc
A
105 CodeLocationNearCall callReturnLocation;
106 CodeLocationDataLabelPtr hotPathBegin;
107 CodeLocationNearCall hotPathOther;
108 CodeBlock* ownerCodeBlock;
9dae56ea
A
109 CodeBlock* callee;
110 unsigned position;
111
112 void setUnlinked() { callee = 0; }
113 bool isLinked() { return callee; }
114 };
115
ba379fdc
A
116 struct MethodCallLinkInfo {
117 MethodCallLinkInfo()
118 : cachedStructure(0)
119 , cachedPrototypeStructure(0)
120 {
121 }
122
123 CodeLocationCall callReturnLocation;
124 CodeLocationDataLabelPtr structureLabel;
125 Structure* cachedStructure;
126 Structure* cachedPrototypeStructure;
127 };
128
9dae56ea
A
129 struct FunctionRegisterInfo {
130 FunctionRegisterInfo(unsigned bytecodeOffset, int functionRegisterIndex)
131 : bytecodeOffset(bytecodeOffset)
132 , functionRegisterIndex(functionRegisterIndex)
133 {
134 }
135
136 unsigned bytecodeOffset;
137 int functionRegisterIndex;
138 };
139
140 struct GlobalResolveInfo {
141 GlobalResolveInfo(unsigned bytecodeOffset)
142 : structure(0)
143 , offset(0)
144 , bytecodeOffset(bytecodeOffset)
145 {
146 }
147
148 Structure* structure;
149 unsigned offset;
150 unsigned bytecodeOffset;
151 };
152
ba379fdc
A
153 // This structure is used to map from a call return location
154 // (given as an offset in bytes into the JIT code) back to
155 // the bytecode index of the corresponding bytecode operation.
156 // This is then used to look up the corresponding handler.
157 struct CallReturnOffsetToBytecodeIndex {
158 CallReturnOffsetToBytecodeIndex(unsigned callReturnOffset, unsigned bytecodeIndex)
159 : callReturnOffset(callReturnOffset)
9dae56ea
A
160 , bytecodeIndex(bytecodeIndex)
161 {
162 }
163
ba379fdc 164 unsigned callReturnOffset;
9dae56ea
A
165 unsigned bytecodeIndex;
166 };
167
168 // valueAtPosition helpers for the binaryChop algorithm below.
169
170 inline void* getStructureStubInfoReturnLocation(StructureStubInfo* structureStubInfo)
171 {
ba379fdc 172 return structureStubInfo->callReturnLocation.executableAddress();
9dae56ea
A
173 }
174
175 inline void* getCallLinkInfoReturnLocation(CallLinkInfo* callLinkInfo)
176 {
ba379fdc
A
177 return callLinkInfo->callReturnLocation.executableAddress();
178 }
179
180 inline void* getMethodCallLinkInfoReturnLocation(MethodCallLinkInfo* methodCallLinkInfo)
181 {
182 return methodCallLinkInfo->callReturnLocation.executableAddress();
9dae56ea
A
183 }
184
ba379fdc 185 inline unsigned getCallReturnOffset(CallReturnOffsetToBytecodeIndex* pc)
9dae56ea 186 {
ba379fdc 187 return pc->callReturnOffset;
9dae56ea
A
188 }
189
190 // Binary chop algorithm, calls valueAtPosition on pre-sorted elements in array,
191 // compares result with key (KeyTypes should be comparable with '--', '<', '>').
192 // Optimized for cases where the array contains the key, checked by assertions.
193 template<typename ArrayType, typename KeyType, KeyType(*valueAtPosition)(ArrayType*)>
194 inline ArrayType* binaryChop(ArrayType* array, size_t size, KeyType key)
195 {
196 // The array must contain at least one element (pre-condition, array does conatin key).
197 // If the array only contains one element, no need to do the comparison.
198 while (size > 1) {
199 // Pick an element to check, half way through the array, and read the value.
200 int pos = (size - 1) >> 1;
201 KeyType val = valueAtPosition(&array[pos]);
202
203 // If the key matches, success!
204 if (val == key)
205 return &array[pos];
206 // The item we are looking for is smaller than the item being check; reduce the value of 'size',
207 // chopping off the right hand half of the array.
208 else if (key < val)
209 size = pos;
210 // Discard all values in the left hand half of the array, up to and including the item at pos.
211 else {
212 size -= (pos + 1);
213 array += (pos + 1);
214 }
215
216 // 'size' should never reach zero.
217 ASSERT(size);
218 }
219
220 // If we reach this point we've chopped down to one element, no need to check it matches
221 ASSERT(size == 1);
222 ASSERT(key == valueAtPosition(&array[0]));
223 return &array[0];
224 }
225#endif
226
ba379fdc 227 class CodeBlock : public WTF::FastAllocBase {
9dae56ea
A
228 friend class JIT;
229 public:
ba379fdc 230 CodeBlock(ScopeNode* ownerNode);
9dae56ea
A
231 CodeBlock(ScopeNode* ownerNode, CodeType, PassRefPtr<SourceProvider>, unsigned sourceOffset);
232 ~CodeBlock();
233
234 void mark();
235 void refStructures(Instruction* vPC) const;
236 void derefStructures(Instruction* vPC) const;
ba379fdc 237#if ENABLE(JIT_OPTIMIZE_CALL)
9dae56ea
A
238 void unlinkCallers();
239#endif
240
241 static void dumpStatistics();
242
243#if !defined(NDEBUG) || ENABLE_OPCODE_SAMPLING
244 void dump(ExecState*) const;
245 void printStructures(const Instruction*) const;
246 void printStructure(const char* name, const Instruction*, int operand) const;
247#endif
248
249 inline bool isKnownNotImmediate(int index)
250 {
251 if (index == m_thisRegister)
252 return true;
253
254 if (isConstantRegisterIndex(index))
255 return getConstant(index).isCell();
256
257 return false;
258 }
259
9dae56ea
A
260 ALWAYS_INLINE bool isTemporaryRegisterIndex(int index)
261 {
ba379fdc 262 return index >= m_numVars;
9dae56ea
A
263 }
264
265 HandlerInfo* handlerForBytecodeOffset(unsigned bytecodeOffset);
266 int lineNumberForBytecodeOffset(CallFrame*, unsigned bytecodeOffset);
267 int expressionRangeForBytecodeOffset(CallFrame*, unsigned bytecodeOffset, int& divot, int& startOffset, int& endOffset);
268 bool getByIdExceptionInfoForBytecodeOffset(CallFrame*, unsigned bytecodeOffset, OpcodeID&);
269
270#if ENABLE(JIT)
271 void addCaller(CallLinkInfo* caller)
272 {
273 caller->callee = this;
274 caller->position = m_linkedCallerList.size();
275 m_linkedCallerList.append(caller);
276 }
277
278 void removeCaller(CallLinkInfo* caller)
279 {
280 unsigned pos = caller->position;
281 unsigned lastPos = m_linkedCallerList.size() - 1;
282
283 if (pos != lastPos) {
284 m_linkedCallerList[pos] = m_linkedCallerList[lastPos];
285 m_linkedCallerList[pos]->position = pos;
286 }
287 m_linkedCallerList.shrink(lastPos);
288 }
289
ba379fdc 290 StructureStubInfo& getStubInfo(ReturnAddressPtr returnAddress)
9dae56ea 291 {
ba379fdc 292 return *(binaryChop<StructureStubInfo, void*, getStructureStubInfoReturnLocation>(m_structureStubInfos.begin(), m_structureStubInfos.size(), returnAddress.value()));
9dae56ea
A
293 }
294
ba379fdc 295 CallLinkInfo& getCallLinkInfo(ReturnAddressPtr returnAddress)
9dae56ea 296 {
ba379fdc 297 return *(binaryChop<CallLinkInfo, void*, getCallLinkInfoReturnLocation>(m_callLinkInfos.begin(), m_callLinkInfos.size(), returnAddress.value()));
9dae56ea
A
298 }
299
ba379fdc
A
300 MethodCallLinkInfo& getMethodCallLinkInfo(ReturnAddressPtr returnAddress)
301 {
302 return *(binaryChop<MethodCallLinkInfo, void*, getMethodCallLinkInfoReturnLocation>(m_methodCallLinkInfos.begin(), m_methodCallLinkInfos.size(), returnAddress.value()));
303 }
304
305 unsigned getBytecodeIndex(CallFrame* callFrame, ReturnAddressPtr returnAddress)
9dae56ea
A
306 {
307 reparseForExceptionInfoIfNecessary(callFrame);
ba379fdc 308 return binaryChop<CallReturnOffsetToBytecodeIndex, unsigned, getCallReturnOffset>(m_exceptionInfo->m_callReturnIndexVector.begin(), m_exceptionInfo->m_callReturnIndexVector.size(), ownerNode()->generatedJITCode().offsetOf(returnAddress.value()))->bytecodeIndex;
9dae56ea
A
309 }
310
311 bool functionRegisterForBytecodeOffset(unsigned bytecodeOffset, int& functionRegisterIndex);
312#endif
313
314 void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
315 bool isNumericCompareFunction() { return m_isNumericCompareFunction; }
316
317 Vector<Instruction>& instructions() { return m_instructions; }
318#ifndef NDEBUG
319 void setInstructionCount(unsigned instructionCount) { m_instructionCount = instructionCount; }
320#endif
321
322#if ENABLE(JIT)
ba379fdc
A
323 JITCode& getJITCode() { return ownerNode()->generatedJITCode(); }
324 void setJITCode(JITCode);
325 ExecutablePool* executablePool() { return ownerNode()->getExecutablePool(); }
9dae56ea
A
326#endif
327
328 ScopeNode* ownerNode() const { return m_ownerNode; }
329
330 void setGlobalData(JSGlobalData* globalData) { m_globalData = globalData; }
331
332 void setThisRegister(int thisRegister) { m_thisRegister = thisRegister; }
333 int thisRegister() const { return m_thisRegister; }
334
335 void setNeedsFullScopeChain(bool needsFullScopeChain) { m_needsFullScopeChain = needsFullScopeChain; }
336 bool needsFullScopeChain() const { return m_needsFullScopeChain; }
337 void setUsesEval(bool usesEval) { m_usesEval = usesEval; }
338 bool usesEval() const { return m_usesEval; }
339 void setUsesArguments(bool usesArguments) { m_usesArguments = usesArguments; }
340 bool usesArguments() const { return m_usesArguments; }
341
342 CodeType codeType() const { return m_codeType; }
343
ba379fdc
A
344 SourceProvider* source() const { ASSERT(m_codeType != NativeCode); return m_source.get(); }
345 unsigned sourceOffset() const { ASSERT(m_codeType != NativeCode); return m_sourceOffset; }
9dae56ea
A
346
347 size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
348 void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
349 unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
350 unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
351
352#if !ENABLE(JIT)
353 void addPropertyAccessInstruction(unsigned propertyAccessInstruction) { m_propertyAccessInstructions.append(propertyAccessInstruction); }
354 void addGlobalResolveInstruction(unsigned globalResolveInstruction) { m_globalResolveInstructions.append(globalResolveInstruction); }
355 bool hasGlobalResolveInstructionAtBytecodeOffset(unsigned bytecodeOffset);
356#else
357 size_t numberOfStructureStubInfos() const { return m_structureStubInfos.size(); }
358 void addStructureStubInfo(const StructureStubInfo& stubInfo) { m_structureStubInfos.append(stubInfo); }
359 StructureStubInfo& structureStubInfo(int index) { return m_structureStubInfos[index]; }
360
361 void addGlobalResolveInfo(unsigned globalResolveInstruction) { m_globalResolveInfos.append(GlobalResolveInfo(globalResolveInstruction)); }
362 GlobalResolveInfo& globalResolveInfo(int index) { return m_globalResolveInfos[index]; }
363 bool hasGlobalResolveInfoAtBytecodeOffset(unsigned bytecodeOffset);
364
365 size_t numberOfCallLinkInfos() const { return m_callLinkInfos.size(); }
366 void addCallLinkInfo() { m_callLinkInfos.append(CallLinkInfo()); }
367 CallLinkInfo& callLinkInfo(int index) { return m_callLinkInfos[index]; }
368
ba379fdc
A
369 void addMethodCallLinkInfos(unsigned n) { m_methodCallLinkInfos.grow(n); }
370 MethodCallLinkInfo& methodCallLinkInfo(int index) { return m_methodCallLinkInfos[index]; }
371
9dae56ea
A
372 void addFunctionRegisterInfo(unsigned bytecodeOffset, int functionIndex) { createRareDataIfNecessary(); m_rareData->m_functionRegisterInfos.append(FunctionRegisterInfo(bytecodeOffset, functionIndex)); }
373#endif
374
375 // Exception handling support
376
377 size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
378 void addExceptionHandler(const HandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); }
379 HandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
380
381 bool hasExceptionInfo() const { return m_exceptionInfo; }
382 void clearExceptionInfo() { m_exceptionInfo.clear(); }
383
384 void addExpressionInfo(const ExpressionRangeInfo& expressionInfo) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_expressionInfo.append(expressionInfo); }
385 void addGetByIdExceptionInfo(const GetByIdExceptionInfo& info) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_getByIdExceptionInfo.append(info); }
386
387 size_t numberOfLineInfos() const { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_lineInfo.size(); }
388 void addLineInfo(const LineInfo& lineInfo) { ASSERT(m_exceptionInfo); m_exceptionInfo->m_lineInfo.append(lineInfo); }
389 LineInfo& lastLineInfo() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_lineInfo.last(); }
390
391#if ENABLE(JIT)
ba379fdc 392 Vector<CallReturnOffsetToBytecodeIndex>& callReturnIndexVector() { ASSERT(m_exceptionInfo); return m_exceptionInfo->m_callReturnIndexVector; }
9dae56ea
A
393#endif
394
395 // Constant Pool
396
397 size_t numberOfIdentifiers() const { return m_identifiers.size(); }
398 void addIdentifier(const Identifier& i) { return m_identifiers.append(i); }
399 Identifier& identifier(int index) { return m_identifiers[index]; }
400
401 size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
402 void addConstantRegister(const Register& r) { return m_constantRegisters.append(r); }
ba379fdc
A
403 Register& constantRegister(int index) { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
404 ALWAYS_INLINE bool isConstantRegisterIndex(int index) { return index >= FirstConstantRegisterIndex; }
405 ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].jsValue(); }
9dae56ea
A
406
407 unsigned addFunctionExpression(FuncExprNode* n) { unsigned size = m_functionExpressions.size(); m_functionExpressions.append(n); return size; }
408 FuncExprNode* functionExpression(int index) const { return m_functionExpressions[index].get(); }
409
410 unsigned addFunction(FuncDeclNode* n) { createRareDataIfNecessary(); unsigned size = m_rareData->m_functions.size(); m_rareData->m_functions.append(n); return size; }
411 FuncDeclNode* function(int index) const { ASSERT(m_rareData); return m_rareData->m_functions[index].get(); }
412
413 bool hasFunctions() const { return m_functionExpressions.size() || (m_rareData && m_rareData->m_functions.size()); }
414
9dae56ea
A
415 unsigned addRegExp(RegExp* r) { createRareDataIfNecessary(); unsigned size = m_rareData->m_regexps.size(); m_rareData->m_regexps.append(r); return size; }
416 RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
417
418
419 // Jump Tables
420
421 size_t numberOfImmediateSwitchJumpTables() const { return m_rareData ? m_rareData->m_immediateSwitchJumpTables.size() : 0; }
422 SimpleJumpTable& addImmediateSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_immediateSwitchJumpTables.append(SimpleJumpTable()); return m_rareData->m_immediateSwitchJumpTables.last(); }
423 SimpleJumpTable& immediateSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_immediateSwitchJumpTables[tableIndex]; }
424
425 size_t numberOfCharacterSwitchJumpTables() const { return m_rareData ? m_rareData->m_characterSwitchJumpTables.size() : 0; }
426 SimpleJumpTable& addCharacterSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_characterSwitchJumpTables.append(SimpleJumpTable()); return m_rareData->m_characterSwitchJumpTables.last(); }
427 SimpleJumpTable& characterSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_characterSwitchJumpTables[tableIndex]; }
428
429 size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
430 StringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(StringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
431 StringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
432
433
434 SymbolTable& symbolTable() { return m_symbolTable; }
435
ba379fdc 436 EvalCodeCache& evalCodeCache() { ASSERT(m_codeType != NativeCode); createRareDataIfNecessary(); return m_rareData->m_evalCodeCache; }
9dae56ea
A
437
438 void shrinkToFit();
439
440 // FIXME: Make these remaining members private.
441
442 int m_numCalleeRegisters;
9dae56ea
A
443 int m_numVars;
444 int m_numParameters;
445
446 private:
447#if !defined(NDEBUG) || ENABLE(OPCODE_SAMPLING)
448 void dump(ExecState*, const Vector<Instruction>::const_iterator& begin, Vector<Instruction>::const_iterator&) const;
449#endif
450
451 void reparseForExceptionInfoIfNecessary(CallFrame*);
452
453 void createRareDataIfNecessary()
454 {
ba379fdc 455 ASSERT(m_codeType != NativeCode);
9dae56ea
A
456 if (!m_rareData)
457 m_rareData.set(new RareData);
458 }
459
460 ScopeNode* m_ownerNode;
461 JSGlobalData* m_globalData;
462
463 Vector<Instruction> m_instructions;
464#ifndef NDEBUG
465 unsigned m_instructionCount;
466#endif
9dae56ea
A
467
468 int m_thisRegister;
469
470 bool m_needsFullScopeChain;
471 bool m_usesEval;
472 bool m_usesArguments;
473 bool m_isNumericCompareFunction;
474
475 CodeType m_codeType;
476
477 RefPtr<SourceProvider> m_source;
478 unsigned m_sourceOffset;
479
480#if !ENABLE(JIT)
481 Vector<unsigned> m_propertyAccessInstructions;
482 Vector<unsigned> m_globalResolveInstructions;
483#else
484 Vector<StructureStubInfo> m_structureStubInfos;
485 Vector<GlobalResolveInfo> m_globalResolveInfos;
486 Vector<CallLinkInfo> m_callLinkInfos;
ba379fdc 487 Vector<MethodCallLinkInfo> m_methodCallLinkInfos;
9dae56ea
A
488 Vector<CallLinkInfo*> m_linkedCallerList;
489#endif
490
491 Vector<unsigned> m_jumpTargets;
492
493 // Constant Pool
494 Vector<Identifier> m_identifiers;
495 Vector<Register> m_constantRegisters;
496 Vector<RefPtr<FuncExprNode> > m_functionExpressions;
497
498 SymbolTable m_symbolTable;
499
500 struct ExceptionInfo {
501 Vector<ExpressionRangeInfo> m_expressionInfo;
502 Vector<LineInfo> m_lineInfo;
503 Vector<GetByIdExceptionInfo> m_getByIdExceptionInfo;
504
505#if ENABLE(JIT)
ba379fdc 506 Vector<CallReturnOffsetToBytecodeIndex> m_callReturnIndexVector;
9dae56ea
A
507#endif
508 };
509 OwnPtr<ExceptionInfo> m_exceptionInfo;
510
511 struct RareData {
512 Vector<HandlerInfo> m_exceptionHandlers;
513
514 // Rare Constants
515 Vector<RefPtr<FuncDeclNode> > m_functions;
9dae56ea
A
516 Vector<RefPtr<RegExp> > m_regexps;
517
518 // Jump Tables
519 Vector<SimpleJumpTable> m_immediateSwitchJumpTables;
520 Vector<SimpleJumpTable> m_characterSwitchJumpTables;
521 Vector<StringJumpTable> m_stringSwitchJumpTables;
522
523 EvalCodeCache m_evalCodeCache;
524
525#if ENABLE(JIT)
526 Vector<FunctionRegisterInfo> m_functionRegisterInfos;
527#endif
528 };
529 OwnPtr<RareData> m_rareData;
530 };
531
532 // Program code is not marked by any function, so we make the global object
533 // responsible for marking it.
534
535 class ProgramCodeBlock : public CodeBlock {
536 public:
537 ProgramCodeBlock(ScopeNode* ownerNode, CodeType codeType, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider)
538 : CodeBlock(ownerNode, codeType, sourceProvider, 0)
539 , m_globalObject(globalObject)
540 {
541 m_globalObject->codeBlocks().add(this);
542 }
543
544 ~ProgramCodeBlock()
545 {
546 if (m_globalObject)
547 m_globalObject->codeBlocks().remove(this);
548 }
549
550 void clearGlobalObject() { m_globalObject = 0; }
551
552 private:
553 JSGlobalObject* m_globalObject; // For program and eval nodes, the global object that marks the constant pool.
554 };
555
556 class EvalCodeBlock : public ProgramCodeBlock {
557 public:
558 EvalCodeBlock(ScopeNode* ownerNode, JSGlobalObject* globalObject, PassRefPtr<SourceProvider> sourceProvider, int baseScopeDepth)
559 : ProgramCodeBlock(ownerNode, EvalCode, globalObject, sourceProvider)
560 , m_baseScopeDepth(baseScopeDepth)
561 {
562 }
563
564 int baseScopeDepth() const { return m_baseScopeDepth; }
565
566 private:
567 int m_baseScopeDepth;
568 };
569
ba379fdc
A
570 inline Register& ExecState::r(int index)
571 {
572 CodeBlock* codeBlock = this->codeBlock();
573 if (codeBlock->isConstantRegisterIndex(index))
574 return codeBlock->constantRegister(index);
575 return this[index];
576 }
577
9dae56ea
A
578} // namespace JSC
579
580#endif // CodeBlock_h