/* | |
* Copyright (C) 1999-2000 Harri Porten (porten@kde.org) | |
* Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved. | |
* | |
* This library is free software; you can redistribute it and/or | |
* modify it under the terms of the GNU Lesser General Public | |
* License as published by the Free Software Foundation; either | |
* version 2 of the License, or (at your option) any later version. | |
* | |
* This library is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
* Lesser General Public License for more details. | |
* | |
* You should have received a copy of the GNU Lesser General Public | |
* License along with this library; if not, write to the Free Software | |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
* | |
*/ | |
#include "config.h" | |
#include "RegExpPrototype.h" | |
#include "ArrayPrototype.h" | |
#include "Error.h" | |
#include "JSArray.h" | |
#include "JSFunction.h" | |
#include "JSObject.h" | |
#include "JSString.h" | |
#include "JSValue.h" | |
#include "ObjectPrototype.h" | |
#include "PrototypeFunction.h" | |
#include "RegExpObject.h" | |
#include "RegExp.h" | |
namespace JSC { | |
ASSERT_CLASS_FITS_IN_CELL(RegExpPrototype); | |
static JSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState*, JSObject*, JSValue, const ArgList&); | |
static JSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState*, JSObject*, JSValue, const ArgList&); | |
static JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState*, JSObject*, JSValue, const ArgList&); | |
static JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState*, JSObject*, JSValue, const ArgList&); | |
// ECMA 15.10.5 | |
const ClassInfo RegExpPrototype::info = { "RegExpPrototype", 0, 0, 0 }; | |
RegExpPrototype::RegExpPrototype(ExecState* exec, NonNullPassRefPtr<Structure> structure, Structure* prototypeFunctionStructure) | |
: JSObject(structure) | |
{ | |
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().compile, regExpProtoFuncCompile), DontEnum); | |
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().exec, regExpProtoFuncExec), DontEnum); | |
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().test, regExpProtoFuncTest), DontEnum); | |
putDirectFunctionWithoutTransition(exec, new (exec) NativeFunctionWrapper(exec, prototypeFunctionStructure, 0, exec->propertyNames().toString, regExpProtoFuncToString), DontEnum); | |
} | |
// ------------------------------ Functions --------------------------- | |
JSValue JSC_HOST_CALL regExpProtoFuncTest(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) | |
{ | |
if (!thisValue.inherits(&RegExpObject::info)) | |
return throwError(exec, TypeError); | |
return asRegExpObject(thisValue)->test(exec, args); | |
} | |
JSValue JSC_HOST_CALL regExpProtoFuncExec(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) | |
{ | |
if (!thisValue.inherits(&RegExpObject::info)) | |
return throwError(exec, TypeError); | |
return asRegExpObject(thisValue)->exec(exec, args); | |
} | |
JSValue JSC_HOST_CALL regExpProtoFuncCompile(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) | |
{ | |
if (!thisValue.inherits(&RegExpObject::info)) | |
return throwError(exec, TypeError); | |
RefPtr<RegExp> regExp; | |
JSValue arg0 = args.at(0); | |
JSValue arg1 = args.at(1); | |
if (arg0.inherits(&RegExpObject::info)) { | |
if (!arg1.isUndefined()) | |
return throwError(exec, TypeError, "Cannot supply flags when constructing one RegExp from another."); | |
regExp = asRegExpObject(arg0)->regExp(); | |
} else { | |
UString pattern = args.isEmpty() ? UString("") : arg0.toString(exec); | |
UString flags = arg1.isUndefined() ? UString("") : arg1.toString(exec); | |
regExp = RegExp::create(&exec->globalData(), pattern, flags); | |
} | |
if (!regExp->isValid()) | |
return throwError(exec, SyntaxError, makeString("Invalid regular expression: ", regExp->errorMessage())); | |
asRegExpObject(thisValue)->setRegExp(regExp.release()); | |
asRegExpObject(thisValue)->setLastIndex(0); | |
return jsUndefined(); | |
} | |
JSValue JSC_HOST_CALL regExpProtoFuncToString(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&) | |
{ | |
if (!thisValue.inherits(&RegExpObject::info)) { | |
if (thisValue.inherits(&RegExpPrototype::info)) | |
return jsNontrivialString(exec, "//"); | |
return throwError(exec, TypeError); | |
} | |
char postfix[5] = { '/', 0, 0, 0, 0 }; | |
int index = 1; | |
if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().global).toBoolean(exec)) | |
postfix[index++] = 'g'; | |
if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().ignoreCase).toBoolean(exec)) | |
postfix[index++] = 'i'; | |
if (asRegExpObject(thisValue)->get(exec, exec->propertyNames().multiline).toBoolean(exec)) | |
postfix[index] = 'm'; | |
UString source = asRegExpObject(thisValue)->get(exec, exec->propertyNames().source).toString(exec); | |
// If source is empty, use "/(?:)/" to avoid colliding with comment syntax | |
return jsNontrivialString(exec, makeString("/", source.size() ? source : UString("(?:)"), postfix)); | |
} | |
} // namespace JSC |