summaryrefslogtreecommitdiffstats
path: root/js/src/irregexp/RegExpShim.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:13:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 01:13:27 +0000
commit40a355a42d4a9444dc753c04c6608dade2f06a23 (patch)
tree871fc667d2de662f171103ce5ec067014ef85e61 /js/src/irregexp/RegExpShim.h
parentAdding upstream version 124.0.1. (diff)
downloadfirefox-40a355a42d4a9444dc753c04c6608dade2f06a23.tar.xz
firefox-40a355a42d4a9444dc753c04c6608dade2f06a23.zip
Adding upstream version 125.0.1.upstream/125.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/irregexp/RegExpShim.h')
-rw-r--r--js/src/irregexp/RegExpShim.h82
1 files changed, 64 insertions, 18 deletions
diff --git a/js/src/irregexp/RegExpShim.h b/js/src/irregexp/RegExpShim.h
index 3f85413421..4d32c84920 100644
--- a/js/src/irregexp/RegExpShim.h
+++ b/js/src/irregexp/RegExpShim.h
@@ -586,15 +586,6 @@ class Object {
// IsCharacterInRangeArray in regexp-macro-assembler.cc.
Object(uintptr_t raw) : asBits_(raw) { MOZ_CRASH("unused"); }
- // Used in regexp-interpreter.cc to check the return value of
- // isolate->stack_guard()->HandleInterrupts(). We want to handle
- // interrupts in the caller, so we always return false from
- // HandleInterrupts and true here.
- inline bool IsException(Isolate*) const {
- MOZ_ASSERT(!value().toBoolean());
- return true;
- }
-
JS::Value value() const { return JS::Value::fromRawBits(asBits_); }
inline static Object cast(Object object) { return object; }
@@ -604,6 +595,14 @@ class Object {
uint64_t asBits_;
} JS_HAZ_GC_POINTER;
+// Used in regexp-interpreter.cc to check the return value of
+// isolate->stack_guard()->HandleInterrupts(). We want to handle
+// interrupts in the caller, so we return a magic value from
+// HandleInterrupts and check for it here.
+inline bool IsException(Object obj, Isolate*) {
+ return obj.value().isMagic(JS_INTERRUPT_REGEXP);
+}
+
class Smi : public Object {
public:
static Smi FromInt(int32_t value) {
@@ -626,6 +625,27 @@ class HeapObject : public Object {
}
};
+// V8's values use low-bit tagging. If the LSB is 0, it's a small
+// integer. If the LSB is 1, it's a pointer to some GC thing. In V8,
+// this wrapper class is used to represent a pointer that has the low
+// bit set, or a small integer that has been shifted left by one
+// bit. We don't use the same tagging system, so all we need is a
+// transparent wrapper that automatically converts to/from the wrapped
+// type.
+template <typename T>
+class Tagged {
+ public:
+ Tagged() {}
+ MOZ_IMPLICIT Tagged(const T& value) : value_(value) {}
+ MOZ_IMPLICIT Tagged(T&& value) : value_(std::move(value)) {}
+
+ T* operator->() { return &value_; }
+ constexpr operator T() const { return value_; }
+
+ private:
+ T value_;
+};
+
// A fixed-size array with Objects (aka Values) as element types.
// Implemented using the dense elements of an ArrayObject.
// Used for named captures.
@@ -668,13 +688,13 @@ T* ByteArrayData::typedData() {
template <typename T>
T ByteArrayData::getTyped(uint32_t index) {
- MOZ_ASSERT(index < length / sizeof(T));
+ MOZ_ASSERT(index < length() / sizeof(T));
return typedData<T>()[index];
}
template <typename T>
void ByteArrayData::setTyped(uint32_t index, T value) {
- MOZ_ASSERT(index < length / sizeof(T));
+ MOZ_ASSERT(index < length() / sizeof(T));
typedData<T>()[index] = value;
}
@@ -684,6 +704,7 @@ class ByteArray : public HeapObject {
ByteArrayData* inner() const {
return static_cast<ByteArrayData*>(value().toPrivate());
}
+ friend bool IsByteArray(Object obj);
public:
PseudoHandle<ByteArrayData> takeOwnership(Isolate* isolate);
@@ -692,8 +713,8 @@ class ByteArray : public HeapObject {
uint8_t get(uint32_t index) { return inner()->get(index); }
void set(uint32_t index, uint8_t val) { inner()->set(index, val); }
- uint32_t length() const { return inner()->length; }
- uint8_t* GetDataStartAddress() { return inner()->data(); }
+ uint32_t length() const { return inner()->length(); }
+ uint8_t* begin() { return inner()->data(); }
static ByteArray cast(Object object) {
ByteArray b;
@@ -701,11 +722,17 @@ class ByteArray : public HeapObject {
return b;
}
- bool IsByteArray() const { return true; }
-
friend class SMRegExpMacroAssembler;
};
+// This is only used in assertions. In debug builds, we put a magic value
+// in the header of each ByteArrayData, and assert here that it matches.
+inline bool IsByteArray(Object obj) {
+ MOZ_ASSERT(ByteArray::cast(obj).inner()->magic() ==
+ ByteArrayData::ExpectedMagic);
+ return true;
+}
+
// This is a convenience class used in V8 for treating a ByteArray as an array
// of fixed-size integers. This version supports integral types up to 32 bits.
template <typename T>
@@ -1030,6 +1057,7 @@ class JSRegExp : public HeapObject {
};
using RegExpFlags = JS::RegExpFlags;
+using RegExpFlag = JS::RegExpFlags::Flag;
inline bool IsUnicode(RegExpFlags flags) { return flags.unicode(); }
inline bool IsGlobal(RegExpFlags flags) { return flags.global(); }
@@ -1042,6 +1070,22 @@ inline bool IsEitherUnicode(RegExpFlags flags) {
return flags.unicode() || flags.unicodeSets();
}
+inline base::Optional<RegExpFlag> TryRegExpFlagFromChar(char c) {
+ RegExpFlag flag;
+
+ // The parser only calls this after verifying that it's a supported flag.
+ MOZ_ALWAYS_TRUE(JS::MaybeParseRegExpFlag(c, &flag));
+
+ return base::Optional(flag);
+}
+
+inline bool operator==(const RegExpFlags& lhs, const int& rhs) {
+ return lhs.value() == rhs;
+}
+inline bool operator!=(const RegExpFlags& lhs, const int& rhs) {
+ return !(lhs == rhs);
+}
+
class Histogram {
public:
inline void AddSample(int sample) {}
@@ -1126,9 +1170,11 @@ class Isolate {
// This is called from inside no-GC code. V8 runs the interrupt
// inside the no-GC code and then "manually relocates unhandlified
- // references" afterwards. We just return false and let the caller
- // handle interrupts.
- Object HandleInterrupts() { return Object(JS::BooleanValue(false)); }
+ // references" afterwards. We just return a magic value and let the
+ // caller handle interrupts.
+ Object HandleInterrupts() {
+ return Object(JS::MagicValue(JS_INTERRUPT_REGEXP));
+ }
JSContext* cx() const { return cx_; }