| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #pragma once
- namespace Js
- {
- class JavascriptRegExp : public DynamicObject
- {
- friend class JavascriptRegularExpressionType;
- friend class RegexHelper;
- private:
- static PropertyId const specialPropertyIdsAll[];
- static PropertyId const specialPropertyIdsWithoutUnicode[];
- static PropertyId const specialPropertyIdsWithoutDotAll[];
- static PropertyId const specialPropertyIdsWithoutDotAllOrUnicode[];
- static const uint defaultSpecialPropertyIdsCount = 6;
- Field(UnifiedRegex::RegexPattern*) pattern;
- // The pattern used by String.prototype.split could be different than the normal pattern. Even
- // when the sticky flag is present in the normal pattern, split() should look for the pattern
- // in the whole input string as opposed to just looking for it at the beginning.
- //
- // Initialization of this pattern is deferred until split() is called, or it's copied from another
- // RegExp object.
- Field(UnifiedRegex::RegexPattern*) splitPattern;
- Field(Var) lastIndexVar; // null => must build lastIndexVar from current lastIndex
- public:
- // Three states for lastIndex value:
- // 1. lastIndexVar has been updated, we must calculate lastIndex from it when we next need it
- static const CharCount NotCachedValue = (CharCount)-2;
- private:
- // 2. ToNumber(lastIndexVar) yields +inf or -inf or an integer not in range [0, MaxCharCount]
- static const CharCount InvalidValue = CharCountFlag;
- // 3. ToNumber(lastIndexVar) yields NaN, +0, -0 or an integer in range [0, MaxCharCount]
- Field(CharCount) lastIndexOrFlag;
- static JavascriptRegExp * GetJavascriptRegExp(Arguments& args, PCWSTR varName, ScriptContext* scriptContext);
- static JavascriptRegExp * ToRegExp(Var var, PCWSTR varName, ScriptContext* scriptContext);
- static RecyclableObject * GetThisObject(Arguments& args, PCWSTR varName, ScriptContext* scriptContext);
- static JavascriptString * GetFirstStringArg(Arguments& args, ScriptContext* scriptContext);
- static bool ShouldApplyPrototypeWebWorkaround(Arguments& args, ScriptContext* scriptContext);
- bool GetPropertyBuiltIns(PropertyId propertyId, Var* value, BOOL* result);
- bool SetPropertyBuiltIns(PropertyId propertyId, Var value, PropertyOperationFlags flags, BOOL* result);
- bool GetSetterBuiltIns(PropertyId propertyId, PropertyValueInfo* info, DescriptorFlags* result);
- inline PropertyId const * GetSpecialPropertyIdsInlined() const;
- Var GetOptions();
- void SetPattern(UnifiedRegex::RegexPattern* pattern)
- {
- this->pattern = pattern;
- }
- void SetSplitPattern(UnifiedRegex::RegexPattern* splitPattern)
- {
- this->splitPattern = splitPattern;
- }
- static CharCount GetLastIndexProperty(RecyclableObject* instance, ScriptContext* scriptContext);
- static void SetLastIndexProperty(Var instance, CharCount lastIndex, ScriptContext* scriptContext);
- static void SetLastIndexProperty(Var instance, Var lastIndex, ScriptContext* scriptContext);
- static bool GetGlobalProperty(RecyclableObject* instance, ScriptContext* scriptContext);
- static bool GetUnicodeProperty(RecyclableObject* instance, ScriptContext* scriptContext);
- static CharCount AddIndex(CharCount base, CharCount offset);
- static CharCount GetIndexOrMax(int64 index);
- static bool HasOriginalRegExType(RecyclableObject* instance);
- static bool HasObservableConstructor(DynamicObject* regexPrototype);
- static bool HasObservableExec(DynamicObject* regexPrototype);
- static bool HasObservableFlags(DynamicObject* regexPrototype);
- static bool HasObservableGlobalFlag(DynamicObject* regexPrototype);
- static bool HasObservableUnicodeFlag(DynamicObject* regexPrototype);
- static Var CallExec(RecyclableObject* thisObj, JavascriptString* string, PCWSTR varName, ScriptContext* scriptContext);
- UnifiedRegex::RegexFlags SetRegexFlag(PropertyId propertyId, UnifiedRegex::RegexFlags flags, UnifiedRegex::RegexFlags flag, ScriptContext* scriptContext);
- // For boxing stack instance
- JavascriptRegExp(JavascriptRegExp * instance, bool deepCopy);
- DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(JavascriptRegExp);
- protected:
- DEFINE_VTABLE_CTOR(JavascriptRegExp, DynamicObject);
- public:
- JavascriptRegExp(UnifiedRegex::RegexPattern* pattern, DynamicType* type);
- JavascriptRegExp(DynamicType * type);
- static uint GetOffsetOfPattern() { return offsetof(JavascriptRegExp, pattern); }
- static uint GetOffsetOfSplitPattern() { return offsetof(JavascriptRegExp, splitPattern); }
- static uint GetOffsetOfLastIndexVar() { return offsetof(JavascriptRegExp, lastIndexVar); }
- static uint GetOffsetOfLastIndexOrFlag() { return offsetof(JavascriptRegExp, lastIndexOrFlag); }
- inline UnifiedRegex::RegexPattern* GetPattern() const { return pattern; }
- inline UnifiedRegex::RegexPattern* GetSplitPattern() const { return splitPattern; }
- InternalString GetSource() const;
- UnifiedRegex::RegexFlags GetFlags() const;
- void CacheLastIndex();
- inline CharCountOrFlag GetLastIndex()
- {
- if (lastIndexOrFlag == NotCachedValue)
- {
- CacheLastIndex();
- }
- return lastIndexOrFlag;
- }
- inline void SetLastIndex(CharCount lastIndex)
- {
- Assert(lastIndex <= MaxCharCount);
- lastIndexVar = nullptr;
- this->lastIndexOrFlag = lastIndex;
- }
- static bool IsRegExpLike(Var aValue, ScriptContext* scriptContext);
- static JavascriptRegExp* CreateRegEx(const char16* pSource, CharCount sourceLen,
- UnifiedRegex::RegexFlags flags, ScriptContext *scriptContext);
- static JavascriptRegExp* CreateRegEx(Var aValue, Var options, ScriptContext *scriptContext);
- static JavascriptRegExp* CreateRegExNoCoerce(Var aValue, Var options, ScriptContext *scriptContext);
- static UnifiedRegex::RegexPattern* CreatePattern(Var aValue, Var options, ScriptContext *scriptContext);
- static Var OP_NewRegEx(UnifiedRegex::RegexPattern* aCompiledRegex, ScriptContext* scriptContext);
- JavascriptString *ToString(bool sourceOnly = false);
- class EntryInfo
- {
- public:
- static FunctionInfo NewInstance;
- static FunctionInfo Exec;
- static FunctionInfo Test;
- static FunctionInfo ToString;
- static FunctionInfo SymbolMatch;
- static FunctionInfo SymbolReplace;
- static FunctionInfo SymbolSearch;
- static FunctionInfo SymbolSplit;
- static FunctionInfo GetterSymbolSpecies;
- static FunctionInfo GetterGlobal;
- static FunctionInfo GetterFlags;
- static FunctionInfo GetterIgnoreCase;
- static FunctionInfo GetterMultiline;
- static FunctionInfo GetterOptions;
- static FunctionInfo GetterSource;
- static FunctionInfo GetterSticky;
- static FunctionInfo GetterUnicode;
- static FunctionInfo GetterDotAll;
- // v5.8 only
- static FunctionInfo Compile;
- };
- static Var NewInstance(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntryExec(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntryTest(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntryToString(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntrySymbolMatch(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntrySymbolReplace(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntrySymbolSearch(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntrySymbolSplit(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntryGetterSymbolSpecies(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntryGetterFlags(RecyclableObject* function, CallInfo callInfo, ...);
- static void AppendFlagForFlagsProperty(StringBuilder<ArenaAllocator>* builder, RecyclableObject* thisObj, PropertyId propertyId, char16 flag, ScriptContext* scriptContext);
- static Var EntryGetterGlobal(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntryGetterIgnoreCase(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntryGetterMultiline(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntryGetterOptions(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntryGetterSource(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntryGetterSticky(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntryGetterUnicode(RecyclableObject* function, CallInfo callInfo, ...);
- static Var EntryGetterDotAll(RecyclableObject* function, CallInfo callInfo, ...);
- // v5.8 only
- static Var EntryCompile(RecyclableObject* function, CallInfo callInfo, ...);
- virtual bool HasReadOnlyPropertiesInvisibleToTypeHandler() override { return true; }
- virtual PropertyQueryFlags HasPropertyQuery(PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info) override;
- virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
- virtual PropertyQueryFlags GetPropertyQuery(Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
- virtual PropertyQueryFlags GetPropertyReferenceQuery(Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext) override;
- virtual BOOL SetProperty(PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info) override;
- virtual BOOL SetProperty(JavascriptString* propertyNameString, Var value, PropertyOperationFlags flags, PropertyValueInfo* info) override;
- virtual BOOL InitProperty(PropertyId propertyId, Var value, PropertyOperationFlags flags = PropertyOperation_None, PropertyValueInfo* info = NULL) override;
- virtual BOOL DeleteProperty(PropertyId propertyId, PropertyOperationFlags flags) override;
- virtual BOOL DeleteProperty(JavascriptString *propertyNameString, PropertyOperationFlags flags) override;
- virtual DescriptorFlags GetSetter(PropertyId propertyId, Var* setterValue, PropertyValueInfo* info, ScriptContext* requestContext) override;
- virtual DescriptorFlags GetSetter(JavascriptString* propertyNameString, Var* setterValue, PropertyValueInfo* info, ScriptContext* requestContext) override;
- virtual BOOL GetDiagValueString(StringBuilder<ArenaAllocator>* stringBuilder, ScriptContext* requestContext) override;
- virtual BOOL GetDiagTypeString(StringBuilder<ArenaAllocator>* stringBuilder, ScriptContext* requestContext) override;
- virtual BOOL IsEnumerable(PropertyId propertyId) override;
- virtual BOOL IsConfigurable(PropertyId propertyId) override;
- virtual BOOL IsWritable(PropertyId propertyId) override;
- virtual BOOL GetSpecialPropertyName(uint32 index, JavascriptString ** propertyName, ScriptContext * requestContext) override;
- virtual uint GetSpecialPropertyCount() const override;
- virtual PropertyId const * GetSpecialPropertyIds() const override;
- static Js::JavascriptRegExp * BoxStackInstance(Js::JavascriptRegExp * instance, bool deepCopy);
- #if ENABLE_TTD
- public:
- virtual TTD::NSSnapObjects::SnapObjectType GetSnapTag_TTD() const override;
- virtual void ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc) override;
- void SetLastIndexInfo_TTD(CharCount lastIndex, Js::Var lastVar);
- #endif
- public:
- virtual VTableValue DummyVirtualFunctionToHinderLinkerICF()
- {
- return VTableValue::VtableJavascriptRegExp;
- }
- };
- template <> inline bool VarIsImpl<JavascriptRegExp>(RecyclableObject* obj)
- {
- return JavascriptOperators::GetTypeId(obj) == TypeIds_RegEx;
- }
- } // namespace Js
|