18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved. 48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is free software; you can redistribute it and/or 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modify it under the terms of the GNU Lesser General Public 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License as published by the Free Software Foundation; either 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * version 2 of the License, or (at your option) any later version. 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * This library is distributed in the hope that it will be useful, 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Lesser General Public License for more details. 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * You should have received a copy of the GNU Lesser General Public 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * License along with this library; if not, write to the Free Software 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RegExpObject.h" 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian#include "Error.h" 25545e470e52f0ac6a3a072bf559c796b42c6066b6Ben Murdoch#include "ExceptionHelpers.h" 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSArray.h" 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSGlobalObject.h" 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSString.h" 29dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block#include "Lookup.h" 308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RegExpConstructor.h" 318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RegExpPrototype.h" 32a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "UStringConcatenate.h" 33e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke#include <wtf/PassOwnPtr.h> 348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC { 368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 37dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic JSValue regExpObjectGlobal(ExecState*, JSValue, const Identifier&); 38dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic JSValue regExpObjectIgnoreCase(ExecState*, JSValue, const Identifier&); 39dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic JSValue regExpObjectMultiline(ExecState*, JSValue, const Identifier&); 40dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic JSValue regExpObjectSource(ExecState*, JSValue, const Identifier&); 41dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Blockstatic JSValue regExpObjectLastIndex(ExecState*, JSValue, const Identifier&); 425f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianstatic void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValue); 438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC 458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "RegExpObject.lut.h" 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC { 498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectASSERT_CLASS_FITS_IN_CELL(RegExpObject); 518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 5281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochconst ClassInfo RegExpObject::s_info = { "RegExp", &JSObjectWithGlobalObject::s_info, 0, ExecState::regExpTable }; 538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* Source for RegExpObject.lut.h 558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@begin regExpTable 568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project global regExpObjectGlobal DontDelete|ReadOnly|DontEnum 578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ignoreCase regExpObjectIgnoreCase DontDelete|ReadOnly|DontEnum 588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project multiline regExpObjectMultiline DontDelete|ReadOnly|DontEnum 598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project source regExpObjectSource DontDelete|ReadOnly|DontEnum 608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lastIndex regExpObjectLastIndex DontDelete|DontEnum 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project@end 628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project*/ 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 642daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben MurdochRegExpObject::RegExpObject(JSGlobalObject* globalObject, Structure* structure, NonNullPassRefPtr<RegExp> regExp) 65e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block : JSObjectWithGlobalObject(globalObject, structure) 662bde8e466a4451c7319e3a072d118917957d6554Steve Block , d(adoptPtr(new RegExpObjectData(regExp))) 678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 6881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ASSERT(inherits(&s_info)); 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectRegExpObject::~RegExpObject() 728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 752bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid RegExpObject::markChildren(MarkStack& markStack) 762bde8e466a4451c7319e3a072d118917957d6554Steve Block{ 772bde8e466a4451c7319e3a072d118917957d6554Steve Block Base::markChildren(markStack); 782bde8e466a4451c7319e3a072d118917957d6554Steve Block if (UNLIKELY(!d->lastIndex.get().isInt32())) 792bde8e466a4451c7319e3a072d118917957d6554Steve Block markStack.append(&d->lastIndex); 802bde8e466a4451c7319e3a072d118917957d6554Steve Block} 812bde8e466a4451c7319e3a072d118917957d6554Steve Block 828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) 838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot); 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 87231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool RegExpObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 88231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 89231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return getStaticValueDescriptor<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, descriptor); 90231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 91231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 92dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSValue regExpObjectGlobal(ExecState*, JSValue slotBase, const Identifier&) 938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 94dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return jsBoolean(asRegExpObject(slotBase)->regExp()->global()); 958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 97dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSValue regExpObjectIgnoreCase(ExecState*, JSValue slotBase, const Identifier&) 988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 99dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return jsBoolean(asRegExpObject(slotBase)->regExp()->ignoreCase()); 1008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 102dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSValue regExpObjectMultiline(ExecState*, JSValue slotBase, const Identifier&) 1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 104dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return jsBoolean(asRegExpObject(slotBase)->regExp()->multiline()); 1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 107dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockJSValue regExpObjectSource(ExecState* exec, JSValue slotBase, const Identifier&) 1088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 109dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block return jsString(exec, asRegExpObject(slotBase)->regExp()->pattern()); 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 112e14391e94c850b8bd03680c23b38978db68687a8John ReckJSValue regExpObjectLastIndex(ExecState*, JSValue slotBase, const Identifier&) 1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1142bde8e466a4451c7319e3a072d118917957d6554Steve Block return asRegExpObject(slotBase)->getLastIndex(); 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1175f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), this, slot); 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1225f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue value) 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1242bde8e466a4451c7319e3a072d118917957d6554Steve Block asRegExpObject(baseObject)->setLastIndex(exec->globalData(), value); 1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1275af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeJSValue RegExpObject::test(ExecState* exec) 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1295af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke return jsBoolean(match(exec)); 1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1325af96e2c7b73ebc627c6894727826a7576d31758Leon ClarkeJSValue RegExpObject::exec(ExecState* exec) 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1345af96e2c7b73ebc627c6894727826a7576d31758Leon Clarke if (match(exec)) 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return exec->lexicalGlobalObject()->regExpConstructor()->arrayOfMatches(exec); 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return jsNull(); 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 139635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project// Shared implementation used by test and exec. 1405af96e2c7b73ebc627c6894727826a7576d31758Leon Clarkebool RegExpObject::match(ExecState* exec) 141635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 142635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); 1432bde8e466a4451c7319e3a072d118917957d6554Steve Block UString input = exec->argument(0).toString(exec); 144635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 145635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!regExp()->global()) { 146635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project int position; 147635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project int length; 148635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project regExpConstructor->performMatch(d->regExp.get(), input, 0, position, length); 149635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return position >= 0; 150635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 151635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1522bde8e466a4451c7319e3a072d118917957d6554Steve Block JSValue jsLastIndex = getLastIndex(); 1532bde8e466a4451c7319e3a072d118917957d6554Steve Block unsigned lastIndex; 1542bde8e466a4451c7319e3a072d118917957d6554Steve Block if (LIKELY(jsLastIndex.isUInt32())) { 1552bde8e466a4451c7319e3a072d118917957d6554Steve Block lastIndex = jsLastIndex.asUInt32(); 1562bde8e466a4451c7319e3a072d118917957d6554Steve Block if (lastIndex > input.length()) { 1572bde8e466a4451c7319e3a072d118917957d6554Steve Block setLastIndex(0); 1582bde8e466a4451c7319e3a072d118917957d6554Steve Block return false; 1592bde8e466a4451c7319e3a072d118917957d6554Steve Block } 1602bde8e466a4451c7319e3a072d118917957d6554Steve Block } else { 1612bde8e466a4451c7319e3a072d118917957d6554Steve Block double doubleLastIndex = jsLastIndex.toInteger(exec); 1622bde8e466a4451c7319e3a072d118917957d6554Steve Block if (doubleLastIndex < 0 || doubleLastIndex > input.length()) { 1632bde8e466a4451c7319e3a072d118917957d6554Steve Block setLastIndex(0); 1642bde8e466a4451c7319e3a072d118917957d6554Steve Block return false; 1652bde8e466a4451c7319e3a072d118917957d6554Steve Block } 1662bde8e466a4451c7319e3a072d118917957d6554Steve Block lastIndex = static_cast<unsigned>(doubleLastIndex); 167635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 168635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 169635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project int position; 170cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block int length = 0; 1712bde8e466a4451c7319e3a072d118917957d6554Steve Block regExpConstructor->performMatch(d->regExp.get(), input, lastIndex, position, length); 172635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (position < 0) { 1732bde8e466a4451c7319e3a072d118917957d6554Steve Block setLastIndex(0); 174635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return false; 175635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 176635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1772bde8e466a4451c7319e3a072d118917957d6554Steve Block setLastIndex(position + length); 178635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return true; 179635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 180635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace JSC 182