2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
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.
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.
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
22 #include "RegExpPrototype.h"
24 #include "ArrayPrototype.h"
27 #include "JSFunction.h"
30 #include "JSStringBuilder.h"
32 #include "ObjectPrototype.h"
33 #include "RegExpObject.h"
35 #include "RegExpCache.h"
36 #include "StringRecursionChecker.h"
37 #include "UStringConcatenate.h"
41 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState*);
42 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState*);
43 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState*);
44 static EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState*);
48 #include "RegExpPrototype.lut.h"
52 const ClassInfo RegExpPrototype::s_info = { "RegExp", &RegExpObject::s_info, 0, ExecState::regExpPrototypeTable };
54 /* Source for RegExpPrototype.lut.h
55 @begin regExpPrototypeTable
56 compile regExpProtoFuncCompile DontEnum|Function 2
57 exec regExpProtoFuncExec DontEnum|Function 1
58 test regExpProtoFuncTest DontEnum|Function 1
59 toString regExpProtoFuncToString DontEnum|Function 0
63 ASSERT_CLASS_FITS_IN_CELL(RegExpPrototype);
65 RegExpPrototype::RegExpPrototype(JSGlobalObject* globalObject, Structure* structure, RegExp* regExp)
66 : RegExpObject(globalObject, structure, regExp)
70 bool RegExpPrototype::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot &slot)
72 return getStaticFunctionSlot<RegExpObject>(exec, ExecState::regExpPrototypeTable(exec), this, propertyName, slot);
75 bool RegExpPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
77 return getStaticFunctionDescriptor<RegExpObject>(exec, ExecState::regExpPrototypeTable(exec), this, propertyName, descriptor);
80 // ------------------------------ Functions ---------------------------
82 EncodedJSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState* exec)
84 JSValue thisValue = exec->hostThisValue();
85 if (!thisValue.inherits(&RegExpObject::s_info))
86 return throwVMTypeError(exec);
87 return JSValue::encode(asRegExpObject(thisValue)->test(exec));
90 EncodedJSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState* exec)
92 JSValue thisValue = exec->hostThisValue();
93 if (!thisValue.inherits(&RegExpObject::s_info))
94 return throwVMTypeError(exec);
95 return JSValue::encode(asRegExpObject(thisValue)->exec(exec));
98 EncodedJSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec)
100 JSValue thisValue = exec->hostThisValue();
101 if (!thisValue.inherits(&RegExpObject::s_info))
102 return throwVMTypeError(exec);
105 JSValue arg0 = exec->argument(0);
106 JSValue arg1 = exec->argument(1);
108 if (arg0.inherits(&RegExpObject::s_info)) {
109 if (!arg1.isUndefined())
110 return throwVMError(exec, createTypeError(exec, "Cannot supply flags when constructing one RegExp from another."));
111 regExp = asRegExpObject(arg0)->regExp();
113 UString pattern = !exec->argumentCount() ? UString("") : arg0.toString(exec);
114 if (exec->hadException())
115 return JSValue::encode(jsUndefined());
117 RegExpFlags flags = NoFlags;
118 if (!arg1.isUndefined()) {
119 flags = regExpFlags(arg1.toString(exec));
120 if (exec->hadException())
121 return JSValue::encode(jsUndefined());
122 if (flags == InvalidFlags)
123 return throwVMError(exec, createSyntaxError(exec, "Invalid flags supplied to RegExp constructor."));
125 regExp = RegExp::create(exec->globalData(), pattern, flags);
128 if (!regExp->isValid())
129 return throwVMError(exec, createSyntaxError(exec, regExp->errorMessage()));
131 asRegExpObject(thisValue)->setRegExp(exec->globalData(), regExp);
132 asRegExpObject(thisValue)->setLastIndex(0);
133 return JSValue::encode(jsUndefined());
136 EncodedJSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec)
138 JSValue thisValue = exec->hostThisValue();
139 if (!thisValue.inherits(&RegExpObject::s_info))
140 return throwVMTypeError(exec);
142 RegExpObject* thisObject = asRegExpObject(thisValue);
144 StringRecursionChecker checker(exec, thisObject);
145 if (EncodedJSValue earlyReturnValue = checker.earlyReturnValue())
146 return earlyReturnValue;
148 char postfix[5] = { '/', 0, 0, 0, 0 };
150 if (thisObject->get(exec, exec->propertyNames().global).toBoolean(exec))
151 postfix[index++] = 'g';
152 if (thisObject->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec))
153 postfix[index++] = 'i';
154 if (thisObject->get(exec, exec->propertyNames().multiline).toBoolean(exec))
155 postfix[index] = 'm';
156 UString source = thisObject->get(exec, exec->propertyNames().source).toString(exec);
157 // If source is empty, use "/(?:)/" to avoid colliding with comment syntax
158 return JSValue::encode(jsMakeNontrivialString(exec, "/", source.length() ? source : UString("(?:)"), postfix));