Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(582)

Side by Side Diff: src/fast-codegen.h

Issue 549109: Rename the fast-codegen* files to full-codegen*. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler.cc ('k') | src/fast-codegen.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28 #ifndef V8_FAST_CODEGEN_H_
29 #define V8_FAST_CODEGEN_H_
30
31 #include "v8.h"
32
33 #include "ast.h"
34
35 namespace v8 {
36 namespace internal {
37
38 class FullCodeGenSyntaxChecker: public AstVisitor {
39 public:
40 FullCodeGenSyntaxChecker() : has_supported_syntax_(true) {}
41
42 void Check(FunctionLiteral* fun);
43
44 bool has_supported_syntax() { return has_supported_syntax_; }
45
46 private:
47 void VisitDeclarations(ZoneList<Declaration*>* decls);
48 void VisitStatements(ZoneList<Statement*>* stmts);
49
50 // AST node visit functions.
51 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
52 AST_NODE_LIST(DECLARE_VISIT)
53 #undef DECLARE_VISIT
54
55 bool has_supported_syntax_;
56
57 DISALLOW_COPY_AND_ASSIGN(FullCodeGenSyntaxChecker);
58 };
59
60
61 // -----------------------------------------------------------------------------
62 // Full code generator.
63
64 class FullCodeGenerator: public AstVisitor {
65 public:
66 FullCodeGenerator(MacroAssembler* masm, Handle<Script> script, bool is_eval)
67 : masm_(masm),
68 function_(NULL),
69 script_(script),
70 is_eval_(is_eval),
71 nesting_stack_(NULL),
72 loop_depth_(0),
73 location_(kStack),
74 true_label_(NULL),
75 false_label_(NULL) {
76 }
77
78 static Handle<Code> MakeCode(FunctionLiteral* fun,
79 Handle<Script> script,
80 bool is_eval);
81
82 void Generate(FunctionLiteral* fun);
83
84 private:
85 class Breakable;
86 class Iteration;
87 class TryCatch;
88 class TryFinally;
89 class Finally;
90 class ForIn;
91
92 class NestedStatement BASE_EMBEDDED {
93 public:
94 explicit NestedStatement(FullCodeGenerator* codegen) : codegen_(codegen) {
95 // Link into codegen's nesting stack.
96 previous_ = codegen->nesting_stack_;
97 codegen->nesting_stack_ = this;
98 }
99 virtual ~NestedStatement() {
100 // Unlink from codegen's nesting stack.
101 ASSERT_EQ(this, codegen_->nesting_stack_);
102 codegen_->nesting_stack_ = previous_;
103 }
104
105 virtual Breakable* AsBreakable() { return NULL; }
106 virtual Iteration* AsIteration() { return NULL; }
107 virtual TryCatch* AsTryCatch() { return NULL; }
108 virtual TryFinally* AsTryFinally() { return NULL; }
109 virtual Finally* AsFinally() { return NULL; }
110 virtual ForIn* AsForIn() { return NULL; }
111
112 virtual bool IsContinueTarget(Statement* target) { return false; }
113 virtual bool IsBreakTarget(Statement* target) { return false; }
114
115 // Generate code to leave the nested statement. This includes
116 // cleaning up any stack elements in use and restoring the
117 // stack to the expectations of the surrounding statements.
118 // Takes a number of stack elements currently on top of the
119 // nested statement's stack, and returns a number of stack
120 // elements left on top of the surrounding statement's stack.
121 // The generated code must preserve the result register (which
122 // contains the value in case of a return).
123 virtual int Exit(int stack_depth) {
124 // Default implementation for the case where there is
125 // nothing to clean up.
126 return stack_depth;
127 }
128 NestedStatement* outer() { return previous_; }
129 protected:
130 MacroAssembler* masm() { return codegen_->masm(); }
131 private:
132 FullCodeGenerator* codegen_;
133 NestedStatement* previous_;
134 DISALLOW_COPY_AND_ASSIGN(NestedStatement);
135 };
136
137 class Breakable : public NestedStatement {
138 public:
139 Breakable(FullCodeGenerator* codegen,
140 BreakableStatement* break_target)
141 : NestedStatement(codegen),
142 target_(break_target) {}
143 virtual ~Breakable() {}
144 virtual Breakable* AsBreakable() { return this; }
145 virtual bool IsBreakTarget(Statement* statement) {
146 return target_ == statement;
147 }
148 BreakableStatement* statement() { return target_; }
149 Label* break_target() { return &break_target_label_; }
150 private:
151 BreakableStatement* target_;
152 Label break_target_label_;
153 DISALLOW_COPY_AND_ASSIGN(Breakable);
154 };
155
156 class Iteration : public Breakable {
157 public:
158 Iteration(FullCodeGenerator* codegen,
159 IterationStatement* iteration_statement)
160 : Breakable(codegen, iteration_statement) {}
161 virtual ~Iteration() {}
162 virtual Iteration* AsIteration() { return this; }
163 virtual bool IsContinueTarget(Statement* statement) {
164 return this->statement() == statement;
165 }
166 Label* continue_target() { return &continue_target_label_; }
167 private:
168 Label continue_target_label_;
169 DISALLOW_COPY_AND_ASSIGN(Iteration);
170 };
171
172 // The environment inside the try block of a try/catch statement.
173 class TryCatch : public NestedStatement {
174 public:
175 explicit TryCatch(FullCodeGenerator* codegen, Label* catch_entry)
176 : NestedStatement(codegen), catch_entry_(catch_entry) { }
177 virtual ~TryCatch() {}
178 virtual TryCatch* AsTryCatch() { return this; }
179 Label* catch_entry() { return catch_entry_; }
180 virtual int Exit(int stack_depth);
181 private:
182 Label* catch_entry_;
183 DISALLOW_COPY_AND_ASSIGN(TryCatch);
184 };
185
186 // The environment inside the try block of a try/finally statement.
187 class TryFinally : public NestedStatement {
188 public:
189 explicit TryFinally(FullCodeGenerator* codegen, Label* finally_entry)
190 : NestedStatement(codegen), finally_entry_(finally_entry) { }
191 virtual ~TryFinally() {}
192 virtual TryFinally* AsTryFinally() { return this; }
193 Label* finally_entry() { return finally_entry_; }
194 virtual int Exit(int stack_depth);
195 private:
196 Label* finally_entry_;
197 DISALLOW_COPY_AND_ASSIGN(TryFinally);
198 };
199
200 // A FinallyEnvironment represents being inside a finally block.
201 // Abnormal termination of the finally block needs to clean up
202 // the block's parameters from the stack.
203 class Finally : public NestedStatement {
204 public:
205 explicit Finally(FullCodeGenerator* codegen) : NestedStatement(codegen) { }
206 virtual ~Finally() {}
207 virtual Finally* AsFinally() { return this; }
208 virtual int Exit(int stack_depth) {
209 return stack_depth + kFinallyStackElementCount;
210 }
211 private:
212 // Number of extra stack slots occupied during a finally block.
213 static const int kFinallyStackElementCount = 2;
214 DISALLOW_COPY_AND_ASSIGN(Finally);
215 };
216
217 // A ForInEnvironment represents being inside a for-in loop.
218 // Abnormal termination of the for-in block needs to clean up
219 // the block's temporary storage from the stack.
220 class ForIn : public Iteration {
221 public:
222 ForIn(FullCodeGenerator* codegen,
223 ForInStatement* statement)
224 : Iteration(codegen, statement) { }
225 virtual ~ForIn() {}
226 virtual ForIn* AsForIn() { return this; }
227 virtual int Exit(int stack_depth) {
228 return stack_depth + kForInStackElementCount;
229 }
230 private:
231 // TODO(lrn): Check that this value is correct when implementing
232 // for-in.
233 static const int kForInStackElementCount = 5;
234 DISALLOW_COPY_AND_ASSIGN(ForIn);
235 };
236
237 enum Location {
238 kAccumulator,
239 kStack
240 };
241
242 int SlotOffset(Slot* slot);
243
244 // Emit code to convert a pure value (in a register, slot, as a literal,
245 // or on top of the stack) into the result expected according to an
246 // expression context.
247 void Apply(Expression::Context context, Register reg);
248 void Apply(Expression::Context context, Slot* slot);
249 void Apply(Expression::Context context, Literal* lit);
250 void ApplyTOS(Expression::Context context);
251
252 // Emit code to discard count elements from the top of stack, then convert
253 // a pure value into the result expected according to an expression
254 // context.
255 void DropAndApply(int count, Expression::Context context, Register reg);
256
257 // Emit code to convert pure control flow to a pair of labels into the
258 // result expected according to an expression context.
259 void Apply(Expression::Context context,
260 Label* materialize_true,
261 Label* materialize_false);
262
263 // Helper function to convert a pure value into a test context. The value
264 // is expected on the stack or the accumulator, depending on the platform.
265 // See the platform-specific implementation for details.
266 void DoTest(Expression::Context context);
267
268 void Move(Slot* dst, Register source, Register scratch1, Register scratch2);
269 void Move(Register dst, Slot* source);
270
271 // Return an operand used to read/write to a known (ie, non-LOOKUP) slot.
272 // May emit code to traverse the context chain, destroying the scratch
273 // register.
274 MemOperand EmitSlotSearch(Slot* slot, Register scratch);
275
276 void VisitForEffect(Expression* expr) {
277 Expression::Context saved_context = context_;
278 context_ = Expression::kEffect;
279 Visit(expr);
280 context_ = saved_context;
281 }
282
283 void VisitForValue(Expression* expr, Location where) {
284 Expression::Context saved_context = context_;
285 Location saved_location = location_;
286 context_ = Expression::kValue;
287 location_ = where;
288 Visit(expr);
289 context_ = saved_context;
290 location_ = saved_location;
291 }
292
293 void VisitForControl(Expression* expr, Label* if_true, Label* if_false) {
294 Expression::Context saved_context = context_;
295 Label* saved_true = true_label_;
296 Label* saved_false = false_label_;
297 context_ = Expression::kTest;
298 true_label_ = if_true;
299 false_label_ = if_false;
300 Visit(expr);
301 context_ = saved_context;
302 true_label_ = saved_true;
303 false_label_ = saved_false;
304 }
305
306 void VisitForValueControl(Expression* expr,
307 Location where,
308 Label* if_true,
309 Label* if_false) {
310 Expression::Context saved_context = context_;
311 Location saved_location = location_;
312 Label* saved_true = true_label_;
313 Label* saved_false = false_label_;
314 context_ = Expression::kValueTest;
315 location_ = where;
316 true_label_ = if_true;
317 false_label_ = if_false;
318 Visit(expr);
319 context_ = saved_context;
320 location_ = saved_location;
321 true_label_ = saved_true;
322 false_label_ = saved_false;
323 }
324
325 void VisitForControlValue(Expression* expr,
326 Location where,
327 Label* if_true,
328 Label* if_false) {
329 Expression::Context saved_context = context_;
330 Location saved_location = location_;
331 Label* saved_true = true_label_;
332 Label* saved_false = false_label_;
333 context_ = Expression::kTestValue;
334 location_ = where;
335 true_label_ = if_true;
336 false_label_ = if_false;
337 Visit(expr);
338 context_ = saved_context;
339 location_ = saved_location;
340 true_label_ = saved_true;
341 false_label_ = saved_false;
342 }
343
344 void VisitDeclarations(ZoneList<Declaration*>* declarations);
345 void DeclareGlobals(Handle<FixedArray> pairs);
346
347 // Platform-specific return sequence
348 void EmitReturnSequence(int position);
349
350 // Platform-specific code sequences for calls
351 void EmitCallWithStub(Call* expr);
352 void EmitCallWithIC(Call* expr, Handle<Object> name, RelocInfo::Mode mode);
353
354 // Platform-specific code for loading variables.
355 void EmitVariableLoad(Variable* expr, Expression::Context context);
356
357 // Platform-specific support for compiling assignments.
358
359 // Load a value from a named property.
360 // The receiver is left on the stack by the IC.
361 void EmitNamedPropertyLoad(Property* expr);
362
363 // Load a value from a keyed property.
364 // The receiver and the key is left on the stack by the IC.
365 void EmitKeyedPropertyLoad(Property* expr);
366
367 // Apply the compound assignment operator. Expects the left operand on top
368 // of the stack and the right one in the accumulator.
369 void EmitBinaryOp(Token::Value op, Expression::Context context);
370
371 // Complete a variable assignment. The right-hand-side value is expected
372 // in the accumulator.
373 void EmitVariableAssignment(Variable* var, Expression::Context context);
374
375 // Complete a named property assignment. The receiver is expected on top
376 // of the stack and the right-hand-side value in the accumulator.
377 void EmitNamedPropertyAssignment(Assignment* expr);
378
379 // Complete a keyed property assignment. The receiver and key are
380 // expected on top of the stack and the right-hand-side value in the
381 // accumulator.
382 void EmitKeyedPropertyAssignment(Assignment* expr);
383
384 void SetFunctionPosition(FunctionLiteral* fun);
385 void SetReturnPosition(FunctionLiteral* fun);
386 void SetStatementPosition(Statement* stmt);
387 void SetStatementPosition(int pos);
388 void SetSourcePosition(int pos);
389
390 // Non-local control flow support.
391 void EnterFinallyBlock();
392 void ExitFinallyBlock();
393
394 // Loop nesting counter.
395 int loop_depth() { return loop_depth_; }
396 void increment_loop_depth() { loop_depth_++; }
397 void decrement_loop_depth() {
398 ASSERT(loop_depth_ > 0);
399 loop_depth_--;
400 }
401
402 MacroAssembler* masm() { return masm_; }
403 static Register result_register();
404 static Register context_register();
405
406 // Set fields in the stack frame. Offsets are the frame pointer relative
407 // offsets defined in, e.g., StandardFrameConstants.
408 void StoreToFrameField(int frame_offset, Register value);
409
410 // Load a value from the current context. Indices are defined as an enum
411 // in v8::internal::Context.
412 void LoadContextField(Register dst, int context_index);
413
414 // AST node visit functions.
415 #define DECLARE_VISIT(type) virtual void Visit##type(type* node);
416 AST_NODE_LIST(DECLARE_VISIT)
417 #undef DECLARE_VISIT
418 // Handles the shortcutted logical binary operations in VisitBinaryOperation.
419 void EmitLogicalOperation(BinaryOperation* expr);
420
421 MacroAssembler* masm_;
422 FunctionLiteral* function_;
423 Handle<Script> script_;
424 bool is_eval_;
425 Label return_label_;
426 NestedStatement* nesting_stack_;
427 int loop_depth_;
428
429 Expression::Context context_;
430 Location location_;
431 Label* true_label_;
432 Label* false_label_;
433
434 friend class NestedStatement;
435
436 DISALLOW_COPY_AND_ASSIGN(FullCodeGenerator);
437 };
438
439
440 } } // namespace v8::internal
441
442 #endif // V8_FAST_CODEGEN_H_
OLDNEW
« no previous file with comments | « src/compiler.cc ('k') | src/fast-codegen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698