]> git.saurik.com Git - apple/javascriptcore.git/blame - bytecode/UnlinkedCodeBlock.h
JavaScriptCore-7600.1.4.16.1.tar.gz
[apple/javascriptcore.git] / bytecode / UnlinkedCodeBlock.h
CommitLineData
93a37866 1/*
81345200 2 * Copyright (C) 2012, 2013, 2014 Apple Inc. All Rights Reserved.
93a37866
A
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef UnlinkedCodeBlock_h
27#define UnlinkedCodeBlock_h
28
29#include "BytecodeConventions.h"
93a37866
A
30#include "CodeSpecializationKind.h"
31#include "CodeType.h"
32#include "ExpressionRangeInfo.h"
33#include "Identifier.h"
34#include "JSCell.h"
35#include "JSString.h"
93a37866
A
36#include "ParserModes.h"
37#include "RegExp.h"
38#include "SpecialPointer.h"
39#include "SymbolTable.h"
81345200 40#include "VirtualRegister.h"
93a37866 41
81345200 42#include <wtf/Compression.h>
93a37866
A
43#include <wtf/RefCountedArray.h>
44#include <wtf/Vector.h>
45
46namespace JSC {
47
48class Debugger;
49class FunctionBodyNode;
50class FunctionExecutable;
51class FunctionParameters;
52class JSScope;
53struct ParserError;
54class ScriptExecutable;
55class SourceCode;
56class SourceProvider;
81345200 57class SymbolTable;
93a37866
A
58class UnlinkedCodeBlock;
59class UnlinkedFunctionCodeBlock;
81345200 60class UnlinkedInstructionStream;
93a37866
A
61
62typedef unsigned UnlinkedValueProfile;
63typedef unsigned UnlinkedArrayProfile;
64typedef unsigned UnlinkedArrayAllocationProfile;
65typedef unsigned UnlinkedObjectAllocationProfile;
66typedef unsigned UnlinkedLLIntCallLinkInfo;
67
68struct ExecutableInfo {
81345200 69 ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor, bool isBuiltinFunction)
93a37866
A
70 : m_needsActivation(needsActivation)
71 , m_usesEval(usesEval)
72 , m_isStrictMode(isStrictMode)
73 , m_isConstructor(isConstructor)
81345200 74 , m_isBuiltinFunction(isBuiltinFunction)
93a37866
A
75 {
76 }
81345200
A
77 bool m_needsActivation : 1;
78 bool m_usesEval : 1;
79 bool m_isStrictMode : 1;
80 bool m_isConstructor : 1;
81 bool m_isBuiltinFunction : 1;
82};
83
84enum UnlinkedFunctionKind {
85 UnlinkedNormalFunction,
86 UnlinkedBuiltinFunction,
93a37866
A
87};
88
89class UnlinkedFunctionExecutable : public JSCell {
90public:
81345200 91 friend class BuiltinExecutables;
93a37866 92 friend class CodeCache;
81345200 93 friend class VM;
93a37866 94 typedef JSCell Base;
81345200 95 static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node, UnlinkedFunctionKind unlinkedFunctionKind)
93a37866 96 {
81345200 97 UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node, unlinkedFunctionKind);
93a37866
A
98 instance->finishCreation(*vm);
99 return instance;
100 }
101
102 const Identifier& name() const { return m_name; }
103 const Identifier& inferredName() const { return m_inferredName; }
104 JSString* nameValue() const { return m_nameValue.get(); }
81345200 105 SymbolTable* symbolTable(CodeSpecializationKind kind)
93a37866
A
106 {
107 return (kind == CodeForCall) ? m_symbolTableForCall.get() : m_symbolTableForConstruct.get();
108 }
109 size_t parameterCount() const;
110 bool isInStrictContext() const { return m_isInStrictContext; }
81345200
A
111 FunctionMode functionMode() const { return m_functionMode; }
112 JSParserStrictness toStrictness() const
113 {
114 if (m_isBuiltinFunction)
115 return JSParseBuiltin;
116 if (m_isInStrictContext)
117 return JSParseStrict;
118 return JSParseNormal;
119 }
93a37866
A
120
121 unsigned firstLineOffset() const { return m_firstLineOffset; }
122 unsigned lineCount() const { return m_lineCount; }
81345200
A
123 unsigned unlinkedFunctionNameStart() const { return m_unlinkedFunctionNameStart; }
124 unsigned unlinkedBodyStartColumn() const { return m_unlinkedBodyStartColumn; }
125 unsigned unlinkedBodyEndColumn() const { return m_unlinkedBodyEndColumn; }
93a37866
A
126 unsigned startOffset() const { return m_startOffset; }
127 unsigned sourceLength() { return m_sourceLength; }
128
129 String paramString() const;
130
81345200 131 UnlinkedFunctionCodeBlock* codeBlockFor(VM&, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, bool bodyIncludesBraces, ParserError&);
93a37866
A
132
133 static UnlinkedFunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
134
81345200 135 FunctionExecutable* link(VM&, const SourceCode&, size_t lineOffset);
93a37866
A
136
137 void clearCodeForRecompilation()
138 {
139 m_symbolTableForCall.clear();
140 m_symbolTableForConstruct.clear();
141 m_codeBlockForCall.clear();
142 m_codeBlockForConstruct.clear();
143 }
144
145 FunctionParameters* parameters() { return m_parameters.get(); }
146
81345200 147 void recordParse(CodeFeatures features, bool hasCapturedVariables)
93a37866
A
148 {
149 m_features = features;
150 m_hasCapturedVariables = hasCapturedVariables;
93a37866
A
151 }
152
153 bool forceUsesArguments() const { return m_forceUsesArguments; }
154
155 CodeFeatures features() const { return m_features; }
156 bool hasCapturedVariables() const { return m_hasCapturedVariables; }
157
158 static const bool needsDestruction = true;
159 static const bool hasImmortalStructure = true;
160 static void destroy(JSCell*);
161
81345200
A
162 bool isBuiltinFunction() const { return m_isBuiltinFunction; }
163
93a37866 164private:
81345200 165 UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*, UnlinkedFunctionKind);
93a37866
A
166 WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
167 WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
168
169 unsigned m_numCapturedVariables : 29;
170 bool m_forceUsesArguments : 1;
171 bool m_isInStrictContext : 1;
172 bool m_hasCapturedVariables : 1;
81345200 173 bool m_isBuiltinFunction : 1;
93a37866
A
174
175 Identifier m_name;
176 Identifier m_inferredName;
177 WriteBarrier<JSString> m_nameValue;
81345200
A
178 WriteBarrier<SymbolTable> m_symbolTableForCall;
179 WriteBarrier<SymbolTable> m_symbolTableForConstruct;
93a37866
A
180 RefPtr<FunctionParameters> m_parameters;
181 unsigned m_firstLineOffset;
182 unsigned m_lineCount;
81345200
A
183 unsigned m_unlinkedFunctionNameStart;
184 unsigned m_unlinkedBodyStartColumn;
185 unsigned m_unlinkedBodyEndColumn;
93a37866
A
186 unsigned m_startOffset;
187 unsigned m_sourceLength;
188
189 CodeFeatures m_features;
190
81345200 191 FunctionMode m_functionMode;
93a37866
A
192
193protected:
194 void finishCreation(VM& vm)
195 {
196 Base::finishCreation(vm);
197 m_nameValue.set(vm, this, jsString(&vm, name().string()));
198 }
199
200 static void visitChildren(JSCell*, SlotVisitor&);
201
202public:
203 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
204 {
81345200 205 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionExecutableType, StructureFlags), info());
93a37866
A
206 }
207
81345200 208 static const unsigned StructureFlags = OverridesVisitChildren | StructureIsImmortal | JSCell::StructureFlags;
93a37866 209
81345200 210 DECLARE_EXPORT_INFO;
93a37866
A
211};
212
213struct UnlinkedStringJumpTable {
214 typedef HashMap<RefPtr<StringImpl>, int32_t> StringOffsetTable;
215 StringOffsetTable offsetTable;
216
217 inline int32_t offsetForValue(StringImpl* value, int32_t defaultOffset)
218 {
219 StringOffsetTable::const_iterator end = offsetTable.end();
220 StringOffsetTable::const_iterator loc = offsetTable.find(value);
221 if (loc == end)
222 return defaultOffset;
223 return loc->value;
224 }
225
226};
227
228struct UnlinkedSimpleJumpTable {
229 Vector<int32_t> branchOffsets;
230 int32_t min;
231
232 int32_t offsetForValue(int32_t value, int32_t defaultOffset);
233 void add(int32_t key, int32_t offset)
234 {
235 if (!branchOffsets[key])
236 branchOffsets[key] = offset;
237 }
238};
239
240struct UnlinkedHandlerInfo {
241 uint32_t start;
242 uint32_t end;
243 uint32_t target;
244 uint32_t scopeDepth;
245};
246
247struct UnlinkedInstruction {
248 UnlinkedInstruction() { u.operand = 0; }
249 UnlinkedInstruction(OpcodeID opcode) { u.opcode = opcode; }
250 UnlinkedInstruction(int operand) { u.operand = operand; }
251 union {
252 OpcodeID opcode;
253 int32_t operand;
81345200 254 unsigned index;
93a37866
A
255 } u;
256};
257
258class UnlinkedCodeBlock : public JSCell {
259public:
260 typedef JSCell Base;
261 static const bool needsDestruction = true;
262 static const bool hasImmortalStructure = true;
263
264 enum { CallFunction, ApplyFunction };
265
266 bool isConstructor() const { return m_isConstructor; }
267 bool isStrictMode() const { return m_isStrictMode; }
268 bool usesEval() const { return m_usesEval; }
269
270 bool needsFullScopeChain() const { return m_needsFullScopeChain; }
93a37866
A
271
272 void addExpressionInfo(unsigned instructionOffset, int divot,
273 int startOffset, int endOffset, unsigned line, unsigned column);
274
275 bool hasExpressionInfo() { return m_expressionInfo.size(); }
276
277 // Special registers
81345200
A
278 void setThisRegister(VirtualRegister thisRegister) { m_thisRegister = thisRegister; }
279 void setActivationRegister(VirtualRegister activationRegister) { m_activationRegister = activationRegister; }
93a37866 280
81345200
A
281 void setArgumentsRegister(VirtualRegister argumentsRegister) { m_argumentsRegister = argumentsRegister; }
282 bool usesArguments() const { return m_argumentsRegister.isValid(); }
283 VirtualRegister argumentsRegister() const { return m_argumentsRegister; }
93a37866
A
284
285
81345200
A
286 bool usesGlobalObject() const { return m_globalObjectRegister.isValid(); }
287 void setGlobalObjectRegister(VirtualRegister globalObjectRegister) { m_globalObjectRegister = globalObjectRegister; }
288 VirtualRegister globalObjectRegister() const { return m_globalObjectRegister; }
93a37866
A
289
290 // Parameter information
291 void setNumParameters(int newValue) { m_numParameters = newValue; }
292 void addParameter() { m_numParameters++; }
293 unsigned numParameters() const { return m_numParameters; }
294
295 unsigned addRegExp(RegExp* r)
296 {
297 createRareDataIfNecessary();
298 unsigned size = m_rareData->m_regexps.size();
299 m_rareData->m_regexps.append(WriteBarrier<RegExp>(*m_vm, this, r));
300 return size;
301 }
302 unsigned numberOfRegExps() const
303 {
304 if (!m_rareData)
305 return 0;
306 return m_rareData->m_regexps.size();
307 }
308 RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
309
310 // Constant Pools
311
312 size_t numberOfIdentifiers() const { return m_identifiers.size(); }
313 void addIdentifier(const Identifier& i) { return m_identifiers.append(i); }
314 const Identifier& identifier(int index) const { return m_identifiers[index]; }
315 const Vector<Identifier>& identifiers() const { return m_identifiers; }
316
317 size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
318 unsigned addConstant(JSValue v)
319 {
320 unsigned result = m_constantRegisters.size();
321 m_constantRegisters.append(WriteBarrier<Unknown>());
322 m_constantRegisters.last().set(*m_vm, this, v);
323 return result;
324 }
325 unsigned addOrFindConstant(JSValue);
81345200 326 const Vector<WriteBarrier<Unknown>>& constantRegisters() { return m_constantRegisters; }
93a37866
A
327 const WriteBarrier<Unknown>& constantRegister(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
328 ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
329 ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
330
331 // Jumps
332 size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
333 void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
334 unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
335 unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
336
337 void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
338 bool isNumericCompareFunction() const { return m_isNumericCompareFunction; }
339
81345200
A
340 bool isBuiltinFunction() const { return m_isBuiltinFunction; }
341
93a37866
A
342 void shrinkToFit()
343 {
344 m_jumpTargets.shrinkToFit();
345 m_identifiers.shrinkToFit();
346 m_constantRegisters.shrinkToFit();
347 m_functionDecls.shrinkToFit();
348 m_functionExprs.shrinkToFit();
349 m_propertyAccessInstructions.shrinkToFit();
350 m_expressionInfo.shrinkToFit();
351
352#if ENABLE(BYTECODE_COMMENTS)
353 m_bytecodeComments.shrinkToFit();
354#endif
355 if (m_rareData) {
356 m_rareData->m_exceptionHandlers.shrinkToFit();
357 m_rareData->m_regexps.shrinkToFit();
358 m_rareData->m_constantBuffers.shrinkToFit();
81345200 359 m_rareData->m_switchJumpTables.shrinkToFit();
93a37866
A
360 m_rareData->m_stringSwitchJumpTables.shrinkToFit();
361 m_rareData->m_expressionInfoFatPositions.shrinkToFit();
362 }
363 }
364
81345200
A
365 void setInstructions(std::unique_ptr<UnlinkedInstructionStream>);
366 const UnlinkedInstructionStream& instructions() const;
93a37866
A
367
368 int m_numVars;
369 int m_numCapturedVars;
370 int m_numCalleeRegisters;
371
372 // Jump Tables
373
81345200
A
374 size_t numberOfSwitchJumpTables() const { return m_rareData ? m_rareData->m_switchJumpTables.size() : 0; }
375 UnlinkedSimpleJumpTable& addSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_switchJumpTables.append(UnlinkedSimpleJumpTable()); return m_rareData->m_switchJumpTables.last(); }
376 UnlinkedSimpleJumpTable& switchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_switchJumpTables[tableIndex]; }
93a37866
A
377
378 size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
379 UnlinkedStringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(UnlinkedStringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
380 UnlinkedStringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
381
382 unsigned addFunctionDecl(UnlinkedFunctionExecutable* n)
383 {
384 unsigned size = m_functionDecls.size();
385 m_functionDecls.append(WriteBarrier<UnlinkedFunctionExecutable>());
386 m_functionDecls.last().set(*m_vm, this, n);
387 return size;
388 }
389 UnlinkedFunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
390 size_t numberOfFunctionDecls() { return m_functionDecls.size(); }
391 unsigned addFunctionExpr(UnlinkedFunctionExecutable* n)
392 {
393 unsigned size = m_functionExprs.size();
394 m_functionExprs.append(WriteBarrier<UnlinkedFunctionExecutable>());
395 m_functionExprs.last().set(*m_vm, this, n);
396 return size;
397 }
398 UnlinkedFunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
399 size_t numberOfFunctionExprs() { return m_functionExprs.size(); }
400
401 // Exception handling support
402 size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
403 void addExceptionHandler(const UnlinkedHandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); }
404 UnlinkedHandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
405
81345200
A
406 SymbolTable* symbolTable() const { return m_symbolTable.get(); }
407 void setSymbolTable(SymbolTable* table) { m_symbolTable.set(*m_vm, this, table); }
93a37866
A
408
409 VM* vm() const { return m_vm; }
410
93a37866
A
411 UnlinkedArrayProfile addArrayProfile() { return m_arrayProfileCount++; }
412 unsigned numberOfArrayProfiles() { return m_arrayProfileCount; }
413 UnlinkedArrayAllocationProfile addArrayAllocationProfile() { return m_arrayAllocationProfileCount++; }
414 unsigned numberOfArrayAllocationProfiles() { return m_arrayAllocationProfileCount; }
415 UnlinkedObjectAllocationProfile addObjectAllocationProfile() { return m_objectAllocationProfileCount++; }
416 unsigned numberOfObjectAllocationProfiles() { return m_objectAllocationProfileCount; }
417 UnlinkedValueProfile addValueProfile() { return m_valueProfileCount++; }
418 unsigned numberOfValueProfiles() { return m_valueProfileCount; }
419
420 UnlinkedLLIntCallLinkInfo addLLIntCallLinkInfo() { return m_llintCallLinkInfoCount++; }
421 unsigned numberOfLLintCallLinkInfos() { return m_llintCallLinkInfoCount; }
422
423 CodeType codeType() const { return m_codeType; }
424
81345200
A
425 VirtualRegister thisRegister() const { return m_thisRegister; }
426 VirtualRegister activationRegister() const { return m_activationRegister; }
427 bool hasActivationRegister() const { return m_activationRegister.isValid(); }
93a37866
A
428
429 void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
430 {
431 m_propertyAccessInstructions.append(propertyAccessInstruction);
432 }
433
434 size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions.size(); }
435 const Vector<unsigned>& propertyAccessInstructions() const { return m_propertyAccessInstructions; }
436
437 typedef Vector<JSValue> ConstantBuffer;
438
439 size_t constantBufferCount() { ASSERT(m_rareData); return m_rareData->m_constantBuffers.size(); }
440 unsigned addConstantBuffer(unsigned length)
441 {
442 createRareDataIfNecessary();
443 unsigned size = m_rareData->m_constantBuffers.size();
444 m_rareData->m_constantBuffers.append(Vector<JSValue>(length));
445 return size;
446 }
447
448 const ConstantBuffer& constantBuffer(unsigned index) const
449 {
450 ASSERT(m_rareData);
451 return m_rareData->m_constantBuffers[index];
452 }
453
454 ConstantBuffer& constantBuffer(unsigned index)
455 {
456 ASSERT(m_rareData);
457 return m_rareData->m_constantBuffers[index];
458 }
459
460 bool hasRareData() const { return m_rareData; }
461
462 int lineNumberForBytecodeOffset(unsigned bytecodeOffset);
463
464 void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot,
465 int& startOffset, int& endOffset, unsigned& line, unsigned& column);
466
81345200 467 void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned firstLine, unsigned lineCount, unsigned endColumn)
93a37866
A
468 {
469 m_features = features;
470 m_hasCapturedVariables = hasCapturedVariables;
471 m_firstLine = firstLine;
472 m_lineCount = lineCount;
81345200
A
473 // For the UnlinkedCodeBlock, startColumn is always 0.
474 m_endColumn = endColumn;
93a37866
A
475 }
476
477 CodeFeatures codeFeatures() const { return m_features; }
478 bool hasCapturedVariables() const { return m_hasCapturedVariables; }
479 unsigned firstLine() const { return m_firstLine; }
480 unsigned lineCount() const { return m_lineCount; }
81345200
A
481 ALWAYS_INLINE unsigned startColumn() const { return 0; }
482 unsigned endColumn() const { return m_endColumn; }
93a37866 483
81345200 484 void dumpExpressionRangeInfo(); // For debugging purpose only.
93a37866
A
485
486protected:
487 UnlinkedCodeBlock(VM*, Structure*, CodeType, const ExecutableInfo&);
488 ~UnlinkedCodeBlock();
489
490 void finishCreation(VM& vm)
491 {
492 Base::finishCreation(vm);
493 if (codeType() == GlobalCode)
494 return;
81345200 495 m_symbolTable.set(vm, this, SymbolTable::create(vm));
93a37866
A
496 }
497
498private:
499
500 void createRareDataIfNecessary()
501 {
502 if (!m_rareData)
503 m_rareData = adoptPtr(new RareData);
504 }
505
81345200
A
506 void getLineAndColumn(ExpressionRangeInfo&, unsigned& line, unsigned& column);
507
508 std::unique_ptr<UnlinkedInstructionStream> m_unlinkedInstructions;
93a37866
A
509
510 int m_numParameters;
511 VM* m_vm;
512
81345200
A
513 VirtualRegister m_thisRegister;
514 VirtualRegister m_argumentsRegister;
515 VirtualRegister m_activationRegister;
516 VirtualRegister m_globalObjectRegister;
93a37866
A
517
518 bool m_needsFullScopeChain : 1;
519 bool m_usesEval : 1;
520 bool m_isNumericCompareFunction : 1;
521 bool m_isStrictMode : 1;
522 bool m_isConstructor : 1;
523 bool m_hasCapturedVariables : 1;
81345200 524 bool m_isBuiltinFunction : 1;
93a37866
A
525 unsigned m_firstLine;
526 unsigned m_lineCount;
81345200 527 unsigned m_endColumn;
93a37866
A
528
529 CodeFeatures m_features;
530 CodeType m_codeType;
531
532 Vector<unsigned> m_jumpTargets;
533
534 // Constant Pools
535 Vector<Identifier> m_identifiers;
81345200
A
536 Vector<WriteBarrier<Unknown>> m_constantRegisters;
537 typedef Vector<WriteBarrier<UnlinkedFunctionExecutable>> FunctionExpressionVector;
93a37866
A
538 FunctionExpressionVector m_functionDecls;
539 FunctionExpressionVector m_functionExprs;
540
81345200 541 WriteBarrier<SymbolTable> m_symbolTable;
93a37866
A
542
543 Vector<unsigned> m_propertyAccessInstructions;
544
545#if ENABLE(BYTECODE_COMMENTS)
546 Vector<Comment> m_bytecodeComments;
547 size_t m_bytecodeCommentIterator;
548#endif
549
93a37866
A
550 unsigned m_arrayProfileCount;
551 unsigned m_arrayAllocationProfileCount;
552 unsigned m_objectAllocationProfileCount;
553 unsigned m_valueProfileCount;
554 unsigned m_llintCallLinkInfoCount;
555
556public:
557 struct RareData {
558 WTF_MAKE_FAST_ALLOCATED;
559 public:
560 Vector<UnlinkedHandlerInfo> m_exceptionHandlers;
561
562 // Rare Constants
81345200 563 Vector<WriteBarrier<RegExp>> m_regexps;
93a37866
A
564
565 // Buffers used for large array literals
566 Vector<ConstantBuffer> m_constantBuffers;
567
568 // Jump Tables
81345200 569 Vector<UnlinkedSimpleJumpTable> m_switchJumpTables;
93a37866 570 Vector<UnlinkedStringJumpTable> m_stringSwitchJumpTables;
93a37866
A
571
572 Vector<ExpressionRangeInfo::FatPosition> m_expressionInfoFatPositions;
573 };
574
575private:
576 OwnPtr<RareData> m_rareData;
577 Vector<ExpressionRangeInfo> m_expressionInfo;
578
579protected:
580
81345200 581 static const unsigned StructureFlags = OverridesVisitChildren | StructureIsImmortal | Base::StructureFlags;
93a37866
A
582 static void visitChildren(JSCell*, SlotVisitor&);
583
584public:
81345200 585 DECLARE_INFO;
93a37866
A
586};
587
588class UnlinkedGlobalCodeBlock : public UnlinkedCodeBlock {
589public:
590 typedef UnlinkedCodeBlock Base;
591
592protected:
593 UnlinkedGlobalCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
594 : Base(vm, structure, codeType, info)
595 {
596 }
597
598 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
599
81345200 600 DECLARE_INFO;
93a37866
A
601};
602
603class UnlinkedProgramCodeBlock : public UnlinkedGlobalCodeBlock {
604private:
605 friend class CodeCache;
606 static UnlinkedProgramCodeBlock* create(VM* vm, const ExecutableInfo& info)
607 {
608 UnlinkedProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedProgramCodeBlock>(vm->heap)) UnlinkedProgramCodeBlock(vm, vm->unlinkedProgramCodeBlockStructure.get(), info);
609 instance->finishCreation(*vm);
610 return instance;
611 }
612
613public:
614 typedef UnlinkedGlobalCodeBlock Base;
615 static void destroy(JSCell*);
616
617 void addFunctionDeclaration(VM& vm, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable)
618 {
619 m_functionDeclarations.append(std::make_pair(name, WriteBarrier<UnlinkedFunctionExecutable>(vm, this, functionExecutable)));
620 }
621
622 void addVariableDeclaration(const Identifier& name, bool isConstant)
623 {
624 m_varDeclarations.append(std::make_pair(name, isConstant));
625 }
626
81345200
A
627 typedef Vector<std::pair<Identifier, bool>> VariableDeclations;
628 typedef Vector<std::pair<Identifier, WriteBarrier<UnlinkedFunctionExecutable>> > FunctionDeclations;
93a37866
A
629
630 const VariableDeclations& variableDeclarations() const { return m_varDeclarations; }
631 const FunctionDeclations& functionDeclarations() const { return m_functionDeclarations; }
632
633 static void visitChildren(JSCell*, SlotVisitor&);
634
635private:
636 UnlinkedProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info)
637 : Base(vm, structure, GlobalCode, info)
638 {
639 }
640
641 VariableDeclations m_varDeclarations;
642 FunctionDeclations m_functionDeclarations;
643
644public:
645 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
646 {
81345200 647 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedProgramCodeBlockType, StructureFlags), info());
93a37866
A
648 }
649
650 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
651
81345200 652 DECLARE_INFO;
93a37866
A
653};
654
655class UnlinkedEvalCodeBlock : public UnlinkedGlobalCodeBlock {
656private:
657 friend class CodeCache;
658
659 static UnlinkedEvalCodeBlock* create(VM* vm, const ExecutableInfo& info)
660 {
661 UnlinkedEvalCodeBlock* instance = new (NotNull, allocateCell<UnlinkedEvalCodeBlock>(vm->heap)) UnlinkedEvalCodeBlock(vm, vm->unlinkedEvalCodeBlockStructure.get(), info);
662 instance->finishCreation(*vm);
663 return instance;
664 }
665
666public:
667 typedef UnlinkedGlobalCodeBlock Base;
668 static void destroy(JSCell*);
669
670 const Identifier& variable(unsigned index) { return m_variables[index]; }
671 unsigned numVariables() { return m_variables.size(); }
672 void adoptVariables(Vector<Identifier, 0, UnsafeVectorOverflow>& variables)
673 {
674 ASSERT(m_variables.isEmpty());
675 m_variables.swap(variables);
676 }
677
678private:
679 UnlinkedEvalCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info)
680 : Base(vm, structure, EvalCode, info)
681 {
682 }
683
684 Vector<Identifier, 0, UnsafeVectorOverflow> m_variables;
685
686public:
687 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
688 {
81345200 689 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedEvalCodeBlockType, StructureFlags), info());
93a37866
A
690 }
691
692 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
693
81345200 694 DECLARE_INFO;
93a37866
A
695};
696
697class UnlinkedFunctionCodeBlock : public UnlinkedCodeBlock {
698public:
699 static UnlinkedFunctionCodeBlock* create(VM* vm, CodeType codeType, const ExecutableInfo& info)
700 {
701 UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(vm->heap)) UnlinkedFunctionCodeBlock(vm, vm->unlinkedFunctionCodeBlockStructure.get(), codeType, info);
702 instance->finishCreation(*vm);
703 return instance;
704 }
705
706 typedef UnlinkedCodeBlock Base;
707 static void destroy(JSCell*);
708
709private:
710 UnlinkedFunctionCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
711 : Base(vm, structure, codeType, info)
712 {
713 }
714
715public:
716 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
717 {
81345200 718 return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionCodeBlockType, StructureFlags), info());
93a37866
A
719 }
720
721 static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
722
81345200 723 DECLARE_INFO;
93a37866
A
724};
725
726}
727
728#endif // UnlinkedCodeBlock_h