RegExpObject.cpp revision ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddb
1/* 2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) 3 * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved. 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 * 19 */ 20 21#include "config.h" 22#include "RegExpObject.h" 23 24#include "Error.h" 25#include "ExceptionHelpers.h" 26#include "JSArray.h" 27#include "JSGlobalObject.h" 28#include "JSString.h" 29#include "Lookup.h" 30#include "RegExpConstructor.h" 31#include "RegExpPrototype.h" 32#include "UStringConcatenate.h" 33#include <wtf/PassOwnPtr.h> 34 35namespace JSC { 36 37static JSValue regExpObjectGlobal(ExecState*, JSValue, const Identifier&); 38static JSValue regExpObjectIgnoreCase(ExecState*, JSValue, const Identifier&); 39static JSValue regExpObjectMultiline(ExecState*, JSValue, const Identifier&); 40static JSValue regExpObjectSource(ExecState*, JSValue, const Identifier&); 41static JSValue regExpObjectLastIndex(ExecState*, JSValue, const Identifier&); 42static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValue); 43 44} // namespace JSC 45 46#include "RegExpObject.lut.h" 47 48namespace JSC { 49 50ASSERT_CLASS_FITS_IN_CELL(RegExpObject); 51 52const ClassInfo RegExpObject::info = { "RegExp", 0, 0, ExecState::regExpTable }; 53 54/* Source for RegExpObject.lut.h 55@begin regExpTable 56 global regExpObjectGlobal DontDelete|ReadOnly|DontEnum 57 ignoreCase regExpObjectIgnoreCase DontDelete|ReadOnly|DontEnum 58 multiline regExpObjectMultiline DontDelete|ReadOnly|DontEnum 59 source regExpObjectSource DontDelete|ReadOnly|DontEnum 60 lastIndex regExpObjectLastIndex DontDelete|DontEnum 61@end 62*/ 63 64RegExpObject::RegExpObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<RegExp> regExp) 65 : JSObjectWithGlobalObject(globalObject, structure) 66 , d(adoptPtr(new RegExpObjectData(regExp, 0))) 67{ 68} 69 70RegExpObject::~RegExpObject() 71{ 72} 73 74bool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) 75{ 76 return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot); 77} 78 79bool RegExpObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) 80{ 81 return getStaticValueDescriptor<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, descriptor); 82} 83 84JSValue regExpObjectGlobal(ExecState*, JSValue slotBase, const Identifier&) 85{ 86 return jsBoolean(asRegExpObject(slotBase)->regExp()->global()); 87} 88 89JSValue regExpObjectIgnoreCase(ExecState*, JSValue slotBase, const Identifier&) 90{ 91 return jsBoolean(asRegExpObject(slotBase)->regExp()->ignoreCase()); 92} 93 94JSValue regExpObjectMultiline(ExecState*, JSValue slotBase, const Identifier&) 95{ 96 return jsBoolean(asRegExpObject(slotBase)->regExp()->multiline()); 97} 98 99JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, const Identifier&) 100{ 101 return jsString(exec, asRegExpObject(slotBase)->regExp()->pattern()); 102} 103 104JSValue regExpObjectLastIndex(ExecState*, JSValue slotBase, const Identifier&) 105{ 106 return jsNumber(asRegExpObject(slotBase)->lastIndex()); 107} 108 109void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) 110{ 111 lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), this, slot); 112} 113 114void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue value) 115{ 116 asRegExpObject(baseObject)->setLastIndex(value.toInteger(exec)); 117} 118 119JSValue RegExpObject::test(ExecState* exec) 120{ 121 return jsBoolean(match(exec)); 122} 123 124JSValue RegExpObject::exec(ExecState* exec) 125{ 126 if (match(exec)) 127 return exec->lexicalGlobalObject()->regExpConstructor()->arrayOfMatches(exec); 128 return jsNull(); 129} 130 131// Shared implementation used by test and exec. 132bool RegExpObject::match(ExecState* exec) 133{ 134 RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); 135 136 UString input = !exec->argumentCount() ? regExpConstructor->input() : exec->argument(0).toString(exec); 137 if (input.isNull()) { 138 throwError(exec, createError(exec, makeUString("No input to ", toString(exec), "."))); 139 return false; 140 } 141 142 if (!regExp()->global()) { 143 int position; 144 int length; 145 regExpConstructor->performMatch(d->regExp.get(), input, 0, position, length); 146 return position >= 0; 147 } 148 149 if (d->lastIndex < 0 || d->lastIndex > input.length()) { 150 d->lastIndex = 0; 151 return false; 152 } 153 154 int position; 155 int length = 0; 156 regExpConstructor->performMatch(d->regExp.get(), input, static_cast<int>(d->lastIndex), position, length); 157 if (position < 0) { 158 d->lastIndex = 0; 159 return false; 160 } 161 162 d->lastIndex = position + length; 163 return true; 164} 165 166} // namespace JSC 167