11cb0ef41Sopenharmony_ci#!/usr/bin/env python
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci# Copyright 2016 the V8 project authors. All rights reserved.
41cb0ef41Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be
51cb0ef41Sopenharmony_ci# found in the LICENSE file.
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci# for py2/py3 compatibility
81cb0ef41Sopenharmony_cifrom __future__ import print_function
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_cifrom collections import namedtuple
111cb0ef41Sopenharmony_ciimport textwrap
121cb0ef41Sopenharmony_ciimport sys
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciSHARD_FILENAME_TEMPLATE = "test/mjsunit/compiler/inline-exception-{shard}.js"
151cb0ef41Sopenharmony_ci# Generates 2 files. Found by trial and error.
161cb0ef41Sopenharmony_ciSHARD_SIZE = 97
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciPREAMBLE = """
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci// Copyright 2016 the V8 project authors. All rights reserved.
211cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
221cb0ef41Sopenharmony_ci// found in the LICENSE file.
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci// Flags: --allow-natives-syntax --no-always-opt
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci// This test file was generated by tools/gen-inlining-tests.py .
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci// Global variables
291cb0ef41Sopenharmony_civar deopt = undefined; // either true or false
301cb0ef41Sopenharmony_civar counter = 0;
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_cifunction resetState() {
331cb0ef41Sopenharmony_ci  counter = 0;
341cb0ef41Sopenharmony_ci}
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_cifunction warmUp(f) {
371cb0ef41Sopenharmony_ci  try {
381cb0ef41Sopenharmony_ci    f();
391cb0ef41Sopenharmony_ci  } catch (ex) {
401cb0ef41Sopenharmony_ci    // ok
411cb0ef41Sopenharmony_ci  }
421cb0ef41Sopenharmony_ci  try {
431cb0ef41Sopenharmony_ci    f();
441cb0ef41Sopenharmony_ci  } catch (ex) {
451cb0ef41Sopenharmony_ci    // ok
461cb0ef41Sopenharmony_ci  }
471cb0ef41Sopenharmony_ci}
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_cifunction resetOptAndAssertResultEquals(expected, f) {
501cb0ef41Sopenharmony_ci  warmUp(f);
511cb0ef41Sopenharmony_ci  resetState();
521cb0ef41Sopenharmony_ci  // %DebugPrint(f);
531cb0ef41Sopenharmony_ci  eval("'dont optimize this function itself please, but do optimize f'");
541cb0ef41Sopenharmony_ci  %OptimizeFunctionOnNextCall(f);
551cb0ef41Sopenharmony_ci  assertEquals(expected, f());
561cb0ef41Sopenharmony_ci}
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_cifunction resetOptAndAssertThrowsWith(expected, f) {
591cb0ef41Sopenharmony_ci  warmUp(f);
601cb0ef41Sopenharmony_ci  resetState();
611cb0ef41Sopenharmony_ci  // %DebugPrint(f);
621cb0ef41Sopenharmony_ci  eval("'dont optimize this function itself please, but do optimize f'");
631cb0ef41Sopenharmony_ci  %OptimizeFunctionOnNextCall(f);
641cb0ef41Sopenharmony_ci  try {
651cb0ef41Sopenharmony_ci    var result = f();
661cb0ef41Sopenharmony_ci    fail("resetOptAndAssertThrowsWith",
671cb0ef41Sopenharmony_ci        "exception: " + expected,
681cb0ef41Sopenharmony_ci        "result: " + result);
691cb0ef41Sopenharmony_ci  } catch (ex) {
701cb0ef41Sopenharmony_ci    assertEquals(expected, ex);
711cb0ef41Sopenharmony_ci  }
721cb0ef41Sopenharmony_ci}
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_cifunction increaseAndReturn15() {
751cb0ef41Sopenharmony_ci  if (deopt) %DeoptimizeFunction(f);
761cb0ef41Sopenharmony_ci  counter++;
771cb0ef41Sopenharmony_ci  return 15;
781cb0ef41Sopenharmony_ci}
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_cifunction increaseAndThrow42() {
811cb0ef41Sopenharmony_ci  if (deopt) %DeoptimizeFunction(f);
821cb0ef41Sopenharmony_ci  counter++;
831cb0ef41Sopenharmony_ci  throw 42;
841cb0ef41Sopenharmony_ci}
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_cifunction increaseAndReturn15_noopt_inner() {
871cb0ef41Sopenharmony_ci  if (deopt) %DeoptimizeFunction(f);
881cb0ef41Sopenharmony_ci  counter++;
891cb0ef41Sopenharmony_ci  return 15;
901cb0ef41Sopenharmony_ci}
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci%NeverOptimizeFunction(increaseAndReturn15_noopt_inner);
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_cifunction increaseAndThrow42_noopt_inner() {
951cb0ef41Sopenharmony_ci  if (deopt) %DeoptimizeFunction(f);
961cb0ef41Sopenharmony_ci  counter++;
971cb0ef41Sopenharmony_ci  throw 42;
981cb0ef41Sopenharmony_ci}
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci%NeverOptimizeFunction(increaseAndThrow42_noopt_inner);
1011cb0ef41Sopenharmony_ci
1021cb0ef41Sopenharmony_ci// Alternative 1
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_cifunction returnOrThrow(doReturn) {
1051cb0ef41Sopenharmony_ci  if (doReturn) {
1061cb0ef41Sopenharmony_ci    return increaseAndReturn15();
1071cb0ef41Sopenharmony_ci  } else {
1081cb0ef41Sopenharmony_ci    return increaseAndThrow42();
1091cb0ef41Sopenharmony_ci  }
1101cb0ef41Sopenharmony_ci}
1111cb0ef41Sopenharmony_ci
1121cb0ef41Sopenharmony_ci// Alternative 2
1131cb0ef41Sopenharmony_ci
1141cb0ef41Sopenharmony_cifunction increaseAndReturn15_calls_noopt() {
1151cb0ef41Sopenharmony_ci  return increaseAndReturn15_noopt_inner();
1161cb0ef41Sopenharmony_ci}
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_cifunction increaseAndThrow42_calls_noopt() {
1191cb0ef41Sopenharmony_ci  return increaseAndThrow42_noopt_inner();
1201cb0ef41Sopenharmony_ci}
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci// Alternative 3.
1231cb0ef41Sopenharmony_ci// When passed either {increaseAndReturn15} or {increaseAndThrow42}, it acts
1241cb0ef41Sopenharmony_ci// as the other one.
1251cb0ef41Sopenharmony_cifunction invertFunctionCall(f) {
1261cb0ef41Sopenharmony_ci  var result;
1271cb0ef41Sopenharmony_ci  try {
1281cb0ef41Sopenharmony_ci    result = f();
1291cb0ef41Sopenharmony_ci  } catch (ex) {
1301cb0ef41Sopenharmony_ci    return ex - 27;
1311cb0ef41Sopenharmony_ci  }
1321cb0ef41Sopenharmony_ci  throw result + 27;
1331cb0ef41Sopenharmony_ci}
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci// Alternative 4: constructor
1361cb0ef41Sopenharmony_cifunction increaseAndStore15Constructor() {
1371cb0ef41Sopenharmony_ci  if (deopt) %DeoptimizeFunction(f);
1381cb0ef41Sopenharmony_ci  ++counter;
1391cb0ef41Sopenharmony_ci  this.x = 15;
1401cb0ef41Sopenharmony_ci}
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_cifunction increaseAndThrow42Constructor() {
1431cb0ef41Sopenharmony_ci  if (deopt) %DeoptimizeFunction(f);
1441cb0ef41Sopenharmony_ci  ++counter;
1451cb0ef41Sopenharmony_ci  this.x = 42;
1461cb0ef41Sopenharmony_ci  throw this.x;
1471cb0ef41Sopenharmony_ci}
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci// Alternative 5: property
1501cb0ef41Sopenharmony_civar magic = {};
1511cb0ef41Sopenharmony_ciObject.defineProperty(magic, 'prop', {
1521cb0ef41Sopenharmony_ci  get: function () {
1531cb0ef41Sopenharmony_ci    if (deopt) %DeoptimizeFunction(f);
1541cb0ef41Sopenharmony_ci    return 15 + 0 * ++counter;
1551cb0ef41Sopenharmony_ci  },
1561cb0ef41Sopenharmony_ci
1571cb0ef41Sopenharmony_ci  set: function(x) {
1581cb0ef41Sopenharmony_ci    // argument should be 37
1591cb0ef41Sopenharmony_ci    if (deopt) %DeoptimizeFunction(f);
1601cb0ef41Sopenharmony_ci    counter -= 36 - x; // increments counter
1611cb0ef41Sopenharmony_ci    throw 42;
1621cb0ef41Sopenharmony_ci  }
1631cb0ef41Sopenharmony_ci})
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci// Generate type feedback.
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ciassertEquals(15, increaseAndReturn15_calls_noopt());
1681cb0ef41Sopenharmony_ciassertThrowsEquals(function() { return increaseAndThrow42_noopt_inner() }, 42);
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ciassertEquals(15, (new increaseAndStore15Constructor()).x);
1711cb0ef41Sopenharmony_ciassertThrowsEquals(function() {
1721cb0ef41Sopenharmony_ci        return (new increaseAndThrow42Constructor()).x;
1731cb0ef41Sopenharmony_ci    },
1741cb0ef41Sopenharmony_ci    42);
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_cifunction runThisShard() {
1771cb0ef41Sopenharmony_ci
1781cb0ef41Sopenharmony_ci""".strip()
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_cidef booltuples(n):
1811cb0ef41Sopenharmony_ci  """booltuples(2) yields 4 tuples: (False, False), (False, True),
1821cb0ef41Sopenharmony_ci  (True, False), (True, True)."""
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ci  assert isinstance(n, int)
1851cb0ef41Sopenharmony_ci  if n <= 0:
1861cb0ef41Sopenharmony_ci    yield ()
1871cb0ef41Sopenharmony_ci  else:
1881cb0ef41Sopenharmony_ci    for initial in booltuples(n-1):
1891cb0ef41Sopenharmony_ci      yield initial + (False,)
1901cb0ef41Sopenharmony_ci      yield initial + (True,)
1911cb0ef41Sopenharmony_ci
1921cb0ef41Sopenharmony_cidef fnname(flags):
1931cb0ef41Sopenharmony_ci    assert len(FLAGLETTERS) == len(flags)
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_ci    return "f_" + ''.join(
1961cb0ef41Sopenharmony_ci          FLAGLETTERS[i] if b else '_'
1971cb0ef41Sopenharmony_ci          for (i, b) in enumerate(flags))
1981cb0ef41Sopenharmony_ci
1991cb0ef41Sopenharmony_ciNUM_TESTS_PRINTED = 0
2001cb0ef41Sopenharmony_ciNUM_TESTS_IN_SHARD = 0
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_cidef printtest(flags):
2031cb0ef41Sopenharmony_ci  """Print a test case. Takes a couple of boolean flags, on which the
2041cb0ef41Sopenharmony_ci  printed Javascript code depends."""
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ci  assert all(isinstance(flag, bool) for flag in flags)
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci  # The alternative flags are in reverse order so that if we take all possible
2091cb0ef41Sopenharmony_ci  # tuples, ordered lexicographically from false to true, we get first the
2101cb0ef41Sopenharmony_ci  # default, then alternative 1, then 2, etc.
2111cb0ef41Sopenharmony_ci  (
2121cb0ef41Sopenharmony_ci    alternativeFn5,      # use alternative #5 for returning/throwing:
2131cb0ef41Sopenharmony_ci                         #   return/throw using property
2141cb0ef41Sopenharmony_ci    alternativeFn4,      # use alternative #4 for returning/throwing:
2151cb0ef41Sopenharmony_ci                         #   return/throw using constructor
2161cb0ef41Sopenharmony_ci    alternativeFn3,      # use alternative #3 for returning/throwing:
2171cb0ef41Sopenharmony_ci                         #   return/throw indirectly, based on function argument
2181cb0ef41Sopenharmony_ci    alternativeFn2,      # use alternative #2 for returning/throwing:
2191cb0ef41Sopenharmony_ci                         #   return/throw indirectly in unoptimized code,
2201cb0ef41Sopenharmony_ci                         #   no branching
2211cb0ef41Sopenharmony_ci    alternativeFn1,      # use alternative #1 for returning/throwing:
2221cb0ef41Sopenharmony_ci                         #   return/throw indirectly, based on boolean arg
2231cb0ef41Sopenharmony_ci    tryThrows,           # in try block, call throwing function
2241cb0ef41Sopenharmony_ci    tryReturns,          # in try block, call returning function
2251cb0ef41Sopenharmony_ci    tryFirstReturns,     # in try block, returning goes before throwing
2261cb0ef41Sopenharmony_ci    tryResultToLocal,    # in try block, result goes to local variable
2271cb0ef41Sopenharmony_ci    doCatch,             # include catch block
2281cb0ef41Sopenharmony_ci    catchReturns,        # in catch block, return
2291cb0ef41Sopenharmony_ci    catchWithLocal,      # in catch block, modify or return the local variable
2301cb0ef41Sopenharmony_ci    catchThrows,         # in catch block, throw
2311cb0ef41Sopenharmony_ci    doFinally,           # include finally block
2321cb0ef41Sopenharmony_ci    finallyReturns,      # in finally block, return local variable
2331cb0ef41Sopenharmony_ci    finallyThrows,       # in finally block, throw
2341cb0ef41Sopenharmony_ci    endReturnLocal,      # at very end, return variable local
2351cb0ef41Sopenharmony_ci    deopt,               # deopt inside inlined function
2361cb0ef41Sopenharmony_ci  ) = flags
2371cb0ef41Sopenharmony_ci
2381cb0ef41Sopenharmony_ci  # BASIC RULES
2391cb0ef41Sopenharmony_ci
2401cb0ef41Sopenharmony_ci  # Only one alternative can be applied at any time.
2411cb0ef41Sopenharmony_ci  if (alternativeFn1 + alternativeFn2 + alternativeFn3 + alternativeFn4
2421cb0ef41Sopenharmony_ci      + alternativeFn5 > 1):
2431cb0ef41Sopenharmony_ci    return
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ci  # In try, return or throw, or both.
2461cb0ef41Sopenharmony_ci  if not (tryReturns or tryThrows): return
2471cb0ef41Sopenharmony_ci
2481cb0ef41Sopenharmony_ci  # Either doCatch or doFinally.
2491cb0ef41Sopenharmony_ci  if not doCatch and not doFinally: return
2501cb0ef41Sopenharmony_ci
2511cb0ef41Sopenharmony_ci  # Catch flags only make sense when catching
2521cb0ef41Sopenharmony_ci  if not doCatch and (catchReturns or catchWithLocal or catchThrows):
2531cb0ef41Sopenharmony_ci    return
2541cb0ef41Sopenharmony_ci
2551cb0ef41Sopenharmony_ci  # Finally flags only make sense when finallying
2561cb0ef41Sopenharmony_ci  if not doFinally and (finallyReturns or finallyThrows):
2571cb0ef41Sopenharmony_ci    return
2581cb0ef41Sopenharmony_ci
2591cb0ef41Sopenharmony_ci  # tryFirstReturns is only relevant when both tryReturns and tryThrows are
2601cb0ef41Sopenharmony_ci  # true.
2611cb0ef41Sopenharmony_ci  if tryFirstReturns and not (tryReturns and tryThrows): return
2621cb0ef41Sopenharmony_ci
2631cb0ef41Sopenharmony_ci  # From the try and finally block, we can return or throw, but not both.
2641cb0ef41Sopenharmony_ci  if catchReturns and catchThrows: return
2651cb0ef41Sopenharmony_ci  if finallyReturns and finallyThrows: return
2661cb0ef41Sopenharmony_ci
2671cb0ef41Sopenharmony_ci  # If at the end we return the local, we need to have touched it.
2681cb0ef41Sopenharmony_ci  if endReturnLocal and not (tryResultToLocal or catchWithLocal): return
2691cb0ef41Sopenharmony_ci
2701cb0ef41Sopenharmony_ci  # PRUNING
2711cb0ef41Sopenharmony_ci
2721cb0ef41Sopenharmony_ci  anyAlternative = any([alternativeFn1, alternativeFn2, alternativeFn3,
2731cb0ef41Sopenharmony_ci      alternativeFn4, alternativeFn5])
2741cb0ef41Sopenharmony_ci  specificAlternative = any([alternativeFn2, alternativeFn3])
2751cb0ef41Sopenharmony_ci  rareAlternative = not specificAlternative
2761cb0ef41Sopenharmony_ci
2771cb0ef41Sopenharmony_ci  # If try returns and throws, then don't catchWithLocal, endReturnLocal, or
2781cb0ef41Sopenharmony_ci  # deopt, or do any alternative.
2791cb0ef41Sopenharmony_ci  if (tryReturns and tryThrows and
2801cb0ef41Sopenharmony_ci      (catchWithLocal or endReturnLocal or deopt or anyAlternative)):
2811cb0ef41Sopenharmony_ci    return
2821cb0ef41Sopenharmony_ci  # We don't do any alternative if we do a finally.
2831cb0ef41Sopenharmony_ci  if doFinally and anyAlternative: return
2841cb0ef41Sopenharmony_ci  # We only use the local variable if we do alternative #2 or #3.
2851cb0ef41Sopenharmony_ci  if ((tryResultToLocal or catchWithLocal or endReturnLocal) and
2861cb0ef41Sopenharmony_ci      not specificAlternative):
2871cb0ef41Sopenharmony_ci    return
2881cb0ef41Sopenharmony_ci  # We don't need to test deopting into a finally.
2891cb0ef41Sopenharmony_ci  if doFinally and deopt: return
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_ci  # We're only interested in alternative #2 if we have endReturnLocal, no
2921cb0ef41Sopenharmony_ci  # catchReturns, and no catchThrows, and deopt.
2931cb0ef41Sopenharmony_ci  if (alternativeFn2 and
2941cb0ef41Sopenharmony_ci      (not endReturnLocal or catchReturns or catchThrows or not deopt)):
2951cb0ef41Sopenharmony_ci    return
2961cb0ef41Sopenharmony_ci
2971cb0ef41Sopenharmony_ci
2981cb0ef41Sopenharmony_ci  # Flag check succeeded.
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_ci  trueFlagNames = [name for (name, value) in flags._asdict().items() if value]
3011cb0ef41Sopenharmony_ci  flagsMsgLine = "  // Variant flags: [{}]".format(', '.join(trueFlagNames))
3021cb0ef41Sopenharmony_ci  write(textwrap.fill(flagsMsgLine, subsequent_indent='  //   '))
3031cb0ef41Sopenharmony_ci  write("")
3041cb0ef41Sopenharmony_ci
3051cb0ef41Sopenharmony_ci  if not anyAlternative:
3061cb0ef41Sopenharmony_ci    fragments = {
3071cb0ef41Sopenharmony_ci      'increaseAndReturn15': 'increaseAndReturn15()',
3081cb0ef41Sopenharmony_ci      'increaseAndThrow42': 'increaseAndThrow42()',
3091cb0ef41Sopenharmony_ci    }
3101cb0ef41Sopenharmony_ci  elif alternativeFn1:
3111cb0ef41Sopenharmony_ci    fragments = {
3121cb0ef41Sopenharmony_ci      'increaseAndReturn15': 'returnOrThrow(true)',
3131cb0ef41Sopenharmony_ci      'increaseAndThrow42': 'returnOrThrow(false)',
3141cb0ef41Sopenharmony_ci    }
3151cb0ef41Sopenharmony_ci  elif alternativeFn2:
3161cb0ef41Sopenharmony_ci    fragments = {
3171cb0ef41Sopenharmony_ci      'increaseAndReturn15': 'increaseAndReturn15_calls_noopt()',
3181cb0ef41Sopenharmony_ci      'increaseAndThrow42': 'increaseAndThrow42_calls_noopt()',
3191cb0ef41Sopenharmony_ci    }
3201cb0ef41Sopenharmony_ci  elif alternativeFn3:
3211cb0ef41Sopenharmony_ci    fragments = {
3221cb0ef41Sopenharmony_ci      'increaseAndReturn15': 'invertFunctionCall(increaseAndThrow42)',
3231cb0ef41Sopenharmony_ci      'increaseAndThrow42': 'invertFunctionCall(increaseAndReturn15)',
3241cb0ef41Sopenharmony_ci    }
3251cb0ef41Sopenharmony_ci  elif alternativeFn4:
3261cb0ef41Sopenharmony_ci    fragments = {
3271cb0ef41Sopenharmony_ci      'increaseAndReturn15': '(new increaseAndStore15Constructor()).x',
3281cb0ef41Sopenharmony_ci      'increaseAndThrow42': '(new increaseAndThrow42Constructor()).x',
3291cb0ef41Sopenharmony_ci    }
3301cb0ef41Sopenharmony_ci  else:
3311cb0ef41Sopenharmony_ci    assert alternativeFn5
3321cb0ef41Sopenharmony_ci    fragments = {
3331cb0ef41Sopenharmony_ci      'increaseAndReturn15': 'magic.prop /* returns 15 */',
3341cb0ef41Sopenharmony_ci      'increaseAndThrow42': '(magic.prop = 37 /* throws 42 */)',
3351cb0ef41Sopenharmony_ci    }
3361cb0ef41Sopenharmony_ci
3371cb0ef41Sopenharmony_ci  # As we print code, we also maintain what the result should be. Variable
3381cb0ef41Sopenharmony_ci  # {result} can be one of three things:
3391cb0ef41Sopenharmony_ci  #
3401cb0ef41Sopenharmony_ci  # - None, indicating returning JS null
3411cb0ef41Sopenharmony_ci  # - ("return", n) with n an integer
3421cb0ef41Sopenharmony_ci  # - ("throw", n), with n an integer
3431cb0ef41Sopenharmony_ci
3441cb0ef41Sopenharmony_ci  result = None
3451cb0ef41Sopenharmony_ci  # We also maintain what the counter should be at the end.
3461cb0ef41Sopenharmony_ci  # The counter is reset just before f is called.
3471cb0ef41Sopenharmony_ci  counter = 0
3481cb0ef41Sopenharmony_ci
3491cb0ef41Sopenharmony_ci  write(    "  f = function {} () {{".format(fnname(flags)))
3501cb0ef41Sopenharmony_ci  write(    "    var local = 888;")
3511cb0ef41Sopenharmony_ci  write(    "    deopt = {};".format("true" if deopt else "false"))
3521cb0ef41Sopenharmony_ci  local = 888
3531cb0ef41Sopenharmony_ci  write(    "    try {")
3541cb0ef41Sopenharmony_ci  write(    "      counter++;")
3551cb0ef41Sopenharmony_ci  counter += 1
3561cb0ef41Sopenharmony_ci  resultTo = "local +=" if tryResultToLocal else "return"
3571cb0ef41Sopenharmony_ci  if tryReturns and not (tryThrows and not tryFirstReturns):
3581cb0ef41Sopenharmony_ci    write(  "      {} 4 + {increaseAndReturn15};".format(resultTo, **fragments))
3591cb0ef41Sopenharmony_ci    if result == None:
3601cb0ef41Sopenharmony_ci      counter += 1
3611cb0ef41Sopenharmony_ci      if tryResultToLocal:
3621cb0ef41Sopenharmony_ci        local += 19
3631cb0ef41Sopenharmony_ci      else:
3641cb0ef41Sopenharmony_ci        result = ("return", 19)
3651cb0ef41Sopenharmony_ci  if tryThrows:
3661cb0ef41Sopenharmony_ci    write(  "      {} 4 + {increaseAndThrow42};".format(resultTo, **fragments))
3671cb0ef41Sopenharmony_ci    if result == None:
3681cb0ef41Sopenharmony_ci      counter += 1
3691cb0ef41Sopenharmony_ci      result = ("throw", 42)
3701cb0ef41Sopenharmony_ci  if tryReturns and tryThrows and not tryFirstReturns:
3711cb0ef41Sopenharmony_ci    write(  "      {} 4 + {increaseAndReturn15};".format(resultTo, **fragments))
3721cb0ef41Sopenharmony_ci    if result == None:
3731cb0ef41Sopenharmony_ci      counter += 1
3741cb0ef41Sopenharmony_ci      if tryResultToLocal:
3751cb0ef41Sopenharmony_ci        local += 19
3761cb0ef41Sopenharmony_ci      else:
3771cb0ef41Sopenharmony_ci        result = ("return", 19)
3781cb0ef41Sopenharmony_ci  write(    "      counter++;")
3791cb0ef41Sopenharmony_ci  if result == None:
3801cb0ef41Sopenharmony_ci    counter += 1
3811cb0ef41Sopenharmony_ci
3821cb0ef41Sopenharmony_ci  if doCatch:
3831cb0ef41Sopenharmony_ci    write(  "    } catch (ex) {")
3841cb0ef41Sopenharmony_ci    write(  "      counter++;")
3851cb0ef41Sopenharmony_ci    if isinstance(result, tuple) and result[0] == 'throw':
3861cb0ef41Sopenharmony_ci      counter += 1
3871cb0ef41Sopenharmony_ci    if catchThrows:
3881cb0ef41Sopenharmony_ci      write("      throw 2 + ex;")
3891cb0ef41Sopenharmony_ci      if isinstance(result, tuple) and result[0] == "throw":
3901cb0ef41Sopenharmony_ci        result = ('throw', 2 + result[1])
3911cb0ef41Sopenharmony_ci    elif catchReturns and catchWithLocal:
3921cb0ef41Sopenharmony_ci      write("      return 2 + local;")
3931cb0ef41Sopenharmony_ci      if isinstance(result, tuple) and result[0] == "throw":
3941cb0ef41Sopenharmony_ci        result = ('return', 2 + local)
3951cb0ef41Sopenharmony_ci    elif catchReturns and not catchWithLocal:
3961cb0ef41Sopenharmony_ci      write("      return 2 + ex;");
3971cb0ef41Sopenharmony_ci      if isinstance(result, tuple) and result[0] == "throw":
3981cb0ef41Sopenharmony_ci        result = ('return', 2 + result[1])
3991cb0ef41Sopenharmony_ci    elif catchWithLocal:
4001cb0ef41Sopenharmony_ci      write("      local += ex;");
4011cb0ef41Sopenharmony_ci      if isinstance(result, tuple) and result[0] == "throw":
4021cb0ef41Sopenharmony_ci        local += result[1]
4031cb0ef41Sopenharmony_ci        result = None
4041cb0ef41Sopenharmony_ci        counter += 1
4051cb0ef41Sopenharmony_ci    else:
4061cb0ef41Sopenharmony_ci      if isinstance(result, tuple) and result[0] == "throw":
4071cb0ef41Sopenharmony_ci        result = None
4081cb0ef41Sopenharmony_ci        counter += 1
4091cb0ef41Sopenharmony_ci    write(  "      counter++;")
4101cb0ef41Sopenharmony_ci
4111cb0ef41Sopenharmony_ci  if doFinally:
4121cb0ef41Sopenharmony_ci    write(  "    } finally {")
4131cb0ef41Sopenharmony_ci    write(  "      counter++;")
4141cb0ef41Sopenharmony_ci    counter += 1
4151cb0ef41Sopenharmony_ci    if finallyThrows:
4161cb0ef41Sopenharmony_ci      write("      throw 25;")
4171cb0ef41Sopenharmony_ci      result = ('throw', 25)
4181cb0ef41Sopenharmony_ci    elif finallyReturns:
4191cb0ef41Sopenharmony_ci      write("      return 3 + local;")
4201cb0ef41Sopenharmony_ci      result = ('return', 3 + local)
4211cb0ef41Sopenharmony_ci    elif not finallyReturns and not finallyThrows:
4221cb0ef41Sopenharmony_ci      write("      local += 2;")
4231cb0ef41Sopenharmony_ci      local += 2
4241cb0ef41Sopenharmony_ci      counter += 1
4251cb0ef41Sopenharmony_ci    else: assert False # unreachable
4261cb0ef41Sopenharmony_ci    write(  "      counter++;")
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_ci  write(    "    }")
4291cb0ef41Sopenharmony_ci  write(    "    counter++;")
4301cb0ef41Sopenharmony_ci  if result == None:
4311cb0ef41Sopenharmony_ci    counter += 1
4321cb0ef41Sopenharmony_ci  if endReturnLocal:
4331cb0ef41Sopenharmony_ci    write(  "    return 5 + local;")
4341cb0ef41Sopenharmony_ci    if result == None:
4351cb0ef41Sopenharmony_ci      result = ('return', 5 + local)
4361cb0ef41Sopenharmony_ci  write(    "  }")
4371cb0ef41Sopenharmony_ci
4381cb0ef41Sopenharmony_ci  if result == None:
4391cb0ef41Sopenharmony_ci    write(  "  resetOptAndAssertResultEquals(undefined, f);")
4401cb0ef41Sopenharmony_ci  else:
4411cb0ef41Sopenharmony_ci    tag, value = result
4421cb0ef41Sopenharmony_ci    if tag == "return":
4431cb0ef41Sopenharmony_ci      write(  "  resetOptAndAssertResultEquals({}, f);".format(value))
4441cb0ef41Sopenharmony_ci    else:
4451cb0ef41Sopenharmony_ci      assert tag == "throw"
4461cb0ef41Sopenharmony_ci      write(  "  resetOptAndAssertThrowsWith({}, f);".format(value))
4471cb0ef41Sopenharmony_ci
4481cb0ef41Sopenharmony_ci  write(  "  assertEquals({}, counter);".format(counter))
4491cb0ef41Sopenharmony_ci  write(  "")
4501cb0ef41Sopenharmony_ci
4511cb0ef41Sopenharmony_ci  global NUM_TESTS_PRINTED, NUM_TESTS_IN_SHARD
4521cb0ef41Sopenharmony_ci  NUM_TESTS_PRINTED += 1
4531cb0ef41Sopenharmony_ci  NUM_TESTS_IN_SHARD += 1
4541cb0ef41Sopenharmony_ci
4551cb0ef41Sopenharmony_ciFILE = None # to be initialised to an open file
4561cb0ef41Sopenharmony_ciSHARD_NUM = 1
4571cb0ef41Sopenharmony_ci
4581cb0ef41Sopenharmony_cidef write(*args):
4591cb0ef41Sopenharmony_ci  return print(*args, file=FILE)
4601cb0ef41Sopenharmony_ci
4611cb0ef41Sopenharmony_ci
4621cb0ef41Sopenharmony_ci
4631cb0ef41Sopenharmony_cidef rotateshard():
4641cb0ef41Sopenharmony_ci  global FILE, NUM_TESTS_IN_SHARD, SHARD_SIZE
4651cb0ef41Sopenharmony_ci  if MODE != 'shard':
4661cb0ef41Sopenharmony_ci    return
4671cb0ef41Sopenharmony_ci  if FILE != None and NUM_TESTS_IN_SHARD < SHARD_SIZE:
4681cb0ef41Sopenharmony_ci    return
4691cb0ef41Sopenharmony_ci  if FILE != None:
4701cb0ef41Sopenharmony_ci    finishshard()
4711cb0ef41Sopenharmony_ci    assert FILE == None
4721cb0ef41Sopenharmony_ci  FILE = open(SHARD_FILENAME_TEMPLATE.format(shard=SHARD_NUM), 'w')
4731cb0ef41Sopenharmony_ci  write_shard_header()
4741cb0ef41Sopenharmony_ci  NUM_TESTS_IN_SHARD = 0
4751cb0ef41Sopenharmony_ci
4761cb0ef41Sopenharmony_cidef finishshard():
4771cb0ef41Sopenharmony_ci  global FILE, SHARD_NUM, MODE
4781cb0ef41Sopenharmony_ci  assert FILE
4791cb0ef41Sopenharmony_ci  write_shard_footer()
4801cb0ef41Sopenharmony_ci  if MODE == 'shard':
4811cb0ef41Sopenharmony_ci    print("Wrote shard {}.".format(SHARD_NUM))
4821cb0ef41Sopenharmony_ci    FILE.close()
4831cb0ef41Sopenharmony_ci    FILE = None
4841cb0ef41Sopenharmony_ci    SHARD_NUM += 1
4851cb0ef41Sopenharmony_ci
4861cb0ef41Sopenharmony_ci
4871cb0ef41Sopenharmony_cidef write_shard_header():
4881cb0ef41Sopenharmony_ci  if MODE == 'shard':
4891cb0ef41Sopenharmony_ci    write("// Shard {}.".format(SHARD_NUM))
4901cb0ef41Sopenharmony_ci    write("")
4911cb0ef41Sopenharmony_ci  write(PREAMBLE)
4921cb0ef41Sopenharmony_ci  write("")
4931cb0ef41Sopenharmony_ci
4941cb0ef41Sopenharmony_cidef write_shard_footer():
4951cb0ef41Sopenharmony_ci  write("}")
4961cb0ef41Sopenharmony_ci  write("%NeverOptimizeFunction(runThisShard);")
4971cb0ef41Sopenharmony_ci  write("")
4981cb0ef41Sopenharmony_ci  write("// {} tests in this shard.".format(NUM_TESTS_IN_SHARD))
4991cb0ef41Sopenharmony_ci  write("// {} tests up to here.".format(NUM_TESTS_PRINTED))
5001cb0ef41Sopenharmony_ci  write("")
5011cb0ef41Sopenharmony_ci  write("runThisShard();")
5021cb0ef41Sopenharmony_ci
5031cb0ef41Sopenharmony_ciFLAGLETTERS="54321trflcrltfrtld"
5041cb0ef41Sopenharmony_ci
5051cb0ef41Sopenharmony_ciflagtuple = namedtuple('flagtuple', (
5061cb0ef41Sopenharmony_ci  "alternativeFn5",
5071cb0ef41Sopenharmony_ci  "alternativeFn4",
5081cb0ef41Sopenharmony_ci  "alternativeFn3",
5091cb0ef41Sopenharmony_ci  "alternativeFn2",
5101cb0ef41Sopenharmony_ci  "alternativeFn1",
5111cb0ef41Sopenharmony_ci  "tryThrows",
5121cb0ef41Sopenharmony_ci  "tryReturns",
5131cb0ef41Sopenharmony_ci  "tryFirstReturns",
5141cb0ef41Sopenharmony_ci  "tryResultToLocal",
5151cb0ef41Sopenharmony_ci  "doCatch",
5161cb0ef41Sopenharmony_ci  "catchReturns",
5171cb0ef41Sopenharmony_ci  "catchWithLocal",
5181cb0ef41Sopenharmony_ci  "catchThrows",
5191cb0ef41Sopenharmony_ci  "doFinally",
5201cb0ef41Sopenharmony_ci  "finallyReturns",
5211cb0ef41Sopenharmony_ci  "finallyThrows",
5221cb0ef41Sopenharmony_ci  "endReturnLocal",
5231cb0ef41Sopenharmony_ci  "deopt"
5241cb0ef41Sopenharmony_ci  ))
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_ciemptyflags = flagtuple(*((False,) * len(flagtuple._fields)))
5271cb0ef41Sopenharmony_cif1 = emptyflags._replace(tryReturns=True, doCatch=True)
5281cb0ef41Sopenharmony_ci
5291cb0ef41Sopenharmony_ci# You can test function printtest with f1.
5301cb0ef41Sopenharmony_ci
5311cb0ef41Sopenharmony_ciallFlagCombinations = [
5321cb0ef41Sopenharmony_ci    flagtuple(*bools)
5331cb0ef41Sopenharmony_ci    for bools in booltuples(len(flagtuple._fields))
5341cb0ef41Sopenharmony_ci]
5351cb0ef41Sopenharmony_ci
5361cb0ef41Sopenharmony_ciif __name__ == '__main__':
5371cb0ef41Sopenharmony_ci  global MODE
5381cb0ef41Sopenharmony_ci  if sys.argv[1:] == []:
5391cb0ef41Sopenharmony_ci    MODE = 'stdout'
5401cb0ef41Sopenharmony_ci    print("// Printing all shards together to stdout.")
5411cb0ef41Sopenharmony_ci    print("")
5421cb0ef41Sopenharmony_ci    write_shard_header()
5431cb0ef41Sopenharmony_ci    FILE = sys.stdout
5441cb0ef41Sopenharmony_ci  elif sys.argv[1:] == ['--shard-and-overwrite']:
5451cb0ef41Sopenharmony_ci    MODE = 'shard'
5461cb0ef41Sopenharmony_ci  else:
5471cb0ef41Sopenharmony_ci    print("Usage:")
5481cb0ef41Sopenharmony_ci    print("")
5491cb0ef41Sopenharmony_ci    print("  python {}".format(sys.argv[0]))
5501cb0ef41Sopenharmony_ci    print("      print all tests to standard output")
5511cb0ef41Sopenharmony_ci    print("  python {} --shard-and-overwrite".format(sys.argv[0]))
5521cb0ef41Sopenharmony_ci    print("      print all tests to {}".format(SHARD_FILENAME_TEMPLATE))
5531cb0ef41Sopenharmony_ci
5541cb0ef41Sopenharmony_ci    print("")
5551cb0ef41Sopenharmony_ci    print(sys.argv[1:])
5561cb0ef41Sopenharmony_ci    print("")
5571cb0ef41Sopenharmony_ci    sys.exit(1)
5581cb0ef41Sopenharmony_ci
5591cb0ef41Sopenharmony_ci  rotateshard()
5601cb0ef41Sopenharmony_ci
5611cb0ef41Sopenharmony_ci  for flags in allFlagCombinations:
5621cb0ef41Sopenharmony_ci    printtest(flags)
5631cb0ef41Sopenharmony_ci    rotateshard()
5641cb0ef41Sopenharmony_ci
5651cb0ef41Sopenharmony_ci  finishshard()
5661cb0ef41Sopenharmony_ci
5671cb0ef41Sopenharmony_ci  if MODE == 'shard':
5681cb0ef41Sopenharmony_ci    print("Total: {} tests.".format(NUM_TESTS_PRINTED))
569