| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 // Create an initial code generator state. Destroying the initial state | 121 // Create an initial code generator state. Destroying the initial state |
| 122 // leaves the code generator with a NULL state. | 122 // leaves the code generator with a NULL state. |
| 123 explicit CodeGenState(CodeGenerator* owner); | 123 explicit CodeGenState(CodeGenerator* owner); |
| 124 | 124 |
| 125 // Create a code generator state based on a code generator's current | 125 // Create a code generator state based on a code generator's current |
| 126 // state. The new state may or may not be inside a typeof, and has its | 126 // state. The new state may or may not be inside a typeof, and has its |
| 127 // own pair of branch targets. | 127 // own pair of branch targets. |
| 128 CodeGenState(CodeGenerator* owner, | 128 CodeGenState(CodeGenerator* owner, |
| 129 TypeofState typeof_state, | 129 TypeofState typeof_state, |
| 130 JumpTarget* true_target, | 130 JumpTarget* true_target, |
| 131 JumpTarget* false_target); | 131 JumpTarget* false_target, |
| 132 JumpTarget* fall_through); |
| 132 | 133 |
| 133 // Destroy a code generator state and restore the owning code generator's | 134 // Destroy a code generator state and restore the owning code generator's |
| 134 // previous state. | 135 // previous state. |
| 135 ~CodeGenState(); | 136 ~CodeGenState(); |
| 136 | 137 |
| 137 // Accessors for the state. | 138 // Accessors for the state. |
| 138 TypeofState typeof_state() const { return typeof_state_; } | 139 TypeofState typeof_state() const { return typeof_state_; } |
| 139 JumpTarget* true_target() const { return true_target_; } | 140 JumpTarget* true_target() const { return true_target_; } |
| 140 JumpTarget* false_target() const { return false_target_; } | 141 JumpTarget* false_target() const { return false_target_; } |
| 142 JumpTarget* fall_through() const { return fall_through_; } |
| 141 | 143 |
| 142 private: | 144 private: |
| 143 // The owning code generator. | 145 // The owning code generator. |
| 144 CodeGenerator* owner_; | 146 CodeGenerator* owner_; |
| 145 | 147 |
| 146 // A flag indicating whether we are compiling the immediate subexpression | 148 // A flag indicating whether we are compiling the immediate subexpression |
| 147 // of a typeof expression. | 149 // of a typeof expression. |
| 148 TypeofState typeof_state_; | 150 TypeofState typeof_state_; |
| 149 | 151 |
| 150 // A pair of jump targets in case the expression has a control-flow | 152 // A pair of jump targets in case the expression has a control-flow |
| 151 // effect. | 153 // effect. |
| 152 JumpTarget* true_target_; | 154 JumpTarget* true_target_; |
| 153 JumpTarget* false_target_; | 155 JumpTarget* false_target_; |
| 154 | 156 |
| 157 JumpTarget* fall_through_; |
| 158 |
| 155 // The previous state of the owning code generator, restored when | 159 // The previous state of the owning code generator, restored when |
| 156 // this state is destroyed. | 160 // this state is destroyed. |
| 157 CodeGenState* previous_; | 161 CodeGenState* previous_; |
| 158 }; | 162 }; |
| 159 | 163 |
| 160 | 164 |
| 161 | 165 |
| 162 | 166 |
| 163 // ------------------------------------------------------------------------- | 167 // ------------------------------------------------------------------------- |
| 164 // CodeGenerator | 168 // CodeGenerator |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 Scope* scope() const { return scope_; } | 221 Scope* scope() const { return scope_; } |
| 218 | 222 |
| 219 void ProcessDeferred(); | 223 void ProcessDeferred(); |
| 220 | 224 |
| 221 bool is_eval() { return is_eval_; } | 225 bool is_eval() { return is_eval_; } |
| 222 | 226 |
| 223 // State | 227 // State |
| 224 TypeofState typeof_state() const { return state_->typeof_state(); } | 228 TypeofState typeof_state() const { return state_->typeof_state(); } |
| 225 JumpTarget* true_target() const { return state_->true_target(); } | 229 JumpTarget* true_target() const { return state_->true_target(); } |
| 226 JumpTarget* false_target() const { return state_->false_target(); } | 230 JumpTarget* false_target() const { return state_->false_target(); } |
| 231 JumpTarget* fall_through() const { return state_->fall_through(); } |
| 227 | 232 |
| 228 // Track loop nesting level. | 233 // Track loop nesting level. |
| 229 int loop_nesting() const { return loop_nesting_; } | 234 int loop_nesting() const { return loop_nesting_; } |
| 230 void IncrementLoopNesting() { loop_nesting_++; } | 235 void IncrementLoopNesting() { loop_nesting_++; } |
| 231 void DecrementLoopNesting() { loop_nesting_--; } | 236 void DecrementLoopNesting() { loop_nesting_--; } |
| 232 | 237 |
| 233 | 238 |
| 234 // Node visitors. | 239 // Node visitors. |
| 235 void VisitStatements(ZoneList<Statement*>* statements); | 240 void VisitStatements(ZoneList<Statement*>* statements); |
| 236 | 241 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 | 292 |
| 288 // Expressions | 293 // Expressions |
| 289 Operand GlobalObject() const { | 294 Operand GlobalObject() const { |
| 290 return ContextOperand(esi, Context::GLOBAL_INDEX); | 295 return ContextOperand(esi, Context::GLOBAL_INDEX); |
| 291 } | 296 } |
| 292 | 297 |
| 293 void LoadCondition(Expression* x, | 298 void LoadCondition(Expression* x, |
| 294 TypeofState typeof_state, | 299 TypeofState typeof_state, |
| 295 JumpTarget* true_target, | 300 JumpTarget* true_target, |
| 296 JumpTarget* false_target, | 301 JumpTarget* false_target, |
| 302 JumpTarget* fall_through, |
| 297 bool force_control); | 303 bool force_control); |
| 298 void Load(Expression* x, TypeofState typeof_state = NOT_INSIDE_TYPEOF); | 304 void Load(Expression* x, TypeofState typeof_state = NOT_INSIDE_TYPEOF); |
| 299 void LoadGlobal(); | 305 void LoadGlobal(); |
| 300 void LoadGlobalReceiver(); | 306 void LoadGlobalReceiver(); |
| 301 | 307 |
| 302 // Generate code to push the value of an expression on top of the frame | 308 // Generate code to push the value of an expression on top of the frame |
| 303 // and then spill the frame fully to memory. This function is used | 309 // and then spill the frame fully to memory. This function is used |
| 304 // temporarily while the code generator is being transformed. | 310 // temporarily while the code generator is being transformed. |
| 305 void LoadAndSpill(Expression* expression, | 311 void LoadAndSpill(Expression* expression, |
| 306 TypeofState typeof_state = NOT_INSIDE_TYPEOF) { | 312 TypeofState typeof_state = NOT_INSIDE_TYPEOF) { |
| 307 ASSERT(in_spilled_code()); | 313 ASSERT(in_spilled_code()); |
| 308 set_in_spilled_code(false); | 314 set_in_spilled_code(false); |
| 309 Load(expression, typeof_state); | 315 Load(expression, typeof_state); |
| 310 frame_->SpillAll(); | 316 frame_->SpillAll(); |
| 311 set_in_spilled_code(true); | 317 set_in_spilled_code(true); |
| 312 } | 318 } |
| 313 | 319 |
| 314 // Call LoadCondition and then spill the virtual frame unless control flow | 320 // Call LoadCondition and then spill the virtual frame unless control flow |
| 315 // cannot reach the end of the expression (ie, by emitting only | 321 // cannot reach the end of the expression (ie, by emitting only |
| 316 // unconditional jumps to the control targets). | 322 // unconditional jumps to the control targets). |
| 317 void LoadConditionAndSpill(Expression* expression, | 323 void LoadConditionAndSpill(Expression* expression, |
| 318 TypeofState typeof_state, | 324 TypeofState typeof_state, |
| 319 JumpTarget* true_target, | 325 JumpTarget* true_target, |
| 320 JumpTarget* false_target, | 326 JumpTarget* false_target, |
| 321 bool force_cc) { | 327 JumpTarget* fall_through, |
| 328 bool force_control) { |
| 322 ASSERT(in_spilled_code()); | 329 ASSERT(in_spilled_code()); |
| 323 set_in_spilled_code(false); | 330 set_in_spilled_code(false); |
| 324 LoadCondition(expression, typeof_state, true_target, false_target, | 331 LoadCondition(expression, typeof_state, true_target, false_target, |
| 325 force_cc); | 332 fall_through, force_control); |
| 326 if (frame_ != NULL) { | 333 if (frame_ != NULL) { |
| 327 frame_->SpillAll(); | 334 frame_->SpillAll(); |
| 328 } | 335 } |
| 329 set_in_spilled_code(true); | 336 set_in_spilled_code(true); |
| 330 } | 337 } |
| 331 | 338 |
| 332 // Read a value from a slot and leave it on top of the expression stack. | 339 // Read a value from a slot and leave it on top of the expression stack. |
| 333 void LoadFromSlot(Slot* slot, TypeofState typeof_state); | 340 void LoadFromSlot(Slot* slot, TypeofState typeof_state); |
| 334 | 341 |
| 335 // Store the value on top of the expression stack into a slot, leaving the | 342 // Store the value on top of the expression stack into a slot, leaving the |
| 336 // value in place. | 343 // value in place. |
| 337 void StoreToSlot(Slot* slot, InitState init_state); | 344 void StoreToSlot(Slot* slot, InitState init_state); |
| 338 | 345 |
| 339 // Special code for typeof expressions: Unfortunately, we must | 346 // Special code for typeof expressions: Unfortunately, we must |
| 340 // be careful when loading the expression in 'typeof' | 347 // be careful when loading the expression in 'typeof' |
| 341 // expressions. We are not allowed to throw reference errors for | 348 // expressions. We are not allowed to throw reference errors for |
| 342 // non-existing properties of the global object, so we must make it | 349 // non-existing properties of the global object, so we must make it |
| 343 // look like an explicit property access, instead of an access | 350 // look like an explicit property access, instead of an access |
| 344 // through the context chain. | 351 // through the context chain. |
| 345 void LoadTypeofExpression(Expression* x); | 352 void LoadTypeofExpression(Expression* x); |
| 346 | 353 |
| 347 void ToBoolean(JumpTarget* true_target, JumpTarget* false_target); | 354 // Emit a branch to one of the true or false targets, and bind the |
| 355 // other target. The fall-through target is either the true or |
| 356 // false target, and is the one that will be bound. Because this |
| 357 // binds the fall-through target, it should be emitted as the last |
| 358 // thing when visiting an expression. |
| 359 static void Branch(Condition cc, |
| 360 JumpTarget* true_target, |
| 361 JumpTarget* false_target, |
| 362 JumpTarget* fall_through); |
| 363 |
| 364 // Branch based on the true and false targets and preferred |
| 365 // fall-through in the code generator's state. |
| 366 void Branch(Condition cc) { |
| 367 Branch(cc, true_target(), false_target(), fall_through()); |
| 368 } |
| 369 |
| 370 void ToBoolean(JumpTarget* true_target, |
| 371 JumpTarget* false_target, |
| 372 JumpTarget* fall_through); |
| 348 | 373 |
| 349 void GenericBinaryOperation(Token::Value op, | 374 void GenericBinaryOperation(Token::Value op, |
| 350 StaticType* type, | 375 StaticType* type, |
| 351 const OverwriteMode overwrite_mode = NO_OVERWRITE); | 376 const OverwriteMode overwrite_mode = NO_OVERWRITE); |
| 352 | 377 |
| 353 void Comparison(Condition cc, | 378 void Comparison(Condition cc, |
| 354 bool strict, | 379 bool strict, |
| 355 JumpTarget* true_target, | 380 JumpTarget* true_target, |
| 356 JumpTarget* false_target); | 381 JumpTarget* false_target, |
| 382 JumpTarget* fall_through); |
| 357 | 383 |
| 358 // Inline small integer literals. To prevent long attacker-controlled byte | 384 // Inline small integer literals. To prevent long attacker-controlled byte |
| 359 // sequences, we only inline small Smis. | 385 // sequences, we only inline small Smis. |
| 360 static const int kMaxSmiInlinedBits = 16; | 386 static const int kMaxSmiInlinedBits = 16; |
| 361 bool IsInlineSmi(Literal* literal); | 387 bool IsInlineSmi(Literal* literal); |
| 362 void SmiComparison(Condition cc, Handle<Object> value, bool strict = false); | 388 void SmiComparison(Condition cc, Handle<Object> value, bool strict); |
| 363 void SmiOperation(Token::Value op, | 389 void SmiOperation(Token::Value op, |
| 364 StaticType* type, | 390 StaticType* type, |
| 365 Handle<Object> value, | 391 Handle<Object> value, |
| 366 bool reversed, | 392 bool reversed, |
| 367 OverwriteMode overwrite_mode); | 393 OverwriteMode overwrite_mode); |
| 368 | 394 |
| 369 void CallWithArguments(ZoneList<Expression*>* arguments, int position); | 395 void CallWithArguments(ZoneList<Expression*>* arguments, int position); |
| 370 | 396 |
| 371 void CheckStack(); | 397 void CheckStack(); |
| 372 void CleanStack(int num_bytes); | 398 void CleanStack(int num_bytes); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 cgen_->set_in_spilled_code(false); | 542 cgen_->set_in_spilled_code(false); |
| 517 GetValue(typeof_state); | 543 GetValue(typeof_state); |
| 518 cgen_->frame()->SpillAll(); | 544 cgen_->frame()->SpillAll(); |
| 519 cgen_->set_in_spilled_code(true); | 545 cgen_->set_in_spilled_code(true); |
| 520 } | 546 } |
| 521 | 547 |
| 522 | 548 |
| 523 } } // namespace v8::internal | 549 } } // namespace v8::internal |
| 524 | 550 |
| 525 #endif // V8_CODEGEN_IA32_H_ | 551 #endif // V8_CODEGEN_IA32_H_ |
| OLD | NEW |