diff --git a/rhino/src/main/java/org/mozilla/javascript/NativeString.java b/rhino/src/main/java/org/mozilla/javascript/NativeString.java index f2b128f07f..7ad34067a3 100644 --- a/rhino/src/main/java/org/mozilla/javascript/NativeString.java +++ b/rhino/src/main/java/org/mozilla/javascript/NativeString.java @@ -624,8 +624,6 @@ public Object execIdCall( return ScriptRuntime.wrapBoolean( (id == Id_equals) ? s1.equals(s2) : s1.equalsIgnoreCase(s2)); } - - case Id_match: case Id_search: case Id_replace: case Id_replaceAll: @@ -864,6 +862,9 @@ else if (Normalizer.Form.NFC.name().equals(formStr)) case SymbolId_iterator: return new NativeStringIterator(scope, requireObjectCoercible(cx, thisObj, f)); + case Id_match: + return js_match(f, cx, scope, thisObj, args); + case Id_matchAll: { // See ECMAScript spec 22.1.3.14 @@ -1041,6 +1042,49 @@ private ScriptableObject defaultIndexPropertyDescriptor(Object value) { return desc; } + /* + * + * See ECMA 22.1.3.13 + * + */ + private static Object js_match( + IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { + Object o = requireObjectCoercible(cx, thisObj, f); + Object regexp = args.length > 0 ? args[0] : Undefined.instance; + RegExpProxy regExpProxy = ScriptRuntime.checkRegExpProxy(cx); + if (regexp != null && !Undefined.isUndefined(regexp)) { + Object matcher = ScriptRuntime.getObjectElem(regexp, SymbolKey.MATCH, cx, scope); + // If method is not undefined, it should be a Callable + if (matcher != null && !Undefined.isUndefined(matcher)) { + if (!(matcher instanceof Callable)) { + throw ScriptRuntime.notFunctionError( + regexp, matcher, SymbolKey.MATCH.getName()); + } + return ((Callable) matcher) + .call(cx, scope, ScriptRuntime.toObject(scope, regexp), new Object[] {o}); + } + } + + String s = ScriptRuntime.toString(o); + String regexpToString = Undefined.isUndefined(regexp) ? "" : ScriptRuntime.toString(regexp); + + String flags = null; + + // Not standard; Done for backward compatibility + if (cx.getLanguageVersion() < Context.VERSION_1_6 && args.length > 1) { + flags = ScriptRuntime.toString(args[1]); + } + + Object compiledRegExp = regExpProxy.compileRegExp(cx, regexpToString, flags); + Scriptable rx = regExpProxy.wrapRegExp(cx, scope, compiledRegExp); + + Object method = ScriptRuntime.getObjectElem(rx, SymbolKey.MATCH, cx, scope); + if (!(method instanceof Callable)) { + throw ScriptRuntime.notFunctionError(rx, method, SymbolKey.MATCH.getName()); + } + return ((Callable) method).call(cx, scope, rx, new Object[] {s}); + } + /* * * See ECMA 15.5.4.6. Uses Java String.indexOf() diff --git a/tests/testsrc/test262.properties b/tests/testsrc/test262.properties index a751b32b25..a15fa64a38 100644 --- a/tests/testsrc/test262.properties +++ b/tests/testsrc/test262.properties @@ -2008,7 +2008,7 @@ built-ins/SetIteratorPrototype 0/11 (0.0%) ~built-ins/SharedArrayBuffer -built-ins/String 92/1182 (7.78%) +built-ins/String 90/1182 (7.61%) fromCharCode/not-a-constructor.js fromCodePoint/not-a-constructor.js prototype/charAt/not-a-constructor.js @@ -2032,11 +2032,9 @@ built-ins/String 92/1182 (7.78%) prototype/matchAll/not-a-constructor.js prototype/matchAll/regexp-matchAll-invocation.js prototype/matchAll/regexp-prototype-matchAll-invocation.js - prototype/match/cstm-matcher-get-err.js prototype/match/cstm-matcher-invocation.js prototype/match/duplicate-named-groups-properties.js prototype/match/duplicate-named-indices-groups-properties.js - prototype/match/invoke-builtin-match.js prototype/match/not-a-constructor.js prototype/normalize/not-a-constructor.js prototype/padEnd/not-a-constructor.js