diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:13:27 +0000 |
commit | 40a355a42d4a9444dc753c04c6608dade2f06a23 (patch) | |
tree | 871fc667d2de662f171103ce5ec067014ef85e61 /js/src/irregexp/RegExpShim.h | |
parent | Adding upstream version 124.0.1. (diff) | |
download | firefox-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.h | 82 |
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_; } |