OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 29 matching lines...) Expand all Loading... |
40 | 40 |
41 class FastCodeGenerator: public AstVisitor { | 41 class FastCodeGenerator: public AstVisitor { |
42 public: | 42 public: |
43 FastCodeGenerator(MacroAssembler* masm, Handle<Script> script, bool is_eval) | 43 FastCodeGenerator(MacroAssembler* masm, Handle<Script> script, bool is_eval) |
44 : masm_(masm), | 44 : masm_(masm), |
45 function_(NULL), | 45 function_(NULL), |
46 script_(script), | 46 script_(script), |
47 is_eval_(is_eval), | 47 is_eval_(is_eval), |
48 nesting_stack_(NULL), | 48 nesting_stack_(NULL), |
49 loop_depth_(0), | 49 loop_depth_(0), |
| 50 location_(kStack), |
50 true_label_(NULL), | 51 true_label_(NULL), |
51 false_label_(NULL) { | 52 false_label_(NULL) { |
52 } | 53 } |
53 | 54 |
54 static Handle<Code> MakeCode(FunctionLiteral* fun, | 55 static Handle<Code> MakeCode(FunctionLiteral* fun, |
55 Handle<Script> script, | 56 Handle<Script> script, |
56 bool is_eval); | 57 bool is_eval); |
57 | 58 |
58 void Generate(FunctionLiteral* fun); | 59 void Generate(FunctionLiteral* fun); |
59 | 60 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 virtual int Exit(int stack_depth) { | 204 virtual int Exit(int stack_depth) { |
204 return stack_depth + kForInStackElementCount; | 205 return stack_depth + kForInStackElementCount; |
205 } | 206 } |
206 private: | 207 private: |
207 // TODO(lrn): Check that this value is correct when implementing | 208 // TODO(lrn): Check that this value is correct when implementing |
208 // for-in. | 209 // for-in. |
209 static const int kForInStackElementCount = 5; | 210 static const int kForInStackElementCount = 5; |
210 DISALLOW_COPY_AND_ASSIGN(ForIn); | 211 DISALLOW_COPY_AND_ASSIGN(ForIn); |
211 }; | 212 }; |
212 | 213 |
| 214 enum Location { |
| 215 kAccumulator, |
| 216 kStack |
| 217 }; |
213 | 218 |
214 int SlotOffset(Slot* slot); | 219 int SlotOffset(Slot* slot); |
215 | 220 |
216 // Emit code to complete the evaluation of an expression based on its | 221 // Emit code to convert a pure value (in a register, slot, as a literal, |
217 // expression context and given its value is in a register, non-lookup | 222 // or on top of the stack) into the result expected according to an |
218 // slot, or a literal. | 223 // expression context. |
219 void Apply(Expression::Context context, Register reg); | 224 void Apply(Expression::Context context, Register reg); |
220 void Apply(Expression::Context context, Slot* slot, Register scratch); | 225 void Apply(Expression::Context context, Slot* slot); |
221 void Apply(Expression::Context context, Literal* lit); | 226 void Apply(Expression::Context context, Literal* lit); |
222 | |
223 // Emit code to complete the evaluation of an expression based on its | |
224 // expression context and given its value is on top of the stack. | |
225 void ApplyTOS(Expression::Context context); | 227 void ApplyTOS(Expression::Context context); |
226 | 228 |
227 // Emit code to discard count elements from the top of stack, then | 229 // Emit code to discard count elements from the top of stack, then convert |
228 // complete the evaluation of an expression based on its expression | 230 // a pure value into the result expected according to an expression |
229 // context and given its value is in a register. | 231 // context. |
230 void DropAndApply(int count, Expression::Context context, Register reg); | 232 void DropAndApply(int count, Expression::Context context, Register reg); |
231 | 233 |
| 234 // Emit code to convert pure control flow to a pair of labels into the |
| 235 // result expected according to an expression context. |
| 236 void Apply(Expression::Context context, |
| 237 Label* materialize_true, |
| 238 Label* materialize_false); |
| 239 |
| 240 // Helper function to convert a pure value into a test context. The value |
| 241 // is expected on the stack or the accumulator, depending on the platform. |
| 242 // See the platform-specific implementation for details. |
| 243 void DoTest(Expression::Context context); |
| 244 |
232 void Move(Slot* dst, Register source, Register scratch1, Register scratch2); | 245 void Move(Slot* dst, Register source, Register scratch1, Register scratch2); |
233 void Move(Register dst, Slot* source); | 246 void Move(Register dst, Slot* source); |
234 | 247 |
235 // Return an operand used to read/write to a known (ie, non-LOOKUP) slot. | 248 // Return an operand used to read/write to a known (ie, non-LOOKUP) slot. |
236 // May emit code to traverse the context chain, destroying the scratch | 249 // May emit code to traverse the context chain, destroying the scratch |
237 // register. | 250 // register. |
238 MemOperand EmitSlotSearch(Slot* slot, Register scratch); | 251 MemOperand EmitSlotSearch(Slot* slot, Register scratch); |
239 | 252 |
240 // Test the JavaScript value in source as if in a test context, compile | 253 void VisitForValue(Expression* expr, Location where) { |
241 // control flow to a pair of labels. | 254 ASSERT(expr->context() == Expression::kValue); |
242 void TestAndBranch(Register source, Label* true_label, Label* false_label); | 255 Location saved_location = location_; |
| 256 location_ = where; |
| 257 Visit(expr); |
| 258 location_ = saved_location; |
| 259 } |
243 | 260 |
244 void VisitForControl(Expression* expr, Label* if_true, Label* if_false) { | 261 void VisitForControl(Expression* expr, Label* if_true, Label* if_false) { |
245 ASSERT(expr->context() == Expression::kTest || | 262 ASSERT(expr->context() == Expression::kTest || |
246 expr->context() == Expression::kValueTest || | 263 expr->context() == Expression::kValueTest || |
247 expr->context() == Expression::kTestValue); | 264 expr->context() == Expression::kTestValue); |
248 Label* saved_true = true_label_; | 265 Label* saved_true = true_label_; |
249 Label* saved_false = false_label_; | 266 Label* saved_false = false_label_; |
250 true_label_ = if_true; | 267 true_label_ = if_true; |
251 false_label_ = if_false; | 268 false_label_ = if_false; |
252 Visit(expr); | 269 Visit(expr); |
(...skipping 17 matching lines...) Expand all Loading... |
270 // Platform-specific support for compiling assignments. | 287 // Platform-specific support for compiling assignments. |
271 | 288 |
272 // Load a value from a named property. | 289 // Load a value from a named property. |
273 // The receiver is left on the stack by the IC. | 290 // The receiver is left on the stack by the IC. |
274 void EmitNamedPropertyLoad(Property* expr); | 291 void EmitNamedPropertyLoad(Property* expr); |
275 | 292 |
276 // Load a value from a keyed property. | 293 // Load a value from a keyed property. |
277 // The receiver and the key is left on the stack by the IC. | 294 // The receiver and the key is left on the stack by the IC. |
278 void EmitKeyedPropertyLoad(Property* expr); | 295 void EmitKeyedPropertyLoad(Property* expr); |
279 | 296 |
280 // Apply the compound assignment operator. Expects both operands on top | 297 // Apply the compound assignment operator. Expects the left operand on top |
281 // of the stack. | 298 // of the stack and the right one in the accumulator. |
282 void EmitCompoundAssignmentOp(Token::Value op, Expression::Context context); | 299 void EmitBinaryOp(Token::Value op, Expression::Context context); |
283 | 300 |
284 // Complete a variable assignment. The right-hand-side value is expected | 301 // Complete a variable assignment. The right-hand-side value is expected |
285 // on top of the stack. | 302 // in the accumulator. |
286 void EmitVariableAssignment(Variable* var, Expression::Context context); | 303 void EmitVariableAssignment(Variable* var, Expression::Context context); |
287 | 304 |
288 // Complete a named property assignment. The receiver and right-hand-side | 305 // Complete a named property assignment. The receiver is expected on top |
289 // value are expected on top of the stack. | 306 // of the stack and the right-hand-side value in the accumulator. |
290 void EmitNamedPropertyAssignment(Assignment* expr); | 307 void EmitNamedPropertyAssignment(Assignment* expr); |
291 | 308 |
292 // Complete a keyed property assignment. The reciever, key, and | 309 // Complete a keyed property assignment. The receiver and key are |
293 // right-hand-side value are expected on top of the stack. | 310 // expected on top of the stack and the right-hand-side value in the |
| 311 // accumulator. |
294 void EmitKeyedPropertyAssignment(Assignment* expr); | 312 void EmitKeyedPropertyAssignment(Assignment* expr); |
295 | 313 |
296 void SetFunctionPosition(FunctionLiteral* fun); | 314 void SetFunctionPosition(FunctionLiteral* fun); |
297 void SetReturnPosition(FunctionLiteral* fun); | 315 void SetReturnPosition(FunctionLiteral* fun); |
298 void SetStatementPosition(Statement* stmt); | 316 void SetStatementPosition(Statement* stmt); |
299 void SetStatementPosition(int pos); | 317 void SetStatementPosition(int pos); |
300 void SetSourcePosition(int pos); | 318 void SetSourcePosition(int pos); |
301 | 319 |
302 // Non-local control flow support. | 320 // Non-local control flow support. |
303 void EnterFinallyBlock(); | 321 void EnterFinallyBlock(); |
(...skipping 27 matching lines...) Expand all Loading... |
331 void EmitLogicalOperation(BinaryOperation* expr); | 349 void EmitLogicalOperation(BinaryOperation* expr); |
332 | 350 |
333 MacroAssembler* masm_; | 351 MacroAssembler* masm_; |
334 FunctionLiteral* function_; | 352 FunctionLiteral* function_; |
335 Handle<Script> script_; | 353 Handle<Script> script_; |
336 bool is_eval_; | 354 bool is_eval_; |
337 Label return_label_; | 355 Label return_label_; |
338 NestedStatement* nesting_stack_; | 356 NestedStatement* nesting_stack_; |
339 int loop_depth_; | 357 int loop_depth_; |
340 | 358 |
| 359 Location location_; |
341 Label* true_label_; | 360 Label* true_label_; |
342 Label* false_label_; | 361 Label* false_label_; |
343 | 362 |
344 friend class NestedStatement; | 363 friend class NestedStatement; |
345 | 364 |
346 DISALLOW_COPY_AND_ASSIGN(FastCodeGenerator); | 365 DISALLOW_COPY_AND_ASSIGN(FastCodeGenerator); |
347 }; | 366 }; |
348 | 367 |
349 | 368 |
350 } } // namespace v8::internal | 369 } } // namespace v8::internal |
351 | 370 |
352 #endif // V8_FAST_CODEGEN_H_ | 371 #endif // V8_FAST_CODEGEN_H_ |
OLD | NEW |