115613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
2a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// Redistribution and use in source and binary forms, with or without
3a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// modification, are permitted provided that the following conditions are
4a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// met:
5a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//
6a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//     * Redistributions of source code must retain the above copyright
7a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//       notice, this list of conditions and the following disclaimer.
8a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//     * Redistributions in binary form must reproduce the above
9a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//       copyright notice, this list of conditions and the following
10a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//       disclaimer in the documentation and/or other materials provided
11a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//       with the distribution.
12a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//     * Neither the name of Google Inc. nor the names of its
13a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//       contributors may be used to endorse or promote products derived
14a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//       from this software without specific prior written permission.
15a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org//
16a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
28a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#ifndef V8_REGEXP_MACRO_ASSEMBLER_IRREGEXP_H_
29a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#define V8_REGEXP_MACRO_ASSEMBLER_IRREGEXP_H_
30a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
3171affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
3271affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
33a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
34c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org#ifdef V8_INTERPRETED_REGEXP
35a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
36a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.orgclass RegExpMacroAssemblerIrregexp: public RegExpMacroAssembler {
37a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org public:
38a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // Create an assembler. Instructions and relocation information are emitted
39a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // into a buffer, with the instructions starting from the beginning and the
40a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // relocation information starting from the end of the buffer. See CodeDesc
41a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // for a detailed comment on the layout (globals.h).
42a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  //
43a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // If the provided buffer is NULL, the assembler allocates and grows its own
44a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // buffer, and buffer_size determines the initial buffer size. The buffer is
45a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // owned by the assembler and deallocated upon destruction of the assembler.
46a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  //
47a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // If the provided buffer is not NULL, the assembler uses the provided buffer
48a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // for code generation and assumes its size to be buffer_size. If the buffer
49a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // is too small, a fatal error occurs. No deallocation of the buffer is done
50a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // upon destruction of the assembler.
515a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  RegExpMacroAssemblerIrregexp(Vector<byte>, Zone* zone);
52a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual ~RegExpMacroAssemblerIrregexp();
533291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  // The byte-code interpreter checks on each push anyway.
543291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  virtual int stack_limit_slack() { return 1; }
55a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void Bind(Label* label);
56a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void AdvanceCurrentPosition(int by);  // Signed cp change.
57a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void PopCurrentPosition();
58a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void PushCurrentPosition();
59a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void Backtrack();
60a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void GoTo(Label* label);
61a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void PushBacktrack(Label* label);
6215613d0b07bac19e341905ff374c930420b3b9c8mstarzinger@chromium.org  virtual bool Succeed();
63a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void Fail();
64a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void PopRegister(int register_index);
653291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  virtual void PushRegister(int register_index,
663291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org                            StackCheckFlag check_stack_limit);
67a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void AdvanceRegister(int reg, int by);  // r[reg] += by.
684a5224e84636d192e82f288bfab0d308bdae5c37whesse@chromium.org  virtual void SetCurrentPositionFromEnd(int by);
69a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void SetRegister(int register_index, int to);
708bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  virtual void WriteCurrentPositionToRegister(int reg, int cp_offset);
71ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  virtual void ClearRegisters(int reg_from, int reg_to);
72a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void ReadCurrentPositionFromRegister(int reg);
73a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void WriteStackPointerToRegister(int reg);
74a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void ReadStackPointerFromRegister(int reg);
7537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  virtual void LoadCurrentCharacter(int cp_offset,
7637abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                                    Label* on_end_of_input,
7737abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                                    bool check_bounds = true,
7837abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                                    int characters = 1);
79c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  virtual void CheckCharacter(unsigned c, Label* on_equal);
80c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  virtual void CheckCharacterAfterAnd(unsigned c,
81c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                                      unsigned mask,
8237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                                      Label* on_equal);
83a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void CheckCharacterGT(uc16 limit, Label* on_greater);
8437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  virtual void CheckCharacterLT(uc16 limit, Label* on_less);
858bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  virtual void CheckGreedyLoop(Label* on_tos_equals_current_position);
86ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  virtual void CheckAtStart(Label* on_at_start);
87a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void CheckNotAtStart(Label* on_not_at_start);
88c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  virtual void CheckNotCharacter(unsigned c, Label* on_not_equal);
89c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  virtual void CheckNotCharacterAfterAnd(unsigned c,
90c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                                         unsigned mask,
9137abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                                         Label* on_not_equal);
9237abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com  virtual void CheckNotCharacterAfterMinusAnd(uc16 c,
9337abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                                              uc16 minus,
9437abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                                              uc16 mask,
9537abdec9cad6edeba05b5c7a9ff73c25f5df2b70christian.plesner.hansen@gmail.com                                              Label* on_not_equal);
961456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  virtual void CheckCharacterInRange(uc16 from,
971456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org                                     uc16 to,
981456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org                                     Label* on_in_range);
991456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  virtual void CheckCharacterNotInRange(uc16 from,
1001456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org                                        uc16 to,
1011456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org                                        Label* on_not_in_range);
1021456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  virtual void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set);
103a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void CheckNotBackReference(int start_reg, Label* on_no_match);
104a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void CheckNotBackReferenceIgnoreCase(int start_reg,
105a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                                               Label* on_no_match);
106a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void IfRegisterLT(int register_index, int comparand, Label* if_lt);
107a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual void IfRegisterGE(int register_index, int comparand, Label* if_ge);
1083291210ab99f306b74430ebbc4b7d939629e699fager@chromium.org  virtual void IfRegisterEqPos(int register_index, Label* if_eq);
109a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
110a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  virtual IrregexpImplementation Implementation();
11183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  virtual Handle<HeapObject> GetCode(Handle<String> source);
11283e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org
113a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org private:
114a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void Expand();
115a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // Code and bitmap emission.
116911335cff40a2630bbe1dfb77b1897be991241bfsgjesse@chromium.org  inline void EmitOrLink(Label* label);
117a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  inline void Emit32(uint32_t x);
118a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  inline void Emit16(uint32_t x);
1191456e708d277e725ca42a03463af16fe471c9210jkummerow@chromium.org  inline void Emit8(uint32_t x);
120ddb913d619a6e602f53dd17b0fe71158ce66888dager@chromium.org  inline void Emit(uint32_t bc, uint32_t arg);
121a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // Bytecode buffer.
122a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int length();
123a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void Copy(Address a);
124a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
125a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // The buffer into which code and relocation info are generated.
126a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  Vector<byte> buffer_;
127a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // The program counter.
128a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  int pc_;
129a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // True if the assembler owns the buffer, false if buffer is external.
130a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  bool own_buffer_;
1318bb60585bafbf81564e6b30fcf18c82615a76f95ager@chromium.org  Label backtrack_;
132a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
133381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  int advance_current_start_;
134381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  int advance_current_offset_;
135381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  int advance_current_end_;
136381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
1371fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  Isolate* isolate_;
1381fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
139381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org  static const int kInvalidPC = -1;
140381abbb58260f2fc7d346d0e2f83d0f132a4c14bager@chromium.org
141a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  DISALLOW_IMPLICIT_CONSTRUCTORS(RegExpMacroAssemblerIrregexp);
142a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org};
143a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
144c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org#endif  // V8_INTERPRETED_REGEXP
14518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
146a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org} }  // namespace v8::internal
147a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
148a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org#endif  // V8_REGEXP_MACRO_ASSEMBLER_IRREGEXP_H_
149