source: webkit/trunk/JavaScriptCore/parser/Nodes.h@ 43642

Last change on this file since 43642 was 43642, checked in by Darin Adler, 16 years ago

JavaScriptCore:

2009-05-13 Darin Adler <Darin Adler>

Reviewed by Cameron Zwarich.

Bug 25674: syntax tree nodes should use arena allocation
https://bugs.webkit.org/show_bug.cgi?id=25674

Step 3: Add some actual arena allocation. About 1% SunSpider speedup.

  • bytecompiler/BytecodeGenerator.cpp: (JSC::BytecodeGenerator::BytecodeGenerator): Updated since VarStack contains const Identifier* now. (JSC::BytecodeGenerator::emitPushNewScope): Updated to take a const Identifier&.
  • bytecompiler/BytecodeGenerator.h: Ditto
  • bytecompiler/SegmentedVector.h: Added isEmpty.
  • debugger/Debugger.cpp: (JSC::Debugger::recompileAllJSFunctions): Moved this function here from WebCore so WebCore doesn't need the details of FunctionBodyNode.
  • debugger/Debugger.h: Ditto.
  • interpreter/Interpreter.cpp: (JSC::Interpreter::execute): Updated since VarStack contains const Identifier* now.
  • jit/JITStubs.cpp: (JSC::JITStubs::cti_vm_lazyLinkCall): Call isHostFunction on the body rather than on the function object, since we can't easily have inlined access to the FunctionBodyNode in JSFunction.h since WebCore needs access to that header. (JSC::JITStubs::cti_op_construct_JSConstruct): Ditto.
  • profiler/Profiler.cpp: (JSC::Profiler::createCallIdentifier): Ditto.
  • parser/Grammar.y: Use JSGlobalData* to pass the global data pointer around whenever possible instead of using void*. Changed SET_EXCEPTION_LOCATION from a macro to an inline function. Marked the structure-creating functions inline. Changed the VarStack to use identifier pointers instead of actual identifiers. This takes advantage of the fact that all identifier pointers come from the arena and avoids referenc count churn. Changed Identifier* to const Identifier* to make sure we don't modify any by accident. Used identifiers for regular expression strings too, using the new scanRegExp that has out parameters instead of the old one that relied on side effects in the Lexer. Move the creation of numeric identifiers out of this file and into the PropertyNode constructor.
  • parser/Lexer.cpp: (JSC::Lexer::setCode): Pass in ParserArena, used for identifiers. (JSC::Lexer::makeIdentifier): Changed return type to const Identifier* and changed to call ParserArena. (JSC::Lexer::scanRegExp): Added out arguments that are const Identifier* as well as a prefix character argument so we can handle the /= case without a string append. (JSC::Lexer::skipRegExp): Added. Skips a regular expression without allocating Identifier objects. (JSC::Lexer::clear): Removed the code to manage m_identifiers, m_pattern, and m_flags, and added code to set m_arena to 0.
  • parser/Lexer.h: Updated for changes above.
  • parser/NodeConstructors.h: (JSC::ParserArenaFreeable::operator new): Added. Calls allocateFreeable on the arena. (JSC::ParserArenaDeletable::operator new): Changed to call the allocateDeletable function on the arena instead of deleteWithArena. (JSC::RegExpNode::RegExpNode): Changed arguments to Identifier instead of UString since these come from the parser which makes identifiers. (JSC::PropertyNode::PropertyNode): Added new constructor that makes numeric identifiers. Some day we might want to optimize this for integers so it doesn't create a string for each one. (JSC::ContinueNode::ContinueNode): Initialize m_ident to nullIdentifier since it's now a const Identifier& so it can't be left uninitialized. (JSC::BreakNode::BreakNode): Ditto. (JSC::CaseClauseNode::CaseClauseNode): Updated to use SourceElements* to keep track of the statements rather than a separate statement vector. (JSC::BlockNode::BlockNode): Ditto. (JSC::ForInNode::ForInNode): Initialize m_ident to nullIdentifier.
  • parser/Nodes.cpp: Moved the comment explaining emitBytecode in here. It seemed strangely out of place in the header. (JSC::ThrowableExpressionData::emitThrowError): Added an overload for UString as well as Identifier. (JSC::SourceElements::singleStatement): Added. (JSC::SourceElements::lastStatement): Added. (JSC::RegExpNode::emitBytecode): Updated since the pattern and flags are now Identifier instead of UString. Also changed the throwError code to use the substitution mechanism instead of doing a string append. (JSC::SourceElements::emitBytecode): Added. Replaces the old statementListEmitCode function, since we now keep the SourceElements objects around. (JSC::BlockNode::lastStatement): Added. (JSC::BlockNode::emitBytecode): Changed to use emitBytecode instead of statementListEmitCode. (JSC::CaseClauseNode::emitBytecode): Added. (JSC::CaseBlockNode::emitBytecodeForBlock): Changed to use emitBytecode instead of statementListEmitCode. (JSC::ScopeNodeData::ScopeNodeData): Changed to store the SourceElements* instead of using releaseContentsIntoVector. (JSC::ScopeNode::emitStatementsBytecode): Added. (JSC::ScopeNode::singleStatement): Added. (JSC::ProgramNode::emitBytecode): Call emitStatementsBytecode instead of statementListEmitCode. (JSC::EvalNode::emitBytecode): Ditto. (JSC::EvalNode::generateBytecode): Removed code to clear the children vector. This optimization is no longer possible since everything is in a single arena. (JSC::FunctionBodyNode::emitBytecode): Call emitStatementsBytecode insetad of statementListEmitCode and check for the return node using the new functions.
  • parser/Nodes.h: Changed VarStack to store const Identifier* instead of Identifier and rely on the arena to control lifetime. Added a new ParserArenaFreeable class. Made ParserArenaDeletable inherit from FastAllocBase instead of having its own operator new. Base the Node class on ParserArenaFreeable. Changed the various Node classes to use const Identifier& instead of Identifier to avoid the need to call their destructors and allow them to function as "freeable" in the arena. Removed extraneous JSC_FAST_CALL on definitions of inline functions. Changed ElementNode, PropertyNode, ArgumentsNode, ParameterNode, CaseClauseNode, ClauseListNode, and CaseBlockNode to use ParserArenaFreeable as a base class since they do not descend from Node. Eliminated the StatementVector type and instead have various classes use SourceElements* instead of StatementVector. This prevents those classes from having th use ParserArenaDeletable to make sure the vector destructor is called.
  • parser/Parser.cpp: (JSC::Parser::parse): Pass the arena to the lexer.
  • parser/Parser.h: Added an include of ParserArena.h, which is no longer included by Nodes.h.
  • parser/ParserArena.cpp: (JSC::ParserArena::ParserArena): Added. Initializes the new members, m_freeableMemory, m_freeablePoolEnd, and m_identifiers. (JSC::ParserArena::freeablePool): Added. Computes the pool pointer, since we store only the current pointer and the end of pool pointer. (JSC::ParserArena::deallocateObjects): Added. Contains the common memory-deallocation logic used by both the destructor and the reset function. (JSC::ParserArena::~ParserArena): Changed to call deallocateObjects. (JSC::ParserArena::reset): Ditto. Also added code to zero out the new structures, and switched to use clear() instead of shrink(0) since we don't really reuse arenas. (JSC::ParserArena::makeNumericIdentifier): Added. (JSC::ParserArena::allocateFreeablePool): Added. Used when the pool is empty. (JSC::ParserArena::isEmpty): Added. No longer inline, which is fine since this is used only for assertions at the moment.
  • parser/ParserArena.h: Added an actual arena of "freeable" objects, ones that don't need destructors to be called. Also added the segmented vector of identifiers that used to be in the Lexer.
  • runtime/FunctionConstructor.cpp: (JSC::extractFunctionBody): Use singleStatement function rather than getting at a StatementVector.
  • runtime/FunctionPrototype.cpp: (JSC::functionProtoFuncToString): Call isHostFunction on the body rather than the function object.
  • runtime/JSFunction.cpp: (JSC::JSFunction::JSFunction): Moved the structure version of this in here from the header. It's not hot enough that it needs to be inlined. (JSC::JSFunction::isHostFunction): Moved this in here from the header. It's now a helper to be used only within the class. (JSC::JSFunction::setBody): Moved this in here. It's not hot enough that it needs to be inlined, and we want to be able to compile the header without the definition of FunctionBodyNode.
  • runtime/JSFunction.h: Eliminated the include of "Nodes.h". This was exposing too much JavaScriptCore dependency to WebCore. Because of this change and some changes made to WebCore, we could now export a lot fewer headers from JavaScriptCore, but I have not done that yet in this check-in. Made a couple functions non-inline. Removes some isHostFunction() assertions.


  • wtf/FastAllocBase.h: Added the conventional using statements we use in WTF so we can use identifiers from the WTF namespace without explicit namespace qualification or namespace directive. This is the usual WTF style, although it's unconventional in the C++ world. We use the namespace primarily for link-time disambiguation, not compile-time.
  • wtf/FastMalloc.cpp: Fixed an incorrect comment.

