1425bb815Sopenharmony_ci// Copyright JS Foundation and other contributors, http://js.foundation
2425bb815Sopenharmony_ci//
3425bb815Sopenharmony_ci// Licensed under the Apache License, Version 2.0 (the "License");
4425bb815Sopenharmony_ci// you may not use this file except in compliance with the License.
5425bb815Sopenharmony_ci// You may obtain a copy of the License at
6425bb815Sopenharmony_ci//
7425bb815Sopenharmony_ci//     http://www.apache.org/licenses/LICENSE-2.0
8425bb815Sopenharmony_ci//
9425bb815Sopenharmony_ci// Unless required by applicable law or agreed to in writing, software
10425bb815Sopenharmony_ci// distributed under the License is distributed on an "AS IS" BASIS
11425bb815Sopenharmony_ci// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12425bb815Sopenharmony_ci// See the License for the specific language governing permissions and
13425bb815Sopenharmony_ci// limitations under the License.
14425bb815Sopenharmony_ci
15425bb815Sopenharmony_civar replace = RegExp.prototype[Symbol.replace];
16425bb815Sopenharmony_ci
17425bb815Sopenharmony_citry {
18425bb815Sopenharmony_ci  replace.call (0, "string", "replace");
19425bb815Sopenharmony_ci  assert (false);
20425bb815Sopenharmony_ci} catch (e) {
21425bb815Sopenharmony_ci  assert (e instanceof TypeError);
22425bb815Sopenharmony_ci}
23425bb815Sopenharmony_ci
24425bb815Sopenharmony_citry {
25425bb815Sopenharmony_ci  replace.call (new RegExp(), {
26425bb815Sopenharmony_ci    toString: () => {
27425bb815Sopenharmony_ci      throw "abrupt string"
28425bb815Sopenharmony_ci    }
29425bb815Sopenharmony_ci  }, "replace");
30425bb815Sopenharmony_ci  assert (false);
31425bb815Sopenharmony_ci} catch (e) {
32425bb815Sopenharmony_ci  assert (e === "abrupt string");
33425bb815Sopenharmony_ci}
34425bb815Sopenharmony_ci
35425bb815Sopenharmony_citry {
36425bb815Sopenharmony_ci  replace.call (new RegExp(), "string", {
37425bb815Sopenharmony_ci    toString: () => {
38425bb815Sopenharmony_ci      throw "abrupt replace"
39425bb815Sopenharmony_ci    }
40425bb815Sopenharmony_ci  });
41425bb815Sopenharmony_ci  assert (false);
42425bb815Sopenharmony_ci} catch (e) {
43425bb815Sopenharmony_ci  assert (e === "abrupt replace");
44425bb815Sopenharmony_ci}
45425bb815Sopenharmony_ci
46425bb815Sopenharmony_citry {
47425bb815Sopenharmony_ci  replace.call ({
48425bb815Sopenharmony_ci    get global() {
49425bb815Sopenharmony_ci      throw "abrupt global"
50425bb815Sopenharmony_ci    }
51425bb815Sopenharmony_ci  }, "string", "replace");
52425bb815Sopenharmony_ci  assert (false);
53425bb815Sopenharmony_ci} catch (e) {
54425bb815Sopenharmony_ci  assert (e === "abrupt global");
55425bb815Sopenharmony_ci}
56425bb815Sopenharmony_ci
57425bb815Sopenharmony_citry {
58425bb815Sopenharmony_ci  replace.call ({
59425bb815Sopenharmony_ci    global: true,
60425bb815Sopenharmony_ci    set lastIndex(idx) {
61425bb815Sopenharmony_ci      throw "abrupt lastIndex"
62425bb815Sopenharmony_ci    }
63425bb815Sopenharmony_ci  }, "string", "replace");
64425bb815Sopenharmony_ci  assert (false);
65425bb815Sopenharmony_ci} catch (e) {
66425bb815Sopenharmony_ci  assert (e === "abrupt lastIndex");
67425bb815Sopenharmony_ci}
68425bb815Sopenharmony_ci
69425bb815Sopenharmony_citry {
70425bb815Sopenharmony_ci  replace.call ({
71425bb815Sopenharmony_ci    get exec() {
72425bb815Sopenharmony_ci      throw "abrupt exec"
73425bb815Sopenharmony_ci    }
74425bb815Sopenharmony_ci  }, "string", "replace");
75425bb815Sopenharmony_ci  assert (false);
76425bb815Sopenharmony_ci} catch (e) {
77425bb815Sopenharmony_ci  assert (e === "abrupt exec");
78425bb815Sopenharmony_ci}
79425bb815Sopenharmony_ci
80425bb815Sopenharmony_citry {
81425bb815Sopenharmony_ci  replace.call ({
82425bb815Sopenharmony_ci    exec: RegExp.prototype.exec
83425bb815Sopenharmony_ci  }, "string", "replace");
84425bb815Sopenharmony_ci  assert (false);
85425bb815Sopenharmony_ci} catch (e) {
86425bb815Sopenharmony_ci  assert (e instanceof TypeError);
87425bb815Sopenharmony_ci}
88425bb815Sopenharmony_ci
89425bb815Sopenharmony_citry {
90425bb815Sopenharmony_ci  replace.call ({
91425bb815Sopenharmony_ci    exec: 42
92425bb815Sopenharmony_ci  }, "string", "replace");
93425bb815Sopenharmony_ci  assert (false);
94425bb815Sopenharmony_ci} catch (e) {
95425bb815Sopenharmony_ci  assert (e instanceof TypeError);
96425bb815Sopenharmony_ci}
97425bb815Sopenharmony_ci
98425bb815Sopenharmony_citry {
99425bb815Sopenharmony_ci  replace.call ({
100425bb815Sopenharmony_ci    exec: () => {
101425bb815Sopenharmony_ci      throw "abrupt exec result"
102425bb815Sopenharmony_ci    }
103425bb815Sopenharmony_ci  }, "string", "replace");
104425bb815Sopenharmony_ci  assert (false);
105425bb815Sopenharmony_ci} catch (e) {
106425bb815Sopenharmony_ci  assert (e === "abrupt exec result");
107425bb815Sopenharmony_ci}
108425bb815Sopenharmony_ci
109425bb815Sopenharmony_citry {
110425bb815Sopenharmony_ci  replace.call ({
111425bb815Sopenharmony_ci    exec: () => {
112425bb815Sopenharmony_ci      return 1
113425bb815Sopenharmony_ci    }
114425bb815Sopenharmony_ci  }, "string", "replace");
115425bb815Sopenharmony_ci  assert (false);
116425bb815Sopenharmony_ci} catch (e) {
117425bb815Sopenharmony_ci  assert (e instanceof TypeError);
118425bb815Sopenharmony_ci}
119425bb815Sopenharmony_ci
120425bb815Sopenharmony_citry {
121425bb815Sopenharmony_ci  replace.call ({
122425bb815Sopenharmony_ci    exec: () => {
123425bb815Sopenharmony_ci      return {
124425bb815Sopenharmony_ci        get length() {
125425bb815Sopenharmony_ci          throw "abrupt result length"
126425bb815Sopenharmony_ci        }
127425bb815Sopenharmony_ci      }
128425bb815Sopenharmony_ci    }
129425bb815Sopenharmony_ci  }, "string", "replace");
130425bb815Sopenharmony_ci  assert (false);
131425bb815Sopenharmony_ci} catch (e) {
132425bb815Sopenharmony_ci  assert (e === "abrupt result length");
133425bb815Sopenharmony_ci}
134425bb815Sopenharmony_ci
135425bb815Sopenharmony_citry {
136425bb815Sopenharmony_ci  replace.call ({
137425bb815Sopenharmony_ci      global: true,
138425bb815Sopenharmony_ci      exec: () => {
139425bb815Sopenharmony_ci        return {
140425bb815Sopenharmony_ci          length: 1,
141425bb815Sopenharmony_ci          get 0() {
142425bb815Sopenharmony_ci            throw "abrupt match"
143425bb815Sopenharmony_ci          }
144425bb815Sopenharmony_ci        }
145425bb815Sopenharmony_ci      }
146425bb815Sopenharmony_ci    },
147425bb815Sopenharmony_ci    "string",
148425bb815Sopenharmony_ci    "replace");
149425bb815Sopenharmony_ci  assert (false);
150425bb815Sopenharmony_ci} catch (e) {
151425bb815Sopenharmony_ci  assert (e === "abrupt match");
152425bb815Sopenharmony_ci}
153425bb815Sopenharmony_ci
154425bb815Sopenharmony_citry {
155425bb815Sopenharmony_ci  replace.call ({
156425bb815Sopenharmony_ci      global: true,
157425bb815Sopenharmony_ci      exec: () => {
158425bb815Sopenharmony_ci        return {
159425bb815Sopenharmony_ci          length: 1,
160425bb815Sopenharmony_ci          get 0() {
161425bb815Sopenharmony_ci            return {
162425bb815Sopenharmony_ci              toString: () => {
163425bb815Sopenharmony_ci                throw "abrupt match toString"
164425bb815Sopenharmony_ci              }
165425bb815Sopenharmony_ci            }
166425bb815Sopenharmony_ci          }
167425bb815Sopenharmony_ci        }
168425bb815Sopenharmony_ci      }
169425bb815Sopenharmony_ci    },
170425bb815Sopenharmony_ci    "string",
171425bb815Sopenharmony_ci    "replace");
172425bb815Sopenharmony_ci  assert (false);
173425bb815Sopenharmony_ci} catch (e) {
174425bb815Sopenharmony_ci  assert (e === "abrupt match toString");
175425bb815Sopenharmony_ci}
176425bb815Sopenharmony_ci
177425bb815Sopenharmony_civar result_obj = {
178425bb815Sopenharmony_ci  toString: () => {
179425bb815Sopenharmony_ci    Object.defineProperty (result_obj, 'toString', {
180425bb815Sopenharmony_ci      value: () => {
181425bb815Sopenharmony_ci        throw "abrupt match toString delayed";
182425bb815Sopenharmony_ci      }
183425bb815Sopenharmony_ci    });
184425bb815Sopenharmony_ci    return "str";
185425bb815Sopenharmony_ci  }
186425bb815Sopenharmony_ci}
187425bb815Sopenharmony_ci
188425bb815Sopenharmony_civar first = true;
189425bb815Sopenharmony_citry {
190425bb815Sopenharmony_ci  replace.call ({
191425bb815Sopenharmony_ci      global: true,
192425bb815Sopenharmony_ci      exec: () => {
193425bb815Sopenharmony_ci        if (!first) {
194425bb815Sopenharmony_ci          return null;
195425bb815Sopenharmony_ci        }
196425bb815Sopenharmony_ci
197425bb815Sopenharmony_ci        first = false;
198425bb815Sopenharmony_ci        return {
199425bb815Sopenharmony_ci          length: 1,
200425bb815Sopenharmony_ci          get 0() {
201425bb815Sopenharmony_ci            return result_obj;
202425bb815Sopenharmony_ci          }
203425bb815Sopenharmony_ci        }
204425bb815Sopenharmony_ci      }
205425bb815Sopenharmony_ci    },
206425bb815Sopenharmony_ci    "string",
207425bb815Sopenharmony_ci    "replace");
208425bb815Sopenharmony_ci  assert (false);
209425bb815Sopenharmony_ci} catch (e) {
210425bb815Sopenharmony_ci  assert (e === "abrupt match toString delayed");
211425bb815Sopenharmony_ci}
212425bb815Sopenharmony_ci
213425bb815Sopenharmony_citry {
214425bb815Sopenharmony_ci  replace.call ({
215425bb815Sopenharmony_ci      global: true,
216425bb815Sopenharmony_ci      get lastIndex() {
217425bb815Sopenharmony_ci        throw "abrupt lastIndex get"
218425bb815Sopenharmony_ci      },
219425bb815Sopenharmony_ci      set lastIndex(i) {},
220425bb815Sopenharmony_ci      exec: () => {
221425bb815Sopenharmony_ci        return {
222425bb815Sopenharmony_ci          length: 1,
223425bb815Sopenharmony_ci          get 0() {
224425bb815Sopenharmony_ci            return {
225425bb815Sopenharmony_ci              toString: () => {
226425bb815Sopenharmony_ci                return ""
227425bb815Sopenharmony_ci              }
228425bb815Sopenharmony_ci            }
229425bb815Sopenharmony_ci          }
230425bb815Sopenharmony_ci        }
231425bb815Sopenharmony_ci      }
232425bb815Sopenharmony_ci    },
233425bb815Sopenharmony_ci    "string",
234425bb815Sopenharmony_ci    "replace");
235425bb815Sopenharmony_ci  assert (false);
236425bb815Sopenharmony_ci} catch (e) {
237425bb815Sopenharmony_ci  assert (e === "abrupt lastIndex get");
238425bb815Sopenharmony_ci}
239425bb815Sopenharmony_ci
240425bb815Sopenharmony_citry {
241425bb815Sopenharmony_ci  replace.call ({
242425bb815Sopenharmony_ci      global: true,
243425bb815Sopenharmony_ci      get lastIndex() {
244425bb815Sopenharmony_ci        return {
245425bb815Sopenharmony_ci          valueOf: () => {
246425bb815Sopenharmony_ci            throw "abrupt lastIndex toNumber"
247425bb815Sopenharmony_ci          }
248425bb815Sopenharmony_ci        }
249425bb815Sopenharmony_ci      },
250425bb815Sopenharmony_ci      set lastIndex(i) {},
251425bb815Sopenharmony_ci      exec: () => {
252425bb815Sopenharmony_ci        return {
253425bb815Sopenharmony_ci          length: 1,
254425bb815Sopenharmony_ci          get 0() {
255425bb815Sopenharmony_ci            return {
256425bb815Sopenharmony_ci              toString: () => {
257425bb815Sopenharmony_ci                return ""
258425bb815Sopenharmony_ci              }
259425bb815Sopenharmony_ci            }
260425bb815Sopenharmony_ci          }
261425bb815Sopenharmony_ci        }
262425bb815Sopenharmony_ci      }
263425bb815Sopenharmony_ci    },
264425bb815Sopenharmony_ci    "string",
265425bb815Sopenharmony_ci    "replace");
266425bb815Sopenharmony_ci  assert (false);
267425bb815Sopenharmony_ci} catch (e) {
268425bb815Sopenharmony_ci  assert (e === "abrupt lastIndex toNumber");
269425bb815Sopenharmony_ci}
270425bb815Sopenharmony_ci
271425bb815Sopenharmony_civar o = {
272425bb815Sopenharmony_ci  global: true,
273425bb815Sopenharmony_ci  exec: () => {
274425bb815Sopenharmony_ci    return {
275425bb815Sopenharmony_ci      length: 1,
276425bb815Sopenharmony_ci      get 0() {
277425bb815Sopenharmony_ci        return {
278425bb815Sopenharmony_ci          toString: () => {
279425bb815Sopenharmony_ci            return ""
280425bb815Sopenharmony_ci          }
281425bb815Sopenharmony_ci        }
282425bb815Sopenharmony_ci      }
283425bb815Sopenharmony_ci    }
284425bb815Sopenharmony_ci  }
285425bb815Sopenharmony_ci}
286425bb815Sopenharmony_ciObject.defineProperty (o, 'lastIndex', {
287425bb815Sopenharmony_ci  configurable: true,
288425bb815Sopenharmony_ci  get: () => {
289425bb815Sopenharmony_ci    Object.defineProperty (o, 'lastIndex', {
290425bb815Sopenharmony_ci      get: () => {
291425bb815Sopenharmony_ci        return {
292425bb815Sopenharmony_ci          valueOf: () => {
293425bb815Sopenharmony_ci            return 42
294425bb815Sopenharmony_ci          }
295425bb815Sopenharmony_ci        };
296425bb815Sopenharmony_ci      },
297425bb815Sopenharmony_ci      set: (i) => {
298425bb815Sopenharmony_ci        throw "abrupt lastIndex put";
299425bb815Sopenharmony_ci      },
300425bb815Sopenharmony_ci      configurable: true
301425bb815Sopenharmony_ci    });
302425bb815Sopenharmony_ci    return {
303425bb815Sopenharmony_ci      valueOf: () => {
304425bb815Sopenharmony_ci        return 24
305425bb815Sopenharmony_ci      }
306425bb815Sopenharmony_ci    };
307425bb815Sopenharmony_ci  },
308425bb815Sopenharmony_ci  set: (i) => {}
309425bb815Sopenharmony_ci});
310425bb815Sopenharmony_ci
311425bb815Sopenharmony_citry {
312425bb815Sopenharmony_ci  replace.call (o,
313425bb815Sopenharmony_ci    "string",
314425bb815Sopenharmony_ci    "replace");
315425bb815Sopenharmony_ci  assert (false);
316425bb815Sopenharmony_ci} catch (e) {
317425bb815Sopenharmony_ci  assert (e === "abrupt lastIndex put");
318425bb815Sopenharmony_ci}
319425bb815Sopenharmony_ci
320425bb815Sopenharmony_cio = {
321425bb815Sopenharmony_ci  global: true,
322425bb815Sopenharmony_ci  exec: () => {
323425bb815Sopenharmony_ci    return {
324425bb815Sopenharmony_ci      length: 1,
325425bb815Sopenharmony_ci      get 0() {
326425bb815Sopenharmony_ci        return {
327425bb815Sopenharmony_ci          toString: () => {
328425bb815Sopenharmony_ci            return ""
329425bb815Sopenharmony_ci          }
330425bb815Sopenharmony_ci        }
331425bb815Sopenharmony_ci      }
332425bb815Sopenharmony_ci    }
333425bb815Sopenharmony_ci  },
334425bb815Sopenharmony_ci};
335425bb815Sopenharmony_ciObject.defineProperty (o, 'lastIndex', {
336425bb815Sopenharmony_ci  get: () => {
337425bb815Sopenharmony_ci    Object.defineProperty (o, 'lastIndex', {
338425bb815Sopenharmony_ci      value: 0,
339425bb815Sopenharmony_ci      writable: false
340425bb815Sopenharmony_ci    });
341425bb815Sopenharmony_ci    return 0;
342425bb815Sopenharmony_ci  },
343425bb815Sopenharmony_ci  set: () => {}
344425bb815Sopenharmony_ci});
345425bb815Sopenharmony_ci
346425bb815Sopenharmony_citry {
347425bb815Sopenharmony_ci  replace.call (o,
348425bb815Sopenharmony_ci    "string",
349425bb815Sopenharmony_ci    "replace");
350425bb815Sopenharmony_ci  assert (false);
351425bb815Sopenharmony_ci} catch (e) {
352425bb815Sopenharmony_ci  assert (e instanceof TypeError);
353425bb815Sopenharmony_ci}
354425bb815Sopenharmony_ci
355425bb815Sopenharmony_cio = {
356425bb815Sopenharmony_ci  global: true
357425bb815Sopenharmony_ci};
358425bb815Sopenharmony_ciObject.defineProperty (o, 'exec', {
359425bb815Sopenharmony_ci  configurable: true,
360425bb815Sopenharmony_ci  value: () => {
361425bb815Sopenharmony_ci    Object.defineProperty (o, 'exec', {
362425bb815Sopenharmony_ci      get: () => {
363425bb815Sopenharmony_ci        throw "abrupt exec"
364425bb815Sopenharmony_ci      },
365425bb815Sopenharmony_ci      set: (v) => {}
366425bb815Sopenharmony_ci    });
367425bb815Sopenharmony_ci    return {
368425bb815Sopenharmony_ci      length: 1,
369425bb815Sopenharmony_ci      0: "thisisastring"
370425bb815Sopenharmony_ci    }
371425bb815Sopenharmony_ci  }
372425bb815Sopenharmony_ci});
373425bb815Sopenharmony_ci
374425bb815Sopenharmony_citry {
375425bb815Sopenharmony_ci  replace.call (o,
376425bb815Sopenharmony_ci    "string",
377425bb815Sopenharmony_ci    "replace");
378425bb815Sopenharmony_ci  assert (false);
379425bb815Sopenharmony_ci} catch (e) {
380425bb815Sopenharmony_ci  assert (e === "abrupt exec");
381425bb815Sopenharmony_ci}
382425bb815Sopenharmony_ci
383425bb815Sopenharmony_citry {
384425bb815Sopenharmony_ci  replace.call ({
385425bb815Sopenharmony_ci    exec: () => {
386425bb815Sopenharmony_ci      return {
387425bb815Sopenharmony_ci        length: 1,
388425bb815Sopenharmony_ci        0: "str",
389425bb815Sopenharmony_ci        get index() {
390425bb815Sopenharmony_ci          throw "abrupt index"
391425bb815Sopenharmony_ci        }
392425bb815Sopenharmony_ci      }
393425bb815Sopenharmony_ci    }
394425bb815Sopenharmony_ci  }, "string", "replace");
395425bb815Sopenharmony_ci  assert (false);
396425bb815Sopenharmony_ci} catch (e) {
397425bb815Sopenharmony_ci  assert (e === "abrupt index");
398425bb815Sopenharmony_ci}
399425bb815Sopenharmony_ci
400425bb815Sopenharmony_citry {
401425bb815Sopenharmony_ci  replace.call ({
402425bb815Sopenharmony_ci    exec: () => {
403425bb815Sopenharmony_ci      return {
404425bb815Sopenharmony_ci        length: 1,
405425bb815Sopenharmony_ci        0: "str",
406425bb815Sopenharmony_ci        get index() {
407425bb815Sopenharmony_ci          return {
408425bb815Sopenharmony_ci            valueOf: () => {
409425bb815Sopenharmony_ci              throw "abrupt index toNumber"
410425bb815Sopenharmony_ci            }
411425bb815Sopenharmony_ci          }
412425bb815Sopenharmony_ci        }
413425bb815Sopenharmony_ci      }
414425bb815Sopenharmony_ci    }
415425bb815Sopenharmony_ci  }, "string", "replace");
416425bb815Sopenharmony_ci  assert (false);
417425bb815Sopenharmony_ci} catch (e) {
418425bb815Sopenharmony_ci  assert (e === "abrupt index toNumber");
419425bb815Sopenharmony_ci}
420425bb815Sopenharmony_ci
421425bb815Sopenharmony_citry {
422425bb815Sopenharmony_ci  replace.call ({
423425bb815Sopenharmony_ci    exec: () => {
424425bb815Sopenharmony_ci      return {
425425bb815Sopenharmony_ci        length: 2,
426425bb815Sopenharmony_ci        0: "str",
427425bb815Sopenharmony_ci        index: 0,
428425bb815Sopenharmony_ci        get 1() {
429425bb815Sopenharmony_ci          throw "abrupt capture"
430425bb815Sopenharmony_ci        }
431425bb815Sopenharmony_ci      }
432425bb815Sopenharmony_ci    }
433425bb815Sopenharmony_ci  }, "string", "replace");
434425bb815Sopenharmony_ci  assert (false);
435425bb815Sopenharmony_ci} catch (e) {
436425bb815Sopenharmony_ci  assert (e === "abrupt capture");
437425bb815Sopenharmony_ci}
438425bb815Sopenharmony_ci
439425bb815Sopenharmony_citry {
440425bb815Sopenharmony_ci  replace.call ({
441425bb815Sopenharmony_ci    exec: () => {
442425bb815Sopenharmony_ci      return {
443425bb815Sopenharmony_ci        length: 2,
444425bb815Sopenharmony_ci        0: "str",
445425bb815Sopenharmony_ci        index: 0,
446425bb815Sopenharmony_ci        1: {
447425bb815Sopenharmony_ci          toString: () => {
448425bb815Sopenharmony_ci            throw "abrupt capture toString"
449425bb815Sopenharmony_ci          }
450425bb815Sopenharmony_ci        }
451425bb815Sopenharmony_ci      }
452425bb815Sopenharmony_ci    }
453425bb815Sopenharmony_ci  }, "string", "replace");
454425bb815Sopenharmony_ci  assert (false);
455425bb815Sopenharmony_ci} catch (e) {
456425bb815Sopenharmony_ci  assert (e === "abrupt capture toString");
457425bb815Sopenharmony_ci}
458425bb815Sopenharmony_ci
459425bb815Sopenharmony_citry {
460425bb815Sopenharmony_ci  replace.call ({
461425bb815Sopenharmony_ci    exec: () => {
462425bb815Sopenharmony_ci      return {
463425bb815Sopenharmony_ci        length: 2,
464425bb815Sopenharmony_ci        0: "str",
465425bb815Sopenharmony_ci        index: 0,
466425bb815Sopenharmony_ci        1: "st"
467425bb815Sopenharmony_ci      }
468425bb815Sopenharmony_ci    }
469425bb815Sopenharmony_ci  }, "string", () => {
470425bb815Sopenharmony_ci    throw "abrupt replace"
471425bb815Sopenharmony_ci  });
472425bb815Sopenharmony_ci  assert (false);
473425bb815Sopenharmony_ci} catch (e) {
474425bb815Sopenharmony_ci  assert (e === "abrupt replace");
475425bb815Sopenharmony_ci}
476425bb815Sopenharmony_ci
477425bb815Sopenharmony_citry {
478425bb815Sopenharmony_ci  replace.call ({
479425bb815Sopenharmony_ci    exec: () => {
480425bb815Sopenharmony_ci      return {
481425bb815Sopenharmony_ci        length: 2,
482425bb815Sopenharmony_ci        0: "str",
483425bb815Sopenharmony_ci        index: 0,
484425bb815Sopenharmony_ci        1: "st"
485425bb815Sopenharmony_ci      }
486425bb815Sopenharmony_ci    }
487425bb815Sopenharmony_ci  }, "string", () => {
488425bb815Sopenharmony_ci    return {
489425bb815Sopenharmony_ci      toString: () => {
490425bb815Sopenharmony_ci        throw "abrupt replace toString"
491425bb815Sopenharmony_ci      }
492425bb815Sopenharmony_ci    }
493425bb815Sopenharmony_ci  });
494425bb815Sopenharmony_ci  assert (false);
495425bb815Sopenharmony_ci} catch (e) {
496425bb815Sopenharmony_ci  assert (e === "abrupt replace toString");
497425bb815Sopenharmony_ci}
498425bb815Sopenharmony_ci
499425bb815Sopenharmony_citry {
500425bb815Sopenharmony_ci  replace.call (/abc/, "abc", () => {
501425bb815Sopenharmony_ci    throw "fastpath abrupt replace"
502425bb815Sopenharmony_ci  });
503425bb815Sopenharmony_ci  assert (false);
504425bb815Sopenharmony_ci} catch (e) {
505425bb815Sopenharmony_ci  assert (e === "fastpath abrupt replace");
506425bb815Sopenharmony_ci}
507425bb815Sopenharmony_ci
508425bb815Sopenharmony_citry {
509425bb815Sopenharmony_ci  replace.call (/abc/, "abc", () => {
510425bb815Sopenharmony_ci    return {
511425bb815Sopenharmony_ci      toString: () => {
512425bb815Sopenharmony_ci        throw "fastpath abrupt replace"
513425bb815Sopenharmony_ci      }
514425bb815Sopenharmony_ci    }
515425bb815Sopenharmony_ci  });
516425bb815Sopenharmony_ci  assert (false);
517425bb815Sopenharmony_ci} catch (e) {
518425bb815Sopenharmony_ci  assert (e === "fastpath abrupt replace");
519425bb815Sopenharmony_ci}
520425bb815Sopenharmony_ci
521425bb815Sopenharmony_ciassert (replace.call (/abc/, "abc", "xyz") === "xyz");
522425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "xyz") === "abxyzfg");
523425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$$-") === "ab-$-fg");
524425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$&-") === "ab-cde-fg");
525425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$`-") === "ab-ab-fg");
526425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$'-") === "ab-fg-fg");
527425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$0-") === "ab-$0-fg");
528425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$1-") === "ab-c-fg");
529425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$2-") === "ab-d-fg");
530425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$3-") === "ab-d-fg");
531425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$4-") === "ab--fg");
532425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$5-") === "ab-e-fg");
533425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$6-") === "ab-$6-fg");
534425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$00-") === "ab-$00-fg");
535425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$01-") === "ab-c-fg");
536425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$10-") === "ab-c0-fg");
537425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$99-") === "ab-$99-fg");
538425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "-$$1-") === "ab-$1-fg");
539425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "$") === "ab$fg");
540425bb815Sopenharmony_ciassert (replace.call (/(c)((d)|(x))(e)/, "abcdefg", "$@") === "ab$@fg");
541425bb815Sopenharmony_ci
542425bb815Sopenharmony_cireplace.call (/(c)((d)|(x))(e)/, "abcdefg", function () {
543425bb815Sopenharmony_ci  assert (arguments[0] === "cde");
544425bb815Sopenharmony_ci  assert (arguments[1] === "c");
545425bb815Sopenharmony_ci  assert (arguments[2] === "d");
546425bb815Sopenharmony_ci  assert (arguments[3] === "d");
547425bb815Sopenharmony_ci  assert (arguments[4] === undefined);
548425bb815Sopenharmony_ci  assert (arguments[5] === "e");
549425bb815Sopenharmony_ci  assert (arguments[6] === 2);
550425bb815Sopenharmony_ci  assert (arguments[7] === "abcdefg");
551425bb815Sopenharmony_ci});
552425bb815Sopenharmony_ci
553425bb815Sopenharmony_civar re = /ab/g;
554425bb815Sopenharmony_ciassert (replace.call (re, "-ab-ab-ab-ab-", "cd") === "-cd-cd-cd-cd-");
555425bb815Sopenharmony_ciassert (re.lastIndex === 0);
556425bb815Sopenharmony_ci
557425bb815Sopenharmony_cire.lastIndex = 5;
558425bb815Sopenharmony_ciassert (replace.call (re, "-ab-ab-ab-ab-", "cd") === "-cd-cd-cd-cd-");
559425bb815Sopenharmony_ciassert (re.lastIndex === 0);
560425bb815Sopenharmony_ci
561425bb815Sopenharmony_ciassert (replace.call (/(?:)/g, "string", "Duck") === "DucksDucktDuckrDuckiDucknDuckgDuck");
562425bb815Sopenharmony_ci
563425bb815Sopenharmony_ciclass Regexplike {
564425bb815Sopenharmony_ci  constructor() {
565425bb815Sopenharmony_ci    this.index = 0;
566425bb815Sopenharmony_ci    this.global = true;
567425bb815Sopenharmony_ci  }
568425bb815Sopenharmony_ci
569425bb815Sopenharmony_ci  exec() {
570425bb815Sopenharmony_ci    if (this.index > 0) {
571425bb815Sopenharmony_ci      return null;
572425bb815Sopenharmony_ci    }
573425bb815Sopenharmony_ci
574425bb815Sopenharmony_ci    this.index = 39;
575425bb815Sopenharmony_ci    var result = {
576425bb815Sopenharmony_ci      length: 1,
577425bb815Sopenharmony_ci      0: "Duck",
578425bb815Sopenharmony_ci      index: this.index
579425bb815Sopenharmony_ci    };
580425bb815Sopenharmony_ci    return result;
581425bb815Sopenharmony_ci  }
582425bb815Sopenharmony_ci}
583425bb815Sopenharmony_ci
584425bb815Sopenharmony_cire = new Regexplike();
585425bb815Sopenharmony_ci
586425bb815Sopenharmony_ci/* Well-behaved RegExp-like object. */
587425bb815Sopenharmony_ciassert (replace.call (re, "What have you brought upon this cursed land", "$&") === "What have you brought upon this cursed Duck");
588425bb815Sopenharmony_ci
589425bb815Sopenharmony_civar replace_count = 0;
590425bb815Sopenharmony_ci
591425bb815Sopenharmony_cifunction replacer() {
592425bb815Sopenharmony_ci  replace_count++;
593425bb815Sopenharmony_ci  return arguments[0];
594425bb815Sopenharmony_ci}
595425bb815Sopenharmony_ci
596425bb815Sopenharmony_cire.index = 0;
597425bb815Sopenharmony_cire.exec = function () {
598425bb815Sopenharmony_ci  if (this.index > 3) {
599425bb815Sopenharmony_ci    return null;
600425bb815Sopenharmony_ci  }
601425bb815Sopenharmony_ci
602425bb815Sopenharmony_ci  var result = {
603425bb815Sopenharmony_ci    length: 1,
604425bb815Sopenharmony_ci    0: "Duck",
605425bb815Sopenharmony_ci    index: this.index++
606425bb815Sopenharmony_ci  };
607425bb815Sopenharmony_ci  return result;
608425bb815Sopenharmony_ci}
609425bb815Sopenharmony_ci
610425bb815Sopenharmony_ci/* Mis-behaving RegExp-like object, replace function is called on each match, but the result is ignored for inconsistent matches. */
611425bb815Sopenharmony_ciassert (replace.call (re, "Badger", replacer) === "Ducker");
612425bb815Sopenharmony_ciassert (replace_count === 4);
613425bb815Sopenharmony_ci
614425bb815Sopenharmony_cire.index = 0;
615425bb815Sopenharmony_ciassert (replace.call (re, "Badger", "Ord") === "Order");
616425bb815Sopenharmony_ci
617425bb815Sopenharmony_citry {
618425bb815Sopenharmony_ci  replace.call (RegExp.prototype, "string", "replace");
619425bb815Sopenharmony_ci  assert (false);
620425bb815Sopenharmony_ci} catch (e) {
621425bb815Sopenharmony_ci  assert (e instanceof TypeError);
622425bb815Sopenharmony_ci}
623425bb815Sopenharmony_ci
624425bb815Sopenharmony_ciassert(replace.call({ exec : ( ) => { return {  } } }, 'һ', "a") === "a");
625425bb815Sopenharmony_ciassert(replace.call({ exec : ( ) => { return {  } } }, 'һһһһһһһһһ', "a") === "a");
626425bb815Sopenharmony_ciassert(replace.call({ exec : ( ) => { return {  } } }, 'һһһһһһһһһһ', "a") === "aһ");
627425bb815Sopenharmony_ci
628425bb815Sopenharmony_ci/* Object with custom @@replace method */
629425bb815Sopenharmony_civar o = {}
630425bb815Sopenharmony_cio[Symbol.replace] = function () {
631425bb815Sopenharmony_ci  return "Duck"
632425bb815Sopenharmony_ci};
633425bb815Sopenharmony_ciassert ("string".replace (o, "Mallard") === "Duck");
634425bb815Sopenharmony_ci
635425bb815Sopenharmony_cio[Symbol.replace] = 42;
636425bb815Sopenharmony_citry {
637425bb815Sopenharmony_ci  "string".replace (o, "Duck");
638425bb815Sopenharmony_ci  assert (false);
639425bb815Sopenharmony_ci} catch (e) {
640425bb815Sopenharmony_ci  assert (e instanceof TypeError);
641425bb815Sopenharmony_ci}
642425bb815Sopenharmony_ci
643425bb815Sopenharmony_ciObject.defineProperty (o, Symbol.replace, {
644425bb815Sopenharmony_ci  get: () => {
645425bb815Sopenharmony_ci    throw "abrupt @@replace get"
646425bb815Sopenharmony_ci  },
647425bb815Sopenharmony_ci  set: (v) => {}
648425bb815Sopenharmony_ci});
649425bb815Sopenharmony_ci
650425bb815Sopenharmony_citry {
651425bb815Sopenharmony_ci  "string".replace (o, "Duck");
652425bb815Sopenharmony_ci  assert (false);
653425bb815Sopenharmony_ci} catch (e) {
654425bb815Sopenharmony_ci  assert (e === "abrupt @@replace get");
655425bb815Sopenharmony_ci}
656425bb815Sopenharmony_ci
657425bb815Sopenharmony_cio = {};
658425bb815Sopenharmony_cio[Symbol.replace] = function () {
659425bb815Sopenharmony_ci  throw "abrupt @@replace"
660425bb815Sopenharmony_ci};
661425bb815Sopenharmony_citry {
662425bb815Sopenharmony_ci  "string".replace (o, "str");
663425bb815Sopenharmony_ci  assert (false);
664425bb815Sopenharmony_ci} catch (e) {
665425bb815Sopenharmony_ci  assert (e === "abrupt @@replace")
666425bb815Sopenharmony_ci}
667425bb815Sopenharmony_ci
668425bb815Sopenharmony_ciclass Regexplike2 {
669425bb815Sopenharmony_ci    exec() {
670425bb815Sopenharmony_ci        return {}
671425bb815Sopenharmony_ci    }
672425bb815Sopenharmony_ci}
673425bb815Sopenharmony_cire = new Regexplike2();
674425bb815Sopenharmony_ciassert (replace.call (re, "1") === "undefined");
675