weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) |
mark.lam@apple.com | 5aca499 | 2016-04-07 03:17:58 +0000 | [diff] [blame] | 3 | * Copyright (C) 2003, 2007-2008, 2016 Apple Inc. All Rights Reserved. |
mjs@apple.com | 0a30b7a | 2009-07-04 14:21:30 +0000 | [diff] [blame] | 4 | * Copyright (C) 2009 Torch Mobile, Inc. |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 5 | * |
| 6 | * This library is free software; you can redistribute it and/or |
| 7 | * modify it under the terms of the GNU Lesser General Public |
| 8 | * License as published by the Free Software Foundation; either |
| 9 | * version 2 of the License, or (at your option) any later version. |
| 10 | * |
| 11 | * This library is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 14 | * Lesser General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU Lesser General Public |
| 17 | * License along with this library; if not, write to the Free Software |
| 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 19 | * |
| 20 | */ |
| 21 | |
| 22 | #include "config.h" |
| 23 | #include "RegExpConstructor.h" |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 24 | |
bweinstein@apple.com | 6ef016b | 2009-08-13 22:22:50 +0000 | [diff] [blame] | 25 | #include "Error.h" |
keith_miller@apple.com | 8af3d8d | 2016-01-22 18:44:46 +0000 | [diff] [blame] | 26 | #include "GetterSetter.h" |
fpizlo@apple.com | fb7eff2 | 2014-02-11 01:45:50 +0000 | [diff] [blame] | 27 | #include "JSCInlines.h" |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 28 | #include "RegExpPrototype.h" |
keith_miller@apple.com | 8dc2c35 | 2016-01-06 18:25:01 +0000 | [diff] [blame] | 29 | #include "StructureInlines.h" |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 30 | |
cwzwarich@webkit.org | 3f782f6 | 2008-09-08 01:28:33 +0000 | [diff] [blame] | 31 | namespace JSC { |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 32 | |
utatane.tea@gmail.com | d80165c | 2016-06-06 01:56:11 +0000 | [diff] [blame] | 33 | static EncodedJSValue regExpConstructorInput(ExecState*, EncodedJSValue, PropertyName); |
| 34 | static EncodedJSValue regExpConstructorMultiline(ExecState*, EncodedJSValue, PropertyName); |
| 35 | static EncodedJSValue regExpConstructorLastMatch(ExecState*, EncodedJSValue, PropertyName); |
| 36 | static EncodedJSValue regExpConstructorLastParen(ExecState*, EncodedJSValue, PropertyName); |
| 37 | static EncodedJSValue regExpConstructorLeftContext(ExecState*, EncodedJSValue, PropertyName); |
| 38 | static EncodedJSValue regExpConstructorRightContext(ExecState*, EncodedJSValue, PropertyName); |
utatane.tea@gmail.com | 6b509c8 | 2016-05-24 06:24:44 +0000 | [diff] [blame] | 39 | template<int N> |
utatane.tea@gmail.com | d80165c | 2016-06-06 01:56:11 +0000 | [diff] [blame] | 40 | static EncodedJSValue regExpConstructorDollar(ExecState*, EncodedJSValue, PropertyName); |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 41 | |
utatane.tea@gmail.com | 78b50c6 | 2016-03-11 17:28:46 +0000 | [diff] [blame] | 42 | static bool setRegExpConstructorInput(ExecState*, EncodedJSValue, EncodedJSValue); |
| 43 | static bool setRegExpConstructorMultiline(ExecState*, EncodedJSValue, EncodedJSValue); |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 44 | |
| 45 | } // namespace JSC |
| 46 | |
| 47 | #include "RegExpConstructor.lut.h" |
| 48 | |
| 49 | namespace JSC { |
| 50 | |
akling@apple.com | 2de49b7 | 2014-07-30 22:26:22 +0000 | [diff] [blame] | 51 | const ClassInfo RegExpConstructor::s_info = { "Function", &InternalFunction::s_info, ®ExpConstructorTable, CREATE_METHOD_TABLE(RegExpConstructor) }; |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 52 | |
| 53 | /* Source for RegExpConstructor.lut.h |
| 54 | @begin regExpConstructorTable |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 55 | input regExpConstructorInput None |
| 56 | $_ regExpConstructorInput DontEnum |
| 57 | multiline regExpConstructorMultiline None |
| 58 | $* regExpConstructorMultiline DontEnum |
| 59 | lastMatch regExpConstructorLastMatch DontDelete|ReadOnly |
| 60 | $& regExpConstructorLastMatch DontDelete|ReadOnly|DontEnum |
| 61 | lastParen regExpConstructorLastParen DontDelete|ReadOnly |
| 62 | $+ regExpConstructorLastParen DontDelete|ReadOnly|DontEnum |
| 63 | leftContext regExpConstructorLeftContext DontDelete|ReadOnly |
| 64 | $` regExpConstructorLeftContext DontDelete|ReadOnly|DontEnum |
| 65 | rightContext regExpConstructorRightContext DontDelete|ReadOnly |
| 66 | $' regExpConstructorRightContext DontDelete|ReadOnly|DontEnum |
utatane.tea@gmail.com | 6b509c8 | 2016-05-24 06:24:44 +0000 | [diff] [blame] | 67 | $1 regExpConstructorDollar<1> DontDelete|ReadOnly |
| 68 | $2 regExpConstructorDollar<2> DontDelete|ReadOnly |
| 69 | $3 regExpConstructorDollar<3> DontDelete|ReadOnly |
| 70 | $4 regExpConstructorDollar<4> DontDelete|ReadOnly |
| 71 | $5 regExpConstructorDollar<5> DontDelete|ReadOnly |
| 72 | $6 regExpConstructorDollar<6> DontDelete|ReadOnly |
| 73 | $7 regExpConstructorDollar<7> DontDelete|ReadOnly |
| 74 | $8 regExpConstructorDollar<8> DontDelete|ReadOnly |
| 75 | $9 regExpConstructorDollar<9> DontDelete|ReadOnly |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 76 | @end |
| 77 | */ |
| 78 | |
akling@apple.com | 5987552 | 2013-09-30 03:45:30 +0000 | [diff] [blame] | 79 | RegExpConstructor::RegExpConstructor(VM& vm, Structure* structure, RegExpPrototype* regExpPrototype) |
| 80 | : InternalFunction(vm, structure) |
mark.lam@apple.com | ff5f4f3 | 2016-03-18 23:14:34 +0000 | [diff] [blame] | 81 | , m_cachedResult(vm, this, regExpPrototype->emptyRegExp()) |
barraclough@apple.com | 0a0af1a | 2012-03-23 19:57:28 +0000 | [diff] [blame] | 82 | , m_multiline(false) |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 83 | { |
mhahnenberg@apple.com | 7317a7f | 2011-09-09 21:43:14 +0000 | [diff] [blame] | 84 | } |
| 85 | |
keith_miller@apple.com | 8af3d8d | 2016-01-22 18:44:46 +0000 | [diff] [blame] | 86 | void RegExpConstructor::finishCreation(VM& vm, RegExpPrototype* regExpPrototype, GetterSetter* speciesSymbol) |
mhahnenberg@apple.com | 7317a7f | 2011-09-09 21:43:14 +0000 | [diff] [blame] | 87 | { |
mark.lam@apple.com | ff5f4f3 | 2016-03-18 23:14:34 +0000 | [diff] [blame] | 88 | Base::finishCreation(vm, ASCIILiteral("RegExp")); |
fpizlo@apple.com | 10ae2d0 | 2013-08-14 02:41:47 +0000 | [diff] [blame] | 89 | ASSERT(inherits(info())); |
barraclough@apple.com | 737a158 | 2011-02-21 19:31:42 +0000 | [diff] [blame] | 90 | |
commit-queue@webkit.org | 5fb8032 | 2014-04-15 17:46:42 +0000 | [diff] [blame] | 91 | putDirectWithoutTransition(vm, vm.propertyNames->prototype, regExpPrototype, DontEnum | DontDelete | ReadOnly); |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 92 | |
weinig@apple.com | 2947a91 | 2008-07-07 02:49:29 +0000 | [diff] [blame] | 93 | // no. of arguments for constructor |
akling@apple.com | 2255806 | 2013-09-26 21:43:49 +0000 | [diff] [blame] | 94 | putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(2), ReadOnly | DontDelete | DontEnum); |
keith_miller@apple.com | 8af3d8d | 2016-01-22 18:44:46 +0000 | [diff] [blame] | 95 | |
keith_miller@apple.com | 73c6d4b | 2016-02-11 04:06:37 +0000 | [diff] [blame] | 96 | putDirectNonIndexAccessor(vm, vm.propertyNames->speciesSymbol, speciesSymbol, Accessor | ReadOnly | DontEnum); |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 97 | } |
| 98 | |
mhahnenberg@apple.com | c58d54d | 2011-12-16 19:06:44 +0000 | [diff] [blame] | 99 | void RegExpConstructor::destroy(JSCell* cell) |
| 100 | { |
ggaren@apple.com | 72da811 | 2012-05-26 22:40:46 +0000 | [diff] [blame] | 101 | static_cast<RegExpConstructor*>(cell)->RegExpConstructor::~RegExpConstructor(); |
mhahnenberg@apple.com | c58d54d | 2011-12-16 19:06:44 +0000 | [diff] [blame] | 102 | } |
| 103 | |
barraclough@apple.com | 0a0af1a | 2012-03-23 19:57:28 +0000 | [diff] [blame] | 104 | void RegExpConstructor::visitChildren(JSCell* cell, SlotVisitor& visitor) |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 105 | { |
barraclough@apple.com | 0a0af1a | 2012-03-23 19:57:28 +0000 | [diff] [blame] | 106 | RegExpConstructor* thisObject = jsCast<RegExpConstructor*>(cell); |
fpizlo@apple.com | 10ae2d0 | 2013-08-14 02:41:47 +0000 | [diff] [blame] | 107 | ASSERT_GC_OBJECT_INHERITS(thisObject, info()); |
barraclough@apple.com | 0a0af1a | 2012-03-23 19:57:28 +0000 | [diff] [blame] | 108 | Base::visitChildren(thisObject, visitor); |
| 109 | thisObject->m_cachedResult.visitChildren(visitor); |
commit-queue@webkit.org | 6e5671b | 2011-09-01 23:49:23 +0000 | [diff] [blame] | 110 | } |
| 111 | |
barraclough@apple.com | 0a0af1a | 2012-03-23 19:57:28 +0000 | [diff] [blame] | 112 | JSValue RegExpConstructor::getBackref(ExecState* exec, unsigned i) |
commit-queue@webkit.org | 6e5671b | 2011-09-01 23:49:23 +0000 | [diff] [blame] | 113 | { |
akling@apple.com | c98b79c | 2014-10-30 03:54:23 +0000 | [diff] [blame] | 114 | JSArray* array = m_cachedResult.lastResult(exec, this); |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 115 | |
barraclough@apple.com | 0a0af1a | 2012-03-23 19:57:28 +0000 | [diff] [blame] | 116 | if (i < array->length()) { |
| 117 | JSValue result = JSValue(array).get(exec, i); |
| 118 | ASSERT(result.isString() || result.isUndefined()); |
| 119 | if (!result.isUndefined()) |
| 120 | return result; |
darin@apple.com | e794585 | 2008-08-31 06:58:07 +0000 | [diff] [blame] | 121 | } |
| 122 | return jsEmptyString(exec); |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 123 | } |
| 124 | |
barraclough@apple.com | 0a0af1a | 2012-03-23 19:57:28 +0000 | [diff] [blame] | 125 | JSValue RegExpConstructor::getLastParen(ExecState* exec) |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 126 | { |
akling@apple.com | c98b79c | 2014-10-30 03:54:23 +0000 | [diff] [blame] | 127 | JSArray* array = m_cachedResult.lastResult(exec, this); |
barraclough@apple.com | 0a0af1a | 2012-03-23 19:57:28 +0000 | [diff] [blame] | 128 | unsigned length = array->length(); |
| 129 | if (length > 1) { |
| 130 | JSValue result = JSValue(array).get(exec, length - 1); |
| 131 | ASSERT(result.isString() || result.isUndefined()); |
| 132 | if (!result.isUndefined()) |
| 133 | return result; |
weinig@apple.com | 2947a91 | 2008-07-07 02:49:29 +0000 | [diff] [blame] | 134 | } |
darin@apple.com | e794585 | 2008-08-31 06:58:07 +0000 | [diff] [blame] | 135 | return jsEmptyString(exec); |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 136 | } |
| 137 | |
barraclough@apple.com | 0a0af1a | 2012-03-23 19:57:28 +0000 | [diff] [blame] | 138 | JSValue RegExpConstructor::getLeftContext(ExecState* exec) |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 139 | { |
akling@apple.com | c98b79c | 2014-10-30 03:54:23 +0000 | [diff] [blame] | 140 | return m_cachedResult.leftContext(exec, this); |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 141 | } |
| 142 | |
barraclough@apple.com | 0a0af1a | 2012-03-23 19:57:28 +0000 | [diff] [blame] | 143 | JSValue RegExpConstructor::getRightContext(ExecState* exec) |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 144 | { |
akling@apple.com | c98b79c | 2014-10-30 03:54:23 +0000 | [diff] [blame] | 145 | return m_cachedResult.rightContext(exec, this); |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 146 | } |
utatane.tea@gmail.com | 6b509c8 | 2016-05-24 06:24:44 +0000 | [diff] [blame] | 147 | |
| 148 | template<int N> |
utatane.tea@gmail.com | d80165c | 2016-06-06 01:56:11 +0000 | [diff] [blame] | 149 | EncodedJSValue regExpConstructorDollar(ExecState* exec, EncodedJSValue thisValue, PropertyName) |
oliver@apple.com | ae0687b | 2013-12-06 03:03:24 +0000 | [diff] [blame] | 150 | { |
utatane.tea@gmail.com | 6b509c8 | 2016-05-24 06:24:44 +0000 | [diff] [blame] | 151 | return JSValue::encode(asRegExpConstructor(JSValue::decode(thisValue))->getBackref(exec, N)); |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 152 | } |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 153 | |
utatane.tea@gmail.com | d80165c | 2016-06-06 01:56:11 +0000 | [diff] [blame] | 154 | EncodedJSValue regExpConstructorInput(ExecState*, EncodedJSValue thisValue, PropertyName) |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 155 | { |
barraclough@apple.com | 674f9cb | 2016-02-09 21:19:59 +0000 | [diff] [blame] | 156 | return JSValue::encode(asRegExpConstructor(JSValue::decode(thisValue))->input()); |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 157 | } |
| 158 | |
utatane.tea@gmail.com | d80165c | 2016-06-06 01:56:11 +0000 | [diff] [blame] | 159 | EncodedJSValue regExpConstructorMultiline(ExecState*, EncodedJSValue thisValue, PropertyName) |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 160 | { |
barraclough@apple.com | 674f9cb | 2016-02-09 21:19:59 +0000 | [diff] [blame] | 161 | return JSValue::encode(jsBoolean(asRegExpConstructor(JSValue::decode(thisValue))->multiline())); |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 162 | } |
| 163 | |
utatane.tea@gmail.com | d80165c | 2016-06-06 01:56:11 +0000 | [diff] [blame] | 164 | EncodedJSValue regExpConstructorLastMatch(ExecState* exec, EncodedJSValue thisValue, PropertyName) |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 165 | { |
barraclough@apple.com | 674f9cb | 2016-02-09 21:19:59 +0000 | [diff] [blame] | 166 | return JSValue::encode(asRegExpConstructor(JSValue::decode(thisValue))->getBackref(exec, 0)); |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 167 | } |
| 168 | |
utatane.tea@gmail.com | d80165c | 2016-06-06 01:56:11 +0000 | [diff] [blame] | 169 | EncodedJSValue regExpConstructorLastParen(ExecState* exec, EncodedJSValue thisValue, PropertyName) |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 170 | { |
barraclough@apple.com | 674f9cb | 2016-02-09 21:19:59 +0000 | [diff] [blame] | 171 | return JSValue::encode(asRegExpConstructor(JSValue::decode(thisValue))->getLastParen(exec)); |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 172 | } |
| 173 | |
utatane.tea@gmail.com | d80165c | 2016-06-06 01:56:11 +0000 | [diff] [blame] | 174 | EncodedJSValue regExpConstructorLeftContext(ExecState* exec, EncodedJSValue thisValue, PropertyName) |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 175 | { |
barraclough@apple.com | 674f9cb | 2016-02-09 21:19:59 +0000 | [diff] [blame] | 176 | return JSValue::encode(asRegExpConstructor(JSValue::decode(thisValue))->getLeftContext(exec)); |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 177 | } |
| 178 | |
utatane.tea@gmail.com | d80165c | 2016-06-06 01:56:11 +0000 | [diff] [blame] | 179 | EncodedJSValue regExpConstructorRightContext(ExecState* exec, EncodedJSValue thisValue, PropertyName) |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 180 | { |
barraclough@apple.com | 674f9cb | 2016-02-09 21:19:59 +0000 | [diff] [blame] | 181 | return JSValue::encode(asRegExpConstructor(JSValue::decode(thisValue))->getRightContext(exec)); |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 182 | } |
| 183 | |
utatane.tea@gmail.com | 78b50c6 | 2016-03-11 17:28:46 +0000 | [diff] [blame] | 184 | bool setRegExpConstructorInput(ExecState* exec, EncodedJSValue thisValue, EncodedJSValue value) |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 185 | { |
utatane.tea@gmail.com | 78b50c6 | 2016-03-11 17:28:46 +0000 | [diff] [blame] | 186 | if (auto constructor = jsDynamicCast<RegExpConstructor*>(JSValue::decode(thisValue))) { |
oliver@apple.com | 2b5f373 | 2014-01-25 01:26:49 +0000 | [diff] [blame] | 187 | constructor->setInput(exec, JSValue::decode(value).toString(exec)); |
utatane.tea@gmail.com | 78b50c6 | 2016-03-11 17:28:46 +0000 | [diff] [blame] | 188 | return true; |
| 189 | } |
| 190 | return false; |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 191 | } |
| 192 | |
utatane.tea@gmail.com | 78b50c6 | 2016-03-11 17:28:46 +0000 | [diff] [blame] | 193 | bool setRegExpConstructorMultiline(ExecState* exec, EncodedJSValue thisValue, EncodedJSValue value) |
weinig@apple.com | caf5e3b | 2008-09-27 02:36:15 +0000 | [diff] [blame] | 194 | { |
utatane.tea@gmail.com | 78b50c6 | 2016-03-11 17:28:46 +0000 | [diff] [blame] | 195 | if (auto constructor = jsDynamicCast<RegExpConstructor*>(JSValue::decode(thisValue))) { |
oliver@apple.com | 2b5f373 | 2014-01-25 01:26:49 +0000 | [diff] [blame] | 196 | constructor->setMultiline(JSValue::decode(value).toBoolean(exec)); |
utatane.tea@gmail.com | 78b50c6 | 2016-03-11 17:28:46 +0000 | [diff] [blame] | 197 | return true; |
| 198 | } |
| 199 | return false; |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 200 | } |
barraclough@apple.com | 1281293 | 2011-03-09 23:04:27 +0000 | [diff] [blame] | 201 | |
keith_miller@apple.com | 3793b13 | 2016-01-11 21:31:04 +0000 | [diff] [blame] | 202 | inline Structure* getRegExpStructure(ExecState* exec, JSGlobalObject* globalObject, JSValue newTarget) |
keith_miller@apple.com | 8dc2c35 | 2016-01-06 18:25:01 +0000 | [diff] [blame] | 203 | { |
| 204 | Structure* structure = globalObject->regExpStructure(); |
sbarati@apple.com | f065433 | 2016-02-23 00:51:02 +0000 | [diff] [blame] | 205 | if (newTarget != jsUndefined()) |
keith_miller@apple.com | 3793b13 | 2016-01-11 21:31:04 +0000 | [diff] [blame] | 206 | structure = InternalFunction::createSubclassStructure(exec, newTarget, structure); |
keith_miller@apple.com | 8dc2c35 | 2016-01-06 18:25:01 +0000 | [diff] [blame] | 207 | return structure; |
| 208 | } |
| 209 | |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 210 | inline RegExpFlags toFlags(ExecState* exec, JSValue flags) |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 211 | { |
mark.lam@apple.com | 284f456 | 2016-08-30 20:54:54 +0000 | [diff] [blame] | 212 | VM& vm = exec->vm(); |
| 213 | auto scope = DECLARE_THROW_SCOPE(vm); |
| 214 | |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 215 | if (flags.isUndefined()) |
| 216 | return NoFlags; |
| 217 | JSString* flagsString = flags.toString(exec); |
mark.lam@apple.com | 451de99 | 2016-09-07 22:10:50 +0000 | [diff] [blame] | 218 | ASSERT(scope.exception() || flagsString); |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 219 | if (!flagsString) { |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 220 | return InvalidFlags; |
| 221 | } |
weinig@apple.com | 2947a91 | 2008-07-07 02:49:29 +0000 | [diff] [blame] | 222 | |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 223 | RegExpFlags result = regExpFlags(flagsString->value(exec)); |
mark.lam@apple.com | e1ab17c | 2016-09-26 19:11:17 +0000 | [diff] [blame] | 224 | RETURN_IF_EXCEPTION(scope, InvalidFlags); |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 225 | if (result == InvalidFlags) |
mark.lam@apple.com | 284f456 | 2016-08-30 20:54:54 +0000 | [diff] [blame] | 226 | throwSyntaxError(exec, scope, ASCIILiteral("Invalid flags supplied to RegExp constructor.")); |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 227 | return result; |
| 228 | } |
| 229 | |
mark.lam@apple.com | 5aca499 | 2016-04-07 03:17:58 +0000 | [diff] [blame] | 230 | static JSObject* regExpCreate(ExecState* exec, JSGlobalObject* globalObject, JSValue newTarget, JSValue patternArg, JSValue flagsArg) |
| 231 | { |
| 232 | VM& vm = exec->vm(); |
mark.lam@apple.com | 284f456 | 2016-08-30 20:54:54 +0000 | [diff] [blame] | 233 | auto scope = DECLARE_THROW_SCOPE(vm); |
| 234 | |
mark.lam@apple.com | 5aca499 | 2016-04-07 03:17:58 +0000 | [diff] [blame] | 235 | String pattern = patternArg.isUndefined() ? emptyString() : patternArg.toString(exec)->value(exec); |
mark.lam@apple.com | e1ab17c | 2016-09-26 19:11:17 +0000 | [diff] [blame] | 236 | RETURN_IF_EXCEPTION(scope, nullptr); |
mark.lam@apple.com | 5aca499 | 2016-04-07 03:17:58 +0000 | [diff] [blame] | 237 | |
| 238 | RegExpFlags flags = toFlags(exec, flagsArg); |
| 239 | if (flags == InvalidFlags) |
| 240 | return nullptr; |
| 241 | |
| 242 | RegExp* regExp = RegExp::create(vm, pattern, flags); |
| 243 | if (!regExp->isValid()) |
mark.lam@apple.com | 284f456 | 2016-08-30 20:54:54 +0000 | [diff] [blame] | 244 | return throwException(exec, scope, createSyntaxError(exec, regExp->errorMessage())); |
mark.lam@apple.com | 5aca499 | 2016-04-07 03:17:58 +0000 | [diff] [blame] | 245 | |
| 246 | Structure* structure = getRegExpStructure(exec, globalObject, newTarget); |
mark.lam@apple.com | e1ab17c | 2016-09-26 19:11:17 +0000 | [diff] [blame] | 247 | RETURN_IF_EXCEPTION(scope, nullptr); |
mark.lam@apple.com | 5aca499 | 2016-04-07 03:17:58 +0000 | [diff] [blame] | 248 | return RegExpObject::create(vm, structure, regExp); |
| 249 | } |
| 250 | |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 251 | JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args, JSObject* callee, JSValue newTarget) |
| 252 | { |
msaboff@apple.com | 8569857 | 2016-03-10 23:38:15 +0000 | [diff] [blame] | 253 | VM& vm = exec->vm(); |
mark.lam@apple.com | 451de99 | 2016-09-07 22:10:50 +0000 | [diff] [blame] | 254 | auto scope = DECLARE_THROW_SCOPE(vm); |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 255 | JSValue patternArg = args.at(0); |
| 256 | JSValue flagsArg = args.at(1); |
| 257 | |
| 258 | bool isPatternRegExp = patternArg.inherits(RegExpObject::info()); |
| 259 | bool constructAsRegexp = isRegExp(vm, exec, patternArg); |
| 260 | |
| 261 | if (newTarget.isUndefined() && constructAsRegexp && flagsArg.isUndefined()) { |
| 262 | JSValue constructor = patternArg.get(exec, vm.propertyNames->constructor); |
mark.lam@apple.com | e1ab17c | 2016-09-26 19:11:17 +0000 | [diff] [blame] | 263 | RETURN_IF_EXCEPTION(scope, nullptr); |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 264 | if (callee == constructor) { |
| 265 | // We know that patternArg is a object otherwise constructAsRegexp would be false. |
| 266 | return patternArg.getObject(); |
barraclough@apple.com | 502e874 | 2011-06-28 18:35:37 +0000 | [diff] [blame] | 267 | } |
weinig@apple.com | 2947a91 | 2008-07-07 02:49:29 +0000 | [diff] [blame] | 268 | } |
| 269 | |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 270 | if (isPatternRegExp) { |
| 271 | RegExp* regExp = jsCast<RegExpObject*>(patternArg)->regExp(); |
| 272 | Structure* structure = getRegExpStructure(exec, globalObject, newTarget); |
mark.lam@apple.com | e1ab17c | 2016-09-26 19:11:17 +0000 | [diff] [blame] | 273 | RETURN_IF_EXCEPTION(scope, nullptr); |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 274 | |
| 275 | if (!flagsArg.isUndefined()) { |
| 276 | RegExpFlags flags = toFlags(exec, flagsArg); |
| 277 | if (flags == InvalidFlags) |
| 278 | return nullptr; |
| 279 | regExp = RegExp::create(vm, regExp->pattern(), flags); |
| 280 | } |
| 281 | |
| 282 | return RegExpObject::create(exec->vm(), structure, regExp); |
| 283 | } |
| 284 | |
| 285 | if (constructAsRegexp) { |
| 286 | JSValue pattern = patternArg.get(exec, vm.propertyNames->source); |
| 287 | if (flagsArg.isUndefined()) |
| 288 | flagsArg = patternArg.get(exec, vm.propertyNames->flags); |
| 289 | patternArg = pattern; |
| 290 | } |
| 291 | |
mark.lam@apple.com | 5aca499 | 2016-04-07 03:17:58 +0000 | [diff] [blame] | 292 | return regExpCreate(exec, globalObject, newTarget, patternArg, flagsArg); |
| 293 | } |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 294 | |
mark.lam@apple.com | 5aca499 | 2016-04-07 03:17:58 +0000 | [diff] [blame] | 295 | EncodedJSValue JSC_HOST_CALL esSpecRegExpCreate(ExecState* exec) |
| 296 | { |
| 297 | JSGlobalObject* globalObject = exec->lexicalGlobalObject(); |
| 298 | JSValue patternArg = exec->argument(0); |
| 299 | JSValue flagsArg = exec->argument(1); |
| 300 | return JSValue::encode(regExpCreate(exec, globalObject, jsUndefined(), patternArg, flagsArg)); |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 301 | } |
| 302 | |
barraclough@apple.com | 11d351a | 2010-06-04 21:38:38 +0000 | [diff] [blame] | 303 | static EncodedJSValue JSC_HOST_CALL constructWithRegExpConstructor(ExecState* exec) |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 304 | { |
barraclough@apple.com | 11d351a | 2010-06-04 21:38:38 +0000 | [diff] [blame] | 305 | ArgList args(exec); |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 306 | return JSValue::encode(constructRegExp(exec, asInternalFunction(exec->callee())->globalObject(), args, exec->callee(), exec->newTarget())); |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 307 | } |
| 308 | |
mhahnenberg@apple.com | 79c8e6e | 2011-10-08 23:26:41 +0000 | [diff] [blame] | 309 | ConstructType RegExpConstructor::getConstructData(JSCell*, ConstructData& constructData) |
| 310 | { |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 311 | constructData.native.function = constructWithRegExpConstructor; |
utatane.tea@gmail.com | f76f1b4 | 2016-03-05 17:01:04 +0000 | [diff] [blame] | 312 | return ConstructType::Host; |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 313 | } |
| 314 | |
barraclough@apple.com | 99ff343 | 2010-06-03 20:00:18 +0000 | [diff] [blame] | 315 | static EncodedJSValue JSC_HOST_CALL callRegExpConstructor(ExecState* exec) |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 316 | { |
ggaren@apple.com | fea29f1 | 2010-05-29 06:33:05 +0000 | [diff] [blame] | 317 | ArgList args(exec); |
keith_miller@apple.com | ae261a8 | 2016-04-06 18:26:11 +0000 | [diff] [blame] | 318 | return JSValue::encode(constructRegExp(exec, asInternalFunction(exec->callee())->globalObject(), args, exec->callee())); |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 319 | } |
| 320 | |
mhahnenberg@apple.com | 2413eb8 | 2011-09-27 22:46:51 +0000 | [diff] [blame] | 321 | CallType RegExpConstructor::getCallData(JSCell*, CallData& callData) |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 322 | { |
| 323 | callData.native.function = callRegExpConstructor; |
utatane.tea@gmail.com | f76f1b4 | 2016-03-05 17:01:04 +0000 | [diff] [blame] | 324 | return CallType::Host; |
weinig@apple.com | 343e3d7 | 2008-06-29 00:09:26 +0000 | [diff] [blame] | 325 | } |
| 326 | |
cwzwarich@webkit.org | 3f782f6 | 2008-09-08 01:28:33 +0000 | [diff] [blame] | 327 | } // namespace JSC |