WebCore:

2009-05-13 Darin Adler <Darin Adler>

Reviewed by Cameron Zwarich.

Bug 25674: syntax tree nodes should use arena allocation
https://bugs.webkit.org/show_bug.cgi?id=25674

  • bindings/js/JSDOMBinding.h: Removed include of JSFunction.h. We don't want the entire DOM binding to depend on that file.
  • bindings/js/JSAudioConstructor.cpp: Added include of Error.h. Before we inherited this automatically because JDDOMBinding.h included JSFunction.h, but that was excessive.
  • bindings/js/JSDOMWindowCustom.cpp: Ditto.
  • bindings/js/JSHTMLInputElementCustom.cpp: Ditto.
  • bindings/js/JSImageConstructor.cpp: Ditto.
  • bindings/js/JSLazyEventListener.cpp: Ditto, but for JSFunction.h.
  • bindings/js/JSMessageChannelConstructor.cpp: Ditto.
  • bindings/js/JSOptionConstructor.cpp: Ditto.
  • bindings/js/JSWorkerConstructor.cpp: Ditto.
  • bindings/js/JSXMLHttpRequestConstructor.cpp: Ditto.
  • bridge/jni/jni_jsobject.mm: Ditto, but for SourceCode.h.
  • inspector/InspectorController.cpp: Ditto.
  • inspector/JavaScriptDebugServer.cpp: (WebCore::JavaScriptDebugServer::recompileAllJSFunctions): Moved mose of this function into the base class in JavaScriptCore, so the details of compilation don't have to be exposed.

WebKit/mac:

2009-05-13 Darin Adler <Darin Adler>

Reviewed by Cameron Zwarich.

Bug 25674: syntax tree nodes should use arena allocation
https://bugs.webkit.org/show_bug.cgi?id=25674

  • Plugins/Hosted/NetscapePluginInstanceProxy.mm: Updated includes. New ones needed due to reducing includes of JSDOMBinding.h.
  • WebView/WebScriptDebugger.mm: Ditto.
  • Property svn:eol-style set to native
