summaryrefslogtreecommitdiffstats
path: root/js/src/irregexp/imported/regexp-bytecode-generator.h
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/irregexp/imported/regexp-bytecode-generator.h')
-rw-r--r--js/src/irregexp/imported/regexp-bytecode-generator.h140
1 files changed, 140 insertions, 0 deletions
diff --git a/js/src/irregexp/imported/regexp-bytecode-generator.h b/js/src/irregexp/imported/regexp-bytecode-generator.h
new file mode 100644
index 0000000000..351f6e0cc6
--- /dev/null
+++ b/js/src/irregexp/imported/regexp-bytecode-generator.h
@@ -0,0 +1,140 @@
+// Copyright 2012 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_REGEXP_REGEXP_BYTECODE_GENERATOR_H_
+#define V8_REGEXP_REGEXP_BYTECODE_GENERATOR_H_
+
+#include "irregexp/imported/regexp-macro-assembler.h"
+
+namespace v8 {
+namespace internal {
+
+// An assembler/generator for the Irregexp byte code.
+class V8_EXPORT_PRIVATE RegExpBytecodeGenerator : public RegExpMacroAssembler {
+ public:
+ // Create an assembler. Instructions and relocation information are emitted
+ // into a buffer, with the instructions starting from the beginning and the
+ // relocation information starting from the end of the buffer. See CodeDesc
+ // for a detailed comment on the layout (globals.h).
+ //
+ // The assembler allocates and grows its own buffer, and buffer_size
+ // determines the initial buffer size. The buffer is owned by the assembler
+ // and deallocated upon destruction of the assembler.
+ RegExpBytecodeGenerator(Isolate* isolate, Zone* zone);
+ ~RegExpBytecodeGenerator() override;
+ // The byte-code interpreter checks on each push anyway.
+ int stack_limit_slack() override { return 1; }
+ bool CanReadUnaligned() const override { return false; }
+ void Bind(Label* label) override;
+ void AdvanceCurrentPosition(int by) override; // Signed cp change.
+ void PopCurrentPosition() override;
+ void PushCurrentPosition() override;
+ void Backtrack() override;
+ void GoTo(Label* label) override;
+ void PushBacktrack(Label* label) override;
+ bool Succeed() override;
+ void Fail() override;
+ void PopRegister(int register_index) override;
+ void PushRegister(int register_index,
+ StackCheckFlag check_stack_limit) override;
+ void AdvanceRegister(int reg, int by) override; // r[reg] += by.
+ void SetCurrentPositionFromEnd(int by) override;
+ void SetRegister(int register_index, int to) override;
+ void WriteCurrentPositionToRegister(int reg, int cp_offset) override;
+ void ClearRegisters(int reg_from, int reg_to) override;
+ void ReadCurrentPositionFromRegister(int reg) override;
+ void WriteStackPointerToRegister(int reg) override;
+ void ReadStackPointerFromRegister(int reg) override;
+ void LoadCurrentCharacterImpl(int cp_offset, Label* on_end_of_input,
+ bool check_bounds, int characters,
+ int eats_at_least) override;
+ void CheckCharacter(unsigned c, Label* on_equal) override;
+ void CheckCharacterAfterAnd(unsigned c, unsigned mask,
+ Label* on_equal) override;
+ void CheckCharacterGT(base::uc16 limit, Label* on_greater) override;
+ void CheckCharacterLT(base::uc16 limit, Label* on_less) override;
+ void CheckGreedyLoop(Label* on_tos_equals_current_position) override;
+ void CheckAtStart(int cp_offset, Label* on_at_start) override;
+ void CheckNotAtStart(int cp_offset, Label* on_not_at_start) override;
+ void CheckNotCharacter(unsigned c, Label* on_not_equal) override;
+ void CheckNotCharacterAfterAnd(unsigned c, unsigned mask,
+ Label* on_not_equal) override;
+ void CheckNotCharacterAfterMinusAnd(base::uc16 c, base::uc16 minus,
+ base::uc16 mask,
+ Label* on_not_equal) override;
+ void CheckCharacterInRange(base::uc16 from, base::uc16 to,
+ Label* on_in_range) override;
+ void CheckCharacterNotInRange(base::uc16 from, base::uc16 to,
+ Label* on_not_in_range) override;
+ bool CheckCharacterInRangeArray(const ZoneList<CharacterRange>* ranges,
+ Label* on_in_range) override {
+ // Disabled in the interpreter, because 1) there is no constant pool that
+ // could store the ByteArray pointer, 2) bytecode size limits are not as
+ // restrictive as code (e.g. branch distances on arm), 3) bytecode for
+ // large character classes is already quite compact.
+ // TODO(jgruber): Consider using BytecodeArrays (with a constant pool)
+ // instead of plain ByteArrays; then we could implement
+ // CheckCharacterInRangeArray in the interpreter.
+ return false;
+ }
+ bool CheckCharacterNotInRangeArray(const ZoneList<CharacterRange>* ranges,
+ Label* on_not_in_range) override {
+ return false;
+ }
+ void CheckBitInTable(Handle<ByteArray> table, Label* on_bit_set) override;
+ void CheckNotBackReference(int start_reg, bool read_backward,
+ Label* on_no_match) override;
+ void CheckNotBackReferenceIgnoreCase(int start_reg, bool read_backward,
+ bool unicode,
+ Label* on_no_match) override;
+ void IfRegisterLT(int register_index, int comparand, Label* if_lt) override;
+ void IfRegisterGE(int register_index, int comparand, Label* if_ge) override;
+ void IfRegisterEqPos(int register_index, Label* if_eq) override;
+
+ IrregexpImplementation Implementation() override;
+ Handle<HeapObject> GetCode(Handle<String> source) override;
+
+ private:
+ void ExpandBuffer();
+
+ // Code and bitmap emission.
+ inline void EmitOrLink(Label* label);
+ inline void Emit32(uint32_t x);
+ inline void Emit16(uint32_t x);
+ inline void Emit8(uint32_t x);
+ inline void Emit(uint32_t bc, uint32_t arg);
+ inline void Emit(uint32_t bc, int32_t arg);
+ // Bytecode buffer.
+ int length();
+ void Copy(byte* a);
+
+ // The buffer into which code and relocation info are generated.
+ static constexpr int kInitialBufferSize = 1024;
+ ZoneVector<byte> buffer_;
+
+ // The program counter.
+ int pc_;
+ Label backtrack_;
+
+ int advance_current_start_;
+ int advance_current_offset_;
+ int advance_current_end_;
+
+ // Stores jump edges emitted for the bytecode (used by
+ // RegExpBytecodePeepholeOptimization).
+ // Key: jump source (offset in buffer_ where jump destination is stored).
+ // Value: jump destination (offset in buffer_ to jump to).
+ ZoneUnorderedMap<int, int> jump_edges_;
+
+ Isolate* isolate_;
+
+ static const int kInvalidPC = -1;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(RegExpBytecodeGenerator);
+};
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_REGEXP_REGEXP_BYTECODE_GENERATOR_H_