JavaScriptCore/runtime/RegExpObject.cpp
changeset 0 4f2f89ce4247
equal deleted inserted replaced
-1:000000000000 0:4f2f89ce4247
       
     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 <wtf/PassOwnPtr.h>
       
    33 
       
    34 namespace JSC {
       
    35 
       
    36 static JSValue regExpObjectGlobal(ExecState*, JSValue, const Identifier&);
       
    37 static JSValue regExpObjectIgnoreCase(ExecState*, JSValue, const Identifier&);
       
    38 static JSValue regExpObjectMultiline(ExecState*, JSValue, const Identifier&);
       
    39 static JSValue regExpObjectSource(ExecState*, JSValue, const Identifier&);
       
    40 static JSValue regExpObjectLastIndex(ExecState*, JSValue, const Identifier&);
       
    41 static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValue);
       
    42 
       
    43 } // namespace JSC
       
    44 
       
    45 #include "RegExpObject.lut.h"
       
    46 
       
    47 namespace JSC {
       
    48 
       
    49 ASSERT_CLASS_FITS_IN_CELL(RegExpObject);
       
    50 
       
    51 const ClassInfo RegExpObject::info = { "RegExp", 0, 0, ExecState::regExpTable };
       
    52 
       
    53 /* Source for RegExpObject.lut.h
       
    54 @begin regExpTable
       
    55     global        regExpObjectGlobal       DontDelete|ReadOnly|DontEnum
       
    56     ignoreCase    regExpObjectIgnoreCase   DontDelete|ReadOnly|DontEnum
       
    57     multiline     regExpObjectMultiline    DontDelete|ReadOnly|DontEnum
       
    58     source        regExpObjectSource       DontDelete|ReadOnly|DontEnum
       
    59     lastIndex     regExpObjectLastIndex    DontDelete|DontEnum
       
    60 @end
       
    61 */
       
    62 
       
    63 RegExpObject::RegExpObject(JSGlobalObject* globalObject, NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<RegExp> regExp)
       
    64     : JSObjectWithGlobalObject(globalObject, structure)
       
    65     , d(adoptPtr(new RegExpObjectData(regExp, 0)))
       
    66 {
       
    67 }
       
    68 
       
    69 RegExpObject::~RegExpObject()
       
    70 {
       
    71 }
       
    72 
       
    73 bool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
       
    74 {
       
    75     return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot);
       
    76 }
       
    77 
       
    78 bool RegExpObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
       
    79 {
       
    80     return getStaticValueDescriptor<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, descriptor);
       
    81 }
       
    82 
       
    83 JSValue regExpObjectGlobal(ExecState*, JSValue slotBase, const Identifier&)
       
    84 {
       
    85     return jsBoolean(asRegExpObject(slotBase)->regExp()->global());
       
    86 }
       
    87 
       
    88 JSValue regExpObjectIgnoreCase(ExecState*, JSValue slotBase, const Identifier&)
       
    89 {
       
    90     return jsBoolean(asRegExpObject(slotBase)->regExp()->ignoreCase());
       
    91 }
       
    92  
       
    93 JSValue regExpObjectMultiline(ExecState*, JSValue slotBase, const Identifier&)
       
    94 {            
       
    95     return jsBoolean(asRegExpObject(slotBase)->regExp()->multiline());
       
    96 }
       
    97 
       
    98 JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, const Identifier&)
       
    99 {
       
   100     return jsString(exec, asRegExpObject(slotBase)->regExp()->pattern());
       
   101 }
       
   102 
       
   103 JSValue regExpObjectLastIndex(ExecState* exec, JSValue slotBase, const Identifier&)
       
   104 {
       
   105     return jsNumber(exec, asRegExpObject(slotBase)->lastIndex());
       
   106 }
       
   107 
       
   108 void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
       
   109 {
       
   110     lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), this, slot);
       
   111 }
       
   112 
       
   113 void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue value)
       
   114 {
       
   115     asRegExpObject(baseObject)->setLastIndex(value.toInteger(exec));
       
   116 }
       
   117 
       
   118 JSValue RegExpObject::test(ExecState* exec)
       
   119 {
       
   120     return jsBoolean(match(exec));
       
   121 }
       
   122 
       
   123 JSValue RegExpObject::exec(ExecState* exec)
       
   124 {
       
   125     if (match(exec))
       
   126         return exec->lexicalGlobalObject()->regExpConstructor()->arrayOfMatches(exec);
       
   127     return jsNull();
       
   128 }
       
   129 
       
   130 static EncodedJSValue JSC_HOST_CALL callRegExpObject(ExecState* exec)
       
   131 {
       
   132     return JSValue::encode(asRegExpObject(exec->callee())->exec(exec));
       
   133 }
       
   134 
       
   135 CallType RegExpObject::getCallData(CallData& callData)
       
   136 {
       
   137     callData.native.function = callRegExpObject;
       
   138     return CallTypeHost;
       
   139 }
       
   140 
       
   141 // Shared implementation used by test and exec.
       
   142 bool RegExpObject::match(ExecState* exec)
       
   143 {
       
   144     RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
       
   145 
       
   146     UString input = !exec->argumentCount() ? regExpConstructor->input() : exec->argument(0).toString(exec);
       
   147     if (input.isNull()) {
       
   148         throwError(exec, createError(exec, makeString("No input to ", toString(exec), ".")));
       
   149         return false;
       
   150     }
       
   151 
       
   152     if (!regExp()->global()) {
       
   153         int position;
       
   154         int length;
       
   155         regExpConstructor->performMatch(d->regExp.get(), input, 0, position, length);
       
   156         return position >= 0;
       
   157     }
       
   158 
       
   159     if (d->lastIndex < 0 || d->lastIndex > input.size()) {
       
   160         d->lastIndex = 0;
       
   161         return false;
       
   162     }
       
   163 
       
   164     int position;
       
   165     int length = 0;
       
   166     regExpConstructor->performMatch(d->regExp.get(), input, static_cast<int>(d->lastIndex), position, length);
       
   167     if (position < 0) {
       
   168         d->lastIndex = 0;
       
   169         return false;
       
   170     }
       
   171 
       
   172     d->lastIndex = position + length;
       
   173     return true;
       
   174 }
       
   175 
       
   176 } // namespace JSC