Changeset 199144 in webkit


Ignore:
Timestamp:
Apr 6, 2016 8:17:58 PM (8 years ago)
Author:
mark.lam@apple.com
Message:

String.prototype.match() should be calling internal function RegExpCreate.
https://bugs.webkit.org/show_bug.cgi?id=156318

Reviewed by Filip Pizlo.

RegExpCreate is not the same as the RegExp constructor. The current implementation
invokes new @RegExp which calls the constructor. This results in failures in
es6/Proxy_internal_get_calls_String.prototype.match.js, and
es6/Proxy_internal_get_calls_String.prototype.search.js due to observable side
effects.

This patch fixes this by factoring out the part of the RegExp constructor that
makes the RegExpCreate function, and changing String's match and search to call
RegExpCreate instead in accordance with the ES6 spec.

  • builtins/StringPrototype.js:

(match):
(search):

  • runtime/CommonIdentifiers.h:
  • runtime/JSGlobalObject.cpp:

(JSC::JSGlobalObject::init):

  • runtime/RegExpConstructor.cpp:

(JSC::toFlags):
(JSC::regExpCreate):
(JSC::constructRegExp):
(JSC::esSpecRegExpCreate):
(JSC::constructWithRegExpConstructor):

  • runtime/RegExpConstructor.h:

(JSC::isRegExp):

