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