blob: 2940d09c322aa8fa952edb62a16f57a6bb1b892b [file]
// Copyright 2008-2009 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_INL_H_
#define V8_REGEXP_REGEXP_BYTECODE_GENERATOR_INL_H_
#include "vm/regexp/regexp-bytecode-generator.h"
// Include the non-inl header before the rest of the headers.
#include "vm/regexp/regexp-bytecodes-inl.h"
namespace dart {
template <typename T>
void RegExpBytecodeWriter::Emit(T value, int offset) {
const int new_pc_within_bc = pc_ + offset;
DCHECK(base::IsInRange(new_pc_within_bc, pc_within_bc_, end_of_bc_));
DCHECK_LE(new_pc_within_bc + sizeof(T), buffer_.size());
// Dart: V8 has mixed sign comparison
// DCHECK_LE(new_pc_within_bc + sizeof(T), end_of_bc_);
DCHECK(Utils::IsAligned(new_pc_within_bc, sizeof(T)));
EMIT_PADDING(offset);
*reinterpret_cast<T*>(buffer_.data() + new_pc_within_bc) = value;
#ifdef DEBUG
pc_within_bc_ = new_pc_within_bc + sizeof(T);
#endif
}
template <typename T>
void RegExpBytecodeWriter::OverwriteValue(T value, int absolute_offset) {
// TODO(jgruber): Consider specializing this function; there should be very
// few uses (updating jump offsets).
ASSERT(Utils::IsAligned(absolute_offset, sizeof(T)));
DCHECK_LE(absolute_offset + sizeof(T), buffer_.size());
*reinterpret_cast<T*>(buffer_.data() + absolute_offset) = value;
}
void RegExpBytecodeWriter::EmitBytecode(RegExpBytecode bc) {
DCHECK_EQ(pc_, end_of_bc_);
DCHECK_EQ(pc_within_bc_, end_of_bc_);
#ifdef DEBUG
end_of_bc_ = pc_ + RegExpBytecodes::Size(bc);
pc_within_bc_ = pc_;
#endif
EnsureCapacity(RegExpBytecodes::Size(bc));
Emit(RegExpBytecodes::ToByte(bc), 0);
}
void RegExpBytecodeWriter::EnsureCapacity(size_t size_delta) {
const size_t required_size = pc_ + size_delta;
size_t size = buffer_.size();
if (LIKELY(size >= required_size)) return;
if (required_size < kInitialBufferSizeInBytes) {
size = kInitialBufferSizeInBytes;
} else if (required_size <= kMaxBufferGrowthInBytes) {
// We use a doubling strategy until hitting the limit.
size = Utils::RoundUpToPowerOfTwo(required_size);
} else {
// .. and kMaxBufferGrowthInBytes chunks afterwards.
size = Utils::RoundUp(required_size, kMaxBufferGrowthInBytes);
}
ExpandBuffer(size);
DCHECK_LE(required_size, buffer_.size());
}
void RegExpBytecodeWriter::ResetPc(int new_pc) {
// Resetting is only allowed at the beginning of a bytecode.
DCHECK_EQ(pc_, pc_within_bc_);
DCHECK_LE(new_pc, pc_);
pc_ = new_pc;
#ifdef DEBUG
pc_within_bc_ = pc_;
end_of_bc_ = pc_;
#endif
}
#ifdef DEBUG
void RegExpBytecodeWriter::EmitPadding(int offset) {
const int padding_to = pc_ + offset;
// Dart: V8 has mixed sign comparison
// DCHECK_LE(padding_to, buffer_.size());
// DCHECK_LE(padding_to, end_of_bc_);
// DCHECK_GE(padding_to, pc_within_bc_);
static constexpr uint8_t kPaddingByte = 0x0;
for (int i = pc_within_bc_; i < padding_to; ++i) {
buffer_[i] = kPaddingByte;
}
pc_within_bc_ = padding_to;
}
#endif
} // namespace dart
#endif // V8_REGEXP_REGEXP_BYTECODE_GENERATOR_INL_H_