Location:
trunk/Source/JavaScriptCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r199141 r199144  
     12016-04-06  Mark Lam  <mark.lam@apple.com>
     2
     3        String.prototype.match() should be calling internal function RegExpCreate.
     4        https://bugs.webkit.org/show_bug.cgi?id=156318
     5
     6        Reviewed by Filip Pizlo.
     7
     8        RegExpCreate is not the same as the RegExp constructor.  The current implementation
     9        invokes new @RegExp which calls the constructor.  This results in failures in
     10        es6/Proxy_internal_get_calls_String.prototype.match.js, and
     11        es6/Proxy_internal_get_calls_String.prototype.search.js due to observable side
     12        effects.
     13
     14        This patch fixes this by factoring out the part of the RegExp constructor that
     15        makes the RegExpCreate function, and changing String's match and search to call
     16        RegExpCreate instead in accordance with the ES6 spec.
     17
     18        * builtins/StringPrototype.js:
     19        (match):
     20        (search):
     21        * runtime/CommonIdentifiers.h:
     22        * runtime/JSGlobalObject.cpp:
     23        (JSC::JSGlobalObject::init):
     24        * runtime/RegExpConstructor.cpp:
     25        (JSC::toFlags):
     26        (JSC::regExpCreate):
     27        (JSC::constructRegExp):
     28        (JSC::esSpecRegExpCreate):
     29        (JSC::constructWithRegExpConstructor):
     30        * runtime/RegExpConstructor.h:
     31        (JSC::isRegExp):
     32
    1332016-04-06  Keith Miller  <keith_miller@apple.com>
    234
  • trunk/Source/JavaScriptCore/builtins/StringPrototype.js

    r198838 r199144  
    22 * Copyright (C) 2015 Andy VanWagoner <thetalecrafter@gmail.com>.
    33 * Copyright (C) 2016 Yusuke Suzuki <utatane.tea@gmail.com>
     4 * Copyright (C) 2016 Apple Inc. All rights reserved.
    45 *
    56 * Redistribution and use in source and binary forms, with or without
     
    4243
    4344    let thisString = @toString(this);
    44     let createdRegExp = new @RegExp(regexp, @undefined);
     45    let createdRegExp = @regExpCreate(regexp, @undefined);
    4546    return createdRegExp[@symbolMatch](thisString);
    4647}
     
    6364
    6465    var thisString = @toString(this);
    65     var createdRegExp = new @RegExp(regexp, @undefined);
     66    var createdRegExp = @regExpCreate(regexp, @undefined);
    6667    return createdRegExp[@symbolSearch](thisString);
    6768}
  • trunk/Source/JavaScriptCore/runtime/CommonIdentifiers.h

    r199128 r199144  
    11/*
    2  *  Copyright (C) 2003, 2007, 2009 Apple Inc. All rights reserved.
     2 *  Copyright (C) 2003, 2007, 2009, 2016 Apple Inc. All rights reserved.
    33 *
    44 *  This library is free software; you can redistribute it and/or
     
    420420    macro(isSet) \
    421421    macro(isMap) \
     422    macro(regExpCreate) \
    422423    macro(SetIterator) \
    423424    macro(setIteratorNext) \
  • trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp

    r199128 r199144  
    11/*
    2  * Copyright (C) 2007, 2008, 2009, 2014-2016 Apple Inc. All rights reserved.
     2 * Copyright (C) 2007-2009, 2014-2016 Apple Inc. All rights reserved.
    33 * Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca)
    44 *
     
    614614        GlobalPropertyInfo(vm.propertyNames->builtinNames().NumberFormatPrivateName(), intl->getDirect(vm, vm.propertyNames->NumberFormat), DontEnum | DontDelete | ReadOnly),
    615615#endif // ENABLE(INTL)
     616
     617        GlobalPropertyInfo(vm.propertyNames->regExpCreatePrivateName, JSFunction::create(vm, this, 2, String(), esSpecRegExpCreate, NoIntrinsic), DontEnum | DontDelete | ReadOnly),
    616618    };
    617619    addStaticGlobals(staticGlobals, WTF_ARRAY_LENGTH(staticGlobals));
  • trunk/Source/JavaScriptCore/runtime/RegExpConstructor.cpp

    r199106 r199144  
    11/*
    22 *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
    3  *  Copyright (C) 2003, 2007, 2008, 2016 Apple Inc. All Rights Reserved.
     3 *  Copyright (C) 2003, 2007-2008, 2016 Apple Inc. All Rights Reserved.
    44 *  Copyright (C) 2009 Torch Mobile, Inc.
    55 *
     
    278278}
    279279
     280static JSObject* regExpCreate(ExecState* exec, JSGlobalObject* globalObject, JSValue newTarget, JSValue patternArg, JSValue flagsArg)
     281{
     282    VM& vm = exec->vm();
     283    String pattern = patternArg.isUndefined() ? emptyString() : patternArg.toString(exec)->value(exec);
     284    if (exec->hadException())
     285        return nullptr;
     286
     287    RegExpFlags flags = toFlags(exec, flagsArg);
     288    if (flags == InvalidFlags)
     289        return nullptr;
     290
     291    RegExp* regExp = RegExp::create(vm, pattern, flags);
     292    if (!regExp->isValid())
     293        return vm.throwException(exec, createSyntaxError(exec, regExp->errorMessage()));
     294
     295    Structure* structure = getRegExpStructure(exec, globalObject, newTarget);
     296    if (vm.exception())
     297        return nullptr;
     298    return RegExpObject::create(vm, structure, regExp);
     299}
     300
    280301JSObject* constructRegExp(ExecState* exec, JSGlobalObject* globalObject, const ArgList& args,  JSObject* callee, JSValue newTarget)
    281302{
     
    320341    }
    321342
    322     String pattern = patternArg.isUndefined() ? emptyString() : patternArg.toString(exec)->value(exec);
    323     if (exec->hadException())
    324         return nullptr;
    325 
    326     RegExpFlags flags = toFlags(exec, flagsArg);
    327     if (flags == InvalidFlags)
    328         return nullptr;
    329 
    330     RegExp* regExp = RegExp::create(vm, pattern, flags);
    331     if (!regExp->isValid())
    332         return vm.throwException(exec, createSyntaxError(exec, regExp->errorMessage()));
    333 
    334     Structure* structure = getRegExpStructure(exec, globalObject, newTarget);
    335     if (vm.exception())
    336         return nullptr;
    337     return RegExpObject::create(vm, structure, regExp);
     343    return regExpCreate(exec, globalObject, newTarget, patternArg, flagsArg);
     344}
     345
     346EncodedJSValue JSC_HOST_CALL esSpecRegExpCreate(ExecState* exec)
     347{
     348    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     349    JSValue patternArg = exec->argument(0);
     350    JSValue flagsArg = exec->argument(1);
     351    return JSValue::encode(regExpCreate(exec, globalObject, jsUndefined(), patternArg, flagsArg));
    338352}
    339353
  • trunk/Source/JavaScriptCore/runtime/RegExpConstructor.h

    r199106 r199144  
    149149}
    150150
     151EncodedJSValue JSC_HOST_CALL esSpecRegExpCreate(ExecState*);
     152
    151153} // namespace JSC
    152154
Note: See TracChangeset for help on using the changeset viewer.