| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef RUNTIME_VM_REGEXP_ASSEMBLER_IR_H_ | 5 #ifndef RUNTIME_VM_REGEXP_ASSEMBLER_IR_H_ |
| 6 #define RUNTIME_VM_REGEXP_ASSEMBLER_IR_H_ | 6 #define RUNTIME_VM_REGEXP_ASSEMBLER_IR_H_ |
| 7 | 7 |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 #include "vm/object.h" | 10 #include "vm/object.h" |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 uint16_t to, | 76 uint16_t to, |
| 77 BlockLabel* on_in_range); | 77 BlockLabel* on_in_range); |
| 78 virtual void CheckCharacterNotInRange(uint16_t from, | 78 virtual void CheckCharacterNotInRange(uint16_t from, |
| 79 uint16_t to, | 79 uint16_t to, |
| 80 BlockLabel* on_not_in_range); | 80 BlockLabel* on_not_in_range); |
| 81 virtual void CheckBitInTable(const TypedData& table, BlockLabel* on_bit_set); | 81 virtual void CheckBitInTable(const TypedData& table, BlockLabel* on_bit_set); |
| 82 | 82 |
| 83 // Checks whether the given offset from the current position is before | 83 // Checks whether the given offset from the current position is before |
| 84 // the end of the string. | 84 // the end of the string. |
| 85 virtual void CheckPosition(intptr_t cp_offset, BlockLabel* on_outside_input); | 85 virtual void CheckPosition(intptr_t cp_offset, BlockLabel* on_outside_input); |
| 86 virtual bool CheckSpecialCharacterClass( | 86 virtual bool CheckSpecialCharacterClass(uint16_t type, |
| 87 uint16_t type, BlockLabel* on_no_match); | 87 BlockLabel* on_no_match); |
| 88 virtual void Fail(); | 88 virtual void Fail(); |
| 89 virtual void IfRegisterGE(intptr_t reg, | 89 virtual void IfRegisterGE(intptr_t reg, |
| 90 intptr_t comparand, BlockLabel* if_ge); | 90 intptr_t comparand, |
| 91 BlockLabel* if_ge); |
| 91 virtual void IfRegisterLT(intptr_t reg, | 92 virtual void IfRegisterLT(intptr_t reg, |
| 92 intptr_t comparand, BlockLabel* if_lt); | 93 intptr_t comparand, |
| 94 BlockLabel* if_lt); |
| 93 virtual void IfRegisterEqPos(intptr_t reg, BlockLabel* if_eq); | 95 virtual void IfRegisterEqPos(intptr_t reg, BlockLabel* if_eq); |
| 94 virtual IrregexpImplementation Implementation(); | 96 virtual IrregexpImplementation Implementation(); |
| 95 virtual void GoTo(BlockLabel* to); | 97 virtual void GoTo(BlockLabel* to); |
| 96 virtual void LoadCurrentCharacter(intptr_t cp_offset, | 98 virtual void LoadCurrentCharacter(intptr_t cp_offset, |
| 97 BlockLabel* on_end_of_input, | 99 BlockLabel* on_end_of_input, |
| 98 bool check_bounds = true, | 100 bool check_bounds = true, |
| 99 intptr_t characters = 1); | 101 intptr_t characters = 1); |
| 100 virtual void PopCurrentPosition(); | 102 virtual void PopCurrentPosition(); |
| 101 virtual void PopRegister(intptr_t register_index); | 103 virtual void PopRegister(intptr_t register_index); |
| 102 virtual void Print(const char* str); | 104 virtual void Print(const char* str); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 kNE, | 144 kNE, |
| 143 kLT, | 145 kLT, |
| 144 kGT, | 146 kGT, |
| 145 kLTE, | 147 kLTE, |
| 146 kGTE, | 148 kGTE, |
| 147 }; | 149 }; |
| 148 | 150 |
| 149 struct InstanceCallDescriptor { | 151 struct InstanceCallDescriptor { |
| 150 // Standard (i.e. most non-Smi) functions. | 152 // Standard (i.e. most non-Smi) functions. |
| 151 explicit InstanceCallDescriptor(const String& name) | 153 explicit InstanceCallDescriptor(const String& name) |
| 152 : name(name), | 154 : name(name), token_kind(Token::kILLEGAL), checked_argument_count(1) {} |
| 153 token_kind(Token::kILLEGAL), | |
| 154 checked_argument_count(1) { } | |
| 155 | 155 |
| 156 InstanceCallDescriptor(const String& name, | 156 InstanceCallDescriptor(const String& name, |
| 157 Token::Kind token_kind, | 157 Token::Kind token_kind, |
| 158 intptr_t checked_argument_count) | 158 intptr_t checked_argument_count) |
| 159 : name(name), | 159 : name(name), |
| 160 token_kind(token_kind), | 160 token_kind(token_kind), |
| 161 checked_argument_count(checked_argument_count) { } | 161 checked_argument_count(checked_argument_count) {} |
| 162 | 162 |
| 163 // Special cases for Smi and indexing functions. | 163 // Special cases for Smi and indexing functions. |
| 164 static InstanceCallDescriptor FromToken(Token::Kind token_kind) { | 164 static InstanceCallDescriptor FromToken(Token::Kind token_kind) { |
| 165 switch (token_kind) { | 165 switch (token_kind) { |
| 166 case Token::kEQ: return InstanceCallDescriptor( | 166 case Token::kEQ: |
| 167 Symbols::EqualOperator(), token_kind, 2); | 167 return InstanceCallDescriptor(Symbols::EqualOperator(), token_kind, |
| 168 case Token::kADD: return InstanceCallDescriptor( | 168 2); |
| 169 Symbols::Plus(), token_kind, 2); | 169 case Token::kADD: |
| 170 case Token::kSUB: return InstanceCallDescriptor( | 170 return InstanceCallDescriptor(Symbols::Plus(), token_kind, 2); |
| 171 Symbols::Minus(), token_kind, 2); | 171 case Token::kSUB: |
| 172 case Token::kBIT_OR: return InstanceCallDescriptor( | 172 return InstanceCallDescriptor(Symbols::Minus(), token_kind, 2); |
| 173 Symbols::BitOr(), token_kind, 2); | 173 case Token::kBIT_OR: |
| 174 case Token::kBIT_AND: return InstanceCallDescriptor( | 174 return InstanceCallDescriptor(Symbols::BitOr(), token_kind, 2); |
| 175 Symbols::BitAnd(), token_kind, 2); | 175 case Token::kBIT_AND: |
| 176 case Token::kLT: return InstanceCallDescriptor( | 176 return InstanceCallDescriptor(Symbols::BitAnd(), token_kind, 2); |
| 177 Symbols::LAngleBracket(), token_kind, 2); | 177 case Token::kLT: |
| 178 case Token::kLTE: return InstanceCallDescriptor( | 178 return InstanceCallDescriptor(Symbols::LAngleBracket(), token_kind, |
| 179 Symbols::LessEqualOperator(), token_kind, 2); | 179 2); |
| 180 case Token::kGT: return InstanceCallDescriptor( | 180 case Token::kLTE: |
| 181 Symbols::RAngleBracket(), token_kind, 2); | 181 return InstanceCallDescriptor(Symbols::LessEqualOperator(), |
| 182 case Token::kGTE: return InstanceCallDescriptor( | 182 token_kind, 2); |
| 183 Symbols::GreaterEqualOperator(), token_kind, 2); | 183 case Token::kGT: |
| 184 case Token::kNEGATE: return InstanceCallDescriptor( | 184 return InstanceCallDescriptor(Symbols::RAngleBracket(), token_kind, |
| 185 Symbols::UnaryMinus(), token_kind, 1); | 185 2); |
| 186 case Token::kINDEX: return InstanceCallDescriptor( | 186 case Token::kGTE: |
| 187 Symbols::IndexToken(), token_kind, 2); | 187 return InstanceCallDescriptor(Symbols::GreaterEqualOperator(), |
| 188 case Token::kASSIGN_INDEX: return InstanceCallDescriptor( | 188 token_kind, 2); |
| 189 Symbols::AssignIndexToken(), token_kind, 2); | 189 case Token::kNEGATE: |
| 190 return InstanceCallDescriptor(Symbols::UnaryMinus(), token_kind, 1); |
| 191 case Token::kINDEX: |
| 192 return InstanceCallDescriptor(Symbols::IndexToken(), token_kind, 2); |
| 193 case Token::kASSIGN_INDEX: |
| 194 return InstanceCallDescriptor(Symbols::AssignIndexToken(), token_kind, |
| 195 2); |
| 190 default: | 196 default: |
| 191 UNREACHABLE(); | 197 UNREACHABLE(); |
| 192 } | 198 } |
| 193 UNREACHABLE(); | 199 UNREACHABLE(); |
| 194 return InstanceCallDescriptor(Symbols::Empty()); | 200 return InstanceCallDescriptor(Symbols::Empty()); |
| 195 } | 201 } |
| 196 | 202 |
| 197 const String& name; | 203 const String& name; |
| 198 Token::Kind token_kind; | 204 Token::Kind token_kind; |
| 199 intptr_t checked_argument_count; | 205 intptr_t checked_argument_count; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 BlockLabel* true_successor); | 293 BlockLabel* true_successor); |
| 288 | 294 |
| 289 // Set up all local variables and parameters. | 295 // Set up all local variables and parameters. |
| 290 void InitializeLocals(); | 296 void InitializeLocals(); |
| 291 | 297 |
| 292 // Allocates a new local, and returns the appropriate id for placing it | 298 // Allocates a new local, and returns the appropriate id for placing it |
| 293 // on the stack. | 299 // on the stack. |
| 294 intptr_t GetNextLocalIndex(); | 300 intptr_t GetNextLocalIndex(); |
| 295 | 301 |
| 296 // We never have any copied parameters. | 302 // We never have any copied parameters. |
| 297 intptr_t num_copied_params() const { | 303 intptr_t num_copied_params() const { return 0; } |
| 298 return 0; | |
| 299 } | |
| 300 | 304 |
| 301 // Return the position register at the specified index, creating it if | 305 // Return the position register at the specified index, creating it if |
| 302 // necessary. Note that the number of such registers can exceed the amount | 306 // necessary. Note that the number of such registers can exceed the amount |
| 303 // required by the number of output captures. | 307 // required by the number of output captures. |
| 304 LocalVariable* position_register(intptr_t index); | 308 LocalVariable* position_register(intptr_t index); |
| 305 | 309 |
| 306 void set_current_instruction(Instruction* instruction); | 310 void set_current_instruction(Instruction* instruction); |
| 307 | 311 |
| 308 // The following functions are responsible for appending instructions | 312 // The following functions are responsible for appending instructions |
| 309 // to the current instruction in various ways. The most simple one | 313 // to the current instruction in various ways. The most simple one |
| (...skipping 19 matching lines...) Expand all Loading... |
| 329 Definition* PeekStack(); | 333 Definition* PeekStack(); |
| 330 void CheckStackLimit(); | 334 void CheckStackLimit(); |
| 331 void GrowStack(); | 335 void GrowStack(); |
| 332 | 336 |
| 333 // Prints the specified argument. Used for debugging. | 337 // Prints the specified argument. Used for debugging. |
| 334 void Print(PushArgumentInstr* argument); | 338 void Print(PushArgumentInstr* argument); |
| 335 | 339 |
| 336 // A utility class tracking ids of various objects such as blocks, temps, etc. | 340 // A utility class tracking ids of various objects such as blocks, temps, etc. |
| 337 class IdAllocator : public ValueObject { | 341 class IdAllocator : public ValueObject { |
| 338 public: | 342 public: |
| 339 IdAllocator() : next_id(0) { } | 343 IdAllocator() : next_id(0) {} |
| 340 | 344 |
| 341 intptr_t Count() const { return next_id; } | 345 intptr_t Count() const { return next_id; } |
| 342 intptr_t Alloc(intptr_t count = 1) { | 346 intptr_t Alloc(intptr_t count = 1) { |
| 343 ASSERT(count >= 0); | 347 ASSERT(count >= 0); |
| 344 intptr_t current_id = next_id; | 348 intptr_t current_id = next_id; |
| 345 next_id += count; | 349 next_id += count; |
| 346 return current_id; | 350 return current_id; |
| 347 } | 351 } |
| 348 void Dealloc(intptr_t count = 1) { | 352 void Dealloc(intptr_t count = 1) { |
| 349 ASSERT(count <= next_id); | 353 ASSERT(count <= next_id); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 426 IdAllocator temp_id_; | 430 IdAllocator temp_id_; |
| 427 IdAllocator arg_id_; | 431 IdAllocator arg_id_; |
| 428 IdAllocator local_id_; | 432 IdAllocator local_id_; |
| 429 IdAllocator indirect_id_; | 433 IdAllocator indirect_id_; |
| 430 }; | 434 }; |
| 431 | 435 |
| 432 | 436 |
| 433 } // namespace dart | 437 } // namespace dart |
| 434 | 438 |
| 435 #endif // RUNTIME_VM_REGEXP_ASSEMBLER_IR_H_ | 439 #endif // RUNTIME_VM_REGEXP_ASSEMBLER_IR_H_ |
| OLD | NEW |