File size: 55.7 KB
Line 
1/*
2 * Copyright (C) 1999-2000 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Cameron Zwarich ([email protected])
6 * Copyright (C) 2007 Maks Orlovich
7 * Copyright (C) 2007 Eric Seidel <[email protected]>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 *
24 */
25
26#ifndef Nodes_h
27#define Nodes_h
28
29#include "Error.h"
30#include "JITCode.h"
31#include "Opcode.h"
32#include "ParserArena.h"
33#include "ResultType.h"
34#include "SourceCode.h"
35#include "SymbolTable.h"
36#include <wtf/FastAllocBase.h>
37#include <wtf/MathExtras.h>
38#include <wtf/OwnPtr.h>
39
40#if PLATFORM(X86) && COMPILER(GCC)
41#define JSC_FAST_CALL __attribute__((regparm(3)))
42#else
43#define JSC_FAST_CALL
44#endif
45
46namespace JSC {
47
48 class ArgumentListNode;
49 class CodeBlock;
50 class BytecodeGenerator;
51 class FuncDeclNode;
52 class EvalCodeBlock;
53 class JSFunction;
54 class ProgramCodeBlock;
55 class PropertyListNode;
56 class ReadModifyResolveNode;
57 class RegisterID;
58 class ScopeChainNode;
59
60 typedef unsigned CodeFeatures;
61
62 const CodeFeatures NoFeatures = 0;
63 const CodeFeatures EvalFeature = 1 << 0;
64 const CodeFeatures ClosureFeature = 1 << 1;
65 const CodeFeatures AssignFeature = 1 << 2;
66 const CodeFeatures ArgumentsFeature = 1 << 3;
67 const CodeFeatures WithFeature = 1 << 4;
68 const CodeFeatures CatchFeature = 1 << 5;
69 const CodeFeatures ThisFeature = 1 << 6;
70 const CodeFeatures AllFeatures = EvalFeature | ClosureFeature | AssignFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature;
71
72 enum Operator {
73 OpEqual,
74 OpPlusEq,
75 OpMinusEq,
76 OpMultEq,
77 OpDivEq,
78 OpPlusPlus,
79 OpMinusMinus,
80 OpAndEq,
81 OpXOrEq,
82 OpOrEq,
83 OpModEq,
84 OpLShift,
85 OpRShift,
86 OpURShift
87 };
88
89 enum LogicalOperator {
90 OpLogicalAnd,
91 OpLogicalOr
92 };
93
94 namespace DeclarationStacks {
95 enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
96 typedef Vector<std::pair<const Identifier*, unsigned> > VarStack;
97 typedef Vector<FuncDeclNode*> FunctionStack;
98 }
99
100 struct SwitchInfo {
101 enum SwitchType { SwitchNone, SwitchImmediate, SwitchCharacter, SwitchString };
102 uint32_t bytecodeOffset;
103 SwitchType switchType;
104 };
105
106 class ParserArenaFreeable : public FastAllocBase {
107 public:
108 using FastAllocBase::operator new;
109
110 // Objects created with this version of new are freed when the arena is deleted.
111 // Destructors are not called. Clients must not call delete on such objects.
112 void* operator new(size_t, JSGlobalData*);
113 };
114
115 class ParserArenaDeletable : public FastAllocBase {
116 public:
117 virtual ~ParserArenaDeletable() { }
118
119 using FastAllocBase::operator new;
120
121 // Objects created with this version of new are deleted when the arena is deleted.
122 // Clients must not call delete directly on such objects.
123 void* operator new(size_t, JSGlobalData*);
124 };
125
126 class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> {
127 protected:
128 ParserArenaRefCounted(JSGlobalData*);
129
130 public:
131 virtual ~ParserArenaRefCounted()
132 {
133 ASSERT(deletionHasBegun());
134 }
135 };
136
137 class Node : public ParserArenaFreeable {
138 protected:
139 Node(JSGlobalData*);
140
141 public:
142 virtual ~Node() { }
143
144 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0) JSC_FAST_CALL = 0;
145
146 int lineNo() const { return m_line; }
147
148 protected:
149 int m_line;
150 };
151
152 class ExpressionNode : public Node {
153 public:
154 ExpressionNode(JSGlobalData*, ResultType = ResultType::unknownType());
155
156 virtual bool isNumber() const JSC_FAST_CALL { return false; }
157 virtual bool isString() const JSC_FAST_CALL { return false; }
158 virtual bool isNull() const JSC_FAST_CALL { return false; }
159 virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return false; }
160 virtual bool isLocation() const JSC_FAST_CALL { return false; }
161 virtual bool isResolveNode() const JSC_FAST_CALL { return false; }
162 virtual bool isBracketAccessorNode() const JSC_FAST_CALL { return false; }
163 virtual bool isDotAccessorNode() const JSC_FAST_CALL { return false; }
164 virtual bool isFuncExprNode() const JSC_FAST_CALL { return false; }
165 virtual bool isSimpleArray() const JSC_FAST_CALL { return false; }
166 virtual bool isAdd() const JSC_FAST_CALL { return false; }
167
168 virtual ExpressionNode* stripUnaryPlus() { return this; }
169
170 ResultType resultDescriptor() const JSC_FAST_CALL { return m_resultType; }
171
172 // This needs to be in public in order to compile using GCC 3.x
173 typedef enum { EvalOperator, FunctionCall } CallerType;
174
175 private:
176 ResultType m_resultType;
177 };
178
179 class StatementNode : public Node {
180 public:
181 StatementNode(JSGlobalData*);
182
183 void setLoc(int line0, int line1) JSC_FAST_CALL;
184 int firstLine() const JSC_FAST_CALL { return lineNo(); }
185 int lastLine() const JSC_FAST_CALL { return m_lastLine; }
186
187 virtual bool isEmptyStatement() const JSC_FAST_CALL { return false; }
188 virtual bool isReturnNode() const JSC_FAST_CALL { return false; }
189 virtual bool isExprStatement() const JSC_FAST_CALL { return false; }
190
191 virtual bool isBlock() const JSC_FAST_CALL { return false; }
192
193 private:
194 int m_lastLine;
195 };
196
197 class NullNode : public ExpressionNode {
198 public:
199 NullNode(JSGlobalData*);
200
201 private:
202 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
203
204 virtual bool isNull() const JSC_FAST_CALL { return true; }
205 };
206
207 class BooleanNode : public ExpressionNode {
208 public:
209 BooleanNode(JSGlobalData*, bool value);
210
211 private:
212 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
213
214 virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; }
215
216 bool m_value;
217 };
218
219 class NumberNode : public ExpressionNode {
220 public:
221 NumberNode(JSGlobalData*, double v);
222
223 double value() const JSC_FAST_CALL { return m_double; }
224 void setValue(double d) JSC_FAST_CALL { m_double = d; }
225
226 private:
227 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
228
229 virtual bool isNumber() const JSC_FAST_CALL { return true; }
230 virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; }
231
232 double m_double;
233 };
234
235 class StringNode : public ExpressionNode {
236 public:
237 StringNode(JSGlobalData*, const Identifier&);
238
239 const Identifier& value() { return m_value; }
240
241 virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL { return true; }
242
243 private:
244 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
245
246 virtual bool isString() const JSC_FAST_CALL { return true; }
247
248 const Identifier& m_value;
249 };
250
251 class ThrowableExpressionData {
252 public:
253 ThrowableExpressionData()
254 : m_divot(static_cast<uint32_t>(-1))
255 , m_startOffset(static_cast<uint16_t>(-1))
256 , m_endOffset(static_cast<uint16_t>(-1))
257 {
258 }
259
260 ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
261 : m_divot(divot)
262 , m_startOffset(startOffset)
263 , m_endOffset(endOffset)
264 {
265 }
266
267 void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset)
268 {
269 m_divot = divot;
270 m_startOffset = startOffset;
271 m_endOffset = endOffset;
272 }
273
274 uint32_t divot() const { return m_divot; }
275 uint16_t startOffset() const { return m_startOffset; }
276 uint16_t endOffset() const { return m_endOffset; }
277
278 protected:
279 RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg);
280 RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg, const UString&);
281 RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* msg, const Identifier&);
282
283 private:
284 uint32_t m_divot;
285 uint16_t m_startOffset;
286 uint16_t m_endOffset;
287 };
288
289 class ThrowableSubExpressionData : public ThrowableExpressionData {
290 public:
291 ThrowableSubExpressionData()
292 : ThrowableExpressionData()
293 , m_subexpressionDivotOffset(0)
294 , m_subexpressionEndOffset(0)
295 {
296 }
297
298 ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
299 : ThrowableExpressionData(divot, startOffset, endOffset)
300 , m_subexpressionDivotOffset(0)
301 , m_subexpressionEndOffset(0)
302 {
303 }
304
305 void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
306 {
307 ASSERT(subexpressionDivot <= divot());
308 if ((divot() - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
309 return;
310 m_subexpressionDivotOffset = divot() - subexpressionDivot;
311 m_subexpressionEndOffset = subexpressionOffset;
312 }
313
314 protected:
315 uint16_t m_subexpressionDivotOffset;
316 uint16_t m_subexpressionEndOffset;
317 };
318
319 class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
320 public:
321 ThrowablePrefixedSubExpressionData()
322 : ThrowableExpressionData()
323 , m_subexpressionDivotOffset(0)
324 , m_subexpressionStartOffset(0)
325 {
326 }
327
328 ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
329 : ThrowableExpressionData(divot, startOffset, endOffset)
330 , m_subexpressionDivotOffset(0)
331 , m_subexpressionStartOffset(0)
332 {
333 }
334
335 void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
336 {
337 ASSERT(subexpressionDivot >= divot());
338 if ((subexpressionDivot - divot()) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
339 return;
340 m_subexpressionDivotOffset = subexpressionDivot - divot();
341 m_subexpressionStartOffset = subexpressionOffset;
342 }
343
344 protected:
345 uint16_t m_subexpressionDivotOffset;
346 uint16_t m_subexpressionStartOffset;
347 };
348
349 class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
350 public:
351 RegExpNode(JSGlobalData*, const Identifier& pattern, const Identifier& flags);
352
353 private:
354 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
355
356 const Identifier& m_pattern;
357 const Identifier& m_flags;
358 };
359
360 class ThisNode : public ExpressionNode {
361 public:
362 ThisNode(JSGlobalData*);
363
364 private:
365 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
366 };
367
368 class ResolveNode : public ExpressionNode {
369 public:
370 ResolveNode(JSGlobalData*, const Identifier&, int startOffset);
371
372 const Identifier& identifier() const { return m_ident; }
373
374 private:
375 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
376
377 virtual bool isPure(BytecodeGenerator&) const JSC_FAST_CALL;
378 virtual bool isLocation() const JSC_FAST_CALL { return true; }
379 virtual bool isResolveNode() const JSC_FAST_CALL { return true; }
380
381 const Identifier& m_ident;
382 int32_t m_startOffset;
383 };
384
385 class ElementNode : public ParserArenaFreeable {
386 public:
387 ElementNode(JSGlobalData*, int elision, ExpressionNode*);
388 ElementNode(JSGlobalData*, ElementNode*, int elision, ExpressionNode*);
389
390 int elision() const { return m_elision; }
391 ExpressionNode* value() { return m_node; }
392 ElementNode* next() { return m_next; }
393
394 private:
395 ElementNode* m_next;
396 int m_elision;
397 ExpressionNode* m_node;
398 };
399
400 class ArrayNode : public ExpressionNode {
401 public:
402 ArrayNode(JSGlobalData*, int elision);
403 ArrayNode(JSGlobalData*, ElementNode*);
404 ArrayNode(JSGlobalData*, int elision, ElementNode*);
405
406 ArgumentListNode* toArgumentList(JSGlobalData*) const;
407
408 private:
409 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
410
411 virtual bool isSimpleArray() const JSC_FAST_CALL;
412
413 ElementNode* m_element;
414 int m_elision;
415 bool m_optional;
416 };
417
418 class PropertyNode : public ParserArenaFreeable {
419 public:
420 enum Type { Constant, Getter, Setter };
421
422 PropertyNode(JSGlobalData*, const Identifier& name, ExpressionNode* value, Type);
423 PropertyNode(JSGlobalData*, double name, ExpressionNode* value, Type);
424
425 const Identifier& name() const { return m_name; }
426
427 private:
428 friend class PropertyListNode;
429 const Identifier& m_name;
430 ExpressionNode* m_assign;
431 Type m_type;
432 };
433
434 class PropertyListNode : public Node {
435 public:
436 PropertyListNode(JSGlobalData*, PropertyNode*);
437 PropertyListNode(JSGlobalData*, PropertyNode*, PropertyListNode*);
438
439 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
440
441 private:
442 PropertyNode* m_node;
443 PropertyListNode* m_next;
444 };
445
446 class ObjectLiteralNode : public ExpressionNode {
447 public:
448 ObjectLiteralNode(JSGlobalData*);
449 ObjectLiteralNode(JSGlobalData*, PropertyListNode*);
450
451 private:
452 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
453
454 PropertyListNode* m_list;
455 };
456
457 class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
458 public:
459 BracketAccessorNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
460
461 ExpressionNode* base() const { return m_base; }
462 ExpressionNode* subscript() const { return m_subscript; }
463
464 private:
465 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
466
467 virtual bool isLocation() const JSC_FAST_CALL { return true; }
468 virtual bool isBracketAccessorNode() const JSC_FAST_CALL { return true; }
469
470 ExpressionNode* m_base;
471 ExpressionNode* m_subscript;
472 bool m_subscriptHasAssignments;
473 };
474
475 class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
476 public:
477 DotAccessorNode(JSGlobalData*, ExpressionNode* base, const Identifier&);
478
479 ExpressionNode* base() const { return m_base; }
480 const Identifier& identifier() const { return m_ident; }
481
482 private:
483 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
484
485 virtual bool isLocation() const JSC_FAST_CALL { return true; }
486 virtual bool isDotAccessorNode() const JSC_FAST_CALL { return true; }
487
488 ExpressionNode* m_base;
489 const Identifier& m_ident;
490 };
491
492 class ArgumentListNode : public Node {
493 public:
494 ArgumentListNode(JSGlobalData*, ExpressionNode*);
495 ArgumentListNode(JSGlobalData*, ArgumentListNode*, ExpressionNode*);
496
497 ArgumentListNode* m_next;
498 ExpressionNode* m_expr;
499
500 private:
501 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
502 };
503
504 class ArgumentsNode : public ParserArenaFreeable {
505 public:
506 ArgumentsNode(JSGlobalData*);
507 ArgumentsNode(JSGlobalData*, ArgumentListNode*);
508
509 ArgumentListNode* m_listNode;
510 };
511
512 class NewExprNode : public ExpressionNode, public ThrowableExpressionData {
513 public:
514 NewExprNode(JSGlobalData*, ExpressionNode*);
515 NewExprNode(JSGlobalData*, ExpressionNode*, ArgumentsNode*);
516
517 private:
518 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
519
520 ExpressionNode* m_expr;
521 ArgumentsNode* m_args;
522 };
523
524 class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
525 public:
526 EvalFunctionCallNode(JSGlobalData*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
527
528 private:
529 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
530
531 ArgumentsNode* m_args;
532 };
533
534 class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
535 public:
536 FunctionCallValueNode(JSGlobalData*, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
537
538 private:
539 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
540
541 ExpressionNode* m_expr;
542 ArgumentsNode* m_args;
543 };
544
545 class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
546 public:
547 FunctionCallResolveNode(JSGlobalData*, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
548
549 private:
550 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
551
552 const Identifier& m_ident;
553 ArgumentsNode* m_args;
554 size_t m_index; // Used by LocalVarFunctionCallNode.
555 size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode
556 };
557
558 class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
559 public:
560 FunctionCallBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
561
562 private:
563 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
564
565 ExpressionNode* m_base;
566 ExpressionNode* m_subscript;
567 ArgumentsNode* m_args;
568 };
569
570 class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
571 public:
572 FunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
573
574 private:
575 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
576
577 protected:
578 ExpressionNode* m_base;
579 const Identifier& m_ident;
580 ArgumentsNode* m_args;
581 };
582
583 class CallFunctionCallDotNode : public FunctionCallDotNode {
584 public:
585 CallFunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
586
587 private:
588 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
589 };
590
591 class ApplyFunctionCallDotNode : public FunctionCallDotNode {
592 public:
593 ApplyFunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
594
595 private:
596 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
597 };
598
599 class PrePostResolveNode : public ExpressionNode, public ThrowableExpressionData {
600 public:
601 PrePostResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
602
603 protected:
604 const Identifier& m_ident;
605 };
606
607 class PostfixResolveNode : public PrePostResolveNode {
608 public:
609 PostfixResolveNode(JSGlobalData*, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
610
611 private:
612 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
613
614 Operator m_operator;
615 };
616
617 class PostfixBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
618 public:
619 PostfixBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
620
621 private:
622 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
623
624 ExpressionNode* m_base;
625 ExpressionNode* m_subscript;
626 Operator m_operator;
627 };
628
629 class PostfixDotNode : public ExpressionNode, public ThrowableSubExpressionData {
630 public:
631 PostfixDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
632
633 private:
634 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
635
636 ExpressionNode* m_base;
637 const Identifier& m_ident;
638 Operator m_operator;
639 };
640
641 class PostfixErrorNode : public ExpressionNode, public ThrowableSubExpressionData {
642 public:
643 PostfixErrorNode(JSGlobalData*, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
644
645 private:
646 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
647
648 ExpressionNode* m_expr;
649 Operator m_operator;
650 };
651
652 class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
653 public:
654 DeleteResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
655
656 private:
657 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
658
659 const Identifier& m_ident;
660 };
661
662 class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
663 public:
664 DeleteBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset);
665
666 private:
667 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
668
669 ExpressionNode* m_base;
670 ExpressionNode* m_subscript;
671 };
672
673 class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
674 public:
675 DeleteDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
676
677 private:
678 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
679
680 ExpressionNode* m_base;
681 const Identifier& m_ident;
682 };
683
684 class DeleteValueNode : public ExpressionNode {
685 public:
686 DeleteValueNode(JSGlobalData*, ExpressionNode*);
687
688 private:
689 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
690
691 ExpressionNode* m_expr;
692 };
693
694 class VoidNode : public ExpressionNode {
695 public:
696 VoidNode(JSGlobalData*, ExpressionNode*);
697
698 private:
699 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
700
701 ExpressionNode* m_expr;
702 };
703
704 class TypeOfResolveNode : public ExpressionNode {
705 public:
706 TypeOfResolveNode(JSGlobalData*, const Identifier&);
707
708 const Identifier& identifier() const { return m_ident; }
709
710 private:
711 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
712
713 const Identifier& m_ident;
714 };
715
716 class TypeOfValueNode : public ExpressionNode {
717 public:
718 TypeOfValueNode(JSGlobalData*, ExpressionNode*);
719
720 private:
721 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
722
723 ExpressionNode* m_expr;
724 };
725
726 class PrefixResolveNode : public PrePostResolveNode {
727 public:
728 PrefixResolveNode(JSGlobalData*, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
729
730 private:
731 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
732
733 Operator m_operator;
734 };
735
736 class PrefixBracketNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
737 public:
738 PrefixBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
739
740 private:
741 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
742
743 ExpressionNode* m_base;
744 ExpressionNode* m_subscript;
745 Operator m_operator;
746 };
747
748 class PrefixDotNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
749 public:
750 PrefixDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
751
752 private:
753 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
754
755 ExpressionNode* m_base;
756 const Identifier& m_ident;
757 Operator m_operator;
758 };
759
760 class PrefixErrorNode : public ExpressionNode, public ThrowableExpressionData {
761 public:
762 PrefixErrorNode(JSGlobalData*, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
763
764 private:
765 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
766
767 ExpressionNode* m_expr;
768 Operator m_operator;
769 };
770
771 class UnaryOpNode : public ExpressionNode {
772 public:
773 UnaryOpNode(JSGlobalData*, ResultType, ExpressionNode*, OpcodeID);
774
775 protected:
776 ExpressionNode* expr() { return m_expr; }
777
778 private:
779 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
780
781 OpcodeID opcodeID() const { return m_opcodeID; }
782
783 ExpressionNode* m_expr;
784 OpcodeID m_opcodeID;
785 };
786
787 class UnaryPlusNode : public UnaryOpNode {
788 public:
789 UnaryPlusNode(JSGlobalData*, ExpressionNode*);
790
791 private:
792 virtual ExpressionNode* stripUnaryPlus() { return expr(); }
793 };
794
795 class NegateNode : public UnaryOpNode {
796 public:
797 NegateNode(JSGlobalData*, ExpressionNode*);
798 };
799
800 class BitwiseNotNode : public UnaryOpNode {
801 public:
802 BitwiseNotNode(JSGlobalData*, ExpressionNode*);
803 };
804
805 class LogicalNotNode : public UnaryOpNode {
806 public:
807 LogicalNotNode(JSGlobalData*, ExpressionNode*);
808 };
809
810 class BinaryOpNode : public ExpressionNode {
811 public:
812 BinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
813 BinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
814
815 RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* dst, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
816
817 private:
818 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
819
820 protected:
821 OpcodeID opcodeID() const { return m_opcodeID; }
822
823 protected:
824 ExpressionNode* m_expr1;
825 ExpressionNode* m_expr2;
826 private:
827 OpcodeID m_opcodeID;
828 protected:
829 bool m_rightHasAssignments;
830 };
831
832 class ReverseBinaryOpNode : public BinaryOpNode {
833 public:
834 ReverseBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
835 ReverseBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
836
837 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
838 };
839
840 class MultNode : public BinaryOpNode {
841 public:
842 MultNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
843 };
844
845 class DivNode : public BinaryOpNode {
846 public:
847 DivNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
848 };
849
850 class ModNode : public BinaryOpNode {
851 public:
852 ModNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
853 };
854
855 class AddNode : public BinaryOpNode {
856 public:
857 AddNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
858
859 virtual bool isAdd() const JSC_FAST_CALL { return true; }
860 };
861
862 class SubNode : public BinaryOpNode {
863 public:
864 SubNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
865 };
866
867 class LeftShiftNode : public BinaryOpNode {
868 public:
869 LeftShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
870 };
871
872 class RightShiftNode : public BinaryOpNode {
873 public:
874 RightShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
875 };
876
877 class UnsignedRightShiftNode : public BinaryOpNode {
878 public:
879 UnsignedRightShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
880 };
881
882 class LessNode : public BinaryOpNode {
883 public:
884 LessNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
885 };
886
887 class GreaterNode : public ReverseBinaryOpNode {
888 public:
889 GreaterNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
890 };
891
892 class LessEqNode : public BinaryOpNode {
893 public:
894 LessEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
895 };
896
897 class GreaterEqNode : public ReverseBinaryOpNode {
898 public:
899 GreaterEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
900 };
901
902 class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
903 public:
904 ThrowableBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
905 ThrowableBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
906
907 private:
908 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
909 };
910
911 class InstanceOfNode : public ThrowableBinaryOpNode {
912 public:
913 InstanceOfNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
914
915 private:
916 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
917 };
918
919 class InNode : public ThrowableBinaryOpNode {
920 public:
921 InNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
922 };
923
924 class EqualNode : public BinaryOpNode {
925 public:
926 EqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
927
928 private:
929 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
930 };
931
932 class NotEqualNode : public BinaryOpNode {
933 public:
934 NotEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
935 };
936
937 class StrictEqualNode : public BinaryOpNode {
938 public:
939 StrictEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
940
941 private:
942 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
943 };
944
945 class NotStrictEqualNode : public BinaryOpNode {
946 public:
947 NotStrictEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
948 };
949
950 class BitAndNode : public BinaryOpNode {
951 public:
952 BitAndNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
953 };
954
955 class BitOrNode : public BinaryOpNode {
956 public:
957 BitOrNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
958 };
959
960 class BitXOrNode : public BinaryOpNode {
961 public:
962 BitXOrNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
963 };
964
965 // m_expr1 && m_expr2, m_expr1 || m_expr2
966 class LogicalOpNode : public ExpressionNode {
967 public:
968 LogicalOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
969
970 private:
971 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
972
973 ExpressionNode* m_expr1;
974 ExpressionNode* m_expr2;
975 LogicalOperator m_operator;
976 };
977
978 // The ternary operator, "m_logical ? m_expr1 : m_expr2"
979 class ConditionalNode : public ExpressionNode {
980 public:
981 ConditionalNode(JSGlobalData*, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
982
983 private:
984 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
985
986 ExpressionNode* m_logical;
987 ExpressionNode* m_expr1;
988 ExpressionNode* m_expr2;
989 };
990
991 class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
992 public:
993 ReadModifyResolveNode(JSGlobalData*, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
994
995 private:
996 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
997
998 const Identifier& m_ident;
999 ExpressionNode* m_right;
1000 size_t m_index; // Used by ReadModifyLocalVarNode.
1001 Operator m_operator;
1002 bool m_rightHasAssignments;
1003 };
1004
1005 class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
1006 public:
1007 AssignResolveNode(JSGlobalData*, const Identifier&, ExpressionNode* right, bool rightHasAssignments);
1008
1009 private:
1010 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1011
1012 const Identifier& m_ident;
1013 ExpressionNode* m_right;
1014 size_t m_index; // Used by ReadModifyLocalVarNode.
1015 bool m_rightHasAssignments;
1016 };
1017
1018 class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
1019 public:
1020 ReadModifyBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
1021
1022 private:
1023 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1024
1025 ExpressionNode* m_base;
1026 ExpressionNode* m_subscript;
1027 ExpressionNode* m_right;
1028 Operator m_operator : 30;
1029 bool m_subscriptHasAssignments : 1;
1030 bool m_rightHasAssignments : 1;
1031 };
1032
1033 class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
1034 public:
1035 AssignBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
1036
1037 private:
1038 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1039
1040 ExpressionNode* m_base;
1041 ExpressionNode* m_subscript;
1042 ExpressionNode* m_right;
1043 bool m_subscriptHasAssignments : 1;
1044 bool m_rightHasAssignments : 1;
1045 };
1046
1047 class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
1048 public:
1049 AssignDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
1050
1051 private:
1052 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1053
1054 ExpressionNode* m_base;
1055 const Identifier& m_ident;
1056 ExpressionNode* m_right;
1057 bool m_rightHasAssignments;
1058 };
1059
1060 class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
1061 public:
1062 ReadModifyDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
1063
1064 private:
1065 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1066
1067 ExpressionNode* m_base;
1068 const Identifier& m_ident;
1069 ExpressionNode* m_right;
1070 Operator m_operator : 31;
1071 bool m_rightHasAssignments : 1;
1072 };
1073
1074 class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
1075 public:
1076 AssignErrorNode(JSGlobalData*, ExpressionNode* left, Operator, ExpressionNode* right, unsigned divot, unsigned startOffset, unsigned endOffset);
1077
1078 private:
1079 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1080
1081 ExpressionNode* m_left;
1082 Operator m_operator;
1083 ExpressionNode* m_right;
1084 };
1085
1086 class CommaNode : public ExpressionNode {
1087 public:
1088 CommaNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2);
1089
1090 private:
1091 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1092
1093 ExpressionNode* m_expr1;
1094 ExpressionNode* m_expr2;
1095 };
1096
1097 class ConstDeclNode : public ExpressionNode {
1098 public:
1099 ConstDeclNode(JSGlobalData*, const Identifier&, ExpressionNode*);
1100
1101 bool hasInitializer() const { return m_init; }
1102 const Identifier& ident() { return m_ident; }
1103
1104 private:
1105 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1106 virtual RegisterID* emitCodeSingle(BytecodeGenerator&) JSC_FAST_CALL;
1107
1108 const Identifier& m_ident;
1109
1110 public:
1111 ConstDeclNode* m_next;
1112
1113 private:
1114 ExpressionNode* m_init;
1115 };
1116
1117 class ConstStatementNode : public StatementNode {
1118 public:
1119 ConstStatementNode(JSGlobalData*, ConstDeclNode* next);
1120
1121 private:
1122 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1123
1124 ConstDeclNode* m_next;
1125 };
1126
1127 class SourceElements : public ParserArenaDeletable {
1128 public:
1129 SourceElements(JSGlobalData*);
1130
1131 void append(StatementNode*);
1132
1133 StatementNode* singleStatement() const;
1134 StatementNode* lastStatement() const;
1135
1136 void emitBytecode(BytecodeGenerator&, RegisterID* dst);
1137
1138 private:
1139 Vector<StatementNode*> m_statements;
1140 };
1141
1142 class BlockNode : public StatementNode {
1143 public:
1144 BlockNode(JSGlobalData*, SourceElements* = 0);
1145
1146 StatementNode* lastStatement() const;
1147
1148 private:
1149 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1150
1151 virtual bool isBlock() const JSC_FAST_CALL { return true; }
1152
1153 SourceElements* m_statements;
1154 };
1155
1156 class EmptyStatementNode : public StatementNode {
1157 public:
1158 EmptyStatementNode(JSGlobalData*);
1159
1160 private:
1161 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1162
1163 virtual bool isEmptyStatement() const JSC_FAST_CALL { return true; }
1164 };
1165
1166 class DebuggerStatementNode : public StatementNode {
1167 public:
1168 DebuggerStatementNode(JSGlobalData*);
1169
1170 private:
1171 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1172 };
1173
1174 class ExprStatementNode : public StatementNode {
1175 public:
1176 ExprStatementNode(JSGlobalData*, ExpressionNode*);
1177
1178 ExpressionNode* expr() const { return m_expr; }
1179
1180 private:
1181 virtual bool isExprStatement() const JSC_FAST_CALL { return true; }
1182
1183 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1184
1185 ExpressionNode* m_expr;
1186 };
1187
1188 class VarStatementNode : public StatementNode {
1189 public:
1190 VarStatementNode(JSGlobalData*, ExpressionNode*);
1191
1192 private:
1193 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1194
1195 ExpressionNode* m_expr;
1196 };
1197
1198 class IfNode : public StatementNode {
1199 public:
1200 IfNode(JSGlobalData*, ExpressionNode* condition, StatementNode* ifBlock);
1201
1202 protected:
1203 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1204
1205 ExpressionNode* m_condition;
1206 StatementNode* m_ifBlock;
1207 };
1208
1209 class IfElseNode : public IfNode {
1210 public:
1211 IfElseNode(JSGlobalData*, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
1212
1213 private:
1214 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1215
1216 StatementNode* m_elseBlock;
1217 };
1218
1219 class DoWhileNode : public StatementNode {
1220 public:
1221 DoWhileNode(JSGlobalData*, StatementNode* statement, ExpressionNode*);
1222
1223 private:
1224 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1225
1226 StatementNode* m_statement;
1227 ExpressionNode* m_expr;
1228 };
1229
1230 class WhileNode : public StatementNode {
1231 public:
1232 WhileNode(JSGlobalData*, ExpressionNode*, StatementNode* statement);
1233
1234 private:
1235 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1236
1237 ExpressionNode* m_expr;
1238 StatementNode* m_statement;
1239 };
1240
1241 class ForNode : public StatementNode {
1242 public:
1243 ForNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl);
1244
1245 private:
1246 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1247
1248 ExpressionNode* m_expr1;
1249 ExpressionNode* m_expr2;
1250 ExpressionNode* m_expr3;
1251 StatementNode* m_statement;
1252 bool m_expr1WasVarDecl;
1253 };
1254
1255 class ForInNode : public StatementNode, public ThrowableExpressionData {
1256 public:
1257 ForInNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, StatementNode*);
1258 ForInNode(JSGlobalData*, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset);
1259
1260 private:
1261 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1262
1263 const Identifier& m_ident;
1264 ExpressionNode* m_init;
1265 ExpressionNode* m_lexpr;
1266 ExpressionNode* m_expr;
1267 StatementNode* m_statement;
1268 bool m_identIsVarDecl;
1269 };
1270
1271 class ContinueNode : public StatementNode, public ThrowableExpressionData {
1272 public:
1273 ContinueNode(JSGlobalData*);
1274 ContinueNode(JSGlobalData*, const Identifier&);
1275
1276 private:
1277 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1278
1279 const Identifier& m_ident;
1280 };
1281
1282 class BreakNode : public StatementNode, public ThrowableExpressionData {
1283 public:
1284 BreakNode(JSGlobalData*);
1285 BreakNode(JSGlobalData*, const Identifier&);
1286
1287 private:
1288 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1289
1290 const Identifier& m_ident;
1291 };
1292
1293 class ReturnNode : public StatementNode, public ThrowableExpressionData {
1294 public:
1295 ReturnNode(JSGlobalData*, ExpressionNode* value);
1296
1297 private:
1298 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1299
1300 virtual bool isReturnNode() const JSC_FAST_CALL { return true; }
1301
1302 ExpressionNode* m_value;
1303 };
1304
1305 class WithNode : public StatementNode {
1306 public:
1307 WithNode(JSGlobalData*, ExpressionNode*, StatementNode*, uint32_t divot, uint32_t expressionLength);
1308
1309 private:
1310 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1311
1312 ExpressionNode* m_expr;
1313 StatementNode* m_statement;
1314 uint32_t m_divot;
1315 uint32_t m_expressionLength;
1316 };
1317
1318 class LabelNode : public StatementNode, public ThrowableExpressionData {
1319 public:
1320 LabelNode(JSGlobalData*, const Identifier& name, StatementNode*);
1321
1322 private:
1323 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1324
1325 const Identifier& m_name;
1326 StatementNode* m_statement;
1327 };
1328
1329 class ThrowNode : public StatementNode, public ThrowableExpressionData {
1330 public:
1331 ThrowNode(JSGlobalData*, ExpressionNode*);
1332
1333 private:
1334 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1335
1336 ExpressionNode* m_expr;
1337 };
1338
1339 class TryNode : public StatementNode {
1340 public:
1341 TryNode(JSGlobalData*, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock);
1342
1343 private:
1344 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* dst = 0) JSC_FAST_CALL;
1345
1346 StatementNode* m_tryBlock;
1347 const Identifier& m_exceptionIdent;
1348 StatementNode* m_catchBlock;
1349 StatementNode* m_finallyBlock;
1350 bool m_catchHasEval;
1351 };
1352
1353 class ParameterNode : public ParserArenaFreeable {
1354 public:
1355 ParameterNode(JSGlobalData*, const Identifier&);
1356 ParameterNode(JSGlobalData*, ParameterNode*, const Identifier&);
1357
1358 const Identifier& ident() const { return m_ident; }
1359 ParameterNode* nextParam() const { return m_next; }
1360
1361 private:
1362 const Identifier& m_ident;
1363 ParameterNode* m_next;
1364 };
1365
1366 struct ScopeNodeData {
1367 typedef DeclarationStacks::VarStack VarStack;
1368 typedef DeclarationStacks::FunctionStack FunctionStack;
1369
1370 ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, int numConstants);
1371
1372 ParserArena m_arena;
1373 VarStack m_varStack;
1374 FunctionStack m_functionStack;
1375 int m_numConstants;
1376 SourceElements* m_statements;
1377
1378 void mark();
1379 };
1380
1381 class ScopeNode : public StatementNode, public ParserArenaRefCounted {
1382 public:
1383 typedef DeclarationStacks::VarStack VarStack;
1384 typedef DeclarationStacks::FunctionStack FunctionStack;
1385
1386 ScopeNode(JSGlobalData*) JSC_FAST_CALL;
1387 ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants) JSC_FAST_CALL;
1388
1389 void adoptData(std::auto_ptr<ScopeNodeData> data)
1390 {
1391 ASSERT(!data->m_arena.contains(this));
1392 ASSERT(!m_data);
1393 m_data.adopt(data);
1394 }
1395 ScopeNodeData* data() const { return m_data.get(); }
1396 void destroyData() { m_data.clear(); }
1397
1398 const SourceCode& source() const { return m_source; }
1399 const UString& sourceURL() const JSC_FAST_CALL { return m_source.provider()->url(); }
1400 intptr_t sourceID() const { return m_source.provider()->asID(); }
1401
1402 void setFeatures(CodeFeatures features) { m_features = features; }
1403 CodeFeatures features() { return m_features; }
1404
1405 bool usesEval() const { return m_features & EvalFeature; }
1406 bool usesArguments() const { return m_features & ArgumentsFeature; }
1407 void setUsesArguments() { m_features |= ArgumentsFeature; }
1408 bool usesThis() const { return m_features & ThisFeature; }
1409 bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); }
1410
1411 VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; }
1412 FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; }
1413
1414 int neededConstants()
1415 {
1416 ASSERT(m_data);
1417 // We may need 2 more constants than the count given by the parser,
1418 // because of the various uses of jsUndefined() and jsNull().
1419 return m_data->m_numConstants + 2;
1420 }
1421
1422 virtual void mark() { }
1423
1424 StatementNode* singleStatement() const; // 0 if there is not exactly one statement
1425
1426 protected:
1427 void setSource(const SourceCode& source) { m_source = source; }
1428
1429 void emitStatementsBytecode(BytecodeGenerator&, RegisterID* dst);
1430
1431 private:
1432 OwnPtr<ScopeNodeData> m_data;
1433 CodeFeatures m_features;
1434 SourceCode m_source;
1435 };
1436
1437 class ProgramNode : public ScopeNode {
1438 public:
1439 static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
1440
1441 ProgramCodeBlock& bytecode(ScopeChainNode* scopeChain) JSC_FAST_CALL
1442 {
1443 if (!m_code)
1444 generateBytecode(scopeChain);
1445 return *m_code;
1446 }
1447
1448 private:
1449 ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
1450
1451 void generateBytecode(ScopeChainNode*) JSC_FAST_CALL;
1452 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1453
1454 OwnPtr<ProgramCodeBlock> m_code;
1455 };
1456
1457 class EvalNode : public ScopeNode {
1458 public:
1459 static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
1460
1461 EvalCodeBlock& bytecode(ScopeChainNode* scopeChain) JSC_FAST_CALL
1462 {
1463 if (!m_code)
1464 generateBytecode(scopeChain);
1465 return *m_code;
1466 }
1467
1468 EvalCodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*) JSC_FAST_CALL;
1469
1470 virtual void mark();
1471
1472 private:
1473 EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
1474
1475 void generateBytecode(ScopeChainNode*) JSC_FAST_CALL;
1476 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1477
1478 OwnPtr<EvalCodeBlock> m_code;
1479 };
1480
1481 class FunctionBodyNode : public ScopeNode {
1482 friend class JIT;
1483 public:
1484#if ENABLE(JIT)
1485 static PassRefPtr<FunctionBodyNode> createNativeThunk(JSGlobalData*) JSC_FAST_CALL;
1486#endif
1487 static FunctionBodyNode* create(JSGlobalData*) JSC_FAST_CALL;
1488 static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
1489 virtual ~FunctionBodyNode();
1490
1491 const Identifier* parameters() const { return m_parameters; }
1492 size_t parameterCount() const { return m_parameterCount; }
1493 UString paramString() const JSC_FAST_CALL;
1494 Identifier* copyParameters();
1495
1496 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1497
1498 bool isGenerated() const
1499 {
1500 return m_code;
1501 }
1502
1503 bool isHostFunction() const
1504 {
1505#if ENABLE(JIT)
1506 return m_jitCode && !m_code;
1507#else
1508 return true;
1509#endif
1510 }
1511
1512 virtual void mark();
1513
1514 void finishParsing(const SourceCode&, ParameterNode*);
1515 void finishParsing(Identifier* parameters, size_t parameterCount);
1516
1517 UString toSourceString() const JSC_FAST_CALL { return source().toString(); }
1518
1519 CodeBlock& bytecodeForExceptionInfoReparse(ScopeChainNode*, CodeBlock*) JSC_FAST_CALL;
1520#if ENABLE(JIT)
1521 JITCode generatedJITCode()
1522 {
1523 ASSERT(m_jitCode);
1524 return m_jitCode;
1525 }
1526
1527 JITCode jitCode(ScopeChainNode* scopeChain)
1528 {
1529 if (!m_jitCode)
1530 generateJITCode(scopeChain);
1531 return m_jitCode;
1532 }
1533#endif
1534 CodeBlock& bytecode(ScopeChainNode* scopeChain) JSC_FAST_CALL
1535 {
1536 ASSERT(scopeChain);
1537 if (!m_code)
1538 generateBytecode(scopeChain);
1539 return *m_code;
1540 }
1541
1542 CodeBlock& generatedBytecode()
1543 {
1544 ASSERT(m_code);
1545 return *m_code;
1546 }
1547
1548 private:
1549 FunctionBodyNode(JSGlobalData*) JSC_FAST_CALL;
1550 FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants) JSC_FAST_CALL;
1551
1552 void generateBytecode(ScopeChainNode*) JSC_FAST_CALL;
1553#if ENABLE(JIT)
1554 void generateJITCode(ScopeChainNode*) JSC_FAST_CALL;
1555
1556 JITCode m_jitCode;
1557#endif
1558 Identifier* m_parameters;
1559 size_t m_parameterCount;
1560 OwnPtr<CodeBlock> m_code;
1561 };
1562
1563 class FuncExprNode : public ExpressionNode, public ParserArenaRefCounted {
1564 public:
1565 FuncExprNode(JSGlobalData*, const Identifier&, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0);
1566
1567 JSFunction* makeFunction(ExecState*, ScopeChainNode*) JSC_FAST_CALL;
1568
1569 FunctionBodyNode* body() { return m_body.get(); }
1570
1571 private:
1572 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1573
1574 virtual bool isFuncExprNode() const JSC_FAST_CALL { return true; }
1575
1576 Identifier m_ident;
1577 RefPtr<FunctionBodyNode> m_body;
1578 };
1579
1580 class FuncDeclNode : public StatementNode, public ParserArenaRefCounted {
1581 public:
1582 FuncDeclNode(JSGlobalData*, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
1583
1584 JSFunction* makeFunction(ExecState*, ScopeChainNode*) JSC_FAST_CALL;
1585
1586 Identifier m_ident;
1587
1588 FunctionBodyNode* body() { return m_body.get(); }
1589
1590 private:
1591 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1592
1593 RefPtr<FunctionBodyNode> m_body;
1594 };
1595
1596 class CaseClauseNode : public ParserArenaFreeable {
1597 public:
1598 CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements* = 0);
1599
1600 ExpressionNode* expr() const { return m_expr; }
1601
1602 void emitBytecode(BytecodeGenerator&, RegisterID* dst);
1603
1604 private:
1605 ExpressionNode* m_expr;
1606 SourceElements* m_statements;
1607 };
1608
1609 class ClauseListNode : public ParserArenaFreeable {
1610 public:
1611 ClauseListNode(JSGlobalData*, CaseClauseNode*);
1612 ClauseListNode(JSGlobalData*, ClauseListNode*, CaseClauseNode*);
1613
1614 CaseClauseNode* getClause() const { return m_clause; }
1615 ClauseListNode* getNext() const { return m_next; }
1616
1617 private:
1618 CaseClauseNode* m_clause;
1619 ClauseListNode* m_next;
1620 };
1621
1622 class CaseBlockNode : public ParserArenaFreeable {
1623 public:
1624 CaseBlockNode(JSGlobalData*, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
1625
1626 RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* dst = 0) JSC_FAST_CALL;
1627
1628 private:
1629 SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
1630 ClauseListNode* m_list1;
1631 CaseClauseNode* m_defaultClause;
1632 ClauseListNode* m_list2;
1633 };
1634
1635 class SwitchNode : public StatementNode {
1636 public:
1637 SwitchNode(JSGlobalData*, ExpressionNode*, CaseBlockNode*);
1638
1639 private:
1640 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) JSC_FAST_CALL;
1641
1642 ExpressionNode* m_expr;
1643 CaseBlockNode* m_block;
1644 };
1645
1646 struct ElementList {
1647 ElementNode* head;
1648 ElementNode* tail;
1649 };
1650
1651 struct PropertyList {
1652 PropertyListNode* head;
1653 PropertyListNode* tail;
1654 };
1655
1656 struct ArgumentList {
1657 ArgumentListNode* head;
1658 ArgumentListNode* tail;
1659 };
1660
1661 struct ConstDeclList {
1662 ConstDeclNode* head;
1663 ConstDeclNode* tail;
1664 };
1665
1666 struct ParameterList {
1667 ParameterNode* head;
1668 ParameterNode* tail;
1669 };
1670
1671 struct ClauseList {
1672 ClauseListNode* head;
1673 ClauseListNode* tail;
1674 };
1675
1676} // namespace JSC
1677
1678#endif // Nodes_h
Note: See TracBrowser for help on using the repository browser.