_Z14ImportCallbackPvPKcS1_PPcS3_Pm:
   26|     60|                     char** found_here, char **buf, size_t *buflen) {
   27|       |  // Don't load file and mark it as failure.
   28|       |  *buf = NULL;
   29|     60|  *buflen = 0;
   30|     60|  return 1;
   31|     60|}
_Z20ConvertJsonnetToJsonRKNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE:
   33|  8.31k|std::string ConvertJsonnetToJson(const std::string& jsonnet) {
   34|  8.31k|  JsonnetVm* jvm = jsonnet_make();
   35|  8.31k|  jsonnet_import_callback(jvm, ImportCallback, jvm);
   36|  8.31k|  int error = 0;
   37|  8.31k|  char* res =
   38|  8.31k|      jsonnet_evaluate_snippet_multi(jvm, /*filename=*/"", jsonnet.c_str(), &error);
   39|       |
   40|  8.31k|  std::string json;
   41|  8.31k|  if (error == 0 && res != nullptr) {
  ------------------
  |  Branch (41:7): [True: 643, False: 7.67k]
  |  Branch (41:21): [True: 643, False: 0]
  ------------------
   42|    643|    json = res;
   43|    643|  }
   44|       |
   45|  8.31k|  if (res) {
  ------------------
  |  Branch (45:7): [True: 8.31k, False: 0]
  ------------------
   46|  8.31k|    jsonnet_realloc(jvm, res, 0);
   47|  8.31k|  }
   48|  8.31k|  jsonnet_destroy(jvm);
   49|  8.31k|  return json;
   50|  8.31k|}
LLVMFuzzerTestOneInput:
   52|  8.31k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
   53|  8.31k|  std::string fuzz_jsonnet(reinterpret_cast<const char*>(data), size);
   54|  8.31k|  ConvertJsonnetToJson(fuzz_jsonnet);
   55|  8.31k|  return 0;
   56|  8.31k|}

libjsonnet.cpp:_ZN7jsonnet8internal12_GLOBAL__N_120build_precedence_mapEv:
 1047|      2|{
 1048|      2|    std::map<BinaryOp, int> r;
 1049|       |
 1050|      2|    r[BOP_MULT] = 5;
 1051|      2|    r[BOP_DIV] = 5;
 1052|      2|    r[BOP_PERCENT] = 5;
 1053|       |
 1054|      2|    r[BOP_PLUS] = 6;
 1055|      2|    r[BOP_MINUS] = 6;
 1056|       |
 1057|      2|    r[BOP_SHIFT_L] = 7;
 1058|      2|    r[BOP_SHIFT_R] = 7;
 1059|       |
 1060|      2|    r[BOP_GREATER] = 8;
 1061|      2|    r[BOP_GREATER_EQ] = 8;
 1062|      2|    r[BOP_LESS] = 8;
 1063|      2|    r[BOP_LESS_EQ] = 8;
 1064|      2|    r[BOP_IN] = 8;
 1065|       |
 1066|      2|    r[BOP_MANIFEST_EQUAL] = 9;
 1067|      2|    r[BOP_MANIFEST_UNEQUAL] = 9;
 1068|       |
 1069|      2|    r[BOP_BITWISE_AND] = 10;
 1070|       |
 1071|      2|    r[BOP_BITWISE_XOR] = 11;
 1072|       |
 1073|      2|    r[BOP_BITWISE_OR] = 12;
 1074|       |
 1075|      2|    r[BOP_AND] = 13;
 1076|       |
 1077|      2|    r[BOP_OR] = 14;
 1078|       |
 1079|      2|    return r;
 1080|      2|}
libjsonnet.cpp:_ZN7jsonnet8internal12_GLOBAL__N_115build_unary_mapEv:
 1083|      2|{
 1084|      2|    std::map<std::string, UnaryOp> r;
 1085|      2|    r["!"] = UOP_NOT;
 1086|      2|    r["~"] = UOP_BITWISE_NOT;
 1087|      2|    r["+"] = UOP_PLUS;
 1088|      2|    r["-"] = UOP_MINUS;
 1089|      2|    return r;
 1090|      2|}
libjsonnet.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116build_binary_mapEv:
 1093|      2|{
 1094|      2|    std::map<std::string, BinaryOp> r;
 1095|       |
 1096|      2|    r["*"] = BOP_MULT;
 1097|      2|    r["/"] = BOP_DIV;
 1098|      2|    r["%"] = BOP_PERCENT;
 1099|       |
 1100|      2|    r["+"] = BOP_PLUS;
 1101|      2|    r["-"] = BOP_MINUS;
 1102|       |
 1103|      2|    r["<<"] = BOP_SHIFT_L;
 1104|      2|    r[">>"] = BOP_SHIFT_R;
 1105|       |
 1106|      2|    r[">"] = BOP_GREATER;
 1107|      2|    r[">="] = BOP_GREATER_EQ;
 1108|      2|    r["<"] = BOP_LESS;
 1109|      2|    r["<="] = BOP_LESS_EQ;
 1110|      2|    r["in"] = BOP_IN;
 1111|       |
 1112|      2|    r["=="] = BOP_MANIFEST_EQUAL;
 1113|      2|    r["!="] = BOP_MANIFEST_UNEQUAL;
 1114|       |
 1115|      2|    r["&"] = BOP_BITWISE_AND;
 1116|      2|    r["^"] = BOP_BITWISE_XOR;
 1117|      2|    r["|"] = BOP_BITWISE_OR;
 1118|       |
 1119|      2|    r["&&"] = BOP_AND;
 1120|      2|    r["||"] = BOP_OR;
 1121|      2|    return r;
 1122|      2|}
_ZN7jsonnet8internal9AllocatorD2Ev:
 1020|  8.31k|    {
 1021|   118M|        for (auto x : allocated) {
  ------------------
  |  Branch (1021:21): [True: 118M, False: 8.31k]
  ------------------
 1022|   118M|            delete x;
 1023|   118M|        }
 1024|  8.31k|        allocated.clear();
 1025|  2.52M|        for (const auto &x : internedIdentifiers) {
  ------------------
  |  Branch (1025:28): [True: 2.52M, False: 8.31k]
  ------------------
 1026|  2.52M|            delete x.second;
 1027|  2.52M|        }
 1028|  8.31k|        internedIdentifiers.clear();
 1029|   199k|        for (const auto &x : internedBuiltins) {
  ------------------
  |  Branch (1029:28): [True: 199k, False: 8.31k]
  ------------------
 1030|   199k|            delete x.second;
 1031|   199k|        }
 1032|  8.31k|        internedBuiltins.clear();
 1033|  8.31k|    }
_ZN7jsonnet8internal10IdentifierC2ERKNSt3__112basic_stringIDiNS2_11char_traitsIDiEENS2_9allocatorIDiEEEE:
  113|  3.17M|    Identifier(const UString &name) : name(name) {}
_ZN7jsonnet8internal3ASTC2ERKNS0_13LocationRangeENS0_7ASTTypeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEE:
  132|   107M|        : location(location), type(type), openFodder(open_fodder)
  133|   107M|    {
  134|   107M|    }
_ZN7jsonnet8internal3ASTD2Ev:
  135|   118M|    virtual ~AST(void) {}
_ZN7jsonnet8internal8ArgParamC2ERKNSt3__16vectorINS0_13FodderElementENS2_9allocatorIS4_EEEEPKNS0_10IdentifierES9_:
  158|   697k|        : idFodder(id_fodder), id(id), expr(nullptr), commaFodder(comma_fodder)
  159|   697k|    {
  160|   697k|    }
_ZN7jsonnet8internal8ArgParamC2EPNS0_3ASTERKNSt3__16vectorINS0_13FodderElementENS4_9allocatorIS6_EEEE:
  163|  7.54M|        : id(nullptr), expr(expr), commaFodder(comma_fodder)
  164|  7.54M|    {
  165|  7.54M|    }
_ZN7jsonnet8internal8ArgParamC2ERKNSt3__16vectorINS0_13FodderElementENS2_9allocatorIS4_EEEEPKNS0_10IdentifierES9_PNS0_3ASTES9_:
  169|  15.7M|        : idFodder(id_fodder), id(id), eqFodder(eq_fodder), expr(expr), commaFodder(comma_fodder)
  170|  15.7M|    {
  171|  15.7M|    }
_ZN7jsonnet8internal17ComprehensionSpecC2ENS1_4KindERKNSt3__16vectorINS0_13FodderElementENS3_9allocatorIS5_EEEESA_PKNS0_10IdentifierESA_PNS0_3ASTE:
  187|   546k|        : kind(kind),
  188|   546k|          openFodder(open_fodder),
  189|   546k|          varFodder(var_fodder),
  190|   546k|          var(var),
  191|   546k|          inFodder(in_fodder),
  192|   546k|          expr(expr)
  193|   546k|    {
  194|   546k|    }
_ZN7jsonnet8internal5ApplyC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_RKNS6_INS0_8ArgParamENS8_ISF_EEEEbSC_SC_b:
  209|  11.0M|        : AST(lr, AST_APPLY, open_fodder),
  210|  11.0M|          target(target),
  211|  11.0M|          fodderL(fodder_l),
  212|  11.0M|          args(args),
  213|  11.0M|          trailingComma(trailing_comma),
  214|  11.0M|          fodderR(fodder_r),
  215|  11.0M|          tailstrictFodder(tailstrict_fodder),
  216|  11.0M|          tailstrict(tailstrict)
  217|  11.0M|    {
  218|  11.0M|    }
_ZN7jsonnet8internal10ApplyBraceC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESE_:
  226|   112k|        : AST(lr, AST_APPLY_BRACE, open_fodder), left(left), right(right)
  227|   112k|    {
  228|   112k|    }
_ZN7jsonnet8internal5Array7ElementC2EPNS0_3ASTERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEE:
  236|  3.36M|        Element(AST *expr, const Fodder &comma_fodder) : expr(expr), commaFodder(comma_fodder) {}
_ZN7jsonnet8internal5ArrayC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERKNS6_INS1_7ElementENS8_ISD_EEEEbSC_:
  244|  1.61M|        : AST(lr, AST_ARRAY, open_fodder),
  245|  1.61M|          elements(elements),
  246|  1.61M|          trailingComma(trailing_comma),
  247|  1.61M|          closeFodder(close_fodder)
  248|  1.61M|    {
  249|  1.61M|    }
_ZN7jsonnet8internal18ArrayComprehensionC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_bRKNS6_INS0_17ComprehensionSpecENS8_ISF_EEEESC_:
  262|   319k|        : AST(lr, AST_ARRAY_COMPREHENSION, open_fodder),
  263|   319k|          body(body),
  264|   319k|          commaFodder(comma_fodder),
  265|   319k|          trailingComma(trailing_comma),
  266|   319k|          specs(specs),
  267|   319k|          closeFodder(close_fodder)
  268|   319k|    {
  269|       |        assert(specs.size() > 0);
  ------------------
  |  Branch (269:9): [True: 319k, False: 0]
  ------------------
  270|   319k|    }
_ZN7jsonnet8internal6AssertC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_SE_SC_SE_:
  286|   359k|        : AST(lr, AST_ASSERT, open_fodder),
  287|   359k|          cond(cond),
  288|   359k|          colonFodder(colon_fodder),
  289|   359k|          message(message),
  290|   359k|          semicolonFodder(semicolon_fodder),
  291|   359k|          rest(rest)
  292|   359k|    {
  293|   359k|    }
_ZN7jsonnet8internal6BinaryC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_NS0_8BinaryOpESE_:
  367|  8.91M|        : AST(lr, AST_BINARY, open_fodder), left(left), opFodder(op_fodder), op(op), right(right)
  368|  8.91M|    {
  369|  8.91M|    }
_ZN7jsonnet8internal19BuiltinFunctionBodyC2ERKNS0_13LocationRangeERKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEERKNS5_6vectorIPKNS0_10IdentifierENS9_ISH_EEEE:
  382|   199k|        : AST(lr, AST_BUILTIN_FUNCTION_BODY, Fodder{}), name(name), params(params)
  383|   199k|    {
  384|   199k|    }
_ZN7jsonnet8internal15BuiltinFunctionC2ERKNS0_13LocationRangeEPKNS0_19BuiltinFunctionBodyE:
  395|   368k|        : AST(lr, AST_BUILTIN_FUNCTION, Fodder{}), body(body)
  396|   368k|    {
  397|   368k|    }
_ZN7jsonnet8internal11ConditionalC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_SE_SC_SE_:
  414|  4.17M|        : AST(lr, AST_CONDITIONAL, open_fodder),
  415|  4.17M|          cond(cond),
  416|  4.17M|          thenFodder(then_fodder),
  417|  4.17M|          branchTrue(branch_true),
  418|  4.17M|          elseFodder(else_fodder),
  419|  4.17M|          branchFalse(branch_false)
  420|  4.17M|    {
  421|  4.17M|    }
_ZN7jsonnet8internal6DollarC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEE:
  426|  43.8k|    Dollar(const LocationRange &lr, const Fodder &open_fodder) : AST(lr, AST_DOLLAR, open_fodder) {}
_ZN7jsonnet8internal5ErrorC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTE:
  433|  1.33M|        : AST(lr, AST_ERROR, open_fodder), expr(expr)
  434|  1.33M|    {
  435|  1.33M|    }
_ZN7jsonnet8internal8FunctionC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEESC_RKNS6_INS0_8ArgParamENS8_ISD_EEEEbSC_PNS0_3ASTE:
  448|  2.27M|        : AST(lr, AST_FUNCTION, open_fodder),
  449|  2.27M|          parenLeftFodder(paren_left_fodder),
  450|  2.27M|          params(params),
  451|  2.27M|          trailingComma(trailing_comma),
  452|  2.27M|          parenRightFodder(paren_right_fodder),
  453|  2.27M|          body(body)
  454|  2.27M|    {
  455|  2.27M|    }
_ZN7jsonnet8internal6ImportC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_13LiteralStringE:
  464|    293|        : AST(lr, AST_IMPORT, open_fodder), file(file)
  465|    293|    {
  466|    293|    }
_ZN7jsonnet8internal9ImportstrC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_13LiteralStringE:
  473|  1.64k|        : AST(lr, AST_IMPORTSTR, open_fodder), file(file)
  474|  1.64k|    {
  475|  1.64k|    }
_ZN7jsonnet8internal9ImportbinC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_13LiteralStringE:
  482|    649|        : AST(lr, AST_IMPORTBIN, open_fodder), file(file)
  483|    649|    {
  484|    649|    }
_ZN7jsonnet8internal5IndexC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_SC_PKNS0_10IdentifierE:
  505|  6.29M|        : AST(lr, AST_INDEX, open_fodder),
  506|  6.29M|          target(target),
  507|  6.29M|          dotFodder(dot_fodder),
  508|  6.29M|          isSlice(false),
  509|  6.29M|          index(nullptr),
  510|  6.29M|          end(nullptr),
  511|  6.29M|          step(nullptr),
  512|  6.29M|          idFodder(id_fodder),
  513|  6.29M|          id(id)
  514|  6.29M|    {
  515|  6.29M|    }
_ZN7jsonnet8internal5IndexC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_bSE_SC_SE_SC_SE_SC_:
  520|  5.03M|        : AST(lr, AST_INDEX, open_fodder),
  521|  5.03M|          target(target),
  522|  5.03M|          dotFodder(dot_fodder),
  523|  5.03M|          isSlice(is_slice),
  524|  5.03M|          index(index),
  525|  5.03M|          endColonFodder(end_colon_fodder),
  526|  5.03M|          end(end),
  527|  5.03M|          stepColonFodder(step_colon_fodder),
  528|  5.03M|          step(step),
  529|  5.03M|          idFodder(id_fodder),
  530|  5.03M|          id(nullptr)
  531|  5.03M|    {
  532|  5.03M|    }
_ZN7jsonnet8internal5Local4BindC2ERKNSt3__16vectorINS0_13FodderElementENS3_9allocatorIS5_EEEEPKNS0_10IdentifierESA_PNS0_3ASTEbSA_RKNS4_INS0_8ArgParamENS6_ISG_EEEEbSA_SA_:
  551|  3.68M|            : varFodder(var_fodder),
  552|  3.68M|              var(var),
  553|  3.68M|              opFodder(op_fodder),
  554|  3.68M|              body(body),
  555|  3.68M|              functionSugar(function_sugar),
  556|  3.68M|              parenLeftFodder(paren_left_fodder),
  557|  3.68M|              params(params),
  558|  3.68M|              trailingComma(trailing_comma),
  559|  3.68M|              parenRightFodder(paren_right_fodder),
  560|  3.68M|              closeFodder(close_fodder)
  561|  3.68M|        {
  562|  3.68M|        }
_ZN7jsonnet8internal5LocalC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERKNS6_INS1_4BindENS8_ISD_EEEEPNS0_3ASTE:
  568|  4.04M|        : AST(lr, AST_LOCAL, open_fodder), binds(binds), body(body)
  569|  4.04M|    {
  570|  4.04M|    }
_ZN7jsonnet8internal14LiteralBooleanC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEb:
  577|   794k|        : AST(lr, AST_LITERAL_BOOLEAN, open_fodder), value(value)
  578|   794k|    {
  579|   794k|    }
_ZN7jsonnet8internal11LiteralNullC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEE:
  585|   456k|        : AST(lr, AST_LITERAL_NULL, open_fodder)
  586|   456k|    {
  587|   456k|    }
_ZN7jsonnet8internal13LiteralNumberC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERKNS5_12basic_stringIcNS5_11char_traitsIcEENS8_IcEEEE:
  595|  6.21M|        : AST(lr, AST_LITERAL_NUMBER, open_fodder),
  596|  6.21M|          value(strtod(str.c_str(), nullptr)),
  597|  6.21M|          originalString(str)
  598|  6.21M|    {
  599|  6.21M|    }
_ZN7jsonnet8internal13LiteralStringC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERKNS5_12basic_stringIDiNS5_11char_traitsIDiEENS8_IDiEEEENS1_9TokenKindERKNSD_IcNSE_IcEENS8_IcEEEESP_:
  612|  16.7M|        : AST(lr, AST_LITERAL_STRING, open_fodder),
  613|  16.7M|          value(value),
  614|  16.7M|          tokenKind(token_kind),
  615|  16.7M|          blockIndent(block_indent),
  616|  16.7M|          blockTermIndent(block_term_indent)
  617|  16.7M|    {
  618|  16.7M|    }
_ZN7jsonnet8internal11ObjectFieldC2ENS1_4KindERKNSt3__16vectorINS0_13FodderElementENS3_9allocatorIS5_EEEESA_SA_SA_NS1_4HideEbbPNS0_3ASTEPKNS0_10IdentifierERKNS0_13LocationRangeERKNS4_INS0_8ArgParamENS6_ISK_EEEEbSA_SD_SD_SA_:
  682|  2.28M|        : kind(kind),
  683|  2.28M|          fodder1(fodder1),
  684|  2.28M|          fodder2(fodder2),
  685|  2.28M|          fodderL(fodder_l),
  686|  2.28M|          fodderR(fodder_r),
  687|  2.28M|          hide(hide),
  688|  2.28M|          superSugar(super_sugar),
  689|  2.28M|          methodSugar(method_sugar),
  690|  2.28M|          expr1(expr1),
  691|  2.28M|          id(id),
  692|  2.28M|          idLocation(id_lr),
  693|  2.28M|          params(params),
  694|  2.28M|          trailingComma(trailing_comma),
  695|  2.28M|          opFodder(op_fodder),
  696|  2.28M|          expr2(expr2),
  697|  2.28M|          expr3(expr3),
  698|  2.28M|          commaFodder(comma_fodder)
  699|  2.28M|    {
  700|       |        // Enforce what is written in comments above.
  701|  2.28M|        assert(kind != ASSERT || (hide == VISIBLE && !superSugar && !methodSugar));
  ------------------
  |  Branch (701:9): [True: 50.9k, False: 0]
  |  Branch (701:9): [True: 50.9k, False: 0]
  |  Branch (701:9): [True: 50.9k, False: 0]
  |  Branch (701:9): [True: 2.23M, False: 50.9k]
  |  Branch (701:9): [True: 2.28M, False: 0]
  ------------------
  702|  2.28M|        assert(kind != LOCAL || (hide == VISIBLE && !superSugar));
  ------------------
  |  Branch (702:9): [True: 92.8k, False: 0]
  |  Branch (702:9): [True: 92.8k, False: 0]
  |  Branch (702:9): [True: 2.19M, False: 92.8k]
  |  Branch (702:9): [True: 2.28M, False: 0]
  ------------------
  703|  2.28M|        assert(kind != FIELD_ID || (id != nullptr && expr1 == nullptr));
  ------------------
  |  Branch (703:9): [True: 1.98M, False: 0]
  |  Branch (703:9): [True: 1.98M, False: 0]
  |  Branch (703:9): [True: 304k, False: 1.98M]
  |  Branch (703:9): [True: 2.28M, False: 0]
  ------------------
  704|  2.28M|        assert(kind == FIELD_ID || kind == LOCAL || id == nullptr);
  ------------------
  |  Branch (704:9): [True: 1.98M, False: 304k]
  |  Branch (704:9): [True: 92.8k, False: 211k]
  |  Branch (704:9): [True: 211k, False: 0]
  |  Branch (704:9): [True: 2.28M, False: 0]
  ------------------
  705|  2.28M|        assert(methodSugar || (params.size() == 0 && !trailingComma));
  ------------------
  |  Branch (705:9): [True: 1.18M, False: 0]
  |  Branch (705:9): [True: 1.18M, False: 0]
  |  Branch (705:9): [True: 1.10M, False: 1.18M]
  |  Branch (705:9): [True: 2.28M, False: 0]
  ------------------
  706|  2.28M|        assert(kind == ASSERT || expr3 == nullptr);
  ------------------
  |  Branch (706:9): [True: 50.9k, False: 2.23M]
  |  Branch (706:9): [True: 2.23M, False: 0]
  |  Branch (706:9): [True: 2.28M, False: 0]
  ------------------
  707|  2.28M|    }
_ZN7jsonnet8internal11ObjectField5LocalERKNSt3__16vectorINS0_13FodderElementENS2_9allocatorIS4_EEEES9_S9_S9_bPKNS0_10IdentifierERKNS3_INS0_8ArgParamENS5_ISD_EEEEbS9_PNS0_3ASTES9_:
  713|  62.5k|    {
  714|  62.5k|        return ObjectField(LOCAL,
  715|  62.5k|                           fodder1,
  716|  62.5k|                           fodder2,
  717|  62.5k|                           fodder_l,
  718|  62.5k|                           fodder_r,
  719|  62.5k|                           VISIBLE,
  720|  62.5k|                           false,
  721|  62.5k|                           method_sugar,
  722|  62.5k|                           nullptr,
  723|  62.5k|                           id,
  724|  62.5k|                           LocationRange(),
  725|  62.5k|                           params,
  726|  62.5k|                           trailing_comma,
  727|  62.5k|                           op_fodder,
  728|  62.5k|                           body,
  729|  62.5k|                           nullptr,
  730|  62.5k|                           comma_fodder);
  731|  62.5k|    }
_ZN7jsonnet8internal11ObjectField5LocalERKNSt3__16vectorINS0_13FodderElementENS2_9allocatorIS4_EEEES9_PKNS0_10IdentifierES9_PNS0_3ASTES9_:
  734|  30.3k|    {
  735|  30.3k|        return ObjectField(LOCAL,
  736|  30.3k|                           fodder1,
  737|  30.3k|                           fodder2,
  738|  30.3k|                           Fodder{},
  739|  30.3k|                           Fodder{},
  740|  30.3k|                           VISIBLE,
  741|  30.3k|                           false,
  742|  30.3k|                           false,
  743|  30.3k|                           nullptr,
  744|  30.3k|                           id,
  745|  30.3k|                           LocationRange(),
  746|  30.3k|                           ArgParams{},
  747|  30.3k|                           false,
  748|  30.3k|                           op_fodder,
  749|  30.3k|                           body,
  750|  30.3k|                           nullptr,
  751|  30.3k|                           comma_fodder);
  752|  30.3k|    }
_ZN7jsonnet8internal11ObjectField6AssertERKNSt3__16vectorINS0_13FodderElementENS2_9allocatorIS4_EEEEPNS0_3ASTES9_SB_S9_:
  779|  50.9k|    {
  780|  50.9k|        return ObjectField(ASSERT,
  781|  50.9k|                           fodder1,
  782|  50.9k|                           Fodder{},
  783|  50.9k|                           Fodder{},
  784|  50.9k|                           Fodder{},
  785|  50.9k|                           VISIBLE,
  786|  50.9k|                           false,
  787|  50.9k|                           false,
  788|  50.9k|                           nullptr,
  789|  50.9k|                           nullptr,
  790|  50.9k|                           LocationRange(),
  791|  50.9k|                           ArgParams{},
  792|  50.9k|                           false,
  793|  50.9k|                           op_fodder,
  794|  50.9k|                           body,
  795|  50.9k|                           msg,
  796|  50.9k|                           comma_fodder);
  797|  50.9k|    }
_ZN7jsonnet8internal6ObjectC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERKNS6_INS0_11ObjectFieldENS8_ISD_EEEEbSC_:
  812|   497k|        : AST(lr, AST_OBJECT, open_fodder),
  813|   497k|          fields(fields),
  814|   497k|          trailingComma(trailing_comma),
  815|   497k|          closeFodder(close_fodder)
  816|   497k|    {
  817|   497k|        assert(fields.size() > 0 || !trailing_comma);
  ------------------
  |  Branch (817:9): [True: 452k, False: 44.8k]
  |  Branch (817:9): [True: 44.8k, False: 0]
  |  Branch (817:9): [True: 497k, False: 0]
  ------------------
  818|   497k|        if (fields.size() > 0)
  ------------------
  |  Branch (818:13): [True: 452k, False: 44.8k]
  ------------------
  819|       |            assert(trailing_comma || fields[fields.size() - 1].commaFodder.size() == 0);
  ------------------
  |  Branch (819:13): [True: 122k, False: 329k]
  |  Branch (819:13): [True: 329k, False: 0]
  |  Branch (819:13): [True: 452k, False: 0]
  ------------------
  820|   497k|    }
_ZN7jsonnet8internal15DesugaredObject5FieldC2ENS0_11ObjectField4HideEPNS0_3ASTES6_:
  833|  2.41M|            : hide(hide), name(name), body(body)
  834|  2.41M|        {
  835|  2.41M|        }
_ZN7jsonnet8internal15DesugaredObjectC2ERKNS0_13LocationRangeERKNSt3__14listIPNS0_3ASTENS5_9allocatorIS8_EEEERKNS5_6vectorINS1_5FieldENS9_ISF_EEEE:
  841|   490k|        : AST(lr, AST_DESUGARED_OBJECT, Fodder{}), asserts(asserts), fields(fields)
  842|   490k|    {
  843|   490k|    }
_ZN7jsonnet8internal19ObjectComprehensionC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERKNS6_INS0_11ObjectFieldENS8_ISD_EEEEbRKNS6_INS0_17ComprehensionSpecENS8_ISI_EEEESC_:
  856|  39.1k|        : AST(lr, AST_OBJECT_COMPREHENSION, open_fodder),
  857|  39.1k|          fields(fields),
  858|  39.1k|          trailingComma(trailing_comma),
  859|  39.1k|          specs(specs),
  860|  39.1k|          closeFodder(close_fodder)
  861|  39.1k|    {
  862|  39.1k|    }
_ZN7jsonnet8internal25ObjectComprehensionSimpleC2ERKNS0_13LocationRangeEPNS0_3ASTES6_PKNS0_10IdentifierES6_:
  873|  38.9k|        : AST(lr, AST_OBJECT_COMPREHENSION_SIMPLE, Fodder{}),
  874|  38.9k|          field(field),
  875|  38.9k|          value(value),
  876|  38.9k|          id(id),
  877|  38.9k|          array(array)
  878|  38.9k|    {
  879|  38.9k|    }
_ZN7jsonnet8internal6ParensC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_:
  888|   438k|        : AST(lr, AST_PARENS, open_fodder), expr(expr), closeFodder(close_fodder)
  889|   438k|    {
  890|   438k|    }
_ZN7jsonnet8internal4SelfC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEE:
  895|  92.4k|    Self(const LocationRange &lr, const Fodder &open_fodder) : AST(lr, AST_SELF, open_fodder) {}
_ZN7jsonnet8internal10SuperIndexC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEESC_PNS0_3ASTESC_PKNS0_10IdentifierE:
  910|  18.3k|        : AST(lr, AST_SUPER_INDEX, open_fodder),
  911|  18.3k|          dotFodder(dot_fodder),
  912|  18.3k|          index(index),
  913|  18.3k|          idFodder(id_fodder),
  914|  18.3k|          id(id)
  915|  18.3k|    {
  916|  18.3k|    }
_ZN7jsonnet8internal7InSuperC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPNS0_3ASTESC_SC_:
  927|  17.3k|        : AST(lr, AST_IN_SUPER, open_fodder),
  928|  17.3k|          element(element),
  929|  17.3k|          inFodder(in_fodder),
  930|  17.3k|          superFodder(super_fodder)
  931|  17.3k|    {
  932|  17.3k|    }
_ZN7jsonnet8internal5UnaryC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEENS0_7UnaryOpEPNS0_3ASTE:
  956|   764k|        : AST(lr, AST_UNARY, open_fodder), op(op), expr(expr)
  957|   764k|    {
  958|   764k|    }
_ZN7jsonnet8internal3VarC2ERKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPKNS0_10IdentifierE:
  965|  34.9M|        : AST(lr, AST_VAR, open_fodder), id(id)
  966|  34.9M|    {
  967|  34.9M|    }
_ZN7jsonnet8internal9Allocator14makeIdentifierERKNSt3__112basic_stringIDiNS2_11char_traitsIDiEENS2_9allocatorIDiEEEE:
  998|  61.3M|    {
  999|  61.3M|        auto it = internedIdentifiers.find(name);
 1000|  61.3M|        if (it != internedIdentifiers.end()) {
  ------------------
  |  Branch (1000:13): [True: 58.8M, False: 2.52M]
  ------------------
 1001|  58.8M|            return it->second;
 1002|  58.8M|        }
 1003|  2.52M|        auto r = new Identifier(name);
 1004|  2.52M|        internedIdentifiers[name] = r;
 1005|  2.52M|        return r;
 1006|  61.3M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_120build_precedence_mapEv:
 1047|      2|{
 1048|      2|    std::map<BinaryOp, int> r;
 1049|       |
 1050|      2|    r[BOP_MULT] = 5;
 1051|      2|    r[BOP_DIV] = 5;
 1052|      2|    r[BOP_PERCENT] = 5;
 1053|       |
 1054|      2|    r[BOP_PLUS] = 6;
 1055|      2|    r[BOP_MINUS] = 6;
 1056|       |
 1057|      2|    r[BOP_SHIFT_L] = 7;
 1058|      2|    r[BOP_SHIFT_R] = 7;
 1059|       |
 1060|      2|    r[BOP_GREATER] = 8;
 1061|      2|    r[BOP_GREATER_EQ] = 8;
 1062|      2|    r[BOP_LESS] = 8;
 1063|      2|    r[BOP_LESS_EQ] = 8;
 1064|      2|    r[BOP_IN] = 8;
 1065|       |
 1066|      2|    r[BOP_MANIFEST_EQUAL] = 9;
 1067|      2|    r[BOP_MANIFEST_UNEQUAL] = 9;
 1068|       |
 1069|      2|    r[BOP_BITWISE_AND] = 10;
 1070|       |
 1071|      2|    r[BOP_BITWISE_XOR] = 11;
 1072|       |
 1073|      2|    r[BOP_BITWISE_OR] = 12;
 1074|       |
 1075|      2|    r[BOP_AND] = 13;
 1076|       |
 1077|      2|    r[BOP_OR] = 14;
 1078|       |
 1079|      2|    return r;
 1080|      2|}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_115build_unary_mapEv:
 1083|      2|{
 1084|      2|    std::map<std::string, UnaryOp> r;
 1085|      2|    r["!"] = UOP_NOT;
 1086|      2|    r["~"] = UOP_BITWISE_NOT;
 1087|      2|    r["+"] = UOP_PLUS;
 1088|      2|    r["-"] = UOP_MINUS;
 1089|      2|    return r;
 1090|      2|}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116build_binary_mapEv:
 1093|      2|{
 1094|      2|    std::map<std::string, BinaryOp> r;
 1095|       |
 1096|      2|    r["*"] = BOP_MULT;
 1097|      2|    r["/"] = BOP_DIV;
 1098|      2|    r["%"] = BOP_PERCENT;
 1099|       |
 1100|      2|    r["+"] = BOP_PLUS;
 1101|      2|    r["-"] = BOP_MINUS;
 1102|       |
 1103|      2|    r["<<"] = BOP_SHIFT_L;
 1104|      2|    r[">>"] = BOP_SHIFT_R;
 1105|       |
 1106|      2|    r[">"] = BOP_GREATER;
 1107|      2|    r[">="] = BOP_GREATER_EQ;
 1108|      2|    r["<"] = BOP_LESS;
 1109|      2|    r["<="] = BOP_LESS_EQ;
 1110|      2|    r["in"] = BOP_IN;
 1111|       |
 1112|      2|    r["=="] = BOP_MANIFEST_EQUAL;
 1113|      2|    r["!="] = BOP_MANIFEST_UNEQUAL;
 1114|       |
 1115|      2|    r["&"] = BOP_BITWISE_AND;
 1116|      2|    r["^"] = BOP_BITWISE_XOR;
 1117|      2|    r["|"] = BOP_BITWISE_OR;
 1118|       |
 1119|      2|    r["&&"] = BOP_AND;
 1120|      2|    r["||"] = BOP_OR;
 1121|      2|    return r;
 1122|      2|}
_ZN7jsonnet8internal9Allocator4makeINS0_6AssertEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_SF_SG_SF_EEEPT_DpOT0_:
  980|   359k|    {
  981|   359k|        auto r = new T(std::forward<Args>(args)...);
  982|   359k|        allocated.push_back(r);
  983|   359k|        return r;
  984|   359k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ErrorEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  980|   573k|    {
  981|   573k|        auto r = new T(std::forward<Args>(args)...);
  982|   573k|        allocated.push_back(r);
  983|   573k|        return r;
  984|   573k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_SF_SG_SF_EEEPT_DpOT0_:
  980|  2.82M|    {
  981|  2.82M|        auto r = new T(std::forward<Args>(args)...);
  982|  2.82M|        allocated.push_back(r);
  983|  2.82M|        return r;
  984|  2.82M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_SF_SA_DnEEEPT_DpOT0_:
  980|  35.1k|    {
  981|  35.1k|        auto r = new T(std::forward<Args>(args)...);
  982|  35.1k|        allocated.push_back(r);
  983|  35.1k|        return r;
  984|  35.1k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_8FunctionEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERSA_RNS6_INS0_8ArgParamENS8_ISE_EEEERbSD_RPNS0_3ASTEEEEPT_DpOT0_:
  980|   176k|    {
  981|   176k|        auto r = new T(std::forward<Args>(args)...);
  982|   176k|        allocated.push_back(r);
  983|   176k|        return r;
  984|   176k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6ImportEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_13LiteralStringEEEEPT_DpOT0_:
  980|    293|    {
  981|    293|        auto r = new T(std::forward<Args>(args)...);
  982|    293|        allocated.push_back(r);
  983|    293|        return r;
  984|    293|    }
_ZN7jsonnet8internal9Allocator4makeINS0_9ImportstrEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_13LiteralStringEEEEPT_DpOT0_:
  980|  1.64k|    {
  981|  1.64k|        auto r = new T(std::forward<Args>(args)...);
  982|  1.64k|        allocated.push_back(r);
  983|  1.64k|        return r;
  984|  1.64k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_9ImportbinEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_13LiteralStringEEEEPT_DpOT0_:
  980|    649|    {
  981|    649|        auto r = new T(std::forward<Args>(args)...);
  982|    649|        allocated.push_back(r);
  983|    649|        return r;
  984|    649|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5LocalEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERNS6_INS3_4BindENS8_ISD_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  980|  2.12M|    {
  981|  2.12M|        auto r = new T(std::forward<Args>(args)...);
  982|  2.12M|        allocated.push_back(r);
  983|  2.12M|        return r;
  984|  2.12M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5UnaryEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERNS0_7UnaryOpERPNS0_3ASTEEEEPT_DpOT0_:
  980|   551k|    {
  981|   551k|        auto r = new T(std::forward<Args>(args)...);
  982|   551k|        allocated.push_back(r);
  983|   551k|        return r;
  984|   551k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6ObjectEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERNS6_INS0_11ObjectFieldENS8_ISD_EEEERbRSA_EEEPT_DpOT0_:
  980|   497k|    {
  981|   497k|        auto r = new T(std::forward<Args>(args)...);
  982|   497k|        allocated.push_back(r);
  983|   497k|        return r;
  984|   497k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_19ObjectComprehensionEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERNS6_INS0_11ObjectFieldENS8_ISD_EEEERbRNS6_INS0_17ComprehensionSpecENS8_ISI_EEEERSA_EEEPT_DpOT0_:
  980|  39.1k|    {
  981|  39.1k|        auto r = new T(std::forward<Args>(args)...);
  982|  39.1k|        allocated.push_back(r);
  983|  39.1k|        return r;
  984|  39.1k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralStringEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS6_12basic_stringIDiNS6_11char_traitsIDiEENS9_IDiEEEENS3_9TokenKindERA1_KcSL_EEEPT_DpOT0_:
  980|   118k|    {
  981|   118k|        auto r = new T(std::forward<Args>(args)...);
  982|   118k|        allocated.push_back(r);
  983|   118k|        return r;
  984|   118k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralStringEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS6_12basic_stringIDiNS6_11char_traitsIDiEENS9_IDiEEEENS3_9TokenKindERNSD_IcNSE_IcEENS9_IcEEEESM_EEEPT_DpOT0_:
  980|  2.47k|    {
  981|  2.47k|        auto r = new T(std::forward<Args>(args)...);
  982|  2.47k|        allocated.push_back(r);
  983|  2.47k|        return r;
  984|  2.47k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ArrayEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEENS6_INS3_7ElementENS8_ISC_EEEEbSB_EEEPT_DpOT0_:
  980|   199k|    {
  981|   199k|        auto r = new T(std::forward<Args>(args)...);
  982|   199k|        allocated.push_back(r);
  983|   199k|        return r;
  984|   199k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_18ArrayComprehensionEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTESB_RbRNS6_INS0_17ComprehensionSpecENS8_ISG_EEEESB_EEEPT_DpOT0_:
  980|   280k|    {
  981|   280k|        auto r = new T(std::forward<Args>(args)...);
  982|   280k|        allocated.push_back(r);
  983|   280k|        return r;
  984|   280k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ArrayEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERNS6_INS3_7ElementENS8_ISC_EEEERbSB_EEEPT_DpOT0_:
  980|   742k|    {
  981|   742k|        auto r = new T(std::forward<Args>(args)...);
  982|   742k|        allocated.push_back(r);
  983|   742k|        return r;
  984|   742k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6ParensEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTESB_EEEPT_DpOT0_:
  980|   438k|    {
  981|   438k|        auto r = new T(std::forward<Args>(args)...);
  982|   438k|        allocated.push_back(r);
  983|   438k|        return r;
  984|   438k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralNumberEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERNS5_12basic_stringIcNS5_11char_traitsIcEENS8_IcEEEEEEEPT_DpOT0_:
  980|  5.49M|    {
  981|  5.49M|        auto r = new T(std::forward<Args>(args)...);
  982|  5.49M|        allocated.push_back(r);
  983|  5.49M|        return r;
  984|  5.49M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralStringEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEENS5_12basic_stringIDiNS5_11char_traitsIDiEENS8_IDiEEEENS3_9TokenKindERA1_KcSK_EEEPT_DpOT0_:
  980|  4.18M|    {
  981|  4.18M|        auto r = new T(std::forward<Args>(args)...);
  982|  4.18M|        allocated.push_back(r);
  983|  4.18M|        return r;
  984|  4.18M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralStringEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEENS5_12basic_stringIDiNS5_11char_traitsIDiEENS8_IDiEEEENS3_9TokenKindERNSC_IcNSD_IcEENS8_IcEEEESL_EEEPT_DpOT0_:
  980|  1.61k|    {
  981|  1.61k|        auto r = new T(std::forward<Args>(args)...);
  982|  1.61k|        allocated.push_back(r);
  983|  1.61k|        return r;
  984|  1.61k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_14LiteralBooleanEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEbEEEPT_DpOT0_:
  980|   745k|    {
  981|   745k|        auto r = new T(std::forward<Args>(args)...);
  982|   745k|        allocated.push_back(r);
  983|   745k|        return r;
  984|   745k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11LiteralNullEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEEEEPT_DpOT0_:
  980|   160k|    {
  981|   160k|        auto r = new T(std::forward<Args>(args)...);
  982|   160k|        allocated.push_back(r);
  983|   160k|        return r;
  984|   160k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6DollarEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEEEEPT_DpOT0_:
  980|  43.8k|    {
  981|  43.8k|        auto r = new T(std::forward<Args>(args)...);
  982|  43.8k|        allocated.push_back(r);
  983|  43.8k|        return r;
  984|  43.8k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_3VarEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEPKNS0_10IdentifierEEEEPT_DpOT0_:
  980|  27.3M|    {
  981|  27.3M|        auto r = new T(std::forward<Args>(args)...);
  982|  27.3M|        allocated.push_back(r);
  983|  27.3M|        return r;
  984|  27.3M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_4SelfEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEEEEEPT_DpOT0_:
  980|  61.6k|    {
  981|  61.6k|        auto r = new T(std::forward<Args>(args)...);
  982|  61.6k|        allocated.push_back(r);
  983|  61.6k|        return r;
  984|  61.6k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_10SuperIndexEJNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEESB_RPNS0_3ASTESB_RPKNS0_10IdentifierEEEEPT_DpOT0_:
  980|  1.53k|    {
  981|  1.53k|        auto r = new T(std::forward<Args>(args)...);
  982|  1.53k|        allocated.push_back(r);
  983|  1.53k|        return r;
  984|  1.53k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5IndexEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_RbSF_SG_SF_SG_SF_SG_EEEPT_DpOT0_:
  980|  1.52M|    {
  981|  1.52M|        auto r = new T(std::forward<Args>(args)...);
  982|  1.52M|        allocated.push_back(r);
  983|  1.52M|        return r;
  984|  1.52M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5IndexEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_SG_RPKNS0_10IdentifierEEEEPT_DpOT0_:
  980|  6.29M|    {
  981|  6.29M|        auto r = new T(std::forward<Args>(args)...);
  982|  6.29M|        allocated.push_back(r);
  983|  6.29M|        return r;
  984|  6.29M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ApplyEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_RNS6_INS0_8ArgParamENS8_ISH_EEEERbSG_SG_SL_EEEPT_DpOT0_:
  980|  7.10M|    {
  981|  7.10M|        auto r = new T(std::forward<Args>(args)...);
  982|  7.10M|        allocated.push_back(r);
  983|  7.10M|        return r;
  984|  7.10M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_10ApplyBraceEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTESF_EEEPT_DpOT0_:
  980|   112k|    {
  981|   112k|        auto r = new T(std::forward<Args>(args)...);
  982|   112k|        allocated.push_back(r);
  983|   112k|        return r;
  984|   112k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_7InSuperEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_SG_EEEPT_DpOT0_:
  980|    496|    {
  981|    496|        auto r = new T(std::forward<Args>(args)...);
  982|    496|        allocated.push_back(r);
  983|    496|        return r;
  984|    496|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6BinaryEJNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPNS0_3ASTERSA_RNS0_8BinaryOpESF_EEEPT_DpOT0_:
  980|  7.58M|    {
  981|  7.58M|        auto r = new T(std::forward<Args>(args)...);
  982|  7.58M|        allocated.push_back(r);
  983|  7.58M|        return r;
  984|  7.58M|    }
pass.cpp:_ZN7jsonnet8internal12_GLOBAL__N_120build_precedence_mapEv:
 1047|      2|{
 1048|      2|    std::map<BinaryOp, int> r;
 1049|       |
 1050|      2|    r[BOP_MULT] = 5;
 1051|      2|    r[BOP_DIV] = 5;
 1052|      2|    r[BOP_PERCENT] = 5;
 1053|       |
 1054|      2|    r[BOP_PLUS] = 6;
 1055|      2|    r[BOP_MINUS] = 6;
 1056|       |
 1057|      2|    r[BOP_SHIFT_L] = 7;
 1058|      2|    r[BOP_SHIFT_R] = 7;
 1059|       |
 1060|      2|    r[BOP_GREATER] = 8;
 1061|      2|    r[BOP_GREATER_EQ] = 8;
 1062|      2|    r[BOP_LESS] = 8;
 1063|      2|    r[BOP_LESS_EQ] = 8;
 1064|      2|    r[BOP_IN] = 8;
 1065|       |
 1066|      2|    r[BOP_MANIFEST_EQUAL] = 9;
 1067|      2|    r[BOP_MANIFEST_UNEQUAL] = 9;
 1068|       |
 1069|      2|    r[BOP_BITWISE_AND] = 10;
 1070|       |
 1071|      2|    r[BOP_BITWISE_XOR] = 11;
 1072|       |
 1073|      2|    r[BOP_BITWISE_OR] = 12;
 1074|       |
 1075|      2|    r[BOP_AND] = 13;
 1076|       |
 1077|      2|    r[BOP_OR] = 14;
 1078|       |
 1079|      2|    return r;
 1080|      2|}
pass.cpp:_ZN7jsonnet8internal12_GLOBAL__N_115build_unary_mapEv:
 1083|      2|{
 1084|      2|    std::map<std::string, UnaryOp> r;
 1085|      2|    r["!"] = UOP_NOT;
 1086|      2|    r["~"] = UOP_BITWISE_NOT;
 1087|      2|    r["+"] = UOP_PLUS;
 1088|      2|    r["-"] = UOP_MINUS;
 1089|      2|    return r;
 1090|      2|}
pass.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116build_binary_mapEv:
 1093|      2|{
 1094|      2|    std::map<std::string, BinaryOp> r;
 1095|       |
 1096|      2|    r["*"] = BOP_MULT;
 1097|      2|    r["/"] = BOP_DIV;
 1098|      2|    r["%"] = BOP_PERCENT;
 1099|       |
 1100|      2|    r["+"] = BOP_PLUS;
 1101|      2|    r["-"] = BOP_MINUS;
 1102|       |
 1103|      2|    r["<<"] = BOP_SHIFT_L;
 1104|      2|    r[">>"] = BOP_SHIFT_R;
 1105|       |
 1106|      2|    r[">"] = BOP_GREATER;
 1107|      2|    r[">="] = BOP_GREATER_EQ;
 1108|      2|    r["<"] = BOP_LESS;
 1109|      2|    r["<="] = BOP_LESS_EQ;
 1110|      2|    r["in"] = BOP_IN;
 1111|       |
 1112|      2|    r["=="] = BOP_MANIFEST_EQUAL;
 1113|      2|    r["!="] = BOP_MANIFEST_UNEQUAL;
 1114|       |
 1115|      2|    r["&"] = BOP_BITWISE_AND;
 1116|      2|    r["^"] = BOP_BITWISE_XOR;
 1117|      2|    r["|"] = BOP_BITWISE_OR;
 1118|       |
 1119|      2|    r["&&"] = BOP_AND;
 1120|      2|    r["||"] = BOP_OR;
 1121|      2|    return r;
 1122|      2|}
_ZN7jsonnet8internal9Allocator5cloneINS0_5ApplyEEEPT_S5_:
  988|   294k|    {
  989|   294k|        auto r = new T(*ast);
  990|   294k|        allocated.push_back(r);
  991|   294k|        return r;
  992|   294k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_5ArrayEEEPT_S5_:
  988|   181k|    {
  989|   181k|        auto r = new T(*ast);
  990|   181k|        allocated.push_back(r);
  991|   181k|        return r;
  992|   181k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_6BinaryEEEPT_S5_:
  988|   981k|    {
  989|   981k|        auto r = new T(*ast);
  990|   981k|        allocated.push_back(r);
  991|   981k|        return r;
  992|   981k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_11ConditionalEEEPT_S5_:
  988|   552k|    {
  989|   552k|        auto r = new T(*ast);
  990|   552k|        allocated.push_back(r);
  991|   552k|        return r;
  992|   552k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_15DesugaredObjectEEEPT_S5_:
  988|  1.08M|    {
  989|  1.08M|        auto r = new T(*ast);
  990|  1.08M|        allocated.push_back(r);
  991|  1.08M|        return r;
  992|  1.08M|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_5ErrorEEEPT_S5_:
  988|  85.0k|    {
  989|  85.0k|        auto r = new T(*ast);
  990|  85.0k|        allocated.push_back(r);
  991|  85.0k|        return r;
  992|  85.0k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_8FunctionEEEPT_S5_:
  988|   161k|    {
  989|   161k|        auto r = new T(*ast);
  990|   161k|        allocated.push_back(r);
  991|   161k|        return r;
  992|   161k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_6ImportEEEPT_S5_:
  988|  1.66k|    {
  989|  1.66k|        auto r = new T(*ast);
  990|  1.66k|        allocated.push_back(r);
  991|  1.66k|        return r;
  992|  1.66k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_9ImportstrEEEPT_S5_:
  988|  7.67k|    {
  989|  7.67k|        auto r = new T(*ast);
  990|  7.67k|        allocated.push_back(r);
  991|  7.67k|        return r;
  992|  7.67k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_9ImportbinEEEPT_S5_:
  988|  1.15k|    {
  989|  1.15k|        auto r = new T(*ast);
  990|  1.15k|        allocated.push_back(r);
  991|  1.15k|        return r;
  992|  1.15k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_5IndexEEEPT_S5_:
  988|   338k|    {
  989|   338k|        auto r = new T(*ast);
  990|   338k|        allocated.push_back(r);
  991|   338k|        return r;
  992|   338k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_7InSuperEEEPT_S5_:
  988|   244k|    {
  989|   244k|        auto r = new T(*ast);
  990|   244k|        allocated.push_back(r);
  991|   244k|        return r;
  992|   244k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_14LiteralBooleanEEEPT_S5_:
  988|  14.0k|    {
  989|  14.0k|        auto r = new T(*ast);
  990|  14.0k|        allocated.push_back(r);
  991|  14.0k|        return r;
  992|  14.0k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_11LiteralNullEEEPT_S5_:
  988|  9.76k|    {
  989|  9.76k|        auto r = new T(*ast);
  990|  9.76k|        allocated.push_back(r);
  991|  9.76k|        return r;
  992|  9.76k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_13LiteralNumberEEEPT_S5_:
  988|   575k|    {
  989|   575k|        auto r = new T(*ast);
  990|   575k|        allocated.push_back(r);
  991|   575k|        return r;
  992|   575k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_13LiteralStringEEEPT_S5_:
  988|  1.77M|    {
  989|  1.77M|        auto r = new T(*ast);
  990|  1.77M|        allocated.push_back(r);
  991|  1.77M|        return r;
  992|  1.77M|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_5LocalEEEPT_S5_:
  988|   306k|    {
  989|   306k|        auto r = new T(*ast);
  990|   306k|        allocated.push_back(r);
  991|   306k|        return r;
  992|   306k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_25ObjectComprehensionSimpleEEEPT_S5_:
  988|  31.4k|    {
  989|  31.4k|        auto r = new T(*ast);
  990|  31.4k|        allocated.push_back(r);
  991|  31.4k|        return r;
  992|  31.4k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_4SelfEEEPT_S5_:
  988|  9.78k|    {
  989|  9.78k|        auto r = new T(*ast);
  990|  9.78k|        allocated.push_back(r);
  991|  9.78k|        return r;
  992|  9.78k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_10SuperIndexEEEPT_S5_:
  988|   245k|    {
  989|   245k|        auto r = new T(*ast);
  990|   245k|        allocated.push_back(r);
  991|   245k|        return r;
  992|   245k|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_5UnaryEEEPT_S5_:
  988|  1.31M|    {
  989|  1.31M|        auto r = new T(*ast);
  990|  1.31M|        allocated.push_back(r);
  991|  1.31M|        return r;
  992|  1.31M|    }
_ZN7jsonnet8internal9Allocator5cloneINS0_3VarEEEPT_S5_:
  988|  2.83M|    {
  989|  2.83M|        auto r = new T(*ast);
  990|  2.83M|        allocated.push_back(r);
  991|  2.83M|        return r;
  992|  2.83M|    }
static_analysis.cpp:_ZN7jsonnet8internal12_GLOBAL__N_120build_precedence_mapEv:
 1047|      2|{
 1048|      2|    std::map<BinaryOp, int> r;
 1049|       |
 1050|      2|    r[BOP_MULT] = 5;
 1051|      2|    r[BOP_DIV] = 5;
 1052|      2|    r[BOP_PERCENT] = 5;
 1053|       |
 1054|      2|    r[BOP_PLUS] = 6;
 1055|      2|    r[BOP_MINUS] = 6;
 1056|       |
 1057|      2|    r[BOP_SHIFT_L] = 7;
 1058|      2|    r[BOP_SHIFT_R] = 7;
 1059|       |
 1060|      2|    r[BOP_GREATER] = 8;
 1061|      2|    r[BOP_GREATER_EQ] = 8;
 1062|      2|    r[BOP_LESS] = 8;
 1063|      2|    r[BOP_LESS_EQ] = 8;
 1064|      2|    r[BOP_IN] = 8;
 1065|       |
 1066|      2|    r[BOP_MANIFEST_EQUAL] = 9;
 1067|      2|    r[BOP_MANIFEST_UNEQUAL] = 9;
 1068|       |
 1069|      2|    r[BOP_BITWISE_AND] = 10;
 1070|       |
 1071|      2|    r[BOP_BITWISE_XOR] = 11;
 1072|       |
 1073|      2|    r[BOP_BITWISE_OR] = 12;
 1074|       |
 1075|      2|    r[BOP_AND] = 13;
 1076|       |
 1077|      2|    r[BOP_OR] = 14;
 1078|       |
 1079|      2|    return r;
 1080|      2|}
static_analysis.cpp:_ZN7jsonnet8internal12_GLOBAL__N_115build_unary_mapEv:
 1083|      2|{
 1084|      2|    std::map<std::string, UnaryOp> r;
 1085|      2|    r["!"] = UOP_NOT;
 1086|      2|    r["~"] = UOP_BITWISE_NOT;
 1087|      2|    r["+"] = UOP_PLUS;
 1088|      2|    r["-"] = UOP_MINUS;
 1089|      2|    return r;
 1090|      2|}
static_analysis.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116build_binary_mapEv:
 1093|      2|{
 1094|      2|    std::map<std::string, BinaryOp> r;
 1095|       |
 1096|      2|    r["*"] = BOP_MULT;
 1097|      2|    r["/"] = BOP_DIV;
 1098|      2|    r["%"] = BOP_PERCENT;
 1099|       |
 1100|      2|    r["+"] = BOP_PLUS;
 1101|      2|    r["-"] = BOP_MINUS;
 1102|       |
 1103|      2|    r["<<"] = BOP_SHIFT_L;
 1104|      2|    r[">>"] = BOP_SHIFT_R;
 1105|       |
 1106|      2|    r[">"] = BOP_GREATER;
 1107|      2|    r[">="] = BOP_GREATER_EQ;
 1108|      2|    r["<"] = BOP_LESS;
 1109|      2|    r["<="] = BOP_LESS_EQ;
 1110|      2|    r["in"] = BOP_IN;
 1111|       |
 1112|      2|    r["=="] = BOP_MANIFEST_EQUAL;
 1113|      2|    r["!="] = BOP_MANIFEST_UNEQUAL;
 1114|       |
 1115|      2|    r["&"] = BOP_BITWISE_AND;
 1116|      2|    r["^"] = BOP_BITWISE_XOR;
 1117|      2|    r["|"] = BOP_BITWISE_OR;
 1118|       |
 1119|      2|    r["&&"] = BOP_AND;
 1120|      2|    r["||"] = BOP_OR;
 1121|      2|    return r;
 1122|      2|}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_120build_precedence_mapEv:
 1047|      2|{
 1048|      2|    std::map<BinaryOp, int> r;
 1049|       |
 1050|      2|    r[BOP_MULT] = 5;
 1051|      2|    r[BOP_DIV] = 5;
 1052|      2|    r[BOP_PERCENT] = 5;
 1053|       |
 1054|      2|    r[BOP_PLUS] = 6;
 1055|      2|    r[BOP_MINUS] = 6;
 1056|       |
 1057|      2|    r[BOP_SHIFT_L] = 7;
 1058|      2|    r[BOP_SHIFT_R] = 7;
 1059|       |
 1060|      2|    r[BOP_GREATER] = 8;
 1061|      2|    r[BOP_GREATER_EQ] = 8;
 1062|      2|    r[BOP_LESS] = 8;
 1063|      2|    r[BOP_LESS_EQ] = 8;
 1064|      2|    r[BOP_IN] = 8;
 1065|       |
 1066|      2|    r[BOP_MANIFEST_EQUAL] = 9;
 1067|      2|    r[BOP_MANIFEST_UNEQUAL] = 9;
 1068|       |
 1069|      2|    r[BOP_BITWISE_AND] = 10;
 1070|       |
 1071|      2|    r[BOP_BITWISE_XOR] = 11;
 1072|       |
 1073|      2|    r[BOP_BITWISE_OR] = 12;
 1074|       |
 1075|      2|    r[BOP_AND] = 13;
 1076|       |
 1077|      2|    r[BOP_OR] = 14;
 1078|       |
 1079|      2|    return r;
 1080|      2|}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_115build_unary_mapEv:
 1083|      2|{
 1084|      2|    std::map<std::string, UnaryOp> r;
 1085|      2|    r["!"] = UOP_NOT;
 1086|      2|    r["~"] = UOP_BITWISE_NOT;
 1087|      2|    r["+"] = UOP_PLUS;
 1088|      2|    r["-"] = UOP_MINUS;
 1089|      2|    return r;
 1090|      2|}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116build_binary_mapEv:
 1093|      2|{
 1094|      2|    std::map<std::string, BinaryOp> r;
 1095|       |
 1096|      2|    r["*"] = BOP_MULT;
 1097|      2|    r["/"] = BOP_DIV;
 1098|      2|    r["%"] = BOP_PERCENT;
 1099|       |
 1100|      2|    r["+"] = BOP_PLUS;
 1101|      2|    r["-"] = BOP_MINUS;
 1102|       |
 1103|      2|    r["<<"] = BOP_SHIFT_L;
 1104|      2|    r[">>"] = BOP_SHIFT_R;
 1105|       |
 1106|      2|    r[">"] = BOP_GREATER;
 1107|      2|    r[">="] = BOP_GREATER_EQ;
 1108|      2|    r["<"] = BOP_LESS;
 1109|      2|    r["<="] = BOP_LESS_EQ;
 1110|      2|    r["in"] = BOP_IN;
 1111|       |
 1112|      2|    r["=="] = BOP_MANIFEST_EQUAL;
 1113|      2|    r["!="] = BOP_MANIFEST_UNEQUAL;
 1114|       |
 1115|      2|    r["&"] = BOP_BITWISE_AND;
 1116|      2|    r["^"] = BOP_BITWISE_XOR;
 1117|      2|    r["|"] = BOP_BITWISE_OR;
 1118|       |
 1119|      2|    r["&&"] = BOP_AND;
 1120|      2|    r["||"] = BOP_OR;
 1121|      2|    return r;
 1122|      2|}
_ZN7jsonnet8internal9Allocator4makeINS0_3VarEJNS0_13LocationRangeENSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERPKNS0_10IdentifierEEEEPT_DpOT0_:
  980|  4.02k|    {
  981|  4.02k|        auto r = new T(std::forward<Args>(args)...);
  982|  4.02k|        allocated.push_back(r);
  983|  4.02k|        return r;
  984|  4.02k|    }
vm.cpp:_ZN7jsonnet8internalL10bop_stringENS0_8BinaryOpE:
  325|    179|{
  326|    179|    switch (bop) {
  327|      6|        case BOP_MULT: return "*";
  ------------------
  |  Branch (327:9): [True: 6, False: 173]
  ------------------
  328|      6|        case BOP_DIV: return "/";
  ------------------
  |  Branch (328:9): [True: 6, False: 173]
  ------------------
  329|      0|        case BOP_PERCENT: return "%";
  ------------------
  |  Branch (329:9): [True: 0, False: 179]
  ------------------
  330|       |
  331|     52|        case BOP_PLUS: return "+";
  ------------------
  |  Branch (331:9): [True: 52, False: 127]
  ------------------
  332|     12|        case BOP_MINUS: return "-";
  ------------------
  |  Branch (332:9): [True: 12, False: 167]
  ------------------
  333|       |
  334|      4|        case BOP_SHIFT_L: return "<<";
  ------------------
  |  Branch (334:9): [True: 4, False: 175]
  ------------------
  335|      3|        case BOP_SHIFT_R: return ">>";
  ------------------
  |  Branch (335:9): [True: 3, False: 176]
  ------------------
  336|       |
  337|     15|        case BOP_GREATER: return ">";
  ------------------
  |  Branch (337:9): [True: 15, False: 164]
  ------------------
  338|     12|        case BOP_GREATER_EQ: return ">=";
  ------------------
  |  Branch (338:9): [True: 12, False: 167]
  ------------------
  339|     19|        case BOP_LESS: return "<";
  ------------------
  |  Branch (339:9): [True: 19, False: 160]
  ------------------
  340|     11|        case BOP_LESS_EQ: return "<=";
  ------------------
  |  Branch (340:9): [True: 11, False: 168]
  ------------------
  341|      0|        case BOP_IN: return "in";
  ------------------
  |  Branch (341:9): [True: 0, False: 179]
  ------------------
  342|       |
  343|      0|        case BOP_MANIFEST_EQUAL: return "==";
  ------------------
  |  Branch (343:9): [True: 0, False: 179]
  ------------------
  344|      0|        case BOP_MANIFEST_UNEQUAL: return "!=";
  ------------------
  |  Branch (344:9): [True: 0, False: 179]
  ------------------
  345|       |
  346|      9|        case BOP_BITWISE_AND: return "&";
  ------------------
  |  Branch (346:9): [True: 9, False: 170]
  ------------------
  347|     16|        case BOP_BITWISE_XOR: return "^";
  ------------------
  |  Branch (347:9): [True: 16, False: 163]
  ------------------
  348|      6|        case BOP_BITWISE_OR: return "|";
  ------------------
  |  Branch (348:9): [True: 6, False: 173]
  ------------------
  349|       |
  350|      3|        case BOP_AND: return "&&";
  ------------------
  |  Branch (350:9): [True: 3, False: 176]
  ------------------
  351|      5|        case BOP_OR: return "||";
  ------------------
  |  Branch (351:9): [True: 5, False: 174]
  ------------------
  352|       |
  353|      0|        default:
  ------------------
  |  Branch (353:9): [True: 0, False: 179]
  ------------------
  354|      0|            std::cerr << "INTERNAL ERROR: Unrecognised binary operator: " << bop << std::endl;
  355|      0|            std::abort();
  356|    179|    }
  357|    179|}
vm.cpp:_ZN7jsonnet8internalL10uop_stringENS0_7UnaryOpE:
  938|    180|{
  939|    180|    switch (uop) {
  940|    118|        case UOP_PLUS: return "+";
  ------------------
  |  Branch (940:9): [True: 118, False: 62]
  ------------------
  941|     18|        case UOP_MINUS: return "-";
  ------------------
  |  Branch (941:9): [True: 18, False: 162]
  ------------------
  942|      5|        case UOP_BITWISE_NOT: return "~";
  ------------------
  |  Branch (942:9): [True: 5, False: 175]
  ------------------
  943|     39|        case UOP_NOT: return "!";
  ------------------
  |  Branch (943:9): [True: 39, False: 141]
  ------------------
  944|       |
  945|      0|        default:
  ------------------
  |  Branch (945:9): [True: 0, False: 180]
  ------------------
  946|      0|            std::cerr << "INTERNAL ERROR: Unrecognised unary operator: " << uop << std::endl;
  947|      0|            std::abort();
  948|    180|    }
  949|    180|}
desugarer.cpp:_ZN7jsonnet8internal12_GLOBAL__N_120build_precedence_mapEv:
 1047|      2|{
 1048|      2|    std::map<BinaryOp, int> r;
 1049|       |
 1050|      2|    r[BOP_MULT] = 5;
 1051|      2|    r[BOP_DIV] = 5;
 1052|      2|    r[BOP_PERCENT] = 5;
 1053|       |
 1054|      2|    r[BOP_PLUS] = 6;
 1055|      2|    r[BOP_MINUS] = 6;
 1056|       |
 1057|      2|    r[BOP_SHIFT_L] = 7;
 1058|      2|    r[BOP_SHIFT_R] = 7;
 1059|       |
 1060|      2|    r[BOP_GREATER] = 8;
 1061|      2|    r[BOP_GREATER_EQ] = 8;
 1062|      2|    r[BOP_LESS] = 8;
 1063|      2|    r[BOP_LESS_EQ] = 8;
 1064|      2|    r[BOP_IN] = 8;
 1065|       |
 1066|      2|    r[BOP_MANIFEST_EQUAL] = 9;
 1067|      2|    r[BOP_MANIFEST_UNEQUAL] = 9;
 1068|       |
 1069|      2|    r[BOP_BITWISE_AND] = 10;
 1070|       |
 1071|      2|    r[BOP_BITWISE_XOR] = 11;
 1072|       |
 1073|      2|    r[BOP_BITWISE_OR] = 12;
 1074|       |
 1075|      2|    r[BOP_AND] = 13;
 1076|       |
 1077|      2|    r[BOP_OR] = 14;
 1078|       |
 1079|      2|    return r;
 1080|      2|}
desugarer.cpp:_ZN7jsonnet8internal12_GLOBAL__N_115build_unary_mapEv:
 1083|      2|{
 1084|      2|    std::map<std::string, UnaryOp> r;
 1085|      2|    r["!"] = UOP_NOT;
 1086|      2|    r["~"] = UOP_BITWISE_NOT;
 1087|      2|    r["+"] = UOP_PLUS;
 1088|      2|    r["-"] = UOP_MINUS;
 1089|      2|    return r;
 1090|      2|}
desugarer.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116build_binary_mapEv:
 1093|      2|{
 1094|      2|    std::map<std::string, BinaryOp> r;
 1095|       |
 1096|      2|    r["*"] = BOP_MULT;
 1097|      2|    r["/"] = BOP_DIV;
 1098|      2|    r["%"] = BOP_PERCENT;
 1099|       |
 1100|      2|    r["+"] = BOP_PLUS;
 1101|      2|    r["-"] = BOP_MINUS;
 1102|       |
 1103|      2|    r["<<"] = BOP_SHIFT_L;
 1104|      2|    r[">>"] = BOP_SHIFT_R;
 1105|       |
 1106|      2|    r[">"] = BOP_GREATER;
 1107|      2|    r[">="] = BOP_GREATER_EQ;
 1108|      2|    r["<"] = BOP_LESS;
 1109|      2|    r["<="] = BOP_LESS_EQ;
 1110|      2|    r["in"] = BOP_IN;
 1111|       |
 1112|      2|    r["=="] = BOP_MANIFEST_EQUAL;
 1113|      2|    r["!="] = BOP_MANIFEST_UNEQUAL;
 1114|       |
 1115|      2|    r["&"] = BOP_BITWISE_AND;
 1116|      2|    r["^"] = BOP_BITWISE_XOR;
 1117|      2|    r["|"] = BOP_BITWISE_OR;
 1118|       |
 1119|      2|    r["&&"] = BOP_AND;
 1120|      2|    r["||"] = BOP_OR;
 1121|      2|    return r;
 1122|      2|}
_ZN7jsonnet8internal9Allocator4makeINS0_6BinaryEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTERKSB_NS0_8BinaryOpESF_EEEPT_DpOT0_:
  980|   109k|    {
  981|   109k|        auto r = new T(std::forward<Args>(args)...);
  982|   109k|        allocated.push_back(r);
  983|   109k|        return r;
  984|   109k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralNumberEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERA4_KcEEEPT_DpOT0_:
  980|   678k|    {
  981|   678k|        auto r = new T(std::forward<Args>(args)...);
  982|   678k|        allocated.push_back(r);
  983|   678k|        return r;
  984|   678k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ApplyEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_3VarESD_NS7_INS0_8ArgParamENS9_ISG_EEEEbSD_SD_bEEEPT_DpOT0_:
  980|   319k|    {
  981|   319k|        auto r = new T(std::forward<Args>(args)...);
  982|   319k|        allocated.push_back(r);
  983|   319k|        return r;
  984|   319k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6BinaryEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS0_8BinaryOpERPNS0_3ASTEEEEPT_DpOT0_:
  980|   534k|    {
  981|   534k|        auto r = new T(std::forward<Args>(args)...);
  982|   534k|        allocated.push_back(r);
  983|   534k|        return r;
  984|   534k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6BinaryEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS0_8BinaryOpEPNS0_5ArrayEEEEPT_DpOT0_:
  980|   319k|    {
  981|   319k|        auto r = new T(std::forward<Args>(args)...);
  982|   319k|        allocated.push_back(r);
  983|   319k|        return r;
  984|   319k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ArrayEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_7ElementENS9_ISE_EEEEbSD_EEEPT_DpOT0_:
  980|   319k|    {
  981|   319k|        auto r = new T(std::forward<Args>(args)...);
  982|   319k|        allocated.push_back(r);
  983|   319k|        return r;
  984|   319k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ApplyEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS8_INS0_8ArgParamENSA_ISH_EEEEbSE_SE_bEEEPT_DpOT0_:
  980|   563k|    {
  981|   563k|        auto r = new T(std::forward<Args>(args)...);
  982|   563k|        allocated.push_back(r);
  983|   563k|        return r;
  984|   563k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERKPNS0_3ASTESD_RSF_SD_SI_EEEPT_DpOT0_:
  980|   185k|    {
  981|   185k|        auto r = new T(std::forward<Args>(args)...);
  982|   185k|        allocated.push_back(r);
  983|   185k|        return r;
  984|   185k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5LocalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_4BindENS9_ISE_EEEEPNS0_11ConditionalEEEEPT_DpOT0_:
  980|   348k|    {
  981|   348k|        auto r = new T(std::forward<Args>(args)...);
  982|   348k|        allocated.push_back(r);
  983|   348k|        return r;
  984|   348k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_8FunctionEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEESD_NS7_INS0_8ArgParamENS9_ISE_EEEEbSD_PNS0_11ConditionalEEEEPT_DpOT0_:
  980|   348k|    {
  981|   348k|        auto r = new T(std::forward<Args>(args)...);
  982|   348k|        allocated.push_back(r);
  983|   348k|        return r;
  984|   348k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_6BinaryESD_RPNS0_3ASTESD_PNS0_5LocalEEEEPT_DpOT0_:
  980|   348k|    {
  981|   348k|        auto r = new T(std::forward<Args>(args)...);
  982|   348k|        allocated.push_back(r);
  983|   348k|        return r;
  984|   348k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6BinaryEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS0_8BinaryOpEPNS0_5ApplyEEEEPT_DpOT0_:
  980|   348k|    {
  981|   348k|        auto r = new T(std::forward<Args>(args)...);
  982|   348k|        allocated.push_back(r);
  983|   348k|        return r;
  984|   348k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5LocalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_4BindENS9_ISE_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  980|   358k|    {
  981|   358k|        auto r = new T(std::forward<Args>(args)...);
  982|   358k|        allocated.push_back(r);
  983|   358k|        return r;
  984|   358k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bSG_SE_DnSE_DnSE_EEEPT_DpOT0_:
  980|   348k|    {
  981|   348k|        auto r = new T(std::forward<Args>(args)...);
  982|   348k|        allocated.push_back(r);
  983|   348k|        return r;
  984|   348k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_5ApplyESD_SF_SD_PNS0_5ErrorEEEEPT_DpOT0_:
  980|   348k|    {
  981|   348k|        auto r = new T(std::forward<Args>(args)...);
  982|   348k|        allocated.push_back(r);
  983|   348k|        return r;
  984|   348k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ArrayEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEENS8_INS3_7ElementENSA_ISF_EEEEbSE_EEEPT_DpOT0_:
  980|   319k|    {
  981|   319k|        auto r = new T(std::forward<Args>(args)...);
  982|   319k|        allocated.push_back(r);
  983|   319k|        return r;
  984|   319k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralStringEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERKNS7_12basic_stringIDiNS7_11char_traitsIDiEENSA_IDiEEEENS3_9TokenKindERA1_KcSP_EEEPT_DpOT0_:
  980|  12.4M|    {
  981|  12.4M|        auto r = new T(std::forward<Args>(args)...);
  982|  12.4M|        allocated.push_back(r);
  983|  12.4M|        return r;
  984|  12.4M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ErrorEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  980|   757k|    {
  981|   757k|        auto r = new T(std::forward<Args>(args)...);
  982|   757k|        allocated.push_back(r);
  983|   757k|        return r;
  984|   757k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTERKSB_SF_SH_SF_EEEPT_DpOT0_:
  980|   359k|    {
  981|   359k|        auto r = new T(std::forward<Args>(args)...);
  982|   359k|        allocated.push_back(r);
  983|   359k|        return r;
  984|   359k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bPNS0_13LiteralStringESE_DnSE_DnSE_EEEPT_DpOT0_:
  980|  3.07M|    {
  981|  3.07M|        auto r = new T(std::forward<Args>(args)...);
  982|  3.07M|        allocated.push_back(r);
  983|  3.07M|        return r;
  984|  3.07M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ApplyEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTERKSB_RNS7_INS0_8ArgParamENS9_ISI_EEEEbSH_SH_bEEEPT_DpOT0_:
  980|   270k|    {
  981|   270k|        auto r = new T(std::forward<Args>(args)...);
  982|   270k|        allocated.push_back(r);
  983|   270k|        return r;
  984|   270k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ApplyEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_5IndexESE_NS8_INS0_8ArgParamENSA_ISH_EEEEbSE_SE_bEEEPT_DpOT0_:
  980|  1.94M|    {
  981|  1.94M|        auto r = new T(std::forward<Args>(args)...);
  982|  1.94M|        allocated.push_back(r);
  983|  1.94M|        return r;
  984|  1.94M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5UnaryEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS0_7UnaryOpERPNS0_3ASTEEEEPT_DpOT0_:
  980|   212k|    {
  981|   212k|        auto r = new T(std::forward<Args>(args)...);
  982|   212k|        allocated.push_back(r);
  983|   212k|        return r;
  984|   212k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11LiteralNullEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEEEEPT_DpOT0_:
  980|   295k|    {
  981|   295k|        auto r = new T(std::forward<Args>(args)...);
  982|   295k|        allocated.push_back(r);
  983|   295k|        return r;
  984|   295k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_3VarEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERPKNS0_10IdentifierEEEEPT_DpOT0_:
  980|  7.29M|    {
  981|  7.29M|        auto r = new T(std::forward<Args>(args)...);
  982|  7.29M|        allocated.push_back(r);
  983|  7.29M|        return r;
  984|  7.29M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ApplyEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_5IndexESD_NS7_INS0_8ArgParamENS9_ISG_EEEEbSD_SD_bEEEPT_DpOT0_:
  980|   862k|    {
  981|   862k|        auto r = new T(std::forward<Args>(args)...);
  982|   862k|        allocated.push_back(r);
  983|   862k|        return r;
  984|   862k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_8FunctionEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEESC_RNS7_INS0_8ArgParamENS9_ISD_EEEEbSC_RPNS0_3ASTEEEEPT_DpOT0_:
  980|   648k|    {
  981|   648k|        auto r = new T(std::forward<Args>(args)...);
  982|   648k|        allocated.push_back(r);
  983|   648k|        return r;
  984|   648k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_4SelfEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEEEEPT_DpOT0_:
  980|  30.7k|    {
  981|  30.7k|        auto r = new T(std::forward<Args>(args)...);
  982|  30.7k|        allocated.push_back(r);
  983|  30.7k|        return r;
  984|  30.7k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTESD_PNS0_14LiteralBooleanESD_PNS0_5ErrorEEEEPT_DpOT0_:
  980|  49.3k|    {
  981|  49.3k|        auto r = new T(std::forward<Args>(args)...);
  982|  49.3k|        allocated.push_back(r);
  983|  49.3k|        return r;
  984|  49.3k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_14LiteralBooleanEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEbEEEPT_DpOT0_:
  980|  49.3k|    {
  981|  49.3k|        auto r = new T(std::forward<Args>(args)...);
  982|  49.3k|        allocated.push_back(r);
  983|  49.3k|        return r;
  984|  49.3k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_8FunctionEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERSB_RNS7_INS0_8ArgParamENS9_ISF_EEEERbSE_RPNS0_3ASTEEEEPT_DpOT0_:
  980|  1.10M|    {
  981|  1.10M|        auto r = new T(std::forward<Args>(args)...);
  982|  1.10M|        allocated.push_back(r);
  983|  1.10M|        return r;
  984|  1.10M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_3VarEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPKNS0_10IdentifierEEEEPT_DpOT0_:
  980|   291k|    {
  981|   291k|        auto r = new T(std::forward<Args>(args)...);
  982|   291k|        allocated.push_back(r);
  983|   291k|        return r;
  984|   291k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_7InSuperESD_PNS0_6BinaryESD_PNS0_3ASTEEEEPT_DpOT0_:
  980|  16.8k|    {
  981|  16.8k|        auto r = new T(std::forward<Args>(args)...);
  982|  16.8k|        allocated.push_back(r);
  983|  16.8k|        return r;
  984|  16.8k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_7InSuperEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTESD_SD_EEEPT_DpOT0_:
  980|  16.8k|    {
  981|  16.8k|        auto r = new T(std::forward<Args>(args)...);
  982|  16.8k|        allocated.push_back(r);
  983|  16.8k|        return r;
  984|  16.8k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_6BinaryEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_10SuperIndexESD_NS0_8BinaryOpERPNS0_3ASTEEEEPT_DpOT0_:
  980|  16.8k|    {
  981|  16.8k|        auto r = new T(std::forward<Args>(args)...);
  982|  16.8k|        allocated.push_back(r);
  983|  16.8k|        return r;
  984|  16.8k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_10SuperIndexEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEESD_PNS0_3ASTESD_DnEEEPT_DpOT0_:
  980|  16.8k|    {
  981|  16.8k|        auto r = new T(std::forward<Args>(args)...);
  982|  16.8k|        allocated.push_back(r);
  983|  16.8k|        return r;
  984|  16.8k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_15DesugaredObjectEJRNS0_13LocationRangeERNSt3__14listIPNS0_3ASTENS6_9allocatorIS9_EEEERNS6_6vectorINS3_5FieldENSA_ISF_EEEEEEEPT_DpOT0_:
  980|   490k|    {
  981|   490k|        auto r = new T(std::forward<Args>(args)...);
  982|   490k|        allocated.push_back(r);
  983|   490k|        return r;
  984|   490k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5LocalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERNS7_INS3_4BindENS9_ISE_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  980|  1.21M|    {
  981|  1.21M|        auto r = new T(std::forward<Args>(args)...);
  982|  1.21M|        allocated.push_back(r);
  983|  1.21M|        return r;
  984|  1.21M|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bPNS0_13LiteralNumberESE_DnSE_DnSE_EEEPT_DpOT0_:
  980|  41.4k|    {
  981|  41.4k|        auto r = new T(std::forward<Args>(args)...);
  982|  41.4k|        allocated.push_back(r);
  983|  41.4k|        return r;
  984|  41.4k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_13LiteralNumberEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEENS7_12basic_stringIcNS7_11char_traitsIcEENSA_IcEEEEEEEPT_DpOT0_:
  980|  41.4k|    {
  981|  41.4k|        auto r = new T(std::forward<Args>(args)...);
  982|  41.4k|        allocated.push_back(r);
  983|  41.4k|        return r;
  984|  41.4k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_18ArrayComprehensionEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_5ArrayESD_bRNS7_INS0_17ComprehensionSpecENS9_ISG_EEEESD_EEEPT_DpOT0_:
  980|  38.9k|    {
  981|  38.9k|        auto r = new T(std::forward<Args>(args)...);
  982|  38.9k|        allocated.push_back(r);
  983|  38.9k|        return r;
  984|  38.9k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ArrayEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERNS7_INS3_7ElementENS9_ISE_EEEEbSD_EEEPT_DpOT0_:
  980|  38.9k|    {
  981|  38.9k|        auto r = new T(std::forward<Args>(args)...);
  982|  38.9k|        allocated.push_back(r);
  983|  38.9k|        return r;
  984|  38.9k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_25ObjectComprehensionSimpleEJRNS0_13LocationRangeEPNS0_5IndexEPNS0_5LocalERPKNS0_10IdentifierERPNS0_3ASTEEEEPT_DpOT0_:
  980|  38.9k|    {
  981|  38.9k|        auto r = new T(std::forward<Args>(args)...);
  982|  38.9k|        allocated.push_back(r);
  983|  38.9k|        return r;
  984|  38.9k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bRPNS0_3ASTESE_DnSE_DnSE_EEEPT_DpOT0_:
  980|  38.9k|    {
  981|  38.9k|        auto r = new T(std::forward<Args>(args)...);
  982|  38.9k|        allocated.push_back(r);
  983|  38.9k|        return r;
  984|  38.9k|    }
_ZN7jsonnet8internal9Allocator15makeBuiltinBodyIZNS0_9Desugarer9stdlibASTENSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEEUlvE_EEPKNS0_19BuiltinFunctionBodyERKNS0_13LocationRangeERKSA_OT_:
 1009|   368k|    {
 1010|   368k|        auto it = internedBuiltins.find(name);
 1011|   368k|        if (it != internedBuiltins.end()) {
  ------------------
  |  Branch (1011:13): [True: 168k, False: 199k]
  ------------------
 1012|   168k|            return it->second;
 1013|   168k|        }
 1014|   199k|        const Identifiers params = make_params();
 1015|   199k|        auto r = new BuiltinFunctionBody(loc, name, params);
 1016|   199k|        internedBuiltins[name] = r;
 1017|   199k|        return r;
 1018|   368k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_15BuiltinFunctionEJRKNS0_13LocationRangeERPKNS0_19BuiltinFunctionBodyEEEEPT_DpOT0_:
  980|   368k|    {
  981|   368k|        auto r = new T(std::forward<Args>(args)...);
  982|   368k|        allocated.push_back(r);
  983|   368k|        return r;
  984|   368k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5LocalEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_4BindENS9_ISD_EEEEPNS0_11ConditionalEEEEPT_DpOT0_:
  980|  4.74k|    {
  981|  4.74k|        auto r = new T(std::forward<Args>(args)...);
  982|  4.74k|        allocated.push_back(r);
  983|  4.74k|        return r;
  984|  4.74k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_11ConditionalEJRKNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_5ApplyERKSC_SF_SD_PNS0_3VarEEEEPT_DpOT0_:
  980|  4.74k|    {
  981|  4.74k|        auto r = new T(std::forward<Args>(args)...);
  982|  4.74k|        allocated.push_back(r);
  983|  4.74k|        return r;
  984|  4.74k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_5ApplyEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_3VarESD_RNS7_INS0_8ArgParamENS9_ISG_EEEEbSD_SD_bEEEPT_DpOT0_:
  980|  4.74k|    {
  981|  4.74k|        auto r = new T(std::forward<Args>(args)...);
  982|  4.74k|        allocated.push_back(r);
  983|  4.74k|        return r;
  984|  4.74k|    }
_ZN7jsonnet8internal9Allocator4makeINS0_3VarEJRKNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERPKNS0_10IdentifierEEEEPT_DpOT0_:
  980|  9.48k|    {
  981|  9.48k|        auto r = new T(std::forward<Args>(args)...);
  982|  9.48k|        allocated.push_back(r);
  983|  9.48k|        return r;
  984|  9.48k|    }
formatter.cpp:_ZN7jsonnet8internal12_GLOBAL__N_120build_precedence_mapEv:
 1047|      2|{
 1048|      2|    std::map<BinaryOp, int> r;
 1049|       |
 1050|      2|    r[BOP_MULT] = 5;
 1051|      2|    r[BOP_DIV] = 5;
 1052|      2|    r[BOP_PERCENT] = 5;
 1053|       |
 1054|      2|    r[BOP_PLUS] = 6;
 1055|      2|    r[BOP_MINUS] = 6;
 1056|       |
 1057|      2|    r[BOP_SHIFT_L] = 7;
 1058|      2|    r[BOP_SHIFT_R] = 7;
 1059|       |
 1060|      2|    r[BOP_GREATER] = 8;
 1061|      2|    r[BOP_GREATER_EQ] = 8;
 1062|      2|    r[BOP_LESS] = 8;
 1063|      2|    r[BOP_LESS_EQ] = 8;
 1064|      2|    r[BOP_IN] = 8;
 1065|       |
 1066|      2|    r[BOP_MANIFEST_EQUAL] = 9;
 1067|      2|    r[BOP_MANIFEST_UNEQUAL] = 9;
 1068|       |
 1069|      2|    r[BOP_BITWISE_AND] = 10;
 1070|       |
 1071|      2|    r[BOP_BITWISE_XOR] = 11;
 1072|       |
 1073|      2|    r[BOP_BITWISE_OR] = 12;
 1074|       |
 1075|      2|    r[BOP_AND] = 13;
 1076|       |
 1077|      2|    r[BOP_OR] = 14;
 1078|       |
 1079|      2|    return r;
 1080|      2|}
formatter.cpp:_ZN7jsonnet8internal12_GLOBAL__N_115build_unary_mapEv:
 1083|      2|{
 1084|      2|    std::map<std::string, UnaryOp> r;
 1085|      2|    r["!"] = UOP_NOT;
 1086|      2|    r["~"] = UOP_BITWISE_NOT;
 1087|      2|    r["+"] = UOP_PLUS;
 1088|      2|    r["-"] = UOP_MINUS;
 1089|      2|    return r;
 1090|      2|}
formatter.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116build_binary_mapEv:
 1093|      2|{
 1094|      2|    std::map<std::string, BinaryOp> r;
 1095|       |
 1096|      2|    r["*"] = BOP_MULT;
 1097|      2|    r["/"] = BOP_DIV;
 1098|      2|    r["%"] = BOP_PERCENT;
 1099|       |
 1100|      2|    r["+"] = BOP_PLUS;
 1101|      2|    r["-"] = BOP_MINUS;
 1102|       |
 1103|      2|    r["<<"] = BOP_SHIFT_L;
 1104|      2|    r[">>"] = BOP_SHIFT_R;
 1105|       |
 1106|      2|    r[">"] = BOP_GREATER;
 1107|      2|    r[">="] = BOP_GREATER_EQ;
 1108|      2|    r["<"] = BOP_LESS;
 1109|      2|    r["<="] = BOP_LESS_EQ;
 1110|      2|    r["in"] = BOP_IN;
 1111|       |
 1112|      2|    r["=="] = BOP_MANIFEST_EQUAL;
 1113|      2|    r["!="] = BOP_MANIFEST_UNEQUAL;
 1114|       |
 1115|      2|    r["&"] = BOP_BITWISE_AND;
 1116|      2|    r["^"] = BOP_BITWISE_XOR;
 1117|      2|    r["|"] = BOP_BITWISE_OR;
 1118|       |
 1119|      2|    r["&&"] = BOP_AND;
 1120|      2|    r["||"] = BOP_OR;
 1121|      2|    return r;
 1122|      2|}

_ZN7jsonnet8internal20jsonnet_builtin_declEm:
   41|   368k|{
   42|   368k|    switch (builtin) {
   43|  8.76k|        case 0: return {U"makeArray", {U"sz", U"func"}};
  ------------------
  |  Branch (43:9): [True: 8.76k, False: 359k]
  ------------------
   44|  8.76k|        case 1: return {U"pow", {U"x", U"n"}};
  ------------------
  |  Branch (44:9): [True: 8.76k, False: 359k]
  ------------------
   45|  8.76k|        case 2: return {U"floor", {U"x"}};
  ------------------
  |  Branch (45:9): [True: 8.76k, False: 359k]
  ------------------
   46|  8.76k|        case 3: return {U"ceil", {U"x"}};
  ------------------
  |  Branch (46:9): [True: 8.76k, False: 359k]
  ------------------
   47|  8.76k|        case 4: return {U"sqrt", {U"x"}};
  ------------------
  |  Branch (47:9): [True: 8.76k, False: 359k]
  ------------------
   48|  8.76k|        case 5: return {U"sin", {U"x"}};
  ------------------
  |  Branch (48:9): [True: 8.76k, False: 359k]
  ------------------
   49|  8.76k|        case 6: return {U"cos", {U"x"}};
  ------------------
  |  Branch (49:9): [True: 8.76k, False: 359k]
  ------------------
   50|  8.76k|        case 7: return {U"tan", {U"x"}};
  ------------------
  |  Branch (50:9): [True: 8.76k, False: 359k]
  ------------------
   51|  8.76k|        case 8: return {U"asin", {U"x"}};
  ------------------
  |  Branch (51:9): [True: 8.76k, False: 359k]
  ------------------
   52|  8.76k|        case 9: return {U"acos", {U"x"}};
  ------------------
  |  Branch (52:9): [True: 8.76k, False: 359k]
  ------------------
   53|  8.76k|        case 10: return {U"atan", {U"x"}};
  ------------------
  |  Branch (53:9): [True: 8.76k, False: 359k]
  ------------------
   54|  8.76k|        case 11: return {U"type", {U"x"}};
  ------------------
  |  Branch (54:9): [True: 8.76k, False: 359k]
  ------------------
   55|  8.76k|        case 12: return {U"filter", {U"func", U"arr"}};
  ------------------
  |  Branch (55:9): [True: 8.76k, False: 359k]
  ------------------
   56|  8.76k|        case 13: return {U"objectHasEx", {U"obj", U"f", U"inc_hidden"}};
  ------------------
  |  Branch (56:9): [True: 8.76k, False: 359k]
  ------------------
   57|  8.76k|        case 14: return {U"length", {U"x"}};
  ------------------
  |  Branch (57:9): [True: 8.76k, False: 359k]
  ------------------
   58|  8.76k|        case 15: return {U"objectFieldsEx", {U"obj", U"inc_hidden"}};
  ------------------
  |  Branch (58:9): [True: 8.76k, False: 359k]
  ------------------
   59|  8.76k|        case 16: return {U"codepoint", {U"str"}};
  ------------------
  |  Branch (59:9): [True: 8.76k, False: 359k]
  ------------------
   60|  8.76k|        case 17: return {U"char", {U"n"}};
  ------------------
  |  Branch (60:9): [True: 8.76k, False: 359k]
  ------------------
   61|  8.76k|        case 18: return {U"log", {U"n"}};
  ------------------
  |  Branch (61:9): [True: 8.76k, False: 359k]
  ------------------
   62|  8.76k|        case 19: return {U"exp", {U"n"}};
  ------------------
  |  Branch (62:9): [True: 8.76k, False: 359k]
  ------------------
   63|  8.76k|        case 20: return {U"mantissa", {U"n"}};
  ------------------
  |  Branch (63:9): [True: 8.76k, False: 359k]
  ------------------
   64|  8.76k|        case 21: return {U"exponent", {U"n"}};
  ------------------
  |  Branch (64:9): [True: 8.76k, False: 359k]
  ------------------
   65|  8.76k|        case 22: return {U"modulo", {U"a", U"b"}};
  ------------------
  |  Branch (65:9): [True: 8.76k, False: 359k]
  ------------------
   66|  8.76k|        case 23: return {U"extVar", {U"x"}};
  ------------------
  |  Branch (66:9): [True: 8.76k, False: 359k]
  ------------------
   67|  8.76k|        case 24: return {U"primitiveEquals", {U"a", U"b"}};
  ------------------
  |  Branch (67:9): [True: 8.76k, False: 359k]
  ------------------
   68|  8.76k|        case 25: return {U"native", {U"name"}};
  ------------------
  |  Branch (68:9): [True: 8.76k, False: 359k]
  ------------------
   69|  8.76k|        case 26: return {U"md5", {U"str"}};
  ------------------
  |  Branch (69:9): [True: 8.76k, False: 359k]
  ------------------
   70|  8.76k|        case 27: return {U"trace", {U"str", U"rest"}};
  ------------------
  |  Branch (70:9): [True: 8.76k, False: 359k]
  ------------------
   71|  8.76k|        case 28: return {U"splitLimit", {U"str", U"c", U"maxsplits"}};
  ------------------
  |  Branch (71:9): [True: 8.76k, False: 359k]
  ------------------
   72|  8.76k|        case 29: return {U"substr", {U"str", U"from", U"len"}};
  ------------------
  |  Branch (72:9): [True: 8.76k, False: 359k]
  ------------------
   73|  8.76k|        case 30: return {U"range", {U"from", U"to"}};
  ------------------
  |  Branch (73:9): [True: 8.76k, False: 359k]
  ------------------
   74|  8.76k|        case 31: return {U"strReplace", {U"str", U"from", U"to"}};
  ------------------
  |  Branch (74:9): [True: 8.76k, False: 359k]
  ------------------
   75|  8.76k|        case 32: return {U"asciiLower", {U"str"}};
  ------------------
  |  Branch (75:9): [True: 8.76k, False: 359k]
  ------------------
   76|  8.76k|        case 33: return {U"asciiUpper", {U"str"}};
  ------------------
  |  Branch (76:9): [True: 8.76k, False: 359k]
  ------------------
   77|  8.76k|        case 34: return {U"join", {U"sep", U"arr"}};
  ------------------
  |  Branch (77:9): [True: 8.76k, False: 359k]
  ------------------
   78|  8.76k|        case 35: return {U"parseJson", {U"str"}};
  ------------------
  |  Branch (78:9): [True: 8.76k, False: 359k]
  ------------------
   79|  8.76k|        case 36: return {U"parseYaml", {U"str"}};
  ------------------
  |  Branch (79:9): [True: 8.76k, False: 359k]
  ------------------
   80|  8.76k|        case 37: return {U"encodeUTF8", {U"str"}};
  ------------------
  |  Branch (80:9): [True: 8.76k, False: 359k]
  ------------------
   81|  8.76k|        case 38: return {U"decodeUTF8", {U"arr"}};
  ------------------
  |  Branch (81:9): [True: 8.76k, False: 359k]
  ------------------
   82|  8.76k|        case 39: return {U"atan2", {U"y", U"x"}};
  ------------------
  |  Branch (82:9): [True: 8.76k, False: 359k]
  ------------------
   83|  8.76k|        case 40: return {U"hypot", {U"a", U"b"}};
  ------------------
  |  Branch (83:9): [True: 8.76k, False: 359k]
  ------------------
   84|  8.76k|        case 41: return {U"objectRemoveKey", {U"obj", U"key"}};
  ------------------
  |  Branch (84:9): [True: 8.76k, False: 359k]
  ------------------
   85|      0|        default:
  ------------------
  |  Branch (85:9): [True: 0, False: 368k]
  ------------------
   86|      0|            std::cerr << "INTERNAL ERROR: Unrecognized builtin function: " << builtin << std::endl;
   87|      0|            std::abort();
   88|   368k|    }
   89|       |    // Quiet, compiler.
   90|      0|    return BuiltinDecl();
   91|   368k|}
_ZN7jsonnet8internal13makeStdlibASTEPNS0_9AllocatorENSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEE:
 1022|  4.02k|DesugaredObject *makeStdlibAST(Allocator *alloc, std::string filename) {
 1023|  4.02k|    Desugarer desugarer(alloc, true);
 1024|  4.02k|    return desugarer.stdlibAST(filename);
 1025|  4.02k|}
_ZN7jsonnet8internal15jsonnet_desugarEPNS0_9AllocatorERPNS0_3ASTEPNSt3__13mapINS6_12basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEENS0_5VmExtENS6_4lessISD_EENSB_INS6_4pairIKSD_SE_EEEEEE:
 1028|  5.23k|{
 1029|  5.23k|    Desugarer desugarer(alloc);
 1030|  5.23k|    desugarer.desugarFile(ast, tlas);
 1031|  5.23k|}
_ZN7jsonnet8internal9DesugarerC2EPNS0_9AllocatorEb:
  229|  9.25k|    Desugarer(Allocator *alloc, bool isStdlib = false) : alloc(alloc), isStdlib(isStdlib) {}
_ZN7jsonnet8internal9Desugarer9stdlibASTENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
  921|  8.76k|    DesugaredObject *stdlibAST(std::string filename) {
  922|       |        // Now, implement the std library by wrapping in a local construct.
  923|  8.76k|        Tokens tokens = jsonnet_lex("std.jsonnet", STD_CODE);
  924|  8.76k|        AST *std_ast = jsonnet_parse(alloc, tokens);
  925|  8.76k|        desugar(std_ast, 0);
  926|  8.76k|        auto *std_obj = dynamic_cast<DesugaredObject *>(std_ast);
  927|  8.76k|        if (std_obj == nullptr) {
  ------------------
  |  Branch (927:13): [True: 0, False: 8.76k]
  ------------------
  928|      0|            std::cerr << "INTERNAL ERROR: std.jsonnet not an object." << std::endl;
  929|      0|            std::abort();
  930|      0|        }
  931|       |
  932|       |        // Bind 'std' builtins that are implemented natively.
  933|  8.76k|        DesugaredObject::Fields &fields = std_obj->fields;
  934|   376k|        for (unsigned long c = 0; c <= max_builtin; ++c) {
  ------------------
  |  Branch (934:35): [True: 368k, False: 8.76k]
  ------------------
  935|   368k|            const auto &decl = jsonnet_builtin_decl(c);
  936|   368k|            auto name = str(decl.name);
  937|   368k|            auto name_utf8 = "std:" + encode_utf8(decl.name);
  938|   368k|            auto fnbody = alloc->makeBuiltinBody(E, name_utf8, [this, &decl]()->Identifiers {
  939|   368k|                Identifiers params;
  940|   368k|                for (const auto &p : decl.params)
  941|   368k|                    params.push_back(this->id(p));
  942|   368k|                return params;
  943|   368k|            });
  944|   368k|            auto field = std::find_if(fields.begin(), fields.end(),
  945|   368k|                [=](const DesugaredObject::Field& f) {
  946|   368k|                    return static_cast<LiteralString*>(f.name)->value == decl.name;
  947|   368k|                });
  948|   368k|            auto fn = make<BuiltinFunction>(E, fnbody);
  949|   368k|            if (field != fields.end()) {
  ------------------
  |  Branch (949:17): [True: 61.3k, False: 306k]
  ------------------
  950|  61.3k|                field->body = fn;
  951|   306k|            } else {
  952|   306k|                fields.emplace_back(ObjectField::HIDDEN, name, fn);
  953|   306k|            }
  954|   368k|        }
  955|  8.76k|        fields.emplace_back(
  956|  8.76k|            ObjectField::HIDDEN, str(U"thisFile"), str(decode_utf8(filename)));
  957|  8.76k|        return std_obj;
  958|  8.76k|    }
_ZN7jsonnet8internal9Desugarer7desugarERPNS0_3ASTEj:
  686|  73.5M|    {
  687|  73.5M|        if (auto *ast = dynamic_cast<Apply *>(ast_)) {
  ------------------
  |  Branch (687:19): [True: 7.14M, False: 66.4M]
  ------------------
  688|  7.14M|            desugar(ast->target, obj_level);
  689|  7.14M|            for (ArgParam &arg : ast->args)
  ------------------
  |  Branch (689:32): [True: 11.8M, False: 7.14M]
  ------------------
  690|  11.8M|                desugar(arg.expr, obj_level);
  691|       |
  692|  66.4M|        } else if (auto *ast = dynamic_cast<ApplyBrace *>(ast_)) {
  ------------------
  |  Branch (692:26): [True: 110k, False: 66.3M]
  ------------------
  693|   110k|            desugar(ast->left, obj_level);
  694|   110k|            desugar(ast->right, obj_level);
  695|   110k|            ast_ =
  696|   110k|                make<Binary>(ast->location, ast->openFodder, ast->left, EF, BOP_PLUS, ast->right);
  697|       |
  698|  66.3M|        } else if (auto *ast = dynamic_cast<Array *>(ast_)) {
  ------------------
  |  Branch (698:26): [True: 996k, False: 65.3M]
  ------------------
  699|   996k|            for (auto &el : ast->elements)
  ------------------
  |  Branch (699:27): [True: 2.87M, False: 996k]
  ------------------
  700|  2.87M|                desugar(el.expr, obj_level);
  701|       |
  702|  65.3M|        } else if (auto *ast = dynamic_cast<ArrayComprehension *>(ast_)) {
  ------------------
  |  Branch (702:26): [True: 319k, False: 65.0M]
  ------------------
  703|   319k|            for (ComprehensionSpec &spec : ast->specs)
  ------------------
  |  Branch (703:42): [True: 534k, False: 319k]
  ------------------
  704|   534k|                desugar(spec.expr, obj_level);
  705|   319k|            desugar(ast->body, obj_level + 1);
  706|       |
  707|   319k|            ast_ = makeArrayComprehension(ast);
  708|       |
  709|  65.0M|        } else if (auto *ast = dynamic_cast<Assert *>(ast_)) {
  ------------------
  |  Branch (709:26): [True: 359k, False: 64.6M]
  ------------------
  710|   359k|            desugar(ast->cond, obj_level);
  711|   359k|            if (ast->message == nullptr) {
  ------------------
  |  Branch (711:17): [True: 26.4k, False: 333k]
  ------------------
  712|  26.4k|                ast->message = str(U"Assertion failed.");
  713|  26.4k|            }
  714|   359k|            desugar(ast->message, obj_level);
  715|   359k|            desugar(ast->rest, obj_level);
  716|       |
  717|       |            // if cond then rest else error msg
  718|   359k|            AST *branch_false = make<Error>(ast->location, EF, ast->message);
  719|   359k|            ast_ = make<Conditional>(
  720|   359k|                ast->location, ast->openFodder, ast->cond, EF, ast->rest, EF, branch_false);
  721|       |
  722|  64.6M|        } else if (auto *ast = dynamic_cast<Binary *>(ast_)) {
  ------------------
  |  Branch (722:26): [True: 7.71M, False: 56.9M]
  ------------------
  723|  7.71M|            desugar(ast->left, obj_level);
  724|  7.71M|            desugar(ast->right, obj_level);
  725|       |
  726|  7.71M|            bool invert = false;
  727|       |
  728|  7.71M|            switch (ast->op) {
  729|   270k|                case BOP_PERCENT: {
  ------------------
  |  Branch (729:17): [True: 270k, False: 7.44M]
  ------------------
  730|   270k|                    AST *f_mod = make<Index>(
  731|   270k|                        E, EF, std(), EF, false, str(U"mod"), EF, nullptr, EF, nullptr, EF);
  732|   270k|                    ArgParams args = {{ast->left, EF}, {ast->right, EF}};
  733|   270k|                    ast_ = make<Apply>(
  734|   270k|                        ast->location, ast->openFodder, f_mod, EF, args, false, EF, EF, false);
  735|   270k|                } break;
  736|       |
  737|   212k|                case BOP_MANIFEST_UNEQUAL: invert = true;
  ------------------
  |  Branch (737:17): [True: 212k, False: 7.50M]
  ------------------
  738|   212k|                [[fallthrough]];
  739|  1.59M|                case BOP_MANIFEST_EQUAL: {
  ------------------
  |  Branch (739:17): [True: 1.37M, False: 6.33M]
  ------------------
  740|  1.59M|                    ast_ = equals(ast->location, ast->left, ast->right);
  741|  1.59M|                    if (invert)
  ------------------
  |  Branch (741:25): [True: 212k, False: 1.37M]
  ------------------
  742|   212k|                        ast_ = make<Unary>(ast->location, ast->openFodder, UOP_NOT, ast_);
  743|  1.59M|                } break;
  744|       |
  745|  5.85M|                default:;
  ------------------
  |  Branch (745:17): [True: 5.85M, False: 1.86M]
  ------------------
  746|       |                    // Otherwise don't change it.
  747|  7.71M|            }
  748|       |
  749|  56.9M|        } else if (dynamic_cast<const BuiltinFunction *>(ast_)) {
  ------------------
  |  Branch (749:20): [True: 0, False: 56.9M]
  ------------------
  750|       |            // Nothing to do.
  751|       |
  752|  56.9M|        } else if (auto *ast = dynamic_cast<Conditional *>(ast_)) {
  ------------------
  |  Branch (752:26): [True: 2.90M, False: 54.0M]
  ------------------
  753|  2.90M|            desugar(ast->cond, obj_level);
  754|  2.90M|            desugar(ast->branchTrue, obj_level);
  755|  2.90M|            if (ast->branchFalse == nullptr)
  ------------------
  |  Branch (755:17): [True: 35.0k, False: 2.86M]
  ------------------
  756|  35.0k|                ast->branchFalse = null();
  757|  2.90M|            desugar(ast->branchFalse, obj_level);
  758|       |
  759|  54.0M|        } else if (auto *ast = dynamic_cast<Dollar *>(ast_)) {
  ------------------
  |  Branch (759:26): [True: 41.1k, False: 54.0M]
  ------------------
  760|  41.1k|            if (obj_level == 0) {
  ------------------
  |  Branch (760:17): [True: 245, False: 40.9k]
  ------------------
  761|    245|                throw StaticError(ast->location, "No top-level object found.");
  762|    245|            }
  763|  40.9k|            ast_ = var(id(U"$"));
  764|       |
  765|  54.0M|        } else if (auto *ast = dynamic_cast<Error *>(ast_)) {
  ------------------
  |  Branch (765:26): [True: 590k, False: 53.4M]
  ------------------
  766|   590k|            desugar(ast->expr, obj_level);
  767|       |
  768|  53.4M|        } else if (auto *ast = dynamic_cast<Function *>(ast_)) {
  ------------------
  |  Branch (768:26): [True: 223k, False: 53.1M]
  ------------------
  769|   223k|            desugar(ast->body, obj_level);
  770|   223k|            desugarParams(ast->params, obj_level);
  771|       |
  772|  53.1M|        } else if (auto *ast = dynamic_cast<Import *>(ast_)) {
  ------------------
  |  Branch (772:26): [True: 279, False: 53.1M]
  ------------------
  773|       |            // TODO(dcunnin): Abstract this into a template function if it becomes more common.
  774|    279|            AST *file = ast->file;
  775|    279|            desugar(file, obj_level);
  776|    279|            ast->file = dynamic_cast<LiteralString *>(file);
  777|       |
  778|  53.1M|        } else if (auto *ast = dynamic_cast<Importstr *>(ast_)) {
  ------------------
  |  Branch (778:26): [True: 1.46k, False: 53.1M]
  ------------------
  779|       |            // TODO(dcunnin): Abstract this into a template function if it becomes more common.
  780|  1.46k|            AST *file = ast->file;
  781|  1.46k|            desugar(file, obj_level);
  782|  1.46k|            ast->file = dynamic_cast<LiteralString *>(file);
  783|       |
  784|  53.1M|        } else if (auto *ast = dynamic_cast<Importbin *>(ast_)) {
  ------------------
  |  Branch (784:26): [True: 595, False: 53.1M]
  ------------------
  785|       |            // TODO(dcunnin): Abstract this into a template function if it becomes more common.
  786|    595|            AST *file = ast->file;
  787|    595|            desugar(file, obj_level);
  788|    595|            ast->file = dynamic_cast<LiteralString *>(file);
  789|       |
  790|  53.1M|        } else if (auto *ast = dynamic_cast<InSuper *>(ast_)) {
  ------------------
  |  Branch (790:26): [True: 14.9k, False: 53.1M]
  ------------------
  791|  14.9k|            desugar(ast->element, obj_level);
  792|       |
  793|  53.1M|        } else if (auto *ast = dynamic_cast<Index *>(ast_)) {
  ------------------
  |  Branch (793:26): [True: 7.87M, False: 45.3M]
  ------------------
  794|  7.87M|            desugar(ast->target, obj_level);
  795|  7.87M|            if (ast->isSlice) {
  ------------------
  |  Branch (795:17): [True: 160k, False: 7.70M]
  ------------------
  796|   160k|                if (ast->index == nullptr)
  ------------------
  |  Branch (796:21): [True: 19.8k, False: 140k]
  ------------------
  797|  19.8k|                    ast->index = null();
  798|   160k|                desugar(ast->index, obj_level);
  799|       |
  800|   160k|                if (ast->end == nullptr)
  ------------------
  |  Branch (800:21): [True: 89.9k, False: 70.6k]
  ------------------
  801|  89.9k|                    ast->end = null();
  802|   160k|                desugar(ast->end, obj_level);
  803|       |
  804|   160k|                if (ast->step == nullptr)
  ------------------
  |  Branch (804:21): [True: 151k, False: 9.44k]
  ------------------
  805|   151k|                    ast->step = null();
  806|   160k|                desugar(ast->step, obj_level);
  807|       |
  808|   160k|                ast_ = make<Apply>(
  809|   160k|                    ast->location,
  810|   160k|                    EF,
  811|   160k|                    make<Index>(
  812|   160k|                        E, EF, std(), EF, false, str(U"slice"), EF, nullptr, EF, nullptr, EF),
  813|   160k|                    EF,
  814|   160k|                    ArgParams{
  815|   160k|                        {ast->target, EF},
  816|   160k|                        {ast->index, EF},
  817|   160k|                        {ast->end, EF},
  818|   160k|                        {ast->step, EF},
  819|   160k|                    },
  820|   160k|                    false,  // trailing comma
  821|   160k|                    EF,
  822|   160k|                    EF,
  823|   160k|                    false  // tailstrict
  824|   160k|                );
  825|  7.70M|            } else {
  826|  7.70M|                if (ast->id != nullptr) {
  ------------------
  |  Branch (826:21): [True: 6.29M, False: 1.41M]
  ------------------
  827|  6.29M|                    assert(ast->index == nullptr);
  ------------------
  |  Branch (827:21): [True: 6.29M, False: 0]
  ------------------
  828|  6.29M|                    ast->index = str(ast->id->name);
  829|  6.29M|                    ast->id = nullptr;
  830|  6.29M|                }
  831|  7.70M|                desugar(ast->index, obj_level);
  832|  7.70M|            }
  833|       |
  834|  45.3M|        } else if (auto *ast = dynamic_cast<Local *>(ast_)) {
  ------------------
  |  Branch (834:26): [True: 2.14M, False: 43.1M]
  ------------------
  835|  2.14M|            for (auto &bind : ast->binds)
  ------------------
  |  Branch (835:29): [True: 2.29M, False: 2.14M]
  ------------------
  836|  2.29M|                desugar(bind.body, obj_level);
  837|  2.14M|            desugar(ast->body, obj_level);
  838|       |
  839|  2.29M|            for (auto &bind : ast->binds) {
  ------------------
  |  Branch (839:29): [True: 2.29M, False: 2.14M]
  ------------------
  840|  2.29M|                if (bind.functionSugar) {
  ------------------
  |  Branch (840:21): [True: 648k, False: 1.64M]
  ------------------
  841|   648k|                    desugarParams(bind.params, obj_level);
  842|   648k|                    bind.body = make<Function>(ast->location,
  843|   648k|                                               ast->openFodder,
  844|   648k|                                               bind.parenLeftFodder,
  845|   648k|                                               bind.params,
  846|   648k|                                               false,
  847|   648k|                                               bind.parenRightFodder,
  848|   648k|                                               bind.body);
  849|   648k|                    bind.functionSugar = false;
  850|   648k|                    bind.params.clear();
  851|   648k|                }
  852|  2.29M|            }
  853|       |
  854|  43.1M|        } else if (dynamic_cast<const LiteralBoolean *>(ast_)) {
  ------------------
  |  Branch (854:20): [True: 746k, False: 42.4M]
  ------------------
  855|       |            // Nothing to do.
  856|       |
  857|  42.4M|        } else if (dynamic_cast<const LiteralNumber *>(ast_)) {
  ------------------
  |  Branch (857:20): [True: 5.21M, False: 37.2M]
  ------------------
  858|       |            // Nothing to do.
  859|       |
  860|  37.2M|        } else if (auto *ast = dynamic_cast<LiteralString *>(ast_)) {
  ------------------
  |  Branch (860:26): [True: 10.7M, False: 26.4M]
  ------------------
  861|  10.7M|            if ((ast->tokenKind != LiteralString::RAW_DESUGARED) &&
  ------------------
  |  Branch (861:17): [True: 4.29M, False: 6.49M]
  ------------------
  862|  4.29M|                (ast->tokenKind != LiteralString::BLOCK) &&
  ------------------
  |  Branch (862:17): [True: 4.28M, False: 1.87k]
  ------------------
  863|  4.28M|                (ast->tokenKind != LiteralString::VERBATIM_DOUBLE) &&
  ------------------
  |  Branch (863:17): [True: 4.28M, False: 249]
  ------------------
  864|  4.28M|                (ast->tokenKind != LiteralString::VERBATIM_SINGLE)) {
  ------------------
  |  Branch (864:17): [True: 4.28M, False: 96]
  ------------------
  865|  4.28M|                ast->value = jsonnet_string_unescape(ast->location, ast->value);
  866|  4.28M|            }
  867|  10.7M|            ast->tokenKind = LiteralString::RAW_DESUGARED;
  868|  10.7M|            ast->blockIndent.clear();
  869|       |
  870|  26.4M|        } else if (dynamic_cast<const LiteralNull *>(ast_)) {
  ------------------
  |  Branch (870:20): [True: 457k, False: 25.9M]
  ------------------
  871|       |            // Nothing to do.
  872|       |
  873|  25.9M|        } else if (auto *ast = dynamic_cast<DesugaredObject *>(ast_)) {
  ------------------
  |  Branch (873:26): [True: 126k, False: 25.8M]
  ------------------
  874|   126k|            for (auto &field : ast->fields) {
  ------------------
  |  Branch (874:30): [True: 92.2k, False: 126k]
  ------------------
  875|  92.2k|                desugar(field.name, obj_level);
  876|  92.2k|                desugar(field.body, obj_level + 1);
  877|  92.2k|            }
  878|   126k|            for (AST *assert : ast->asserts) {
  ------------------
  |  Branch (878:30): [True: 1.79k, False: 126k]
  ------------------
  879|  1.79k|                desugar(assert, obj_level + 1);
  880|  1.79k|            }
  881|       |
  882|  25.8M|        } else if (auto *ast = dynamic_cast<Object *>(ast_)) {
  ------------------
  |  Branch (882:26): [True: 490k, False: 25.3M]
  ------------------
  883|   490k|            ast_ = makeObject(ast, obj_level);
  884|       |
  885|  25.3M|        } else if (auto *ast = dynamic_cast<ObjectComprehension *>(ast_)) {
  ------------------
  |  Branch (885:26): [True: 39.0k, False: 25.3M]
  ------------------
  886|  39.0k|            ast_ = makeObjectComprehension(ast, obj_level);
  887|       |
  888|  25.3M|        } else if (auto *ast = dynamic_cast<ObjectComprehensionSimple *>(ast_)) {
  ------------------
  |  Branch (888:26): [True: 6.37k, False: 25.3M]
  ------------------
  889|  6.37k|            desugar(ast->field, obj_level);
  890|  6.37k|            desugar(ast->value, obj_level + 1);
  891|  6.37k|            desugar(ast->array, obj_level);
  892|       |
  893|  25.3M|        } else if (auto *ast = dynamic_cast<Parens *>(ast_)) {
  ------------------
  |  Branch (893:26): [True: 438k, False: 24.8M]
  ------------------
  894|       |            // Strip parens.
  895|   438k|            desugar(ast->expr, obj_level);
  896|   438k|            ast_ = ast->expr;
  897|       |
  898|  24.8M|        } else if (dynamic_cast<const Self *>(ast_)) {
  ------------------
  |  Branch (898:20): [True: 92.2k, False: 24.7M]
  ------------------
  899|       |            // Nothing to do.
  900|       |
  901|  24.7M|        } else if (auto *ast = dynamic_cast<SuperIndex *>(ast_)) {
  ------------------
  |  Branch (901:26): [True: 15.4k, False: 24.7M]
  ------------------
  902|  15.4k|            if (ast->id != nullptr) {
  ------------------
  |  Branch (902:17): [True: 530, False: 14.9k]
  ------------------
  903|    530|                assert(ast->index == nullptr);
  ------------------
  |  Branch (903:17): [True: 530, False: 0]
  ------------------
  904|    530|                ast->index = str(ast->id->name);
  905|    530|                ast->id = nullptr;
  906|    530|            }
  907|  15.4k|            desugar(ast->index, obj_level);
  908|       |
  909|  24.7M|        } else if (auto *ast = dynamic_cast<Unary *>(ast_)) {
  ------------------
  |  Branch (909:26): [True: 776k, False: 23.9M]
  ------------------
  910|   776k|            desugar(ast->expr, obj_level);
  911|       |
  912|  23.9M|        } else if (dynamic_cast<const Var *>(ast_)) {
  ------------------
  |  Branch (912:20): [True: 23.9M, False: 0]
  ------------------
  913|       |            // Nothing to do.
  914|       |
  915|  23.9M|        } else {
  916|      0|            std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl;
  917|      0|            std::abort();
  918|      0|        }
  919|  73.5M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_6BinaryEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTERKSB_NS0_8BinaryOpESF_EEEPT_DpOT0_:
  110|   109k|    {
  111|   109k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   109k|    }
_ZN7jsonnet8internal9Desugarer22makeArrayComprehensionEPNS0_18ArrayComprehensionE:
  417|   319k|    AST* makeArrayComprehension(ArrayComprehension *ast) {
  418|   319k|        int n = ast->specs.size();
  419|   319k|        AST *zero = make<LiteralNumber>(E, EF, "0.0");
  420|   319k|        AST *one = make<LiteralNumber>(E, EF, "1.0");
  421|   319k|        auto *_r = id(U"$r");
  422|   319k|        auto *_l = id(U"$l");
  423|   319k|        std::vector<const Identifier *> _i(n);
  424|   854k|        for (int i = 0; i < n; ++i) {
  ------------------
  |  Branch (424:25): [True: 534k, False: 319k]
  ------------------
  425|   534k|            UStringStream ss;
  426|   534k|            ss << U"$i_" << i;
  427|   534k|            _i[i] = id(ss.str());
  428|   534k|        }
  429|   319k|        std::vector<const Identifier *> _aux(n);
  430|   854k|        for (int i = 0; i < n; ++i) {
  ------------------
  |  Branch (430:25): [True: 534k, False: 319k]
  ------------------
  431|   534k|            UStringStream ss;
  432|   534k|            ss << U"$aux_" << i;
  433|   534k|            _aux[i] = id(ss.str());
  434|   534k|        }
  435|       |
  436|       |        // Build it from the inside out.  We keep wrapping 'in' with more ASTs.
  437|   319k|        assert(ast->specs[0].kind == ComprehensionSpec::FOR);
  ------------------
  |  Branch (437:9): [True: 319k, False: 0]
  ------------------
  438|       |
  439|   319k|        int last_for = n - 1;
  440|   505k|        while (ast->specs[last_for].kind != ComprehensionSpec::FOR)
  ------------------
  |  Branch (440:16): [True: 185k, False: 319k]
  ------------------
  441|   185k|            last_for--;
  442|       |        // $aux_{last_for}($i_{last_for} + 1, $r + [body])
  443|   319k|        AST *in = make<Apply>(
  444|   319k|            ast->body->location,
  445|   319k|            EF,
  446|   319k|            var(_aux[last_for]),
  447|   319k|            EF,
  448|   319k|            ArgParams{{make<Binary>(E, EF, var(_i[last_for]), EF, BOP_PLUS, one), EF},
  449|   319k|                {make<Binary>(E, EF, var(_r), EF, BOP_PLUS, singleton(ast->body)), EF}},
  450|   319k|            false,  // trailingComma
  451|   319k|            EF,
  452|   319k|            EF,
  453|   319k|            true  // tailstrict
  454|   319k|        );
  455|   854k|        for (int i = n - 1; i >= 0; --i) {
  ------------------
  |  Branch (455:29): [True: 534k, False: 319k]
  ------------------
  456|   534k|            const ComprehensionSpec &spec = ast->specs[i];
  457|   534k|            AST *out;
  458|   534k|            if (i > 0) {
  ------------------
  |  Branch (458:17): [True: 215k, False: 319k]
  ------------------
  459|   215k|                int prev_for = i - 1;
  460|  1.03G|                while (ast->specs[prev_for].kind != ComprehensionSpec::FOR)
  ------------------
  |  Branch (460:24): [True: 1.03G, False: 215k]
  ------------------
  461|  1.03G|                    prev_for--;
  462|       |
  463|       |                // aux_{prev_for}($i_{prev_for} + 1, $r)
  464|   215k|                out = make<Apply>(  // False branch.
  465|   215k|                    E,
  466|   215k|                    EF,
  467|   215k|                    var(_aux[prev_for]),
  468|   215k|                    EF,
  469|   215k|                    ArgParams{{
  470|   215k|                        make<Binary>(E, EF, var(_i[prev_for]), EF, BOP_PLUS, one),
  471|   215k|                            EF,
  472|   215k|                            },
  473|   215k|                      {
  474|   215k|                        var(_r),
  475|   215k|                            EF,
  476|   215k|                            }},
  477|   215k|                    false,  // trailingComma
  478|   215k|                    EF,
  479|   215k|                    EF,
  480|   215k|                    true  // tailstrict
  481|   215k|                );
  482|   319k|            } else {
  483|   319k|                out = var(_r);
  484|   319k|            }
  485|   534k|            switch (spec.kind) {
  ------------------
  |  Branch (485:21): [True: 534k, False: 0]
  ------------------
  486|   185k|                case ComprehensionSpec::IF: {
  ------------------
  |  Branch (486:17): [True: 185k, False: 348k]
  ------------------
  487|       |                  /*
  488|       |                    if [[[...cond...]]] then
  489|       |                    [[[...in...]]]
  490|       |                    else
  491|       |                    [[[...out...]]]
  492|       |                  */
  493|   185k|                    in = make<Conditional>(ast->location,
  494|   185k|                                           EF,
  495|   185k|                                           spec.expr,
  496|   185k|                                           EF,
  497|   185k|                                           in,  // True branch.
  498|   185k|                                           EF,
  499|   185k|                                           out);  // False branch.
  500|   185k|                } break;
  501|   348k|                case ComprehensionSpec::FOR: {
  ------------------
  |  Branch (501:17): [True: 348k, False: 185k]
  ------------------
  502|       |                    /*
  503|       |                      local $l = [[[...array...]]]
  504|       |                      aux_{i}(i_{i}, r) =
  505|       |                      if i_{i} >= std.length($l) then
  506|       |                      [[[...out...]]]
  507|       |                      else
  508|       |                      local [[[...var...]]] = $l[i_{i}];
  509|       |                      [[[...in...]]];
  510|       |                      if std.type($l) == "array" then
  511|       |                      aux_{i}(0, $r) tailstrict
  512|       |                      else
  513|       |                      error "In comprehension, can only iterate over array..";
  514|       |                    */
  515|   348k|                    in = make<Local>(
  516|   348k|                        ast->location,
  517|   348k|                        EF,
  518|   348k|                        Local::Binds{
  519|   348k|                          bind(_l, spec.expr),  // Need to check expr is an array
  520|   348k|                              bind(_aux[i],
  521|   348k|                                   make<Function>(
  522|   348k|                                       ast->location,
  523|   348k|                                       EF,
  524|   348k|                                       EF,
  525|   348k|                                       ArgParams{{EF, _i[i], EF}, {EF, _r, EF}},
  526|   348k|                                       false,  // trailingComma
  527|   348k|                                       EF,
  528|   348k|                                       make<Conditional>(ast->location,
  529|   348k|                                                         EF,
  530|   348k|                                                         make<Binary>(E,
  531|   348k|                                                                      EF,
  532|   348k|                                                                      var(_i[i]),
  533|   348k|                                                                      EF,
  534|   348k|                                                                      BOP_GREATER_EQ,
  535|   348k|                                                                      length(var(_l))),
  536|   348k|                                                         EF,
  537|   348k|                                                         out,
  538|   348k|                                                         EF,
  539|   348k|                                                         make<Local>(
  540|   348k|                                                             ast->location,
  541|   348k|                                                             EF,
  542|   348k|                                                             singleBind(spec.var,
  543|   348k|                                                                        make<Index>(E,
  544|   348k|                                                                                    EF,
  545|   348k|                                                                                    var(_l),
  546|   348k|                                                                                    EF,
  547|   348k|                                                                                    false,
  548|   348k|                                                                                    var(_i[i]),
  549|   348k|                                                                                    EF,
  550|   348k|                                                                                    nullptr,
  551|   348k|                                                                                    EF,
  552|   348k|                                                                                    nullptr,
  553|   348k|                                                                                    EF)),
  554|   348k|                                                             in))))},
  555|   348k|                        make<Conditional>(
  556|   348k|                            ast->location,
  557|   348k|                            EF,
  558|   348k|                            equals(ast->location, type(var(_l)), str(U"array")),
  559|   348k|                            EF,
  560|   348k|                            make<Apply>(
  561|   348k|                                E,
  562|   348k|                                EF,
  563|   348k|                                var(_aux[i]),
  564|   348k|                                EF,
  565|   348k|                                ArgParams{{zero, EF},
  566|   348k|                                  {
  567|   348k|                                    i == 0 ? make<Array>(
  ------------------
  |  Branch (567:37): [True: 319k, False: 29.2k]
  ------------------
  568|   319k|                                        E, EF, Array::Elements{}, false, EF)
  569|   348k|                                        : static_cast<AST *>(var(_r)),
  570|   348k|                                        EF,
  571|   348k|                                        }},
  572|   348k|                                false,  // trailingComma
  573|   348k|                                EF,
  574|   348k|                                EF,
  575|   348k|                                true),  // tailstrict
  576|   348k|                            EF,
  577|   348k|                            error(ast->location,
  578|   348k|                                  U"In comprehension, can only iterate over array.")));
  579|   348k|                } break;
  580|   534k|            }
  581|   534k|        }
  582|       |
  583|   319k|        return in;
  584|   319k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_13LiteralNumberEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERA4_KcEEEPT_DpOT0_:
  110|   678k|    {
  111|   678k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   678k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ApplyEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_3VarESD_NS7_INS0_8ArgParamENS9_ISG_EEEEbSD_SD_bEEEPT_DpOT0_:
  110|   319k|    {
  111|   319k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   319k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_6BinaryEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS0_8BinaryOpERPNS0_3ASTEEEEPT_DpOT0_:
  110|   534k|    {
  111|   534k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   534k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_6BinaryEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS0_8BinaryOpEPNS0_5ArrayEEEEPT_DpOT0_:
  110|   319k|    {
  111|   319k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   319k|    }
_ZN7jsonnet8internal9Desugarer9singletonEPNS0_3ASTE:
  163|   319k|    {
  164|   319k|        return make<Array>(
  165|   319k|            body->location, EF, Array::Elements{Array::Element(body, EF)}, false, EF);
  166|   319k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ArrayEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_7ElementENS9_ISE_EEEEbSD_EEEPT_DpOT0_:
  110|   319k|    {
  111|   319k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   319k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ApplyEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS8_INS0_8ArgParamENSA_ISH_EEEEbSE_SE_bEEEPT_DpOT0_:
  110|   563k|    {
  111|   563k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   563k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERKPNS0_3ASTESD_RSF_SD_SI_EEEPT_DpOT0_:
  110|   185k|    {
  111|   185k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   185k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5LocalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_4BindENS9_ISE_EEEEPNS0_11ConditionalEEEEPT_DpOT0_:
  110|   348k|    {
  111|   348k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   348k|    }
_ZN7jsonnet8internal9Desugarer4bindEPKNS0_10IdentifierEPNS0_3ASTE:
  153|  1.45M|    {
  154|  1.45M|        return Local::Bind(EF, id, EF, body, false, EF, ArgParams{}, false, EF, EF);
  155|  1.45M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_8FunctionEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEESD_NS7_INS0_8ArgParamENS9_ISE_EEEEbSD_PNS0_11ConditionalEEEEPT_DpOT0_:
  110|   348k|    {
  111|   348k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   348k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_6BinaryESD_RPNS0_3ASTESD_PNS0_5LocalEEEEPT_DpOT0_:
  110|   348k|    {
  111|   348k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   348k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_6BinaryEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_NS0_8BinaryOpEPNS0_5ApplyEEEEPT_DpOT0_:
  110|   348k|    {
  111|   348k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   348k|    }
_ZN7jsonnet8internal9Desugarer6lengthEPNS0_3ASTE:
  199|   348k|    {
  200|   348k|        return stdFunc(U"length", v);
  201|   348k|    }
_ZN7jsonnet8internal9Desugarer7stdFuncERKNSt3__112basic_stringIDiNS2_11char_traitsIDiEENS2_9allocatorIDiEEEEPNS0_3ASTE:
  169|   702k|    {
  170|   702k|        return make<Apply>(
  171|   702k|            v->location,
  172|   702k|            EF,
  173|   702k|            make<Index>(E, EF, std(), EF, false, str(name), EF, nullptr, EF, nullptr, EF),
  174|   702k|            EF,
  175|   702k|            ArgParams{{v, EF}},
  176|   702k|            false,  // trailingComma
  177|   702k|            EF,
  178|   702k|            EF,
  179|   702k|            true  // tailstrict
  180|   702k|        );
  181|   702k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5LocalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_4BindENS9_ISE_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  110|   358k|    {
  111|   358k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   358k|    }
_ZN7jsonnet8internal9Desugarer10singleBindEPKNS0_10IdentifierEPNS0_3ASTE:
  158|   362k|    {
  159|   362k|        return {bind(id, body)};
  160|   362k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bSG_SE_DnSE_DnSE_EEEPT_DpOT0_:
  110|   348k|    {
  111|   348k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   348k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_5ApplyESD_SF_SD_PNS0_5ErrorEEEEPT_DpOT0_:
  110|   348k|    {
  111|   348k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   348k|    }
_ZN7jsonnet8internal9Desugarer4typeEPNS0_3ASTE:
  204|   353k|    {
  205|   353k|        return stdFunc(U"type", v);
  206|   353k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ArrayEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEENS8_INS3_7ElementENSA_ISF_EEEEbSE_EEEPT_DpOT0_:
  110|   319k|    {
  111|   319k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   319k|    }
_ZN7jsonnet8internal9Desugarer5errorERKNS0_13LocationRangeERKNSt3__112basic_stringIDiNS5_11char_traitsIDiEENS5_9allocatorIDiEEEE:
  224|   348k|    {
  225|   348k|        return error(str(loc, msg));
  226|   348k|    }
_ZN7jsonnet8internal9Desugarer5errorEPNS0_3ASTE:
  219|   398k|    {
  220|   398k|        return make<Error>(msg->location, EF, msg);
  221|   398k|    }
_ZN7jsonnet8internal9Desugarer3strERKNS0_13LocationRangeERKNSt3__112basic_stringIDiNS5_11char_traitsIDiEENS5_9allocatorIDiEEEE:
  130|  2.34M|    {
  131|  2.34M|        return make<LiteralString>(loc, EF, s, LiteralString::RAW_DESUGARED, "", "");
  132|  2.34M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_13LiteralStringEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERKNS7_12basic_stringIDiNS7_11char_traitsIDiEENSA_IDiEEEENS3_9TokenKindERA1_KcSP_EEEPT_DpOT0_:
  110|  12.4M|    {
  111|  12.4M|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  12.4M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ErrorEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  110|   757k|    {
  111|   757k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   757k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_11ConditionalEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTERKSB_SF_SH_SF_EEEPT_DpOT0_:
  110|   359k|    {
  111|   359k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   359k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bPNS0_13LiteralStringESE_DnSE_DnSE_EEEPT_DpOT0_:
  110|  3.07M|    {
  111|  3.07M|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  3.07M|    }
_ZN7jsonnet8internal9Desugarer3stdEv:
  145|  3.08M|    {
  146|       |        // In most places, there is a "$std" variable inserted by
  147|       |        // the desugarer. On the standard library itself there isn't,
  148|       |        // so use "std" instead.
  149|  3.08M|        return var(id(isStdlib ? U"std" : U"$std"));
  ------------------
  |  Branch (149:23): [True: 1.39M, False: 1.69M]
  ------------------
  150|  3.08M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ApplyEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTERKSB_RNS7_INS0_8ArgParamENS9_ISI_EEEEbSH_SH_bEEEPT_DpOT0_:
  110|   270k|    {
  111|   270k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   270k|    }
_ZN7jsonnet8internal9Desugarer6equalsERKNS0_13LocationRangeEPNS0_3ASTES6_:
  214|  1.93M|    {
  215|  1.93M|        return stdFunc(loc, U"equals", a, b);
  216|  1.93M|    }
_ZN7jsonnet8internal9Desugarer7stdFuncERKNS0_13LocationRangeERKNSt3__112basic_stringIDiNS5_11char_traitsIDiEENS5_9allocatorIDiEEEEPNS0_3ASTESF_:
  184|  1.94M|    {
  185|  1.94M|        return make<Apply>(
  186|  1.94M|            loc,
  187|  1.94M|            EF,
  188|  1.94M|            make<Index>(E, EF, std(), EF, false, str(name), EF, nullptr, EF, nullptr, EF),
  189|  1.94M|            EF,
  190|  1.94M|            ArgParams{{a, EF}, {b, EF}},
  191|  1.94M|            false,  // trailingComma
  192|  1.94M|            EF,
  193|  1.94M|            EF,
  194|  1.94M|            true  // tailstrict
  195|  1.94M|        );
  196|  1.94M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ApplyEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_5IndexESE_NS8_INS0_8ArgParamENSA_ISH_EEEEbSE_SE_bEEEPT_DpOT0_:
  110|  1.94M|    {
  111|  1.94M|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  1.94M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5UnaryEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS0_7UnaryOpERPNS0_3ASTEEEEPT_DpOT0_:
  110|   212k|    {
  111|   212k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   212k|    }
_ZN7jsonnet8internal9Desugarer4nullEv:
  135|   295k|    {
  136|   295k|        return make<LiteralNull>(E, EF);
  137|   295k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_11LiteralNullEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEEEEPT_DpOT0_:
  110|   295k|    {
  111|   295k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   295k|    }
_ZN7jsonnet8internal9Desugarer3varEPKNS0_10IdentifierE:
  140|  7.29M|    {
  141|  7.29M|        return make<Var>(E, EF, ident);
  142|  7.29M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_3VarEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERPKNS0_10IdentifierEEEEPT_DpOT0_:
  110|  7.29M|    {
  111|  7.29M|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  7.29M|    }
_ZN7jsonnet8internal9Desugarer2idERKNSt3__112basic_stringIDiNS2_11char_traitsIDiEENS2_9allocatorIDiEEEE:
  120|  5.49M|    {
  121|  5.49M|        return alloc->makeIdentifier(s);
  122|  5.49M|    }
_ZN7jsonnet8internal9Desugarer13desugarParamsERNSt3__16vectorINS0_8ArgParamENS2_9allocatorIS4_EEEEj:
  232|  3.14M|    {
  233|  3.93M|        for (auto &param : params) {
  ------------------
  |  Branch (233:26): [True: 3.93M, False: 3.14M]
  ------------------
  234|  3.93M|            if (param.expr) {
  ------------------
  |  Branch (234:17): [True: 186k, False: 3.74M]
  ------------------
  235|       |                // Default arg.
  236|   186k|                desugar(param.expr, obj_level);
  237|   186k|            }
  238|  3.93M|        }
  239|  3.14M|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ApplyEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_5IndexESD_NS7_INS0_8ArgParamENS9_ISG_EEEEbSD_SD_bEEEPT_DpOT0_:
  110|   862k|    {
  111|   862k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   862k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_8FunctionEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEESC_RNS7_INS0_8ArgParamENS9_ISD_EEEEbSC_RPNS0_3ASTEEEEPT_DpOT0_:
  110|   648k|    {
  111|   648k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   648k|    }
_ZN7jsonnet8internal9Desugarer10makeObjectEPNS0_6ObjectEj:
  586|   490k|    AST* makeObject(Object *ast, unsigned obj_level) {
  587|       |        // Hidden variable to allow outer/top binding.
  588|   490k|        if (obj_level == 0) {
  ------------------
  |  Branch (588:13): [True: 29.8k, False: 461k]
  ------------------
  589|  29.8k|            const Identifier *hidden_var = id(U"$");
  590|  29.8k|            auto *body = make<Self>(E, EF);
  591|  29.8k|            ast->fields.push_back(ObjectField::Local(EF, EF, hidden_var, EF, body, EF));
  592|  29.8k|        }
  593|       |
  594|   490k|        SuperVars svs = desugarFields(ast, ast->fields, obj_level);
  595|       |
  596|   490k|        DesugaredObject::Fields new_fields;
  597|   490k|        ASTs new_asserts;
  598|  2.14M|        for (const ObjectField &field : ast->fields) {
  ------------------
  |  Branch (598:39): [True: 2.14M, False: 490k]
  ------------------
  599|  2.14M|            if (field.kind == ObjectField::ASSERT) {
  ------------------
  |  Branch (599:17): [True: 49.3k, False: 2.09M]
  ------------------
  600|  49.3k|                new_asserts.push_back(field.expr2);
  601|  2.09M|            } else if (field.kind == ObjectField::FIELD_EXPR) {
  ------------------
  |  Branch (601:24): [True: 2.09M, False: 0]
  ------------------
  602|  2.09M|                new_fields.emplace_back(field.hide, field.expr1, field.expr2);
  603|  2.09M|            } else {
  604|      0|                std::cerr << "INTERNAL ERROR: field should have been desugared: " << field.kind
  605|      0|                          << std::endl;
  606|      0|            }
  607|  2.14M|        }
  608|       |
  609|   490k|        AST* retval = make<DesugaredObject>(ast->location, new_asserts, new_fields);
  610|   490k|        if (svs.size() > 0) {
  ------------------
  |  Branch (610:13): [True: 2.61k, False: 488k]
  ------------------
  611|  2.61k|            Local::Binds binds;
  612|   257k|            for (const auto &pair : svs) {
  ------------------
  |  Branch (612:35): [True: 257k, False: 2.61k]
  ------------------
  613|   257k|                if (pair.second == nullptr) {
  ------------------
  |  Branch (613:21): [True: 491, False: 257k]
  ------------------
  614|       |                    // Self binding
  615|    491|                    binds.push_back(bind(pair.first, make<Self>(E, EF)));
  616|   257k|                } else {
  617|       |                    // Super binding
  618|   257k|                    binds.push_back(bind(pair.first, pair.second));
  619|   257k|                }
  620|   257k|            }
  621|  2.61k|            retval = make<Local>(ast->location, EF, binds, retval);
  622|  2.61k|        }
  623|       |
  624|   490k|        return retval;
  625|   490k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_4SelfEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEEEEPT_DpOT0_:
  110|  30.7k|    {
  111|  30.7k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  30.7k|    }
_ZN7jsonnet8internal9Desugarer13desugarFieldsEPNS0_3ASTERNSt3__16vectorINS0_11ObjectFieldENS4_9allocatorIS6_EEEEj:
  246|   529k|    {
  247|       |        // Desugar children
  248|  2.27M|        for (auto &field : fields) {
  ------------------
  |  Branch (248:26): [True: 2.27M, False: 529k]
  ------------------
  249|  2.27M|            if (field.expr1 != nullptr)
  ------------------
  |  Branch (249:17): [True: 150k, False: 2.12M]
  ------------------
  250|   150k|                desugar(field.expr1, obj_level);
  251|  2.27M|            desugar(field.expr2, obj_level + 1);
  252|  2.27M|            if (field.expr3 != nullptr)
  ------------------
  |  Branch (252:17): [True: 38.7k, False: 2.23M]
  ------------------
  253|  38.7k|                desugar(field.expr3, obj_level + 1);
  254|  2.27M|            desugarParams(field.params, obj_level + 1);
  255|  2.27M|        }
  256|       |
  257|       |        // Simplify asserts
  258|  2.27M|        for (auto &field : fields) {
  ------------------
  |  Branch (258:26): [True: 2.27M, False: 529k]
  ------------------
  259|  2.27M|            if (field.kind != ObjectField::ASSERT)
  ------------------
  |  Branch (259:17): [True: 2.22M, False: 49.3k]
  ------------------
  260|  2.22M|                continue;
  261|  49.3k|            AST *msg = field.expr3;
  262|  49.3k|            field.expr3 = nullptr;
  263|  49.3k|            if (msg == nullptr) {
  ------------------
  |  Branch (263:17): [True: 10.5k, False: 38.7k]
  ------------------
  264|       |                // The location is what appears in the stacktrace.
  265|  10.5k|                msg = str(field.expr2->location, U"Object assertion failed.");
  266|  10.5k|            }
  267|       |
  268|       |            // if expr2 then true else error msg
  269|  49.3k|            field.expr2 = make<Conditional>(field.expr2->location,
  270|  49.3k|                                            EF,
  271|  49.3k|                                            field.expr2,
  272|  49.3k|                                            EF,
  273|  49.3k|                                            make<LiteralBoolean>(E, EF, true),
  274|  49.3k|                                            EF,
  275|  49.3k|                                            error(msg));
  276|  49.3k|        }
  277|       |
  278|       |        // Remove methods
  279|  2.27M|        for (auto &field : fields) {
  ------------------
  |  Branch (279:26): [True: 2.27M, False: 529k]
  ------------------
  280|  2.27M|            if (!field.methodSugar)
  ------------------
  |  Branch (280:17): [True: 1.17M, False: 1.10M]
  ------------------
  281|  1.17M|                continue;
  282|  1.10M|            field.expr2 = make<Function>(field.expr2->location,
  283|  1.10M|                                         EF,
  284|  1.10M|                                         field.fodderL,
  285|  1.10M|                                         field.params,
  286|  1.10M|                                         field.trailingComma,
  287|  1.10M|                                         field.fodderR,
  288|  1.10M|                                         field.expr2);
  289|  1.10M|            field.methodSugar = false;
  290|  1.10M|            field.params.clear();
  291|  1.10M|        }
  292|       |
  293|       |        // Remove object-level locals
  294|   529k|        auto copy = fields;
  295|   529k|        fields.clear();
  296|   529k|        Local::Binds binds;
  297|  2.27M|        for (auto &local : copy) {
  ------------------
  |  Branch (297:26): [True: 2.27M, False: 529k]
  ------------------
  298|  2.27M|            if (local.kind != ObjectField::LOCAL)
  ------------------
  |  Branch (298:17): [True: 2.18M, False: 91.7k]
  ------------------
  299|  2.18M|                continue;
  300|  91.7k|            binds.push_back(bind(local.id, local.expr2));
  301|  91.7k|        }
  302|  2.27M|        for (auto &field : copy) {
  ------------------
  |  Branch (302:26): [True: 2.27M, False: 529k]
  ------------------
  303|  2.27M|            if (field.kind == ObjectField::LOCAL)
  ------------------
  |  Branch (303:17): [True: 91.7k, False: 2.18M]
  ------------------
  304|  91.7k|                continue;
  305|  2.18M|            if (!binds.empty())
  ------------------
  |  Branch (305:17): [True: 1.16M, False: 1.01M]
  ------------------
  306|  1.16M|                field.expr2 = make<Local>(field.expr2->location, EF, binds, field.expr2);
  307|  2.18M|            fields.push_back(field);
  308|  2.18M|        }
  309|       |
  310|       |        // Change all to FIELD_EXPR
  311|  2.18M|        for (auto &field : fields) {
  ------------------
  |  Branch (311:26): [True: 2.18M, False: 529k]
  ------------------
  312|  2.18M|            switch (field.kind) {
  ------------------
  |  Branch (312:21): [True: 2.18M, False: 0]
  ------------------
  313|  49.3k|                case ObjectField::ASSERT:
  ------------------
  |  Branch (313:17): [True: 49.3k, False: 2.13M]
  ------------------
  314|       |                    // Nothing to do.
  315|  49.3k|                    break;
  316|       |
  317|  1.98M|                case ObjectField::FIELD_ID:
  ------------------
  |  Branch (317:17): [True: 1.98M, False: 200k]
  ------------------
  318|  1.98M|                    field.expr1 = str(field.idLocation, field.id->name);
  319|  1.98M|                    field.kind = ObjectField::FIELD_EXPR;
  320|  1.98M|                    break;
  321|       |
  322|  42.6k|                case ObjectField::FIELD_EXPR:
  ------------------
  |  Branch (322:17): [True: 42.6k, False: 2.14M]
  ------------------
  323|       |                    // Nothing to do.
  324|  42.6k|                    break;
  325|       |
  326|   108k|                case ObjectField::FIELD_STR:
  ------------------
  |  Branch (326:17): [True: 108k, False: 2.07M]
  ------------------
  327|       |                    // Just set the flag.
  328|   108k|                    field.kind = ObjectField::FIELD_EXPR;
  329|   108k|                    break;
  330|       |
  331|      0|                case ObjectField::LOCAL:
  ------------------
  |  Branch (331:17): [True: 0, False: 2.18M]
  ------------------
  332|      0|                    std::cerr << "Locals should be removed by now." << std::endl;
  333|      0|                    abort();
  334|  2.18M|            }
  335|  2.18M|        }
  336|       |
  337|       |        /** Replaces all occurrences of self, super[f] and e in super with variables.
  338|       |         *
  339|       |         * Returns all variables and original expressions via super_vars.
  340|       |         */
  341|   529k|        class SubstituteSelfSuper : public CompilerPass {
  342|   529k|            Desugarer *desugarer;
  343|   529k|            SuperVars &superVars;
  344|   529k|            unsigned &counter;
  345|   529k|            const Identifier *newSelf;
  346|       |
  347|   529k|           public:
  348|   529k|            SubstituteSelfSuper(Desugarer *desugarer, SuperVars &super_vars, unsigned &counter)
  349|   529k|                : CompilerPass(*desugarer->alloc),
  350|   529k|                  desugarer(desugarer),
  351|   529k|                  superVars(super_vars),
  352|   529k|                  counter(counter),
  353|   529k|                  newSelf(nullptr)
  354|   529k|            {
  355|   529k|            }
  356|   529k|            void visitExpr(AST *&expr)
  357|   529k|            {
  358|   529k|                if (dynamic_cast<Self *>(expr)) {
  359|   529k|                    if (newSelf == nullptr) {
  360|   529k|                        newSelf = desugarer->id(U"$outer_self");
  361|   529k|                        superVars.emplace_back(newSelf, nullptr);
  362|   529k|                    }
  363|   529k|                    expr = alloc.make<Var>(expr->location, expr->openFodder, newSelf);
  364|   529k|                } else if (auto *super_index = dynamic_cast<SuperIndex *>(expr)) {
  365|   529k|                    UStringStream ss;
  366|   529k|                    ss << U"$outer_super_index" << (counter++);
  367|   529k|                    const Identifier *super_var = desugarer->id(ss.str());
  368|       |                    // Desugaring of expr should already have occurred.
  369|   529k|                    assert(super_index->index != nullptr);
  370|       |                    // Re-use super_index since we're replacing it here.
  371|   529k|                    superVars.emplace_back(super_var, super_index);
  372|   529k|                    expr = alloc.make<Var>(expr->location, expr->openFodder, super_var);
  373|   529k|                } else if (auto *in_super = dynamic_cast<InSuper *>(expr)) {
  374|   529k|                    UStringStream ss;
  375|   529k|                    ss << U"$outer_in_super" << (counter++);
  376|   529k|                    const Identifier *in_super_var = desugarer->id(ss.str());
  377|       |                    // Re-use in_super since we're replacing it here.
  378|   529k|                    superVars.emplace_back(in_super_var, in_super);
  379|   529k|                    expr = alloc.make<Var>(expr->location, expr->openFodder, in_super_var);
  380|   529k|                }
  381|   529k|                CompilerPass::visitExpr(expr);
  382|   529k|            }
  383|   529k|        };
  384|       |
  385|   529k|        SuperVars super_vars;
  386|   529k|        unsigned counter = 0;
  387|       |
  388|       |        // Remove +:
  389|  2.18M|        for (auto &field : fields) {
  ------------------
  |  Branch (389:26): [True: 2.18M, False: 529k]
  ------------------
  390|  2.18M|            if (!field.superSugar)
  ------------------
  |  Branch (390:17): [True: 2.16M, False: 16.8k]
  ------------------
  391|  2.16M|                continue;
  392|       |            // We have to bind self/super from expr1 outside the class, as we copy the expression
  393|       |            // into the field body.
  394|       |            // Clone it so that we maintain the AST as a tree.
  395|  16.8k|            AST *index = clone(field.expr1);
  396|       |            // This will remove self/super.
  397|  16.8k|            SubstituteSelfSuper(this, super_vars, counter).expr(index);
  398|  16.8k|            field.expr2 = make<Conditional>(
  399|  16.8k|                ast->location,
  400|  16.8k|                EF,
  401|  16.8k|                make<InSuper>(ast->location, EF, index, EF, EF),
  402|  16.8k|                EF,
  403|  16.8k|                make<Binary>(ast->location,
  404|  16.8k|                             EF,
  405|  16.8k|                             make<SuperIndex>(ast->location, EF, EF, clone(index), EF, nullptr),
  406|  16.8k|                             EF,
  407|  16.8k|                             BOP_PLUS,
  408|  16.8k|                             field.expr2),
  409|  16.8k|                EF,
  410|  16.8k|                clone(field.expr2));
  411|  16.8k|            field.superSugar = false;
  412|  16.8k|        }
  413|       |
  414|   529k|        return super_vars;
  415|   529k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTESD_PNS0_14LiteralBooleanESD_PNS0_5ErrorEEEEPT_DpOT0_:
  110|  49.3k|    {
  111|  49.3k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  49.3k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_14LiteralBooleanEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEbEEEPT_DpOT0_:
  110|  49.3k|    {
  111|  49.3k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  49.3k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_8FunctionEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERSB_RNS7_INS0_8ArgParamENS9_ISF_EEEERbSE_RPNS0_3ASTEEEEPT_DpOT0_:
  110|  1.10M|    {
  111|  1.10M|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  1.10M|    }
_ZN7jsonnet8internal9Desugarer5cloneEPNS0_3ASTE:
  115|  50.4k|    {
  116|  50.4k|        return clone_ast(*alloc, ast);
  117|  50.4k|    }
_ZZN7jsonnet8internal9Desugarer13desugarFieldsEPNS0_3ASTERNSt3__16vectorINS0_11ObjectFieldENS4_9allocatorIS6_EEEEjEN19SubstituteSelfSuperC2EPS1_RNS5_INS4_4pairIPKNS0_10IdentifierES3_EENS7_ISH_EEEERj:
  349|  16.8k|                : CompilerPass(*desugarer->alloc),
  350|  16.8k|                  desugarer(desugarer),
  351|  16.8k|                  superVars(super_vars),
  352|  16.8k|                  counter(counter),
  353|  16.8k|                  newSelf(nullptr)
  354|  16.8k|            {
  355|  16.8k|            }
_ZZN7jsonnet8internal9Desugarer13desugarFieldsEPNS0_3ASTERNSt3__16vectorINS0_11ObjectFieldENS4_9allocatorIS6_EEEEjEN19SubstituteSelfSuper9visitExprERS3_:
  357|  1.45M|            {
  358|  1.45M|                if (dynamic_cast<Self *>(expr)) {
  ------------------
  |  Branch (358:21): [True: 3.87k, False: 1.45M]
  ------------------
  359|  3.87k|                    if (newSelf == nullptr) {
  ------------------
  |  Branch (359:25): [True: 596, False: 3.28k]
  ------------------
  360|    596|                        newSelf = desugarer->id(U"$outer_self");
  361|    596|                        superVars.emplace_back(newSelf, nullptr);
  362|    596|                    }
  363|  3.87k|                    expr = alloc.make<Var>(expr->location, expr->openFodder, newSelf);
  364|  1.45M|                } else if (auto *super_index = dynamic_cast<SuperIndex *>(expr)) {
  ------------------
  |  Branch (364:34): [True: 144k, False: 1.30M]
  ------------------
  365|   144k|                    UStringStream ss;
  366|   144k|                    ss << U"$outer_super_index" << (counter++);
  367|   144k|                    const Identifier *super_var = desugarer->id(ss.str());
  368|       |                    // Desugaring of expr should already have occurred.
  369|   144k|                    assert(super_index->index != nullptr);
  ------------------
  |  Branch (369:21): [True: 144k, False: 0]
  ------------------
  370|       |                    // Re-use super_index since we're replacing it here.
  371|   144k|                    superVars.emplace_back(super_var, super_index);
  372|   144k|                    expr = alloc.make<Var>(expr->location, expr->openFodder, super_var);
  373|  1.30M|                } else if (auto *in_super = dynamic_cast<InSuper *>(expr)) {
  ------------------
  |  Branch (373:34): [True: 143k, False: 1.16M]
  ------------------
  374|   143k|                    UStringStream ss;
  375|   143k|                    ss << U"$outer_in_super" << (counter++);
  376|   143k|                    const Identifier *in_super_var = desugarer->id(ss.str());
  377|       |                    // Re-use in_super since we're replacing it here.
  378|   143k|                    superVars.emplace_back(in_super_var, in_super);
  379|   143k|                    expr = alloc.make<Var>(expr->location, expr->openFodder, in_super_var);
  380|   143k|                }
  381|  1.45M|                CompilerPass::visitExpr(expr);
  382|  1.45M|            }
_ZN7jsonnet8internal9Desugarer4makeINS0_11ConditionalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_7InSuperESD_PNS0_6BinaryESD_PNS0_3ASTEEEEPT_DpOT0_:
  110|  16.8k|    {
  111|  16.8k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  16.8k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_7InSuperEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERPNS0_3ASTESD_SD_EEEPT_DpOT0_:
  110|  16.8k|    {
  111|  16.8k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  16.8k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_6BinaryEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_10SuperIndexESD_NS0_8BinaryOpERPNS0_3ASTEEEEPT_DpOT0_:
  110|  16.8k|    {
  111|  16.8k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  16.8k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_10SuperIndexEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEESD_PNS0_3ASTESD_DnEEEPT_DpOT0_:
  110|  16.8k|    {
  111|  16.8k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  16.8k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_15DesugaredObjectEJRNS0_13LocationRangeERNSt3__14listIPNS0_3ASTENS6_9allocatorIS9_EEEERNS6_6vectorINS3_5FieldENSA_ISF_EEEEEEEPT_DpOT0_:
  110|   490k|    {
  111|   490k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   490k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5LocalEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERNS7_INS3_4BindENS9_ISE_EEEERPNS0_3ASTEEEEPT_DpOT0_:
  110|  1.21M|    {
  111|  1.21M|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  1.21M|    }
_ZN7jsonnet8internal9Desugarer23makeObjectComprehensionEPNS0_19ObjectComprehensionEj:
  627|  39.0k|    AST* makeObjectComprehension(ObjectComprehension *ast, unsigned obj_level) {
  628|       |        // Hidden variable to allow outer/top binding.
  629|  39.0k|        if (obj_level == 0) {
  ------------------
  |  Branch (629:13): [True: 415, False: 38.5k]
  ------------------
  630|    415|            const Identifier *hidden_var = id(U"$");
  631|    415|            auto *body = make<Self>(E, EF);
  632|    415|            ast->fields.push_back(ObjectField::Local(EF, EF, hidden_var, EF, body, EF));
  633|    415|        }
  634|       |
  635|  39.0k|        SuperVars svs = desugarFields(ast, ast->fields, obj_level);
  636|       |
  637|  39.0k|        AST *field = ast->fields.front().expr1;
  638|  39.0k|        AST *value = ast->fields.front().expr2;
  639|       |
  640|       |        /*  {
  641|       |            [arr[0]]: local x = arr[1], y = arr[2], z = arr[3]; val_expr
  642|       |            for arr in [ [key_expr, x, y, z] for ...  ]
  643|       |            }
  644|       |        */
  645|  39.0k|        auto *_arr = id(U"$arr");
  646|  39.0k|        AST *zero = make<LiteralNumber>(E, EF, "0.0");
  647|  39.0k|        int counter = 1;
  648|  39.0k|        Local::Binds binds;
  649|  39.0k|        Array::Elements arr_e{Array::Element(field, EF)};
  650|  50.5k|        for (ComprehensionSpec &spec : ast->specs) {
  ------------------
  |  Branch (650:38): [True: 50.5k, False: 39.0k]
  ------------------
  651|  50.5k|            if (spec.kind == ComprehensionSpec::FOR) {
  ------------------
  |  Branch (651:17): [True: 41.4k, False: 9.13k]
  ------------------
  652|  41.4k|                std::stringstream num;
  653|  41.4k|                num << counter++;
  654|  41.4k|                binds.push_back(bind(spec.var,
  655|  41.4k|                                     make<Index>(E,
  656|  41.4k|                                                 EF,
  657|  41.4k|                                                 var(_arr),
  658|  41.4k|                                                 EF,
  659|  41.4k|                                                 false,
  660|  41.4k|                                                 make<LiteralNumber>(E, EF, num.str()),
  661|  41.4k|                                                 EF,
  662|  41.4k|                                                 nullptr,
  663|  41.4k|                                                 EF,
  664|  41.4k|                                                 nullptr,
  665|  41.4k|                                                 EF)));
  666|  41.4k|                arr_e.emplace_back(var(spec.var), EF);
  667|  41.4k|            }
  668|  50.5k|        }
  669|  39.0k|        AST *arr = make<ArrayComprehension>(ast->location,
  670|  39.0k|                                            EF,
  671|  39.0k|                                            make<Array>(ast->location, EF, arr_e, false, EF),
  672|  39.0k|                                            EF,
  673|  39.0k|                                            false,
  674|  39.0k|                                            ast->specs,
  675|  39.0k|                                            EF);
  676|  39.0k|        desugar(arr, obj_level);
  677|  39.0k|        return make<ObjectComprehensionSimple>(
  678|  39.0k|            ast->location,
  679|  39.0k|            make<Index>(E, EF, var(_arr), EF, false, zero, EF, nullptr, EF, nullptr, EF),
  680|  39.0k|            make<Local>(ast->location, EF, binds, value),
  681|  39.0k|            _arr,
  682|  39.0k|            arr);
  683|  39.0k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bPNS0_13LiteralNumberESE_DnSE_DnSE_EEEPT_DpOT0_:
  110|  41.4k|    {
  111|  41.4k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  41.4k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_13LiteralNumberEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEENS7_12basic_stringIcNS7_11char_traitsIcEENSA_IcEEEEEEEPT_DpOT0_:
  110|  41.4k|    {
  111|  41.4k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  41.4k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_18ArrayComprehensionEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_5ArrayESD_bRNS7_INS0_17ComprehensionSpecENS9_ISG_EEEESD_EEEPT_DpOT0_:
  110|  38.9k|    {
  111|  38.9k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  38.9k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ArrayEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEERNS7_INS3_7ElementENS9_ISE_EEEEbSD_EEEPT_DpOT0_:
  110|  38.9k|    {
  111|  38.9k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  38.9k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_25ObjectComprehensionSimpleEJRNS0_13LocationRangeEPNS0_5IndexEPNS0_5LocalERPKNS0_10IdentifierERPNS0_3ASTEEEEPT_DpOT0_:
  110|  38.9k|    {
  111|  38.9k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  38.9k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5IndexEJRKNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_3VarESE_bRPNS0_3ASTESE_DnSE_DnSE_EEEPT_DpOT0_:
  110|  38.9k|    {
  111|  38.9k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  38.9k|    }
_ZN7jsonnet8internal9Desugarer3strERKNSt3__112basic_stringIDiNS2_11char_traitsIDiEENS2_9allocatorIDiEEEE:
  125|  10.1M|    {
  126|  10.1M|        return make<LiteralString>(E, EF, s, LiteralString::RAW_DESUGARED, "", "");
  127|  10.1M|    }
_ZZN7jsonnet8internal9Desugarer9stdlibASTENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEENKUlvE_clEv:
  938|   199k|            auto fnbody = alloc->makeBuiltinBody(E, name_utf8, [this, &decl]()->Identifiers {
  939|   199k|                Identifiers params;
  940|   199k|                for (const auto &p : decl.params)
  ------------------
  |  Branch (940:36): [True: 293k, False: 199k]
  ------------------
  941|   293k|                    params.push_back(this->id(p));
  942|   199k|                return params;
  943|   199k|            });
_ZZN7jsonnet8internal9Desugarer9stdlibASTENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEENKUlRKNS0_15DesugaredObject5FieldEE_clESC_:
  945|  44.9M|                [=](const DesugaredObject::Field& f) {
  946|  44.9M|                    return static_cast<LiteralString*>(f.name)->value == decl.name;
  947|  44.9M|                });
_ZN7jsonnet8internal9Desugarer4makeINS0_15BuiltinFunctionEJRKNS0_13LocationRangeERPKNS0_19BuiltinFunctionBodyEEEEPT_DpOT0_:
  110|   368k|    {
  111|   368k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|   368k|    }
_ZN7jsonnet8internal9Desugarer11desugarFileERPNS0_3ASTEPNSt3__13mapINS5_12basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEENS0_5VmExtENS5_4lessISC_EENSA_INS5_4pairIKSC_SD_EEEEEE:
  961|  5.23k|    {
  962|  5.23k|        desugar(ast, 0);
  963|       |
  964|  5.23k|        DesugaredObject *std_obj = stdlibAST(ast->location.file);
  965|       |
  966|  5.23k|        std::vector<std::string> empty;
  967|  5.23k|        auto line_end_blank = Fodder{{FodderElement::LINE_END, 1, 0, empty}};
  968|  5.23k|        auto line_end = Fodder{{FodderElement::LINE_END, 0, 0, empty}};
  969|       |
  970|       |        // local body = ast;
  971|       |        // if std.type(body) == "function") then
  972|       |        //     body(tlas...)
  973|       |        // else
  974|       |        //     body
  975|  5.23k|        if (tlas != nullptr) {
  ------------------
  |  Branch (975:13): [True: 4.74k, False: 495]
  ------------------
  976|  4.74k|            LocationRange tla_loc("Top-level function");
  977|  4.74k|            ArgParams args;
  978|  4.74k|            for (const auto &pair : *tlas) {
  ------------------
  |  Branch (978:35): [True: 0, False: 4.74k]
  ------------------
  979|      0|                AST *expr;
  980|      0|                if (pair.second.isCode) {
  ------------------
  |  Branch (980:21): [True: 0, False: 0]
  ------------------
  981|      0|                    Tokens tokens = jsonnet_lex("tla:" + pair.first, pair.second.data.c_str());
  982|      0|                    expr = jsonnet_parse(alloc, tokens);
  983|      0|                    desugar(expr, 0);
  984|      0|                } else {
  985|      0|                    expr = str(decode_utf8(pair.second.data));
  986|      0|                }
  987|       |                // Add them as named arguments, so order does not matter.
  988|      0|                args.emplace_back(EF, id(decode_utf8(pair.first)), EF, expr, EF);
  989|      0|            }
  990|  4.74k|            const Identifier *body = id(U"top_level");
  991|  4.74k|            ast =
  992|  4.74k|                make<Local>(ast->location,
  993|  4.74k|                            line_end_blank,
  994|  4.74k|                            singleBind(body, ast),
  995|  4.74k|                            make<Conditional>(E,
  996|  4.74k|                                              line_end,
  997|  4.74k|                                              primitiveEquals(E, type(var(body)), str(U"function")),
  998|  4.74k|                                              EF,
  999|  4.74k|                                              make<Apply>(tla_loc,
 1000|  4.74k|                                                          EF,
 1001|  4.74k|                                                          make<Var>(E, line_end, body),
 1002|  4.74k|                                                          EF,
 1003|  4.74k|                                                          args,
 1004|  4.74k|                                                          false,  // trailing comma
 1005|  4.74k|                                                          EF,
 1006|  4.74k|                                                          EF,
 1007|  4.74k|                                                          false  // tailstrict
 1008|  4.74k|                                                          ),
 1009|  4.74k|                                              line_end,
 1010|  4.74k|                                              make<Var>(E, line_end, body)));
 1011|  4.74k|        }
 1012|       |
 1013|       |        // local $std = (std.jsonnet stuff); std = $std; ast
 1014|       |        // The standard library is bound to $std, which cannot be overriden,
 1015|       |        // so redefining std won't break expressions that desugar to calls
 1016|       |        // to standard library functions.
 1017|  5.23k|        ast = make<Local>(ast->location, EF, singleBind(id(U"std"), std()), ast);
 1018|  5.23k|        ast = make<Local>(ast->location, EF, singleBind(id(U"$std"), std_obj), ast);
 1019|  5.23k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5LocalEJRNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEENS7_INS3_4BindENS9_ISD_EEEEPNS0_11ConditionalEEEEPT_DpOT0_:
  110|  4.74k|    {
  111|  4.74k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  4.74k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_11ConditionalEJRKNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEEPNS0_5ApplyERKSC_SF_SD_PNS0_3VarEEEEPT_DpOT0_:
  110|  4.74k|    {
  111|  4.74k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  4.74k|    }
_ZN7jsonnet8internal9Desugarer15primitiveEqualsERKNS0_13LocationRangeEPNS0_3ASTES6_:
  209|  4.74k|    {
  210|  4.74k|        return stdFunc(loc, U"primitiveEquals", a, b);
  211|  4.74k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_5ApplyEJRNS0_13LocationRangeERKNSt3__16vectorINS0_13FodderElementENS6_9allocatorIS8_EEEEPNS0_3VarESD_RNS7_INS0_8ArgParamENS9_ISG_EEEEbSD_SD_bEEEPT_DpOT0_:
  110|  4.74k|    {
  111|  4.74k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  4.74k|    }
_ZN7jsonnet8internal9Desugarer4makeINS0_3VarEJRKNS0_13LocationRangeERNSt3__16vectorINS0_13FodderElementENS7_9allocatorIS9_EEEERPKNS0_10IdentifierEEEEPT_DpOT0_:
  110|  9.48k|    {
  111|  9.48k|        return alloc->make<T>(std::forward<Args>(args)...);
  112|  9.48k|    }

_ZN7jsonnet8internal7FmtOptsC2Ev:
   37|  8.31k|        : stringStyle('s'),
   38|  8.31k|          commentStyle('s'),
   39|  8.31k|          indent(2),
   40|  8.31k|          maxBlankLines(2),
   41|  8.31k|          padArrays(false),
   42|  8.31k|          padObjects(true),
   43|  8.31k|          stripComments(false),
   44|  8.31k|          stripAllButComments(false),
   45|  8.31k|          stripEverything(false),
   46|  8.31k|          prettyFieldNames(true),
   47|  8.31k|          sortImports(true)
   48|  8.31k|    {
   49|  8.31k|    }

_ZN7jsonnet8internal26allowed_at_end_of_operatorEc:
  174|  5.47M|bool allowed_at_end_of_operator(char c) {
  175|  5.47M|    switch (c) {
  ------------------
  |  Branch (175:13): [True: 1.73M, False: 3.74M]
  ------------------
  176|   896k|        case '+':
  ------------------
  |  Branch (176:9): [True: 896k, False: 4.57M]
  ------------------
  177|   933k|        case '-':
  ------------------
  |  Branch (177:9): [True: 37.0k, False: 5.43M]
  ------------------
  178|  1.48M|        case '~':
  ------------------
  |  Branch (178:9): [True: 547k, False: 4.92M]
  ------------------
  179|  1.64M|        case '!':
  ------------------
  |  Branch (179:9): [True: 167k, False: 5.30M]
  ------------------
  180|  1.73M|        case '$': return false;
  ------------------
  |  Branch (180:9): [True: 82.0k, False: 5.38M]
  ------------------
  181|  5.47M|    }
  182|  3.74M|    return true;
  183|  5.47M|}
_ZN7jsonnet8internal20lex_get_keyword_kindERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  207|  52.6M|{
  208|  52.6M|    auto it = keywords.find(identifier);
  209|  52.6M|    if (it == keywords.end())
  ------------------
  |  Branch (209:9): [True: 38.5M, False: 14.1M]
  ------------------
  210|  38.5M|        return Token::IDENTIFIER;
  211|  14.1M|    return it->second;
  212|  52.6M|}
_ZN7jsonnet8internal10lex_numberERPKcRKNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEERKNS0_8LocationE:
  215|  5.51M|{
  216|       |    // This function should be understood with reference to the linked image:
  217|       |    // https://www.json.org/img/number.png
  218|       |
  219|       |    // Note, we deviate from the json.org documentation as follows:
  220|       |    // * There is no reason to lex negative numbers as atomic tokens, it is better to parse them
  221|       |    //   as a unary operator combined with a numeric literal.  This avoids x-1 being tokenized as
  222|       |    //   <identifier> <number> instead of the intended <identifier> <binop> <number>.
  223|       |    // * We support digit separators using the _ character for readability in
  224|       |    //   large numeric literals.
  225|       |
  226|  5.51M|    enum State {
  227|  5.51M|        BEGIN,
  228|  5.51M|        AFTER_ZERO,
  229|  5.51M|        AFTER_ONE_TO_NINE,
  230|  5.51M|        AFTER_INT_UNDERSCORE,
  231|  5.51M|        AFTER_DOT,
  232|  5.51M|        AFTER_DIGIT,
  233|  5.51M|        AFTER_FRAC_UNDERSCORE,
  234|  5.51M|        AFTER_E,
  235|  5.51M|        AFTER_EXP_SIGN,
  236|  5.51M|        AFTER_EXP_DIGIT,
  237|  5.51M|        AFTER_EXP_UNDERSCORE
  238|  5.51M|    } state;
  239|       |
  240|  5.51M|    std::string r;
  241|       |
  242|  5.51M|    state = BEGIN;
  243|  11.9M|    while (true) {
  ------------------
  |  Branch (243:12): [True: 11.9M, Folded]
  ------------------
  244|  11.9M|        switch (state) {
  ------------------
  |  Branch (244:17): [True: 11.9M, False: 0]
  ------------------
  245|  5.51M|            case BEGIN:
  ------------------
  |  Branch (245:13): [True: 5.51M, False: 6.46M]
  ------------------
  246|  5.51M|                switch (*c) {
  247|  1.28M|                    case '0': state = AFTER_ZERO; break;
  ------------------
  |  Branch (247:21): [True: 1.28M, False: 4.22M]
  ------------------
  248|       |
  249|  1.57M|                    case '1':
  ------------------
  |  Branch (249:21): [True: 1.57M, False: 3.93M]
  ------------------
  250|  1.89M|                    case '2':
  ------------------
  |  Branch (250:21): [True: 322k, False: 5.18M]
  ------------------
  251|  2.12M|                    case '3':
  ------------------
  |  Branch (251:21): [True: 226k, False: 5.28M]
  ------------------
  252|  2.36M|                    case '4':
  ------------------
  |  Branch (252:21): [True: 241k, False: 5.26M]
  ------------------
  253|  2.42M|                    case '5':
  ------------------
  |  Branch (253:21): [True: 55.5k, False: 5.45M]
  ------------------
  254|  2.68M|                    case '6':
  ------------------
  |  Branch (254:21): [True: 257k, False: 5.25M]
  ------------------
  255|  2.70M|                    case '7':
  ------------------
  |  Branch (255:21): [True: 26.4k, False: 5.48M]
  ------------------
  256|  3.52M|                    case '8':
  ------------------
  |  Branch (256:21): [True: 819k, False: 4.69M]
  ------------------
  257|  4.22M|                    case '9': state = AFTER_ONE_TO_NINE; break;
  ------------------
  |  Branch (257:21): [True: 700k, False: 4.81M]
  ------------------
  258|       |
  259|      0|                    default: throw StaticError(filename, begin, "couldn't lex number");
  ------------------
  |  Branch (259:21): [True: 0, False: 5.51M]
  ------------------
  260|  5.51M|                }
  261|  5.51M|                break;
  262|       |
  263|  5.51M|            case AFTER_ZERO:
  ------------------
  |  Branch (263:13): [True: 1.28M, False: 10.6M]
  ------------------
  264|  1.28M|                switch (*c) {
  265|  18.8k|                    case '.': state = AFTER_DOT; break;
  ------------------
  |  Branch (265:21): [True: 18.8k, False: 1.26M]
  ------------------
  266|       |
  267|    352|                    case 'e':
  ------------------
  |  Branch (267:21): [True: 352, False: 1.28M]
  ------------------
  268|    467|                    case 'E': state = AFTER_E; break;
  ------------------
  |  Branch (268:21): [True: 115, False: 1.28M]
  ------------------
  269|       |
  270|      1|                    case '_': {
  ------------------
  |  Branch (270:21): [True: 1, False: 1.28M]
  ------------------
  271|      1|                        std::stringstream ss;
  272|      1|                        ss << "couldn't lex number, _ not allowed after leading 0";
  273|      1|                        throw StaticError(filename, begin, ss.str());
  274|    352|                    }
  275|       |
  276|  1.26M|                    default: goto end;
  ------------------
  |  Branch (276:21): [True: 1.26M, False: 19.2k]
  ------------------
  277|  1.28M|                }
  278|  19.2k|                break;
  279|       |
  280|  4.92M|            case AFTER_ONE_TO_NINE:
  ------------------
  |  Branch (280:13): [True: 4.92M, False: 7.05M]
  ------------------
  281|  4.92M|                switch (*c) {
  282|  11.7k|                    case '.': state = AFTER_DOT; break;
  ------------------
  |  Branch (282:21): [True: 11.7k, False: 4.91M]
  ------------------
  283|       |
  284|    736|                    case 'e':
  ------------------
  |  Branch (284:21): [True: 736, False: 4.92M]
  ------------------
  285|  2.03k|                    case 'E': state = AFTER_E; break;
  ------------------
  |  Branch (285:21): [True: 1.30k, False: 4.92M]
  ------------------
  286|       |
  287|   277k|                    case '0':
  ------------------
  |  Branch (287:21): [True: 277k, False: 4.64M]
  ------------------
  288|   294k|                    case '1':
  ------------------
  |  Branch (288:21): [True: 17.2k, False: 4.90M]
  ------------------
  289|   392k|                    case '2':
  ------------------
  |  Branch (289:21): [True: 97.8k, False: 4.82M]
  ------------------
  290|   427k|                    case '3':
  ------------------
  |  Branch (290:21): [True: 35.3k, False: 4.88M]
  ------------------
  291|   469k|                    case '4':
  ------------------
  |  Branch (291:21): [True: 41.6k, False: 4.88M]
  ------------------
  292|   556k|                    case '5':
  ------------------
  |  Branch (292:21): [True: 86.9k, False: 4.83M]
  ------------------
  293|   610k|                    case '6':
  ------------------
  |  Branch (293:21): [True: 54.1k, False: 4.87M]
  ------------------
  294|   638k|                    case '7':
  ------------------
  |  Branch (294:21): [True: 28.1k, False: 4.89M]
  ------------------
  295|   673k|                    case '8':
  ------------------
  |  Branch (295:21): [True: 34.3k, False: 4.89M]
  ------------------
  296|   697k|                    case '9': state = AFTER_ONE_TO_NINE; break;
  ------------------
  |  Branch (296:21): [True: 24.9k, False: 4.89M]
  ------------------
  297|       |
  298|     86|                    case '_': state = AFTER_INT_UNDERSCORE; goto skip_char;
  ------------------
  |  Branch (298:21): [True: 86, False: 4.92M]
  ------------------
  299|       |
  300|  4.21M|                    default: goto end;
  ------------------
  |  Branch (300:21): [True: 4.21M, False: 711k]
  ------------------
  301|  4.92M|                }
  302|   711k|                break;
  303|       |
  304|   711k|            case AFTER_INT_UNDERSCORE:
  ------------------
  |  Branch (304:13): [True: 86, False: 11.9M]
  ------------------
  305|     86|                switch (*c) {
  306|       |                    // The only valid transition from _ is to a digit.
  307|      0|                    case '0':
  ------------------
  |  Branch (307:21): [True: 0, False: 86]
  ------------------
  308|      1|                    case '1':
  ------------------
  |  Branch (308:21): [True: 1, False: 85]
  ------------------
  309|      1|                    case '2':
  ------------------
  |  Branch (309:21): [True: 0, False: 86]
  ------------------
  310|      1|                    case '3':
  ------------------
  |  Branch (310:21): [True: 0, False: 86]
  ------------------
  311|      1|                    case '4':
  ------------------
  |  Branch (311:21): [True: 0, False: 86]
  ------------------
  312|      1|                    case '5':
  ------------------
  |  Branch (312:21): [True: 0, False: 86]
  ------------------
  313|      1|                    case '6':
  ------------------
  |  Branch (313:21): [True: 0, False: 86]
  ------------------
  314|      1|                    case '7':
  ------------------
  |  Branch (314:21): [True: 0, False: 86]
  ------------------
  315|     80|                    case '8':
  ------------------
  |  Branch (315:21): [True: 79, False: 7]
  ------------------
  316|     80|                    case '9': state = AFTER_ONE_TO_NINE; break;
  ------------------
  |  Branch (316:21): [True: 0, False: 86]
  ------------------
  317|       |
  318|      6|                    default: {
  ------------------
  |  Branch (318:21): [True: 6, False: 80]
  ------------------
  319|      6|                        std::stringstream ss;
  320|      6|                        ss << "couldn't lex number, junk after _: " << *c;
  321|      6|                        throw StaticError(filename, begin, ss.str());
  322|     80|                    }
  323|     86|                }
  324|     80|                break;
  325|       |
  326|  30.5k|            case AFTER_DOT:
  ------------------
  |  Branch (326:13): [True: 30.5k, False: 11.9M]
  ------------------
  327|  30.5k|                switch (*c) {
  328|    986|                    case '0':
  ------------------
  |  Branch (328:21): [True: 986, False: 29.5k]
  ------------------
  329|  10.1k|                    case '1':
  ------------------
  |  Branch (329:21): [True: 9.13k, False: 21.4k]
  ------------------
  330|  10.5k|                    case '2':
  ------------------
  |  Branch (330:21): [True: 438, False: 30.1k]
  ------------------
  331|  11.0k|                    case '3':
  ------------------
  |  Branch (331:21): [True: 487, False: 30.0k]
  ------------------
  332|  11.6k|                    case '4':
  ------------------
  |  Branch (332:21): [True: 586, False: 29.9k]
  ------------------
  333|  29.2k|                    case '5':
  ------------------
  |  Branch (333:21): [True: 17.6k, False: 12.9k]
  ------------------
  334|  29.4k|                    case '6':
  ------------------
  |  Branch (334:21): [True: 181, False: 30.3k]
  ------------------
  335|  29.5k|                    case '7':
  ------------------
  |  Branch (335:21): [True: 79, False: 30.4k]
  ------------------
  336|  29.9k|                    case '8':
  ------------------
  |  Branch (336:21): [True: 461, False: 30.0k]
  ------------------
  337|  30.5k|                    case '9': state = AFTER_DIGIT; break;
  ------------------
  |  Branch (337:21): [True: 582, False: 29.9k]
  ------------------
  338|       |
  339|      8|                    default: {
  ------------------
  |  Branch (339:21): [True: 8, False: 30.5k]
  ------------------
  340|      8|                        std::stringstream ss;
  341|      8|                        ss << "couldn't lex number, junk after decimal point: " << *c;
  342|      8|                        throw StaticError(filename, begin, ss.str());
  343|  29.9k|                    }
  344|  30.5k|                }
  345|  30.5k|                break;
  346|       |
  347|   206k|            case AFTER_DIGIT:
  ------------------
  |  Branch (347:13): [True: 206k, False: 11.7M]
  ------------------
  348|   206k|                switch (*c) {
  349|    533|                    case 'e':
  ------------------
  |  Branch (349:21): [True: 533, False: 206k]
  ------------------
  350|    954|                    case 'E': state = AFTER_E; break;
  ------------------
  |  Branch (350:21): [True: 421, False: 206k]
  ------------------
  351|       |
  352|  19.0k|                    case '0':
  ------------------
  |  Branch (352:21): [True: 19.0k, False: 187k]
  ------------------
  353|  46.0k|                    case '1':
  ------------------
  |  Branch (353:21): [True: 27.0k, False: 179k]
  ------------------
  354|  55.5k|                    case '2':
  ------------------
  |  Branch (354:21): [True: 9.52k, False: 197k]
  ------------------
  355|  74.2k|                    case '3':
  ------------------
  |  Branch (355:21): [True: 18.7k, False: 188k]
  ------------------
  356|  83.4k|                    case '4':
  ------------------
  |  Branch (356:21): [True: 9.15k, False: 197k]
  ------------------
  357|   110k|                    case '5':
  ------------------
  |  Branch (357:21): [True: 26.9k, False: 179k]
  ------------------
  358|   128k|                    case '6':
  ------------------
  |  Branch (358:21): [True: 18.3k, False: 188k]
  ------------------
  359|   138k|                    case '7':
  ------------------
  |  Branch (359:21): [True: 9.61k, False: 197k]
  ------------------
  360|   149k|                    case '8':
  ------------------
  |  Branch (360:21): [True: 11.1k, False: 195k]
  ------------------
  361|   176k|                    case '9': state = AFTER_DIGIT; break;
  ------------------
  |  Branch (361:21): [True: 26.5k, False: 180k]
  ------------------
  362|       |
  363|     74|                    case '_': state = AFTER_FRAC_UNDERSCORE; goto skip_char;
  ------------------
  |  Branch (363:21): [True: 74, False: 206k]
  ------------------
  364|       |
  365|  29.5k|                    default: goto end;
  ------------------
  |  Branch (365:21): [True: 29.5k, False: 177k]
  ------------------
  366|   206k|                }
  367|   177k|                break;
  368|       |
  369|   177k|            case AFTER_FRAC_UNDERSCORE:
  ------------------
  |  Branch (369:13): [True: 74, False: 11.9M]
  ------------------
  370|     74|                switch (*c) {
  371|       |                    // The only valid transition from _ is to a digit.
  372|      0|                    case '0':
  ------------------
  |  Branch (372:21): [True: 0, False: 74]
  ------------------
  373|      3|                    case '1':
  ------------------
  |  Branch (373:21): [True: 3, False: 71]
  ------------------
  374|      3|                    case '2':
  ------------------
  |  Branch (374:21): [True: 0, False: 74]
  ------------------
  375|      3|                    case '3':
  ------------------
  |  Branch (375:21): [True: 0, False: 74]
  ------------------
  376|      5|                    case '4':
  ------------------
  |  Branch (376:21): [True: 2, False: 72]
  ------------------
  377|      5|                    case '5':
  ------------------
  |  Branch (377:21): [True: 0, False: 74]
  ------------------
  378|      5|                    case '6':
  ------------------
  |  Branch (378:21): [True: 0, False: 74]
  ------------------
  379|      5|                    case '7':
  ------------------
  |  Branch (379:21): [True: 0, False: 74]
  ------------------
  380|     72|                    case '8':
  ------------------
  |  Branch (380:21): [True: 67, False: 7]
  ------------------
  381|     72|                    case '9': state = AFTER_DIGIT; break;
  ------------------
  |  Branch (381:21): [True: 0, False: 74]
  ------------------
  382|       |
  383|      2|                    default: {
  ------------------
  |  Branch (383:21): [True: 2, False: 72]
  ------------------
  384|      2|                        std::stringstream ss;
  385|      2|                        ss << "couldn't lex number, junk after _: " << *c;
  386|      2|                        throw StaticError(filename, begin, ss.str());
  387|     72|                    }
  388|     74|                }
  389|     72|                break;
  390|       |
  391|  3.45k|            case AFTER_E:
  ------------------
  |  Branch (391:13): [True: 3.45k, False: 11.9M]
  ------------------
  392|  3.45k|                switch (*c) {
  393|    357|                    case '+':
  ------------------
  |  Branch (393:21): [True: 357, False: 3.10k]
  ------------------
  394|    899|                    case '-': state = AFTER_EXP_SIGN; break;
  ------------------
  |  Branch (394:21): [True: 542, False: 2.91k]
  ------------------
  395|       |
  396|  1.07k|                    case '0':
  ------------------
  |  Branch (396:21): [True: 1.07k, False: 2.38k]
  ------------------
  397|  1.16k|                    case '1':
  ------------------
  |  Branch (397:21): [True: 90, False: 3.36k]
  ------------------
  398|  1.29k|                    case '2':
  ------------------
  |  Branch (398:21): [True: 132, False: 3.32k]
  ------------------
  399|  1.31k|                    case '3':
  ------------------
  |  Branch (399:21): [True: 14, False: 3.44k]
  ------------------
  400|  1.40k|                    case '4':
  ------------------
  |  Branch (400:21): [True: 95, False: 3.36k]
  ------------------
  401|  1.76k|                    case '5':
  ------------------
  |  Branch (401:21): [True: 357, False: 3.10k]
  ------------------
  402|  2.02k|                    case '6':
  ------------------
  |  Branch (402:21): [True: 263, False: 3.19k]
  ------------------
  403|  2.06k|                    case '7':
  ------------------
  |  Branch (403:21): [True: 39, False: 3.42k]
  ------------------
  404|  2.29k|                    case '8':
  ------------------
  |  Branch (404:21): [True: 227, False: 3.23k]
  ------------------
  405|  2.52k|                    case '9': state = AFTER_EXP_DIGIT; break;
  ------------------
  |  Branch (405:21): [True: 236, False: 3.22k]
  ------------------
  406|       |
  407|     32|                    default: {
  ------------------
  |  Branch (407:21): [True: 32, False: 3.42k]
  ------------------
  408|     32|                        std::stringstream ss;
  409|     32|                        ss << "couldn't lex number, junk after 'E': " << *c;
  410|     32|                        throw StaticError(filename, begin, ss.str());
  411|  2.29k|                    }
  412|  3.45k|                }
  413|  3.42k|                break;
  414|       |
  415|  3.42k|            case AFTER_EXP_SIGN:
  ------------------
  |  Branch (415:13): [True: 899, False: 11.9M]
  ------------------
  416|    899|                switch (*c) {
  417|     16|                    case '0':
  ------------------
  |  Branch (417:21): [True: 16, False: 883]
  ------------------
  418|    108|                    case '1':
  ------------------
  |  Branch (418:21): [True: 92, False: 807]
  ------------------
  419|    199|                    case '2':
  ------------------
  |  Branch (419:21): [True: 91, False: 808]
  ------------------
  420|    641|                    case '3':
  ------------------
  |  Branch (420:21): [True: 442, False: 457]
  ------------------
  421|    862|                    case '4':
  ------------------
  |  Branch (421:21): [True: 221, False: 678]
  ------------------
  422|    876|                    case '5':
  ------------------
  |  Branch (422:21): [True: 14, False: 885]
  ------------------
  423|    876|                    case '6':
  ------------------
  |  Branch (423:21): [True: 0, False: 899]
  ------------------
  424|    877|                    case '7':
  ------------------
  |  Branch (424:21): [True: 1, False: 898]
  ------------------
  425|    889|                    case '8':
  ------------------
  |  Branch (425:21): [True: 12, False: 887]
  ------------------
  426|    893|                    case '9': state = AFTER_EXP_DIGIT; break;
  ------------------
  |  Branch (426:21): [True: 4, False: 895]
  ------------------
  427|       |
  428|      6|                    default: {
  ------------------
  |  Branch (428:21): [True: 6, False: 893]
  ------------------
  429|      6|                        std::stringstream ss;
  430|      6|                        ss << "couldn't lex number, junk after exponent sign: " << *c;
  431|      6|                        throw StaticError(filename, begin, ss.str());
  432|    889|                    }
  433|    899|                }
  434|    893|                break;
  435|       |
  436|  14.8k|            case AFTER_EXP_DIGIT:
  ------------------
  |  Branch (436:13): [True: 14.8k, False: 11.9M]
  ------------------
  437|  14.8k|                switch (*c) {
  438|  1.35k|                    case '0':
  ------------------
  |  Branch (438:21): [True: 1.35k, False: 13.4k]
  ------------------
  439|  3.04k|                    case '1':
  ------------------
  |  Branch (439:21): [True: 1.69k, False: 13.1k]
  ------------------
  440|  3.67k|                    case '2':
  ------------------
  |  Branch (440:21): [True: 624, False: 14.2k]
  ------------------
  441|  4.97k|                    case '3':
  ------------------
  |  Branch (441:21): [True: 1.30k, False: 13.5k]
  ------------------
  442|  6.39k|                    case '4':
  ------------------
  |  Branch (442:21): [True: 1.42k, False: 13.4k]
  ------------------
  443|  7.40k|                    case '5':
  ------------------
  |  Branch (443:21): [True: 1.00k, False: 13.8k]
  ------------------
  444|  8.29k|                    case '6':
  ------------------
  |  Branch (444:21): [True: 892, False: 13.9k]
  ------------------
  445|  9.08k|                    case '7':
  ------------------
  |  Branch (445:21): [True: 789, False: 14.0k]
  ------------------
  446|  10.5k|                    case '8':
  ------------------
  |  Branch (446:21): [True: 1.42k, False: 13.4k]
  ------------------
  447|  11.1k|                    case '9': state = AFTER_EXP_DIGIT; break;
  ------------------
  |  Branch (447:21): [True: 653, False: 14.1k]
  ------------------
  448|       |
  449|    264|                    case '_': state = AFTER_EXP_UNDERSCORE; goto skip_char;
  ------------------
  |  Branch (449:21): [True: 264, False: 14.5k]
  ------------------
  450|       |
  451|  3.41k|                    default: goto end;
  ------------------
  |  Branch (451:21): [True: 3.41k, False: 11.4k]
  ------------------
  452|  14.8k|                }
  453|  11.1k|                break;
  454|       |
  455|  11.1k|            case AFTER_EXP_UNDERSCORE:
  ------------------
  |  Branch (455:13): [True: 264, False: 11.9M]
  ------------------
  456|    264|                switch (*c) {
  457|       |                    // The only valid transition from _ is to a digit.
  458|      0|                    case '0':
  ------------------
  |  Branch (458:21): [True: 0, False: 264]
  ------------------
  459|    249|                    case '1':
  ------------------
  |  Branch (459:21): [True: 249, False: 15]
  ------------------
  460|    249|                    case '2':
  ------------------
  |  Branch (460:21): [True: 0, False: 264]
  ------------------
  461|    249|                    case '3':
  ------------------
  |  Branch (461:21): [True: 0, False: 264]
  ------------------
  462|    250|                    case '4':
  ------------------
  |  Branch (462:21): [True: 1, False: 263]
  ------------------
  463|    250|                    case '5':
  ------------------
  |  Branch (463:21): [True: 0, False: 264]
  ------------------
  464|    250|                    case '6':
  ------------------
  |  Branch (464:21): [True: 0, False: 264]
  ------------------
  465|    255|                    case '7':
  ------------------
  |  Branch (465:21): [True: 5, False: 259]
  ------------------
  466|    261|                    case '8':
  ------------------
  |  Branch (466:21): [True: 6, False: 258]
  ------------------
  467|    261|                    case '9': state = AFTER_EXP_DIGIT; break;
  ------------------
  |  Branch (467:21): [True: 0, False: 264]
  ------------------
  468|       |
  469|      3|                    default: {
  ------------------
  |  Branch (469:21): [True: 3, False: 261]
  ------------------
  470|      3|                        std::stringstream ss;
  471|      3|                        ss << "couldn't lex number, junk after _: " << *c;
  472|      3|                        throw StaticError(filename, begin, ss.str());
  473|    261|                    }
  474|    264|                }
  475|    261|                break;
  476|  11.9M|        }
  477|  6.46M|        r += *c;
  478|       |
  479|  6.46M|skip_char:
  480|  6.46M|        c++;
  481|  6.46M|    }
  482|  5.51M|end:
  483|  5.51M|    return r;
  484|  5.51M|}
_ZN7jsonnet8internal11jsonnet_lexERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEPKc:
  521|  17.0k|{
  522|  17.0k|    unsigned long line_number = 1;
  523|  17.0k|    const char *line_start = input;
  524|       |
  525|  17.0k|    Tokens r;
  526|       |
  527|  17.0k|    const char *c = input;
  528|       |
  529|  17.0k|    Fodder fodder;
  530|  17.0k|    bool fresh_line = true;  // Are we tokenizing from the beginning of a new line?
  531|       |
  532|   125M|    while (*c != '\0') {
  ------------------
  |  Branch (532:12): [True: 125M, False: 7.58k]
  ------------------
  533|       |        // Used to ensure we have actually advanced the pointer by the end of the iteration.
  534|   125M|        const char *original_c = c;
  535|       |
  536|   125M|        Token::Kind kind;
  537|   125M|        std::string data;
  538|   125M|        std::string string_block_indent;
  539|   125M|        std::string string_block_term_indent;
  540|       |
  541|   125M|        unsigned new_lines, indent;
  542|   125M|        lex_ws(c, new_lines, indent, line_start, line_number);
  543|       |
  544|       |        // If it's the end of the file, discard final whitespace.
  545|   125M|        if (*c == '\0')
  ------------------
  |  Branch (545:13): [True: 8.91k, False: 125M]
  ------------------
  546|  8.91k|            break;
  547|       |
  548|   125M|        if (new_lines > 0) {
  ------------------
  |  Branch (548:13): [True: 13.1M, False: 112M]
  ------------------
  549|       |            // Otherwise store whitespace in fodder.
  550|  13.1M|            unsigned blanks = new_lines - 1;
  551|  13.1M|            fodder.emplace_back(FodderElement::LINE_END, blanks, indent, EMPTY);
  552|  13.1M|            fresh_line = true;
  553|  13.1M|        }
  554|       |
  555|   125M|        Location begin(line_number, c - line_start + 1);
  556|       |
  557|   125M|        switch (*c) {
  558|       |            // The following operators should never be combined with subsequent symbols.
  559|   546k|            case '{':
  ------------------
  |  Branch (559:13): [True: 546k, False: 124M]
  ------------------
  560|   546k|                kind = Token::BRACE_L;
  561|   546k|                c++;
  562|   546k|                break;
  563|       |
  564|   537k|            case '}':
  ------------------
  |  Branch (564:13): [True: 537k, False: 124M]
  ------------------
  565|   537k|                kind = Token::BRACE_R;
  566|   537k|                c++;
  567|   537k|                break;
  568|       |
  569|  2.80M|            case '[':
  ------------------
  |  Branch (569:13): [True: 2.80M, False: 122M]
  ------------------
  570|  2.80M|                kind = Token::BRACKET_L;
  571|  2.80M|                c++;
  572|  2.80M|                break;
  573|       |
  574|  2.79M|            case ']':
  ------------------
  |  Branch (574:13): [True: 2.79M, False: 122M]
  ------------------
  575|  2.79M|                kind = Token::BRACKET_R;
  576|  2.79M|                c++;
  577|  2.79M|                break;
  578|       |
  579|  10.9M|            case ',':
  ------------------
  |  Branch (579:13): [True: 10.9M, False: 114M]
  ------------------
  580|  10.9M|                kind = Token::COMMA;
  581|  10.9M|                c++;
  582|  10.9M|                break;
  583|       |
  584|  6.29M|            case '.':
  ------------------
  |  Branch (584:13): [True: 6.29M, False: 118M]
  ------------------
  585|  6.29M|                kind = Token::DOT;
  586|  6.29M|                c++;
  587|  6.29M|                break;
  588|       |
  589|  9.48M|            case '(':
  ------------------
  |  Branch (589:13): [True: 9.48M, False: 115M]
  ------------------
  590|  9.48M|                kind = Token::PAREN_L;
  591|  9.48M|                c++;
  592|  9.48M|                break;
  593|       |
  594|  9.47M|            case ')':
  ------------------
  |  Branch (594:13): [True: 9.47M, False: 115M]
  ------------------
  595|  9.47M|                kind = Token::PAREN_R;
  596|  9.47M|                c++;
  597|  9.47M|                break;
  598|       |
  599|  2.48M|            case ';':
  ------------------
  |  Branch (599:13): [True: 2.48M, False: 122M]
  ------------------
  600|  2.48M|                kind = Token::SEMICOLON;
  601|  2.48M|                c++;
  602|  2.48M|                break;
  603|       |
  604|       |            // Numeric literals.
  605|  1.28M|            case '0':
  ------------------
  |  Branch (605:13): [True: 1.28M, False: 123M]
  ------------------
  606|  2.86M|            case '1':
  ------------------
  |  Branch (606:13): [True: 1.57M, False: 123M]
  ------------------
  607|  3.18M|            case '2':
  ------------------
  |  Branch (607:13): [True: 322k, False: 124M]
  ------------------
  608|  3.41M|            case '3':
  ------------------
  |  Branch (608:13): [True: 226k, False: 125M]
  ------------------
  609|  3.65M|            case '4':
  ------------------
  |  Branch (609:13): [True: 241k, False: 124M]
  ------------------
  610|  3.70M|            case '5':
  ------------------
  |  Branch (610:13): [True: 55.5k, False: 125M]
  ------------------
  611|  3.96M|            case '6':
  ------------------
  |  Branch (611:13): [True: 257k, False: 124M]
  ------------------
  612|  3.99M|            case '7':
  ------------------
  |  Branch (612:13): [True: 26.4k, False: 125M]
  ------------------
  613|  4.81M|            case '8':
  ------------------
  |  Branch (613:13): [True: 819k, False: 124M]
  ------------------
  614|  5.51M|            case '9':
  ------------------
  |  Branch (614:13): [True: 700k, False: 124M]
  ------------------
  615|  5.51M|                kind = Token::NUMBER;
  616|  5.51M|                data = lex_number(c, filename, begin);
  617|  5.51M|                break;
  618|       |
  619|       |            // UString literals.
  620|   189k|            case '"': {
  ------------------
  |  Branch (620:13): [True: 189k, False: 125M]
  ------------------
  621|   189k|                c++;
  622|  43.5M|                for (;; ++c) {
  623|  43.5M|                    if (*c == '\0') {
  ------------------
  |  Branch (623:25): [True: 26, False: 43.5M]
  ------------------
  624|     26|                        throw StaticError(filename, begin, "unterminated string");
  625|     26|                    }
  626|  43.5M|                    if (*c == '"') {
  ------------------
  |  Branch (626:25): [True: 189k, False: 43.3M]
  ------------------
  627|   189k|                        break;
  628|   189k|                    }
  629|  43.3M|                    if (*c == '\\' && *(c + 1) != '\0') {
  ------------------
  |  Branch (629:25): [True: 70.9k, False: 43.2M]
  |  Branch (629:39): [True: 70.9k, False: 1]
  ------------------
  630|  70.9k|                        data += *c;
  631|  70.9k|                        ++c;
  632|  70.9k|                    }
  633|  43.3M|                    if (*c == '\n') {
  ------------------
  |  Branch (633:25): [True: 1.55M, False: 41.7M]
  ------------------
  634|       |                        // Maintain line/column counters.
  635|  1.55M|                        line_number++;
  636|  1.55M|                        line_start = c + 1;
  637|  1.55M|                    }
  638|  43.3M|                    data += *c;
  639|  43.3M|                }
  640|   189k|                c++;  // Advance beyond the ".
  641|   189k|                kind = Token::STRING_DOUBLE;
  642|   189k|            } break;
  643|       |
  644|       |            // UString literals.
  645|  4.11M|            case '\'': {
  ------------------
  |  Branch (645:13): [True: 4.11M, False: 121M]
  ------------------
  646|  4.11M|                c++;
  647|  60.6M|                for (;; ++c) {
  648|  60.6M|                    if (*c == '\0') {
  ------------------
  |  Branch (648:25): [True: 27, False: 60.6M]
  ------------------
  649|     27|                        throw StaticError(filename, begin, "unterminated string");
  650|     27|                    }
  651|  60.6M|                    if (*c == '\'') {
  ------------------
  |  Branch (651:25): [True: 4.11M, False: 56.5M]
  ------------------
  652|  4.11M|                        break;
  653|  4.11M|                    }
  654|  56.5M|                    if (*c == '\\' && *(c + 1) != '\0') {
  ------------------
  |  Branch (654:25): [True: 469k, False: 56.0M]
  |  Branch (654:39): [True: 469k, False: 1]
  ------------------
  655|   469k|                        data += *c;
  656|   469k|                        ++c;
  657|   469k|                    }
  658|  56.5M|                    if (*c == '\n') {
  ------------------
  |  Branch (658:25): [True: 274k, False: 56.2M]
  ------------------
  659|       |                        // Maintain line/column counters.
  660|   274k|                        line_number++;
  661|   274k|                        line_start = c + 1;
  662|   274k|                    }
  663|  56.5M|                    data += *c;
  664|  56.5M|                }
  665|  4.11M|                c++;  // Advance beyond the '.
  666|  4.11M|                kind = Token::STRING_SINGLE;
  667|  4.11M|            } break;
  668|       |
  669|       |            // Verbatim string literals.
  670|       |            // ' and " quoting is interpreted here, unlike non-verbatim strings
  671|       |            // where it is done later by jsonnet_string_unescape.  This is OK
  672|       |            // in this case because no information is lost by resoving the
  673|       |            // repeated quote into a single quote, so we can go back to the
  674|       |            // original form in the formatter.
  675|  2.23k|            case '@': {
  ------------------
  |  Branch (675:13): [True: 2.23k, False: 125M]
  ------------------
  676|  2.23k|                c++;
  677|  2.23k|                if (*c != '"' && *c != '\'') {
  ------------------
  |  Branch (677:21): [True: 645, False: 1.59k]
  |  Branch (677:34): [True: 18, False: 627]
  ------------------
  678|     18|                    std::stringstream ss;
  679|     18|                    ss << "couldn't lex verbatim string, junk after '@': " << *c;
  680|     18|                    throw StaticError(filename, begin, ss.str());
  681|     18|                }
  682|  2.21k|                const char quot = *c;
  683|  2.21k|                c++;  // Advance beyond the opening quote.
  684|  16.8k|                for (;; ++c) {
  685|  16.8k|                    if (*c == '\0') {
  ------------------
  |  Branch (685:25): [True: 27, False: 16.8k]
  ------------------
  686|     27|                        throw StaticError(filename, begin, "unterminated verbatim string");
  687|     27|                    }
  688|  16.8k|                    if (*c == quot) {
  ------------------
  |  Branch (688:25): [True: 2.64k, False: 14.1k]
  ------------------
  689|  2.64k|                        if (*(c + 1) == quot) {
  ------------------
  |  Branch (689:29): [True: 448, False: 2.19k]
  ------------------
  690|    448|                            c++;
  691|  2.19k|                        } else {
  692|  2.19k|                            break;
  693|  2.19k|                        }
  694|  2.64k|                    }
  695|  14.6k|                    data += *c;
  696|  14.6k|                }
  697|  2.19k|                c++;  // Advance beyond the closing quote.
  698|  2.19k|                if (quot == '"') {
  ------------------
  |  Branch (698:21): [True: 1.58k, False: 611]
  ------------------
  699|  1.58k|                    kind = Token::VERBATIM_STRING_DOUBLE;
  700|  1.58k|                } else {
  701|    611|                    kind = Token::VERBATIM_STRING_SINGLE;
  702|    611|                }
  703|  2.19k|            } break;
  704|       |
  705|       |            // Keywords
  706|  70.0M|            default:
  ------------------
  |  Branch (706:13): [True: 70.0M, False: 55.2M]
  ------------------
  707|  70.0M|                if (is_identifier_first(*c)) {
  ------------------
  |  Branch (707:21): [True: 52.6M, False: 17.3M]
  ------------------
  708|  52.6M|                    std::string id;
  709|   283M|                    for (; is_identifier(*c); ++c)
  ------------------
  |  Branch (709:28): [True: 230M, False: 52.6M]
  ------------------
  710|   230M|                        id += *c;
  711|  52.6M|                    kind = lex_get_keyword_kind(id);
  712|  52.6M|                    data = id;
  713|       |
  714|  52.6M|                } else if (is_symbol(*c) || *c == '#') {
  ------------------
  |  Branch (714:28): [True: 14.4M, False: 2.97M]
  |  Branch (714:45): [True: 2.97M, False: 137]
  ------------------
  715|       |                    // Single line C++ and Python style comments.
  716|  17.3M|                    if (*c == '#' || (*c == '/' && *(c + 1) == '/')) {
  ------------------
  |  Branch (716:25): [True: 2.97M, False: 14.4M]
  |  Branch (716:39): [True: 1.12M, False: 13.2M]
  |  Branch (716:52): [True: 816k, False: 312k]
  ------------------
  717|  3.78M|                        std::vector<std::string> comment(1);
  718|  3.78M|                        unsigned blanks;
  719|  3.78M|                        unsigned indent;
  720|  3.78M|                        lex_until_newline(c, comment[0], blanks, indent, line_start, line_number);
  721|  3.78M|                        auto kind = fresh_line ? FodderElement::PARAGRAPH : FodderElement::LINE_END;
  ------------------
  |  Branch (721:37): [True: 3.76M, False: 16.4k]
  ------------------
  722|  3.78M|                        fodder.emplace_back(kind, blanks, indent, comment);
  723|  3.78M|                        fresh_line = true;
  724|  3.78M|                        continue;  // We've not got a token, just fodder, so keep scanning.
  725|  3.78M|                    }
  726|       |
  727|       |                    // Multi-line C style comment.
  728|  13.6M|                    if (*c == '/' && *(c + 1) == '*') {
  ------------------
  |  Branch (728:25): [True: 312k, False: 13.2M]
  |  Branch (728:38): [True: 195k, False: 117k]
  ------------------
  729|   195k|                        unsigned margin = c - line_start;
  730|       |
  731|   195k|                        const char *initial_c = c;
  732|   195k|                        c += 2;  // Avoid matching /*/: skip the /* before starting the search for
  733|       |                                 // */.
  734|       |
  735|  55.3M|                        while (!(*c == '*' && *(c + 1) == '/')) {
  ------------------
  |  Branch (735:34): [True: 339k, False: 55.0M]
  |  Branch (735:47): [True: 195k, False: 143k]
  ------------------
  736|  55.1M|                            if (*c == '\0') {
  ------------------
  |  Branch (736:33): [True: 64, False: 55.1M]
  ------------------
  737|     64|                                auto msg = "multi-line comment has no terminating */.";
  738|     64|                                throw StaticError(filename, begin, msg);
  739|     64|                            }
  740|  55.1M|                            if (*c == '\n') {
  ------------------
  |  Branch (740:33): [True: 8.74M, False: 46.4M]
  ------------------
  741|       |                                // Just keep track of the line / column counters.
  742|  8.74M|                                line_number++;
  743|  8.74M|                                line_start = c + 1;
  744|  8.74M|                            }
  745|  55.1M|                            ++c;
  746|  55.1M|                        }
  747|   195k|                        c += 2;  // Move the pointer to the char after the closing '/'.
  748|       |
  749|   195k|                        std::string comment(initial_c,
  750|   195k|                                            c - initial_c);  // Includes the "/*" and "*/".
  751|       |
  752|       |                        // Lex whitespace after comment
  753|   195k|                        unsigned new_lines_after, indent_after;
  754|   195k|                        lex_ws(c, new_lines_after, indent_after, line_start, line_number);
  755|   195k|                        std::vector<std::string> lines;
  756|   195k|                        if (comment.find('\n') >= comment.length()) {
  ------------------
  |  Branch (756:29): [True: 83.7k, False: 111k]
  ------------------
  757|       |                            // Comment looks like /* foo */
  758|  83.7k|                            lines.push_back(comment);
  759|  83.7k|                            fodder.emplace_back(FodderElement::INTERSTITIAL, 0, 0, lines);
  760|  83.7k|                            if (new_lines_after > 0) {
  ------------------
  |  Branch (760:33): [True: 79.1k, False: 4.58k]
  ------------------
  761|  79.1k|                                fodder.emplace_back(FodderElement::LINE_END,
  762|  79.1k|                                                    new_lines_after - 1,
  763|  79.1k|                                                    indent_after,
  764|  79.1k|                                                    EMPTY);
  765|  79.1k|                                fresh_line = true;
  766|  79.1k|                            }
  767|   111k|                        } else {
  768|   111k|                            lines = line_split(comment, margin);
  769|   111k|                            assert(lines[0][0] == '/');
  ------------------
  |  Branch (769:29): [True: 111k, False: 0]
  ------------------
  770|       |                            // Little hack to support PARAGRAPHs with * down the LHS:
  771|       |                            // Add a space to lines that start with a '*'
  772|   111k|                            bool all_star = true;
  773|  8.85M|                            for (auto &l : lines) {
  ------------------
  |  Branch (773:42): [True: 8.85M, False: 111k]
  ------------------
  774|  8.85M|                                if (l[0] != '*')
  ------------------
  |  Branch (774:37): [True: 8.76M, False: 88.7k]
  ------------------
  775|  8.76M|                                    all_star = false;
  776|  8.85M|                            }
  777|   111k|                            if (all_star) {
  ------------------
  |  Branch (777:33): [True: 0, False: 111k]
  ------------------
  778|      0|                                for (auto &l : lines) {
  ------------------
  |  Branch (778:46): [True: 0, False: 0]
  ------------------
  779|      0|                                    if (l[0] == '*')
  ------------------
  |  Branch (779:41): [True: 0, False: 0]
  ------------------
  780|      0|                                        l = " " + l;
  781|      0|                                }
  782|      0|                            }
  783|   111k|                            if (new_lines_after == 0) {
  ------------------
  |  Branch (783:33): [True: 12.8k, False: 98.8k]
  ------------------
  784|       |                                // Ensure a line end after the paragraph.
  785|  12.8k|                                new_lines_after = 1;
  786|  12.8k|                                indent_after = 0;
  787|  12.8k|                            }
  788|   111k|                            fodder_push_back(fodder,
  789|   111k|                                             FodderElement(FodderElement::PARAGRAPH,
  790|   111k|                                                           new_lines_after - 1,
  791|   111k|                                                           indent_after,
  792|   111k|                                                           lines));
  793|   111k|                            fresh_line = true;
  794|   111k|                        }
  795|   195k|                        continue;  // We've not got a token, just fodder, so keep scanning.
  796|   195k|                    }
  797|       |
  798|       |                    // Text block
  799|  13.4M|                    if (*c == '|' && *(c + 1) == '|' && *(c + 2) == '|') {
  ------------------
  |  Branch (799:25): [True: 251k, False: 13.1M]
  |  Branch (799:38): [True: 191k, False: 60.1k]
  |  Branch (799:57): [True: 5.58k, False: 185k]
  ------------------
  800|  5.58k|                        c += 3;  // Skip the "|||".
  801|       |
  802|  5.58k|                        bool chomp_trailing_nl = false;
  803|  5.58k|                        if (*c == '-') {
  ------------------
  |  Branch (803:29): [True: 610, False: 4.97k]
  ------------------
  804|    610|                            chomp_trailing_nl = true;
  805|    610|                            c++;
  806|    610|                        }
  807|       |
  808|  7.25k|                        while (is_horz_ws(*c)) ++c;  // Chomp whitespace at end of line.
  ------------------
  |  Branch (808:32): [True: 1.67k, False: 5.58k]
  ------------------
  809|  5.58k|                        if (*c != '\n') {
  ------------------
  |  Branch (809:29): [True: 41, False: 5.54k]
  ------------------
  810|     41|                            auto msg = "text block syntax requires new line after |||.";
  811|     41|                            throw StaticError(filename, begin, msg);
  812|     41|                        }
  813|  5.54k|                        std::stringstream block;
  814|  5.54k|                        c++;  // Skip the "\n"
  815|  5.54k|                        line_number++;
  816|       |                        // Skip any blank lines at the beginning of the block.
  817|  7.56k|                        while (*c == '\n') {
  ------------------
  |  Branch (817:32): [True: 2.02k, False: 5.54k]
  ------------------
  818|  2.02k|                            line_number++;
  819|  2.02k|                            ++c;
  820|  2.02k|                            block << '\n';
  821|  2.02k|                        }
  822|  5.54k|                        line_start = c;
  823|  5.54k|                        const char *first_line = c;
  824|  5.54k|                        int ws_chars = whitespace_check(first_line, c);
  825|  5.54k|                        string_block_indent = std::string(first_line, ws_chars);
  826|  5.54k|                        if (ws_chars == 0) {
  ------------------
  |  Branch (826:29): [True: 20, False: 5.52k]
  ------------------
  827|     20|                            auto msg = "text block's first line must start with whitespace.";
  828|     20|                            throw StaticError(filename, begin, msg);
  829|     20|                        }
  830|  8.04k|                        while (true) {
  ------------------
  |  Branch (830:32): [True: 8.04k, Folded]
  ------------------
  831|  8.04k|                            assert(ws_chars > 0);
  ------------------
  |  Branch (831:29): [True: 8.04k, False: 0]
  ------------------
  832|       |                            // Read up to the \n
  833|   257k|                            for (c = &c[ws_chars]; *c != '\n'; ++c) {
  ------------------
  |  Branch (833:52): [True: 249k, False: 7.97k]
  ------------------
  834|   249k|                                if (*c == '\0')
  ------------------
  |  Branch (834:37): [True: 73, False: 249k]
  ------------------
  835|     73|                                    throw StaticError(filename, begin, "unexpected EOF");
  836|   249k|                                block << *c;
  837|   249k|                            }
  838|       |                            // Add the \n
  839|  7.97k|                            block << '\n';
  840|  7.97k|                            ++c;
  841|  7.97k|                            line_number++;
  842|  7.97k|                            line_start = c;
  843|       |                            // Skip any blank lines
  844|  8.92k|                            while (*c == '\n') {
  ------------------
  |  Branch (844:36): [True: 957, False: 7.97k]
  ------------------
  845|    957|                                line_number++;
  846|    957|                                ++c;
  847|    957|                                block << '\n';
  848|    957|                            }
  849|       |                            // Examine next line
  850|  7.97k|                            ws_chars = whitespace_check(first_line, c);
  851|  7.97k|                            if (ws_chars == 0) {
  ------------------
  |  Branch (851:33): [True: 5.44k, False: 2.52k]
  ------------------
  852|       |                                // End of text block (or indentation error).
  853|       |                                // Count actual whitespace on this line.
  854|  5.44k|                                int actual_ws = 0;
  855|  67.5k|                                while (c[actual_ws] == ' ' ||
  ------------------
  |  Branch (855:40): [True: 61.6k, False: 5.95k]
  ------------------
  856|  62.1k|                                       c[actual_ws] == '\t') {
  ------------------
  |  Branch (856:40): [True: 506, False: 5.44k]
  ------------------
  857|  62.1k|                                    actual_ws++;
  858|  62.1k|                                }
  859|       |
  860|       |                                // Check if this is the terminator |||
  861|  5.44k|                                bool is_terminator = (
  862|  5.44k|                                    c[actual_ws] == '|' &&
  ------------------
  |  Branch (862:37): [True: 5.37k, False: 73]
  ------------------
  863|  5.37k|                                    c[actual_ws + 1] == '|' &&
  ------------------
  |  Branch (863:37): [True: 5.36k, False: 7]
  ------------------
  864|  5.36k|                                    c[actual_ws + 2] == '|');
  ------------------
  |  Branch (864:37): [True: 5.36k, False: 9]
  ------------------
  865|       |
  866|  5.44k|                                if (!is_terminator) {
  ------------------
  |  Branch (866:37): [True: 89, False: 5.36k]
  ------------------
  867|       |                                    // Not a terminator - check if it's an
  868|       |                                    // indentation issue.
  869|     89|                                    if (actual_ws > 0) {
  ------------------
  |  Branch (869:41): [True: 39, False: 50]
  ------------------
  870|       |                                        // Has whitespace but doesn't match expected
  871|       |                                        // indentation.
  872|     39|                                        std::stringstream msg;
  873|     39|                                        msg << "text block indentation mismatch: "
  874|     39|                                                "expected at least ";
  875|     39|                                        describe_whitespace(msg, string_block_indent);
  876|     39|                                        msg << ", found ";
  877|     39|                                        describe_whitespace(msg, std::string(c, actual_ws));
  878|     39|                                        throw StaticError(filename, begin, msg.str());
  879|     50|                                    } else {
  880|       |                                        // No whitespace and no ||| - missing
  881|       |                                        // terminator.
  882|     50|                                        auto msg =
  883|     50|                                            "text block not terminated with |||";
  884|     50|                                        throw StaticError(filename, begin, msg);
  885|     50|                                    }
  886|     89|                                }
  887|       |
  888|       |                                // Valid termination - skip over any whitespace.
  889|  66.6k|                                while (*c == ' ' || *c == '\t') {
  ------------------
  |  Branch (889:40): [True: 61.2k, False: 5.38k]
  |  Branch (889:53): [True: 22, False: 5.36k]
  ------------------
  890|  61.2k|                                    string_block_term_indent += *c;
  891|  61.2k|                                    ++c;
  892|  61.2k|                                }
  893|       |                                // Skip the |||
  894|  5.36k|                                c += 3;  // Leave after the last |
  895|  5.36k|                                data = block.str();
  896|  5.36k|                                kind = Token::STRING_BLOCK;
  897|  5.36k|                                if (chomp_trailing_nl) {
  ------------------
  |  Branch (897:37): [True: 594, False: 4.76k]
  ------------------
  898|    594|                                    assert(data.back() == '\n');
  ------------------
  |  Branch (898:37): [True: 594, False: 0]
  ------------------
  899|    594|                                    data.pop_back();
  900|    594|                                }
  901|  5.36k|                                break;  // Out of the while loop.
  902|  5.36k|                            }
  903|  7.97k|                        }
  904|       |
  905|  5.36k|                        break;  // Out of the switch.
  906|  5.52k|                    }
  907|       |
  908|  13.4M|                    const char *operator_begin = c;
  909|  41.2M|                    for (; is_symbol(*c); ++c) {
  ------------------
  |  Branch (909:28): [True: 27.8M, False: 13.4M]
  ------------------
  910|       |                        // Not allowed // in operators
  911|  27.8M|                        if (*c == '/' && *(c + 1) == '/')
  ------------------
  |  Branch (911:29): [True: 117k, False: 27.7M]
  |  Branch (911:42): [True: 351, False: 117k]
  ------------------
  912|    351|                            break;
  913|       |                        // Not allowed /* in operators
  914|  27.8M|                        if (*c == '/' && *(c + 1) == '*')
  ------------------
  |  Branch (914:29): [True: 117k, False: 27.7M]
  |  Branch (914:42): [True: 311, False: 117k]
  ------------------
  915|    311|                            break;
  916|       |                        // Not allowed ||| in operators
  917|  27.8M|                        if (*c == '|' && *(c + 1) == '|' && *(c + 2) == '|')
  ------------------
  |  Branch (917:29): [True: 432k, False: 27.3M]
  |  Branch (917:42): [True: 186k, False: 246k]
  |  Branch (917:61): [True: 738, False: 185k]
  ------------------
  918|    738|                            break;
  919|  27.8M|                    }
  920|       |                    // Not allowed to end with a + - ~ ! unless a single char.
  921|       |                    // So, wind it back if we need to (but not too far).
  922|  15.1M|                    while (c > operator_begin + 1 && !allowed_at_end_of_operator(*(c - 1))) {
  ------------------
  |  Branch (922:28): [True: 5.47M, False: 9.66M]
  |  Branch (922:54): [True: 1.73M, False: 3.74M]
  ------------------
  923|  1.73M|                        c--;
  924|  1.73M|                    }
  925|  13.4M|                    data += std::string(operator_begin, c);
  926|  13.4M|                    if (data == "$") {
  ------------------
  |  Branch (926:25): [True: 45.2k, False: 13.3M]
  ------------------
  927|  45.2k|                        kind = Token::DOLLAR;
  928|  45.2k|                        data = "";
  929|  13.3M|                    } else {
  930|  13.3M|                        kind = Token::OPERATOR;
  931|  13.3M|                    }
  932|  13.4M|                } else {
  933|    137|                    std::stringstream ss;
  934|    137|                    ss << "Could not lex the character ";
  935|    137|                    auto uc = (unsigned char)(*c);
  936|    137|                    if (*c < 32)
  ------------------
  |  Branch (936:25): [True: 123, False: 14]
  ------------------
  937|    123|                        ss << "code " << unsigned(uc);
  938|     14|                    else
  939|     14|                        ss << "'" << *c << "'";
  940|    137|                    throw StaticError(filename, begin, ss.str());
  941|    137|                }
  942|   125M|        }
  943|       |
  944|       |        // Ensure that a bug in the above code does not cause an infinite memory consuming loop due
  945|       |        // to pushing empty tokens.
  946|   121M|        if (c == original_c) {
  ------------------
  |  Branch (946:13): [True: 0, False: 121M]
  ------------------
  947|      0|            throw StaticError(filename, begin, "internal lexing error:  pointer did not advance");
  948|      0|        }
  949|       |
  950|   121M|        Location end(line_number, (c + 1) - line_start);
  951|   121M|        r.emplace_back(kind,
  952|   121M|                       fodder,
  953|   121M|                       data,
  954|   121M|                       string_block_indent,
  955|   121M|                       string_block_term_indent,
  956|   121M|                       LocationRange(filename, begin, end));
  957|   121M|        fodder.clear();
  958|   121M|        fresh_line = false;
  959|   121M|    }
  960|       |
  961|  16.5k|    Location begin(line_number, c - line_start + 1);
  962|  16.5k|    Location end(line_number, (c + 1) - line_start + 1);
  963|  16.5k|    r.emplace_back(Token::END_OF_FILE, fodder, "", "", "", LocationRange(filename, begin, end));
  964|  16.5k|    return r;
  965|  17.0k|}
lexer.cpp:_ZN7jsonnet8internalL6lex_wsERPKcRjS4_S3_Rm:
   81|   129M|{
   82|   129M|    indent = 0;
   83|   129M|    new_lines = 0;
   84|   298M|    for (; *c != '\0' && is_ws(*c); c++) {
  ------------------
  |  Branch (84:12): [True: 298M, False: 9.47k]
  |  Branch (84:26): [True: 168M, False: 129M]
  ------------------
   85|   168M|        switch (*c) {
  ------------------
  |  Branch (85:17): [True: 168M, False: 0]
  ------------------
   86|   527k|            case '\r':
  ------------------
  |  Branch (86:13): [True: 527k, False: 168M]
  ------------------
   87|       |                // Ignore.
   88|   527k|                break;
   89|       |
   90|  18.9M|            case '\n':
  ------------------
  |  Branch (90:13): [True: 18.9M, False: 149M]
  ------------------
   91|  18.9M|                indent = 0;
   92|  18.9M|                new_lines++;
   93|  18.9M|                line_number++;
   94|  18.9M|                line_start = c + 1;
   95|  18.9M|                break;
   96|       |
   97|   149M|            case ' ': indent += 1; break;
  ------------------
  |  Branch (97:13): [True: 149M, False: 19.5M]
  ------------------
   98|       |
   99|       |            // This only works for \t at the beginning of lines, but we strip it everywhere else
  100|       |            // anyway.  The only case where this will cause a problem is spaces followed by \t
  101|       |            // at the beginning of a line.  However that is rare, ill-advised, and if re-indentation
  102|       |            // is enabled it will be fixed later.
  103|  45.0k|            case '\t': indent += 8; break;
  ------------------
  |  Branch (103:13): [True: 45.0k, False: 168M]
  ------------------
  104|   168M|        }
  105|   168M|    }
  106|   129M|}
lexer.cpp:_ZN7jsonnet8internalL5is_wsEc:
   39|   298M|{
   40|   298M|    return c == '\n' || is_horz_ws(c);
  ------------------
  |  Branch (40:12): [True: 18.9M, False: 279M]
  |  Branch (40:25): [True: 149M, False: 129M]
  ------------------
   41|   298M|}
lexer.cpp:_ZN7jsonnet8internalL19is_identifier_firstEc:
  143|   353M|{
  144|   353M|    return is_upper(c) || is_lower(c) || c == '_';
  ------------------
  |  Branch (144:12): [True: 5.16M, False: 347M]
  |  Branch (144:27): [True: 263M, False: 84.1M]
  |  Branch (144:42): [True: 3.77M, False: 80.3M]
  ------------------
  145|   353M|}
lexer.cpp:_ZN7jsonnet8internalL8is_upperEc:
  128|   353M|{
  129|   353M|    return c >= 'A' && c <= 'Z';
  ------------------
  |  Branch (129:12): [True: 275M, False: 77.2M]
  |  Branch (129:24): [True: 5.16M, False: 270M]
  ------------------
  130|   353M|}
lexer.cpp:_ZN7jsonnet8internalL8is_lowerEc:
  133|   347M|{
  134|   347M|    return c >= 'a' && c <= 'z';
  ------------------
  |  Branch (134:12): [True: 264M, False: 83.8M]
  |  Branch (134:24): [True: 263M, False: 267k]
  ------------------
  135|   347M|}
lexer.cpp:_ZN7jsonnet8internalL13is_identifierEc:
  148|   283M|{
  149|   283M|    return is_identifier_first(c) || is_number(c);
  ------------------
  |  Branch (149:12): [True: 220M, False: 62.9M]
  |  Branch (149:38): [True: 10.3M, False: 52.6M]
  ------------------
  150|   283M|}
lexer.cpp:_ZN7jsonnet8internalL9is_numberEc:
  138|  62.9M|{
  139|  62.9M|    return c >= '0' && c <= '9';
  ------------------
  |  Branch (139:12): [True: 14.9M, False: 48.0M]
  |  Branch (139:24): [True: 10.3M, False: 4.58M]
  ------------------
  140|  62.9M|}
lexer.cpp:_ZN7jsonnet8internalL9is_symbolEc:
  153|  58.6M|{
  154|  58.6M|    switch (c) {
  ------------------
  |  Branch (154:13): [True: 42.2M, False: 16.3M]
  ------------------
  155|  1.21M|        case '!':
  ------------------
  |  Branch (155:9): [True: 1.21M, False: 57.4M]
  ------------------
  156|  1.38M|        case '$':
  ------------------
  |  Branch (156:9): [True: 172k, False: 58.4M]
  ------------------
  157|  7.85M|        case ':':
  ------------------
  |  Branch (157:9): [True: 6.47M, False: 52.1M]
  ------------------
  158|  8.41M|        case '~':
  ------------------
  |  Branch (158:9): [True: 561k, False: 58.0M]
  ------------------
  159|  16.1M|        case '+':
  ------------------
  |  Branch (159:9): [True: 7.74M, False: 50.8M]
  ------------------
  160|  17.2M|        case '-':
  ------------------
  |  Branch (160:9): [True: 1.06M, False: 57.5M]
  ------------------
  161|  18.4M|        case '&':
  ------------------
  |  Branch (161:9): [True: 1.26M, False: 57.3M]
  ------------------
  162|  19.1M|        case '|':
  ------------------
  |  Branch (162:9): [True: 684k, False: 57.9M]
  ------------------
  163|  19.1M|        case '^':
  ------------------
  |  Branch (163:9): [True: 1.45k, False: 58.6M]
  ------------------
  164|  32.1M|        case '=':
  ------------------
  |  Branch (164:9): [True: 12.9M, False: 45.6M]
  ------------------
  165|  33.2M|        case '<':
  ------------------
  |  Branch (165:9): [True: 1.09M, False: 57.5M]
  ------------------
  166|  34.7M|        case '>':
  ------------------
  |  Branch (166:9): [True: 1.49M, False: 57.1M]
  ------------------
  167|  40.4M|        case '*':
  ------------------
  |  Branch (167:9): [True: 5.71M, False: 52.9M]
  ------------------
  168|  41.6M|        case '/':
  ------------------
  |  Branch (168:9): [True: 1.24M, False: 57.3M]
  ------------------
  169|  42.2M|        case '%': return true;
  ------------------
  |  Branch (169:9): [True: 548k, False: 58.0M]
  ------------------
  170|  58.6M|    }
  171|  16.3M|    return false;
  172|  58.6M|}
lexer.cpp:_ZN7jsonnet8internalL17lex_until_newlineERPKcRNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEERjSC_S3_Rm:
  113|  3.78M|{
  114|  3.78M|    const char *original_c = c;
  115|  3.78M|    const char *last_non_space = c;
  116|  49.7M|    for (; *c != '\0' && *c != '\n'; c++) {
  ------------------
  |  Branch (116:12): [True: 49.7M, False: 273]
  |  Branch (116:26): [True: 45.9M, False: 3.78M]
  ------------------
  117|  45.9M|        if (!is_horz_ws(*c))
  ------------------
  |  Branch (117:13): [True: 39.3M, False: 6.53M]
  ------------------
  118|  39.3M|            last_non_space = c;
  119|  45.9M|    }
  120|  3.78M|    text = std::string(original_c, last_non_space - original_c + 1);
  121|       |    // Consume subsequent whitespace including the '\n'.
  122|  3.78M|    unsigned new_lines;
  123|  3.78M|    lex_ws(c, new_lines, indent, line_start, line_number);
  124|  3.78M|    blanks = new_lines == 0 ? 0 : new_lines - 1;
  ------------------
  |  Branch (124:14): [True: 273, False: 3.78M]
  ------------------
  125|  3.78M|}
lexer.cpp:_ZN7jsonnet8internalL10line_splitERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEj:
   60|   111k|{
   61|   111k|    std::vector<std::string> ret;
   62|   111k|    std::stringstream ss;
   63|  49.7M|    for (size_t i = 0; i < s.length(); ++i) {
  ------------------
  |  Branch (63:24): [True: 49.5M, False: 111k]
  ------------------
   64|  49.5M|        if (s[i] == '\n') {
  ------------------
  |  Branch (64:13): [True: 8.74M, False: 40.8M]
  ------------------
   65|  8.74M|            ret.emplace_back(strip_ws(ss.str(), margin));
   66|  8.74M|            ss.str("");
   67|  40.8M|        } else {
   68|  40.8M|            ss << s[i];
   69|  40.8M|        }
   70|  49.5M|    }
   71|   111k|    ret.emplace_back(strip_ws(ss.str(), margin));
   72|   111k|    return ret;
   73|   111k|}
lexer.cpp:_ZN7jsonnet8internalL8strip_wsERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEj:
   45|  8.85M|{
   46|  8.85M|    if (s.size() == 0)
  ------------------
  |  Branch (46:9): [True: 7.53M, False: 1.32M]
  ------------------
   47|  7.53M|        return s;  // Avoid underflow below.
   48|  1.32M|    size_t i = 0;
   49|  3.44M|    while (i < s.length() && is_horz_ws(s[i]) && i < margin)
  ------------------
  |  Branch (49:12): [True: 3.44M, False: 4.30k]
  |  Branch (49:30): [True: 2.61M, False: 831k]
  |  Branch (49:50): [True: 2.12M, False: 485k]
  ------------------
   50|  2.12M|        i++;
   51|  1.32M|    size_t j = s.size();
   52|  3.55M|    while (j > i && is_horz_ws(s[j - 1])) {
  ------------------
  |  Branch (52:12): [True: 3.41M, False: 141k]
  |  Branch (52:21): [True: 2.23M, False: 1.17M]
  ------------------
   53|  2.23M|        j--;
   54|  2.23M|    }
   55|  1.32M|    return std::string(&s[i], &s[j]);
   56|  8.85M|}
lexer.cpp:_ZN7jsonnet8internalL10is_horz_wsEc:
   33|   331M|{
   34|   331M|    return c == ' ' || c == '\t' || c == '\r';
  ------------------
  |  Branch (34:12): [True: 160M, False: 171M]
  |  Branch (34:24): [True: 91.1k, False: 171M]
  |  Branch (34:37): [True: 536k, False: 170M]
  ------------------
   35|   331M|}
lexer.cpp:_ZN7jsonnet8internalL16whitespace_checkEPKcS2_:
  489|  13.5k|{
  490|  13.5k|    int i = 0;
  491|   117k|    while (a[i] == ' ' || a[i] == '\t') {
  ------------------
  |  Branch (491:12): [True: 1.51k, False: 116k]
  |  Branch (491:27): [True: 108k, False: 8.06k]
  ------------------
  492|   109k|        if (b[i] != a[i])
  ------------------
  |  Branch (492:13): [True: 5.44k, False: 104k]
  ------------------
  493|  5.44k|            return 0;
  494|   104k|        i++;
  495|   104k|    }
  496|  8.06k|    return i;
  497|  13.5k|}
lexer.cpp:_ZN7jsonnet8internalL19describe_whitespaceERNSt3__118basic_stringstreamIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERKNS1_12basic_stringIcS4_S6_EE:
  499|     78|static void describe_whitespace(std::stringstream& msg, const std::string& ws) {
  500|     78|    int spaces = 0;
  501|     78|    int tabs = 0;
  502|  1.93k|    for (char c : ws) {
  ------------------
  |  Branch (502:17): [True: 1.93k, False: 78]
  ------------------
  503|  1.93k|        if (c == ' ')
  ------------------
  |  Branch (503:13): [True: 466, False: 1.47k]
  ------------------
  504|    466|            spaces++;
  505|  1.47k|        else if (c == '\t')
  ------------------
  |  Branch (505:18): [True: 1.47k, False: 0]
  ------------------
  506|  1.47k|            tabs++;
  507|  1.93k|    }
  508|     78|    if (spaces > 0 && tabs > 0) {
  ------------------
  |  Branch (508:9): [True: 38, False: 40]
  |  Branch (508:23): [True: 8, False: 30]
  ------------------
  509|      8|        msg << spaces << (spaces == 1 ? " space" : " spaces") << " and " << tabs
  ------------------
  |  Branch (509:27): [True: 6, False: 2]
  ------------------
  510|      8|            << (tabs == 1 ? " tab" : " tabs");
  ------------------
  |  Branch (510:17): [True: 1, False: 7]
  ------------------
  511|     70|    } else if (spaces > 0) {
  ------------------
  |  Branch (511:16): [True: 30, False: 40]
  ------------------
  512|     30|        msg << spaces << (spaces == 1 ? " space" : " spaces");
  ------------------
  |  Branch (512:27): [True: 11, False: 19]
  ------------------
  513|     40|    } else if (tabs > 0) {
  ------------------
  |  Branch (513:16): [True: 40, False: 0]
  ------------------
  514|     40|        msg << tabs << (tabs == 1 ? " tab" : " tabs");
  ------------------
  |  Branch (514:25): [True: 11, False: 29]
  ------------------
  515|     40|    } else {
  516|      0|        msg << "no indentation";
  517|      0|    }
  518|     78|}

_ZN7jsonnet8internal13FodderElementC2ENS1_4KindEjjRKNSt3__16vectorINS3_12basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEENS8_ISA_EEEE:
   92|  17.2M|        : kind(kind), blanks(blanks), indent(indent), comment(comment)
   93|  17.2M|    {
   94|  17.2M|        assert(kind != LINE_END || comment.size() <= 1);
  ------------------
  |  Branch (94:9): [True: 3.96M, False: 13.2M]
  |  Branch (94:9): [True: 13.2M, False: 0]
  |  Branch (94:9): [True: 17.2M, False: 0]
  ------------------
   95|  17.2M|        assert(kind != INTERSTITIAL || (blanks == 0 && indent == 0 && comment.size() == 1));
  ------------------
  |  Branch (95:9): [True: 83.7k, False: 0]
  |  Branch (95:9): [True: 83.7k, False: 0]
  |  Branch (95:9): [True: 83.7k, False: 0]
  |  Branch (95:9): [True: 17.1M, False: 83.7k]
  |  Branch (95:9): [True: 17.2M, False: 0]
  ------------------
   96|  17.2M|        assert(kind != PARAGRAPH || comment.size() >= 1);
  ------------------
  |  Branch (96:9): [True: 13.3M, False: 3.88M]
  |  Branch (96:9): [True: 3.88M, False: 0]
  |  Branch (96:9): [True: 17.2M, False: 0]
  ------------------
   97|  17.2M|    }
_ZNK7jsonnet8internal5Token6data32Ev:
  299|  42.8M|    {
  300|  42.8M|        return decode_utf8(data);
  301|  42.8M|    }
_ZN7jsonnet8internal5TokenC2ENS1_4KindERKNSt3__16vectorINS0_13FodderElementENS3_9allocatorIS5_EEEERKNS3_12basic_stringIcNS3_11char_traitsIcEENS6_IcEEEESH_SH_RKNS0_13LocationRangeE:
  308|   121M|        : kind(kind),
  309|   121M|          fodder(fodder),
  310|   121M|          data(data),
  311|   121M|          stringBlockIndent(string_block_indent),
  312|   121M|          stringBlockTermIndent(string_block_term_indent),
  313|   121M|          location(location)
  314|   121M|    {
  315|   121M|    }
_ZN7jsonnet8internal5Token8toStringENS1_4KindE:
  320|  1.09k|    {
  321|  1.09k|        switch (v) {
  322|     24|            case BRACE_L: return "\"{\"";
  ------------------
  |  Branch (322:13): [True: 24, False: 1.07k]
  ------------------
  323|     35|            case BRACE_R: return "\"}\"";
  ------------------
  |  Branch (323:13): [True: 35, False: 1.06k]
  ------------------
  324|      2|            case BRACKET_L: return "\"[\"";
  ------------------
  |  Branch (324:13): [True: 2, False: 1.09k]
  ------------------
  325|     68|            case BRACKET_R: return "\"]\"";
  ------------------
  |  Branch (325:13): [True: 68, False: 1.03k]
  ------------------
  326|     60|            case COMMA: return "\",\"";
  ------------------
  |  Branch (326:13): [True: 60, False: 1.03k]
  ------------------
  327|     34|            case DOLLAR: return "\"$\"";
  ------------------
  |  Branch (327:13): [True: 34, False: 1.06k]
  ------------------
  328|     24|            case DOT: return "\".\"";
  ------------------
  |  Branch (328:13): [True: 24, False: 1.07k]
  ------------------
  329|       |
  330|      0|            case PAREN_L: return "\"(\"";
  ------------------
  |  Branch (330:13): [True: 0, False: 1.09k]
  ------------------
  331|     43|            case PAREN_R: return "\")\"";
  ------------------
  |  Branch (331:13): [True: 43, False: 1.05k]
  ------------------
  332|     31|            case SEMICOLON: return "\";\"";
  ------------------
  |  Branch (332:13): [True: 31, False: 1.06k]
  ------------------
  333|       |
  334|    115|            case IDENTIFIER: return "IDENTIFIER";
  ------------------
  |  Branch (334:13): [True: 115, False: 984]
  ------------------
  335|     43|            case NUMBER: return "NUMBER";
  ------------------
  |  Branch (335:13): [True: 43, False: 1.05k]
  ------------------
  336|    154|            case OPERATOR: return "OPERATOR";
  ------------------
  |  Branch (336:13): [True: 154, False: 945]
  ------------------
  337|     30|            case STRING_SINGLE: return "STRING_SINGLE";
  ------------------
  |  Branch (337:13): [True: 30, False: 1.06k]
  ------------------
  338|     12|            case STRING_DOUBLE: return "STRING_DOUBLE";
  ------------------
  |  Branch (338:13): [True: 12, False: 1.08k]
  ------------------
  339|      2|            case VERBATIM_STRING_SINGLE: return "VERBATIM_STRING_SINGLE";
  ------------------
  |  Branch (339:13): [True: 2, False: 1.09k]
  ------------------
  340|      4|            case VERBATIM_STRING_DOUBLE: return "VERBATIM_STRING_DOUBLE";
  ------------------
  |  Branch (340:13): [True: 4, False: 1.09k]
  ------------------
  341|     12|            case STRING_BLOCK: return "STRING_BLOCK";
  ------------------
  |  Branch (341:13): [True: 12, False: 1.08k]
  ------------------
  342|       |
  343|      1|            case ASSERT: return "assert";
  ------------------
  |  Branch (343:13): [True: 1, False: 1.09k]
  ------------------
  344|      3|            case ELSE: return "else";
  ------------------
  |  Branch (344:13): [True: 3, False: 1.09k]
  ------------------
  345|      0|            case ERROR: return "error";
  ------------------
  |  Branch (345:13): [True: 0, False: 1.09k]
  ------------------
  346|      1|            case FALSE: return "false";
  ------------------
  |  Branch (346:13): [True: 1, False: 1.09k]
  ------------------
  347|      2|            case FOR: return "for";
  ------------------
  |  Branch (347:13): [True: 2, False: 1.09k]
  ------------------
  348|      1|            case FUNCTION: return "function";
  ------------------
  |  Branch (348:13): [True: 1, False: 1.09k]
  ------------------
  349|      2|            case IF: return "if";
  ------------------
  |  Branch (349:13): [True: 2, False: 1.09k]
  ------------------
  350|      1|            case IMPORT: return "import";
  ------------------
  |  Branch (350:13): [True: 1, False: 1.09k]
  ------------------
  351|      1|            case IMPORTSTR: return "importstr";
  ------------------
  |  Branch (351:13): [True: 1, False: 1.09k]
  ------------------
  352|      1|            case IMPORTBIN: return "importbin";
  ------------------
  |  Branch (352:13): [True: 1, False: 1.09k]
  ------------------
  353|     19|            case IN: return "in";
  ------------------
  |  Branch (353:13): [True: 19, False: 1.08k]
  ------------------
  354|      1|            case LOCAL: return "local";
  ------------------
  |  Branch (354:13): [True: 1, False: 1.09k]
  ------------------
  355|      0|            case NULL_LIT: return "null";
  ------------------
  |  Branch (355:13): [True: 0, False: 1.09k]
  ------------------
  356|      0|            case SELF: return "self";
  ------------------
  |  Branch (356:13): [True: 0, False: 1.09k]
  ------------------
  357|      1|            case SUPER: return "super";
  ------------------
  |  Branch (357:13): [True: 1, False: 1.09k]
  ------------------
  358|      1|            case TAILSTRICT: return "tailstrict";
  ------------------
  |  Branch (358:13): [True: 1, False: 1.09k]
  ------------------
  359|      6|            case THEN: return "then";
  ------------------
  |  Branch (359:13): [True: 6, False: 1.09k]
  ------------------
  360|      0|            case TRUE: return "true";
  ------------------
  |  Branch (360:13): [True: 0, False: 1.09k]
  ------------------
  361|       |
  362|    365|            case END_OF_FILE: return "end of file";
  ------------------
  |  Branch (362:13): [True: 365, False: 734]
  ------------------
  363|      0|            default:
  ------------------
  |  Branch (363:13): [True: 0, False: 1.09k]
  ------------------
  364|      0|                std::cerr << "INTERNAL ERROR: Unknown token kind: " << v << std::endl;
  365|      0|                std::abort();
  366|  1.09k|        }
  367|  1.09k|    }
parser.cpp:_ZN7jsonnet8internallsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEENS0_5Token4KindE:
  387|    631|{
  388|    631|    o << Token::toString(v);
  389|    631|    return o;
  390|    631|}
parser.cpp:_ZN7jsonnet8internallsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS0_5TokenE:
  393|    501|{
  394|    501|    if (v.data == "") {
  ------------------
  |  Branch (394:9): [True: 338, False: 163]
  ------------------
  395|    338|        o << Token::toString(v.kind);
  396|    338|    } else if (v.kind == Token::OPERATOR) {
  ------------------
  |  Branch (396:16): [True: 33, False: 130]
  ------------------
  397|     33|        o << "\"" << v.data << "\"";
  398|    130|    } else {
  399|    130|        o << "(" << Token::toString(v.kind) << ", \"" << v.data << "\")";
  400|    130|    }
  401|    501|    return o;
  402|    501|}
lexer.cpp:_ZN7jsonnet8internalL16fodder_push_backERNSt3__16vectorINS0_13FodderElementENS1_9allocatorIS3_EEEERKS3_:
  143|   111k|{
  144|   111k|    if (fodder_has_clean_endline(a) && elem.kind == FodderElement::LINE_END) {
  ------------------
  |  Branch (144:9): [True: 97.0k, False: 14.7k]
  |  Branch (144:40): [True: 0, False: 97.0k]
  ------------------
  145|      0|        if (elem.comment.size() > 0) {
  ------------------
  |  Branch (145:13): [True: 0, False: 0]
  ------------------
  146|       |            // The line end had a comment, so create a single line paragraph for it.
  147|      0|            a.emplace_back(FodderElement::PARAGRAPH, elem.blanks, elem.indent, elem.comment);
  148|      0|        } else {
  149|       |            // Merge it into the previous line end.
  150|      0|            a.back().indent = elem.indent;
  151|      0|            a.back().blanks += elem.blanks;
  152|      0|        }
  153|   111k|    } else {
  154|   111k|        if (!fodder_has_clean_endline(a) && elem.kind == FodderElement::PARAGRAPH) {
  ------------------
  |  Branch (154:13): [True: 14.7k, False: 97.0k]
  |  Branch (154:45): [True: 14.7k, False: 0]
  ------------------
  155|  14.7k|            a.emplace_back(FodderElement::LINE_END, 0, elem.indent, std::vector<std::string>());
  156|  14.7k|        }
  157|   111k|        a.push_back(elem);
  158|   111k|    }
  159|   111k|}
lexer.cpp:_ZN7jsonnet8internalL24fodder_has_clean_endlineERKNSt3__16vectorINS0_13FodderElementENS1_9allocatorIS3_EEEE:
  134|   223k|{
  135|   223k|    return !fodder.empty() && fodder.back().kind != FodderElement::INTERSTITIAL;
  ------------------
  |  Branch (135:12): [True: 200k, False: 23.3k]
  |  Branch (135:31): [True: 194k, False: 6.12k]
  ------------------
  136|   223k|}

jsonnet_version:
  334|  16.6k|{
  335|  16.6k|    return LIB_JSONNET_VERSION;
  ------------------
  |  |   34|  16.6k|#define LIB_JSONNET_VERSION "v0.22.0"
  ------------------
  336|  16.6k|}
jsonnet_make:
  339|  8.31k|{
  340|  8.31k|    TRY
  ------------------
  |  |  319|  8.31k|#define TRY try {
  ------------------
  341|  8.31k|        return new JsonnetVm();
  342|  8.31k|    CATCH("jsonnet_make")
  ------------------
  |  |  321|  8.31k|    }                                                                                         \
  |  |  322|  8.31k|    catch (const std::bad_alloc &)                                                            \
  |  |  323|  8.31k|    {                                                                                         \
  |  |  324|      0|        memory_panic();                                                                       \
  |  |  325|      0|    }                                                                                         \
  |  |  326|  8.31k|    catch (const std::exception &e)                                                           \
  |  |  327|  8.31k|    {                                                                                         \
  |  |  328|      0|        std::cerr << "Something went wrong during " func ", please report this: " << e.what() \
  |  |  329|      0|                  << std::endl;                                                               \
  |  |  330|      0|        abort();                                                                              \
  |  |  331|      0|    }
  ------------------
  343|      0|    return nullptr;
  344|  8.31k|}
jsonnet_destroy:
  347|  8.31k|{
  348|  8.31k|    TRY
  ------------------
  |  |  319|  8.31k|#define TRY try {
  ------------------
  349|  8.31k|        delete vm;
  350|  8.31k|    CATCH("jsonnet_destroy")
  ------------------
  |  |  321|  8.31k|    }                                                                                         \
  |  |  322|  8.31k|    catch (const std::bad_alloc &)                                                            \
  |  |  323|  8.31k|    {                                                                                         \
  |  |  324|      0|        memory_panic();                                                                       \
  |  |  325|      0|    }                                                                                         \
  |  |  326|  8.31k|    catch (const std::exception &e)                                                           \
  |  |  327|  8.31k|    {                                                                                         \
  |  |  328|      0|        std::cerr << "Something went wrong during " func ", please report this: " << e.what() \
  |  |  329|      0|                  << std::endl;                                                               \
  |  |  330|      0|        abort();                                                                              \
  |  |  331|      0|    }
  ------------------
  351|  8.31k|}
jsonnet_import_callback:
  379|  8.31k|{
  380|  8.31k|    vm->importCallback = cb;
  381|  8.31k|    vm->importCallbackContext = ctx;
  382|  8.31k|}
jsonnet_evaluate_snippet_multi:
  738|  8.31k|{
  739|  8.31k|    TRY
  ------------------
  |  |  319|  8.31k|#define TRY try {
  ------------------
  740|  8.31k|        return jsonnet_evaluate_snippet_aux(vm, filename, snippet, error, MULTI);
  741|  8.31k|    CATCH("jsonnet_evaluate_snippet_multi")
  ------------------
  |  |  321|  8.31k|    }                                                                                         \
  |  |  322|  8.31k|    catch (const std::bad_alloc &)                                                            \
  |  |  323|  8.31k|    {                                                                                         \
  |  |  324|      0|        memory_panic();                                                                       \
  |  |  325|      0|    }                                                                                         \
  |  |  326|  8.31k|    catch (const std::exception &e)                                                           \
  |  |  327|  8.31k|    {                                                                                         \
  |  |  328|      0|        std::cerr << "Something went wrong during " func ", please report this: " << e.what() \
  |  |  329|      0|                  << std::endl;                                                               \
  |  |  330|      0|        abort();                                                                              \
  |  |  331|      0|    }
  ------------------
  742|      0|    return nullptr;  // Never happens.
  743|  8.31k|}
jsonnet_realloc:
  755|  15.9k|{
  756|  15.9k|    (void)vm;
  757|  15.9k|    if (str == nullptr) {
  ------------------
  |  Branch (757:9): [True: 7.67k, False: 8.31k]
  ------------------
  758|  7.67k|        if (sz == 0)
  ------------------
  |  Branch (758:13): [True: 0, False: 7.67k]
  ------------------
  759|      0|            return nullptr;
  760|  7.67k|        auto *r = static_cast<char *>(::malloc(sz));
  761|  7.67k|        if (r == nullptr)
  ------------------
  |  Branch (761:13): [True: 0, False: 7.67k]
  ------------------
  762|      0|            memory_panic();
  763|  7.67k|        return r;
  764|  8.31k|    } else {
  765|  8.31k|        if (sz == 0) {
  ------------------
  |  Branch (765:13): [True: 8.31k, False: 0]
  ------------------
  766|  8.31k|            ::free(str);
  767|  8.31k|            return nullptr;
  768|  8.31k|        } else {
  769|      0|            auto *r = static_cast<char *>(::realloc(str, sz));
  770|      0|            if (r == nullptr)
  ------------------
  |  Branch (770:17): [True: 0, False: 0]
  ------------------
  771|      0|                memory_panic();
  772|      0|            return r;
  773|      0|        }
  774|  8.31k|    }
  775|  15.9k|}
_ZN9JsonnetVmC2Ev:
  228|  8.31k|        : gcGrowthTrigger(2.0),
  229|  8.31k|          maxStack(500),
  230|  8.31k|          gcMinObjects(1000),
  231|  8.31k|          maxTrace(20),
  232|  8.31k|          importCallback(default_import_callback),
  233|  8.31k|          importCallbackContext(this),
  234|  8.31k|          stringOutput(false),
  235|  8.31k|          trailingNewline(true),
  236|  8.31k|          fmtDebugDesugaring(false)
  237|  8.31k|    {
  238|  8.31k|        jpaths.emplace_back("/usr/share/jsonnet-" + std::string(jsonnet_version()) + "/");
  239|  8.31k|        jpaths.emplace_back("/usr/local/share/jsonnet-" + std::string(jsonnet_version()) + "/");
  240|  8.31k|    }
libjsonnet.cpp:_ZL11from_stringP9JsonnetVmRKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   90|  7.67k|{
   91|  7.67k|    char *r = jsonnet_realloc(vm, nullptr, v.length() + 1);
   92|  7.67k|    std::memcpy(r, v.c_str(), v.length() + 1);
   93|  7.67k|    return r;
   94|  7.67k|}
libjsonnet.cpp:_ZL28jsonnet_evaluate_snippet_auxP9JsonnetVmPKcS2_PiN12_GLOBAL__N_18EvalKindE:
  541|  8.31k|{
  542|  8.31k|    try {
  543|  8.31k|        Allocator alloc;
  544|  8.31k|        AST *expr;
  545|  8.31k|        Tokens tokens = jsonnet_lex(filename, snippet);
  546|       |
  547|  8.31k|        expr = jsonnet_parse(&alloc, tokens);
  548|       |
  549|  8.31k|        jsonnet_desugar(&alloc, expr, &vm->tla);
  550|       |
  551|  8.31k|        unsigned max_stack = vm->maxStack;
  552|       |
  553|       |        // For the stdlib desugaring.
  554|  8.31k|        max_stack++;
  555|       |
  556|       |        // For the TLA desugaring.
  557|  8.31k|        max_stack++;
  558|       |
  559|  8.31k|        jsonnet_static_analysis(expr);
  560|  8.31k|        switch (kind) {
  561|      0|            case REGULAR: {
  ------------------
  |  Branch (561:13): [True: 0, False: 8.31k]
  ------------------
  562|      0|                std::string json_str = jsonnet_vm_execute(&alloc,
  563|      0|                                                          expr,
  564|      0|                                                          vm->ext,
  565|      0|                                                          max_stack,
  566|      0|                                                          vm->gcMinObjects,
  567|      0|                                                          vm->gcGrowthTrigger,
  568|      0|                                                          vm->nativeCallbacks,
  569|      0|                                                          vm->importCallback,
  570|      0|                                                          vm->importCallbackContext,
  571|      0|                                                          vm->stringOutput);
  572|      0|                if (vm->trailingNewline) {
  ------------------
  |  Branch (572:21): [True: 0, False: 0]
  ------------------
  573|      0|                    json_str += "\n";
  574|      0|                }
  575|      0|                *error = false;
  576|      0|                return from_string(vm, json_str);
  577|      0|            } break;
  578|       |
  579|  4.02k|            case MULTI: {
  ------------------
  |  Branch (579:13): [True: 4.02k, False: 4.29k]
  ------------------
  580|  4.02k|                std::map<std::string, std::string> files =
  581|  4.02k|                    jsonnet_vm_execute_multi(&alloc,
  582|  4.02k|                                             expr,
  583|  4.02k|                                             vm->ext,
  584|  4.02k|                                             max_stack,
  585|  4.02k|                                             vm->gcMinObjects,
  586|  4.02k|                                             vm->gcGrowthTrigger,
  587|  4.02k|                                             vm->nativeCallbacks,
  588|  4.02k|                                             vm->importCallback,
  589|  4.02k|                                             vm->importCallbackContext,
  590|  4.02k|                                             vm->stringOutput);
  591|  4.02k|                size_t sz = 1;  // final sentinel
  592|  6.01k|                for (const auto &pair : files) {
  ------------------
  |  Branch (592:39): [True: 6.01k, False: 4.02k]
  ------------------
  593|  6.01k|                    sz += pair.first.length() + 1;   // include sentinel
  594|  6.01k|                    sz += pair.second.length() + 2;  // Add a '\n' as well as sentinel
  595|  6.01k|                }
  596|  4.02k|                char *buf = (char *)::malloc(sz);
  597|  4.02k|                if (buf == nullptr)
  ------------------
  |  Branch (597:21): [True: 0, False: 4.02k]
  ------------------
  598|      0|                    memory_panic();
  599|  4.02k|                std::ptrdiff_t i = 0;
  600|  6.01k|                for (const auto &pair : files) {
  ------------------
  |  Branch (600:39): [True: 6.01k, False: 4.02k]
  ------------------
  601|  6.01k|                    memcpy(&buf[i], pair.first.c_str(), pair.first.length() + 1);
  602|  6.01k|                    i += pair.first.length() + 1;
  603|  6.01k|                    memcpy(&buf[i], pair.second.c_str(), pair.second.length());
  604|  6.01k|                    i += pair.second.length();
  605|  6.01k|                    if (vm->trailingNewline) {
  ------------------
  |  Branch (605:25): [True: 6.01k, False: 0]
  ------------------
  606|  6.01k|                        buf[i] = '\n';
  607|  6.01k|                        i++;
  608|  6.01k|                    }
  609|  6.01k|                    buf[i] = '\0';
  610|  6.01k|                    i++;
  611|  6.01k|                }
  612|  4.02k|                buf[i] = '\0';  // final sentinel
  613|  4.02k|                *error = false;
  614|  4.02k|                return buf;
  615|      0|            } break;
  616|       |
  617|      0|            case STREAM: {
  ------------------
  |  Branch (617:13): [True: 0, False: 8.31k]
  ------------------
  618|      0|                if (!vm->trailingNewline) {
  ------------------
  |  Branch (618:21): [True: 0, False: 0]
  ------------------
  619|      0|                    *error = true;
  620|      0|                    return from_string(vm, "INTERNAL: trailing-newline is required for streamed output");
  621|      0|                }
  622|      0|                std::vector<std::string> documents =
  623|      0|                    jsonnet_vm_execute_stream(&alloc,
  624|      0|                                              expr,
  625|      0|                                              vm->ext,
  626|      0|                                              max_stack,
  627|      0|                                              vm->gcMinObjects,
  628|      0|                                              vm->gcGrowthTrigger,
  629|      0|                                              vm->nativeCallbacks,
  630|      0|                                              vm->importCallback,
  631|      0|                                              vm->importCallbackContext,
  632|      0|                                              vm->stringOutput);
  633|      0|                size_t sz = 1;  // final sentinel
  634|      0|                for (const auto &doc : documents) {
  ------------------
  |  Branch (634:38): [True: 0, False: 0]
  ------------------
  635|      0|                    sz += doc.length() + 2;  // Add a '\n' as well as sentinel
  636|      0|                }
  637|      0|                char *buf = (char *)::malloc(sz);
  638|      0|                if (buf == nullptr)
  ------------------
  |  Branch (638:21): [True: 0, False: 0]
  ------------------
  639|      0|                    memory_panic();
  640|      0|                std::ptrdiff_t i = 0;
  641|      0|                for (const auto &doc : documents) {
  ------------------
  |  Branch (641:38): [True: 0, False: 0]
  ------------------
  642|      0|                    memcpy(&buf[i], doc.c_str(), doc.length());
  643|      0|                    i += doc.length();
  644|      0|                    buf[i] = '\n';
  645|      0|                    i++;
  646|      0|                    buf[i] = '\0';
  647|      0|                    i++;
  648|      0|                }
  649|      0|                buf[i] = '\0';  // final sentinel
  650|      0|                *error = false;
  651|      0|                return buf;
  652|      0|            } break;
  653|       |
  654|      0|            default:
  ------------------
  |  Branch (654:13): [True: 0, False: 8.31k]
  ------------------
  655|      0|                fputs("INTERNAL ERROR: bad value of 'kind', probably memory corruption.\n", stderr);
  656|      0|                abort();
  657|  8.31k|        }
  658|       |
  659|  8.31k|    } catch (StaticError &e) {
  660|  4.29k|        std::stringstream ss;
  661|  4.29k|        ss << "STATIC ERROR: " << e << std::endl;
  662|  4.29k|        *error = true;
  663|  4.29k|        return from_string(vm, ss.str());
  664|       |
  665|  4.29k|    } catch (RuntimeError &e) {
  666|  3.37k|        std::stringstream ss;
  667|  3.37k|        ss << "RUNTIME ERROR: " << e.msg << std::endl;
  668|  3.37k|        const long max_above = vm->maxTrace / 2;
  669|  3.37k|        const long max_below = vm->maxTrace - max_above;
  670|  3.37k|        const long sz = e.stackTrace.size();
  671|   334k|        for (long i = 0; i < sz; ++i) {
  ------------------
  |  Branch (671:26): [True: 330k, False: 3.37k]
  ------------------
  672|   330k|            const auto &f = e.stackTrace[i];
  673|   330k|            if (vm->maxTrace > 0 && i >= max_above && i < sz - max_below) {
  ------------------
  |  Branch (673:17): [True: 330k, False: 0]
  |  Branch (673:37): [True: 315k, False: 15.6k]
  |  Branch (673:55): [True: 305k, False: 9.47k]
  ------------------
  674|   305k|                if (i == max_above)
  ------------------
  |  Branch (674:21): [True: 817, False: 304k]
  ------------------
  675|    817|                    ss << "\t..." << std::endl;
  676|   305k|            } else {
  677|  25.1k|                ss << "\t" << f.location << "\t" << f.name << std::endl;
  678|  25.1k|            }
  679|   330k|        }
  680|  3.37k|        *error = true;
  681|  3.37k|        return from_string(vm, ss.str());
  682|  3.37k|    }
  683|       |
  684|      0|    return nullptr;  // Quiet, compiler.
  685|  8.31k|}

_ZN7jsonnet8internal22jsonnet_unparse_numberEd:
   38|  3.62M|{
   39|  3.62M|    std::stringstream ss;
   40|       |    // Make sure we output the same thing, even if the user
   41|       |    // of the library changed the global locale
   42|  3.62M|    ss.imbue(std::locale::classic());
   43|  3.62M|    if (v == floor(v)) {
  ------------------
  |  Branch (43:9): [True: 3.51M, False: 116k]
  ------------------
   44|  3.51M|        ss << std::fixed << std::setprecision(0) << v;
   45|  3.51M|    } else {
   46|       |        // See "What Every Computer Scientist Should Know About Floating-Point Arithmetic"
   47|       |        // Theorem 15
   48|       |        // https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
   49|   116k|        ss << std::setprecision(17);
   50|   116k|        ss << v;
   51|   116k|    }
   52|  3.62M|    return ss.str();
   53|  3.62M|}
_ZN7jsonnet8internal13jsonnet_parseEPNS0_9AllocatorERNSt3__14listINS0_5TokenENS3_9allocatorIS5_EEEE:
 1210|  16.5k|{
 1211|  16.5k|    Parser parser(tokens, alloc);
 1212|  16.5k|    unsigned parse_depth = 0;
 1213|  16.5k|    AST *expr = parser.parse(MAX_PRECEDENCE, parse_depth);
 1214|  16.5k|    if (tokens.front().kind != Token::END_OF_FILE) {
  ------------------
  |  Branch (1214:9): [True: 218, False: 16.2k]
  ------------------
 1215|    218|        std::stringstream ss;
 1216|    218|        ss << "did not expect: " << tokens.front();
 1217|    218|        throw StaticError(tokens.front().location, ss.str());
 1218|    218|    }
 1219|       |
 1220|  16.2k|    return expr;
 1221|  16.5k|}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16ParserC2ERNSt3__14listINS0_5TokenENS3_9allocatorIS5_EEEEPNS0_9AllocatorE:
  155|  16.5k|    Parser(Tokens &tokens, Allocator *alloc) : tokens(tokens), alloc(alloc) {}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser5parseEjj:
  980|  46.7M|    {
  981|  46.7M|        if (current_depth >= MAX_PARSER_DEPTH) {
  ------------------
  |  Branch (981:13): [True: 3, False: 46.7M]
  ------------------
  982|      3|            throw StaticError(peek().location, "Exceeded maximum parse depth limit.");
  983|      3|        }
  984|       |
  985|  46.7M|        AST *ast = maybeParseGreedy(current_depth + 1);
  986|       |        // There cannot be an operator after a greedy parse.
  987|  46.7M|        if (ast != nullptr) return ast;
  ------------------
  |  Branch (987:13): [True: 6.09M, False: 40.7M]
  ------------------
  988|       |
  989|       |        // If we get here, we could be parsing an infix construct.
  990|       |
  991|       |        // Allocate this on the heap to control stack growth.
  992|  40.7M|        std::unique_ptr<Token> begin_(new Token(peek()));
  993|  40.7M|        const Token &begin = *begin_;
  994|       |
  995|  40.7M|        AST *lhs = parseTerminalBracketsOrUnary(current_depth + 1);
  996|       |
  997|  40.7M|        return parseInfix(lhs, begin, max_precedence, current_depth + 1);
  998|  46.7M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser4peekEv:
  123|   386M|    {
  124|   386M|        return tokens.front();
  125|   386M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser16maybeParseGreedyEj:
  811|  46.7M|    {
  812|  46.7M|        if (current_depth >= MAX_PARSER_DEPTH) {
  ------------------
  |  Branch (812:13): [True: 2, False: 46.7M]
  ------------------
  813|      2|            throw StaticError(peek().location, "Exceeded maximum parse depth limit.");
  814|      2|        }
  815|       |
  816|       |        // Allocate this on the heap to control stack growth.
  817|  46.7M|        std::unique_ptr<Token> begin_(new Token(peek()));
  818|  46.7M|        const Token &begin = *begin_;
  819|       |
  820|  46.7M|        switch (begin.kind) {
  821|       |            // These cases have effectively MAX_PRECEDENCE as the first
  822|       |            // call to parse will parse them.
  823|   360k|            case Token::ASSERT: {
  ------------------
  |  Branch (823:13): [True: 360k, False: 46.4M]
  ------------------
  824|   360k|                pop();
  825|   360k|                AST *cond = parse(MAX_PRECEDENCE, current_depth + 1);
  826|   360k|                Fodder colonFodder;
  827|   360k|                AST *msg = nullptr;
  828|   360k|                if (peek().kind == Token::OPERATOR && peek().data == ":") {
  ------------------
  |  Branch (828:21): [True: 333k, False: 27.0k]
  |  Branch (828:55): [True: 333k, False: 1]
  ------------------
  829|   333k|                    Token colon = pop();
  830|   333k|                    colonFodder = colon.fodder;
  831|   333k|                    msg = parse(MAX_PRECEDENCE, current_depth + 1);
  832|   333k|                }
  833|   360k|                Token semicolon = popExpect(Token::SEMICOLON);
  834|   360k|                AST *rest = parse(MAX_PRECEDENCE, current_depth + 1);
  835|   360k|                return alloc->make<Assert>(span(begin, rest),
  836|   360k|                                           begin.fodder,
  837|   360k|                                           cond,
  838|   360k|                                           colonFodder,
  839|   360k|                                           msg,
  840|   360k|                                           semicolon.fodder,
  841|   360k|                                           rest);
  842|      0|            }
  843|       |
  844|   573k|            case Token::ERROR: {
  ------------------
  |  Branch (844:13): [True: 573k, False: 46.2M]
  ------------------
  845|   573k|                pop();
  846|   573k|                AST *expr = parse(MAX_PRECEDENCE, current_depth + 1);
  847|   573k|                return alloc->make<Error>(span(begin, expr), begin.fodder, expr);
  848|      0|            }
  849|       |
  850|  2.85M|            case Token::IF: {
  ------------------
  |  Branch (850:13): [True: 2.85M, False: 43.9M]
  ------------------
  851|  2.85M|                pop();
  852|  2.85M|                AST *cond = parse(MAX_PRECEDENCE, current_depth + 1);
  853|  2.85M|                Token then = popExpect(Token::THEN);
  854|  2.85M|                AST *branch_true = parse(MAX_PRECEDENCE, current_depth + 1);
  855|  2.85M|                if (peek().kind == Token::ELSE) {
  ------------------
  |  Branch (855:21): [True: 2.82M, False: 35.5k]
  ------------------
  856|  2.82M|                    Token else_ = pop();
  857|  2.82M|                    AST *branch_false = parse(MAX_PRECEDENCE, current_depth + 1);
  858|  2.82M|                    return alloc->make<Conditional>(span(begin, branch_false),
  859|  2.82M|                                                    begin.fodder,
  860|  2.82M|                                                    cond,
  861|  2.82M|                                                    then.fodder,
  862|  2.82M|                                                    branch_true,
  863|  2.82M|                                                    else_.fodder,
  864|  2.82M|                                                    branch_false);
  865|  2.82M|                }
  866|  35.5k|                return alloc->make<Conditional>(span(begin, branch_true),
  867|  35.5k|                                                begin.fodder,
  868|  35.5k|                                                cond,
  869|  35.5k|                                                then.fodder,
  870|  35.5k|                                                branch_true,
  871|  35.5k|                                                Fodder{},
  872|  35.5k|                                                nullptr);
  873|  2.85M|            }
  874|       |
  875|   177k|            case Token::FUNCTION: {
  ------------------
  |  Branch (875:13): [True: 177k, False: 46.6M]
  ------------------
  876|   177k|                pop();  // Still available in 'begin'.
  877|   177k|                Token paren_l = pop();
  878|   177k|                if (paren_l.kind == Token::PAREN_L) {
  ------------------
  |  Branch (878:21): [True: 177k, False: 5]
  ------------------
  879|   177k|                    std::vector<AST *> params_asts;
  880|   177k|                    bool got_comma;
  881|   177k|                    Fodder paren_r_fodder;
  882|   177k|                    ArgParams params = parseParams("function parameter", got_comma, paren_r_fodder, current_depth);
  883|   177k|                    AST *body = parse(MAX_PRECEDENCE, current_depth + 1);
  884|   177k|                    return alloc->make<Function>(span(begin, body),
  885|   177k|                                                 begin.fodder,
  886|   177k|                                                 paren_l.fodder,
  887|   177k|                                                 params,
  888|   177k|                                                 got_comma,
  889|   177k|                                                 paren_r_fodder,
  890|   177k|                                                 body);
  891|   177k|                } else {
  892|      5|                    std::stringstream ss;
  893|      5|                    ss << "expected ( but got " << paren_l;
  894|      5|                    throw StaticError(paren_l.location, ss.str());
  895|      5|                }
  896|   177k|            }
  897|       |
  898|    417|            case Token::IMPORT: {
  ------------------
  |  Branch (898:13): [True: 417, False: 46.7M]
  ------------------
  899|    417|                pop();
  900|    417|                AST *body = parse(MAX_PRECEDENCE, current_depth + 1);
  901|    417|                if (body->type == AST_LITERAL_STRING) {
  ------------------
  |  Branch (901:21): [True: 294, False: 123]
  ------------------
  902|    294|                    auto *lit = static_cast<LiteralString *>(body);
  903|    294|                    if (lit->tokenKind == LiteralString::BLOCK) {
  ------------------
  |  Branch (903:25): [True: 1, False: 293]
  ------------------
  904|      1|                        throw StaticError(lit->location,
  905|      1|                                          "Cannot use text blocks in import statements.");
  906|      1|                    }
  907|    293|                    return alloc->make<Import>(span(begin, body), begin.fodder, lit);
  908|    294|                } else {
  909|    123|                    std::stringstream ss;
  910|    123|                    ss << "computed imports are not allowed.";
  911|    123|                    throw StaticError(body->location, ss.str());
  912|    123|                }
  913|    417|            }
  914|       |
  915|  1.93k|            case Token::IMPORTSTR: {
  ------------------
  |  Branch (915:13): [True: 1.93k, False: 46.7M]
  ------------------
  916|  1.93k|                pop();
  917|  1.93k|                AST *body = parse(MAX_PRECEDENCE, current_depth + 1);
  918|  1.93k|                if (body->type == AST_LITERAL_STRING) {
  ------------------
  |  Branch (918:21): [True: 1.65k, False: 289]
  ------------------
  919|  1.65k|                    auto *lit = static_cast<LiteralString *>(body);
  920|  1.65k|                    if (lit->tokenKind == LiteralString::BLOCK) {
  ------------------
  |  Branch (920:25): [True: 1, False: 1.64k]
  ------------------
  921|      1|                        throw StaticError(lit->location,
  922|      1|                                          "Cannot use text blocks in import statements.");
  923|      1|                    }
  924|  1.64k|                    return alloc->make<Importstr>(span(begin, body), begin.fodder, lit);
  925|  1.65k|                } else {
  926|    289|                    std::stringstream ss;
  927|    289|                    ss << "computed imports are not allowed.";
  928|    289|                    throw StaticError(body->location, ss.str());
  929|    289|                }
  930|  1.93k|            }
  931|       |
  932|    733|            case Token::IMPORTBIN: {
  ------------------
  |  Branch (932:13): [True: 733, False: 46.7M]
  ------------------
  933|    733|                pop();
  934|    733|                AST *body = parse(MAX_PRECEDENCE, current_depth + 1);
  935|    733|                if (body->type == AST_LITERAL_STRING) {
  ------------------
  |  Branch (935:21): [True: 649, False: 84]
  ------------------
  936|    649|                    auto *lit = static_cast<LiteralString *>(body);
  937|    649|                    if (lit->tokenKind == LiteralString::BLOCK) {
  ------------------
  |  Branch (937:25): [True: 0, False: 649]
  ------------------
  938|      0|                        throw StaticError(lit->location,
  939|      0|                                          "Cannot use text blocks in import statements.");
  940|      0|                    }
  941|    649|                    return alloc->make<Importbin>(span(begin, body), begin.fodder, lit);
  942|    649|                } else {
  943|     84|                    std::stringstream ss;
  944|     84|                    ss << "computed imports are not allowed.";
  945|     84|                    throw StaticError(body->location, ss.str());
  946|     84|                }
  947|    733|            }
  948|       |
  949|  2.12M|            case Token::LOCAL: {
  ------------------
  |  Branch (949:13): [True: 2.12M, False: 44.6M]
  ------------------
  950|  2.12M|                pop();
  951|  2.12M|                Local::Binds binds;
  952|  2.23M|                do {
  953|  2.23M|                    Token delim = parseBind(binds, current_depth + 1);
  954|  2.23M|                    if (delim.kind != Token::SEMICOLON && delim.kind != Token::COMMA) {
  ------------------
  |  Branch (954:25): [True: 115k, False: 2.12M]
  |  Branch (954:59): [True: 12, False: 115k]
  ------------------
  955|     12|                        std::stringstream ss;
  956|     12|                        ss << "expected , or ; but got " << delim;
  957|     12|                        throw StaticError(delim.location, ss.str());
  958|     12|                    }
  959|  2.23M|                    if (delim.kind == Token::SEMICOLON)
  ------------------
  |  Branch (959:25): [True: 2.12M, False: 116k]
  ------------------
  960|  2.12M|                        break;
  961|  2.23M|                } while (true);
  ------------------
  |  Branch (961:26): [True: 115k, Folded]
  ------------------
  962|  2.12M|                AST *body = parse(MAX_PRECEDENCE, current_depth + 1);
  963|  2.12M|                return alloc->make<Local>(span(begin, body), begin.fodder, binds, body);
  964|  2.12M|            }
  965|       |
  966|  40.7M|            default:
  ------------------
  |  Branch (966:13): [True: 40.7M, False: 6.09M]
  ------------------
  967|  40.7M|            return nullptr;
  968|  46.7M|        }
  969|  46.7M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser3popEv:
  111|   121M|    {
  112|   121M|        Token tok = peek();
  113|   121M|        tokens.pop_front();
  114|   121M|        return tok;
  115|   121M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser9popExpectENS0_5Token4KindEPKc:
  136|  18.9M|    {
  137|  18.9M|        Token tok = pop();
  138|  18.9M|        if (tok.kind != k) {
  ------------------
  |  Branch (138:13): [True: 238, False: 18.9M]
  ------------------
  139|    238|            std::stringstream ss;
  140|    238|            ss << "expected token " << k << " but got " << tok;
  141|    238|            throw StaticError(tok.location, ss.str());
  142|    238|        }
  143|  18.9M|        if (data != nullptr && tok.data != data) {
  ------------------
  |  Branch (143:13): [True: 2.29M, False: 16.6M]
  |  Branch (143:32): [True: 19, False: 2.29M]
  ------------------
  144|     19|            std::stringstream ss;
  145|     19|            ss << "expected operator " << data << " but got " << tok.data;
  146|     19|            throw StaticError(tok.location, ss.str());
  147|     19|        }
  148|  18.9M|        return tok;
  149|  18.9M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14spanERKNS0_5TokenEPNS0_3ASTE:
   94|  14.2M|{
   95|  14.2M|    return LocationRange(begin.location.file, begin.location.begin, end->location.end);
   96|  14.2M|}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser11parseParamsERKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEERbRNS3_6vectorINS0_13FodderElementENS7_ISE_EEEEj:
  218|  1.93M|    {
  219|  1.93M|        ArgParams params;
  220|  1.93M|        Token paren_r = parseArgs(params, element_kind, got_comma, current_depth);
  221|       |
  222|       |        // Check they're all identifiers
  223|       |        // parseArgs returns f(x) with x as an expression.  Convert it here.
  224|  3.78M|        for (auto &p : params) {
  ------------------
  |  Branch (224:22): [True: 3.78M, False: 1.93M]
  ------------------
  225|  3.78M|            if (p.id == nullptr) {
  ------------------
  |  Branch (225:17): [True: 3.60M, False: 185k]
  ------------------
  226|  3.60M|                if (p.expr->type != AST_VAR) {
  ------------------
  |  Branch (226:21): [True: 4, False: 3.60M]
  ------------------
  227|      4|                    throw StaticError(p.expr->location, "could not parse parameter here.");
  228|      4|                }
  229|  3.60M|                auto *pv = static_cast<Var *>(p.expr);
  230|  3.60M|                p.id = pv->id;
  231|  3.60M|                p.idFodder = pv->openFodder;
  232|  3.60M|                p.expr = nullptr;
  233|  3.60M|            }
  234|  3.78M|        }
  235|       |
  236|  1.93M|        close_fodder = paren_r.fodder;
  237|       |
  238|  1.93M|        return params;
  239|  1.93M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser9parseArgsERNSt3__16vectorINS0_8ArgParamENS3_9allocatorIS5_EEEERKNS3_12basic_stringIcNS3_11char_traitsIcEENS6_IcEEEERbj:
  167|  9.04M|    {
  168|  9.04M|        got_comma = false;
  169|  9.04M|        bool first = true;
  170|  24.8M|        do {
  171|  24.8M|            Token next = peek();
  172|  24.8M|            if (next.kind == Token::PAREN_R) {
  ------------------
  |  Branch (172:17): [True: 9.04M, False: 15.7M]
  ------------------
  173|       |                // got_comma can be true or false here.
  174|  9.04M|                return pop();
  175|  9.04M|            }
  176|  15.7M|            if (!first && !got_comma) {
  ------------------
  |  Branch (176:17): [True: 6.72M, False: 9.04M]
  |  Branch (176:27): [True: 88, False: 6.72M]
  ------------------
  177|     88|                std::stringstream ss;
  178|     88|                ss << "expected a comma before next " << element_kind << ".";
  179|     88|                throw StaticError(next.location, ss.str());
  180|     88|            }
  181|       |            // Either id=expr or id or expr, but note that expr could be id==1 so this needs
  182|       |            // look-ahead.
  183|  15.7M|            Fodder id_fodder;
  184|  15.7M|            const Identifier *id = nullptr;
  185|  15.7M|            Fodder eq_fodder;
  186|  15.7M|            if (peek().kind == Token::IDENTIFIER) {
  ------------------
  |  Branch (186:17): [True: 13.4M, False: 2.30M]
  ------------------
  187|  13.4M|                Token maybe_eq = doublePeek();
  188|  13.4M|                if (maybe_eq.kind == Token::OPERATOR && maybe_eq.data == "=") {
  ------------------
  |  Branch (188:21): [True: 1.39M, False: 12.0M]
  |  Branch (188:57): [True: 212k, False: 1.18M]
  ------------------
  189|   212k|                    id_fodder = peek().fodder;
  190|   212k|                    id = alloc->makeIdentifier(peek().data32());
  191|   212k|                    eq_fodder = maybe_eq.fodder;
  192|   212k|                    pop();  // id
  193|   212k|                    pop();  // eq
  194|   212k|                }
  195|  13.4M|            }
  196|  15.7M|            AST *expr = parse(MAX_PRECEDENCE, current_depth + 1);
  197|  15.7M|            got_comma = false;
  198|  15.7M|            first = false;
  199|  15.7M|            Fodder comma_fodder;
  200|  15.7M|            if (peek().kind == Token::COMMA) {
  ------------------
  |  Branch (200:17): [True: 6.72M, False: 9.04M]
  ------------------
  201|  6.72M|                Token comma = pop();
  202|  6.72M|                comma_fodder = comma.fodder;
  203|  6.72M|                got_comma = true;
  204|  6.72M|            }
  205|  15.7M|            args.emplace_back(id_fodder, id, eq_fodder, expr, comma_fodder);
  206|  15.7M|        } while (true);
  ------------------
  |  Branch (206:18): [True: 15.7M, Folded]
  ------------------
  207|  9.04M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser10doublePeekEv:
  129|  13.4M|    {
  130|  13.4M|        Tokens::iterator it = tokens.begin();  // First one.
  131|  13.4M|        it++;                                  // Now pointing at the second one.
  132|  13.4M|        return *(it);
  133|  13.4M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser9parseBindERNSt3__16vectorINS0_5Local4BindENS3_9allocatorIS6_EEEEj:
  248|  2.23M|    {
  249|  2.23M|        Token var_id = popExpect(Token::IDENTIFIER);
  250|  2.23M|        auto *id = alloc->makeIdentifier(var_id.data32());
  251|  2.23M|        for (const auto &bind : binds) {
  ------------------
  |  Branch (251:31): [True: 313k, False: 2.23M]
  ------------------
  252|   313k|            if (bind.var == id)
  ------------------
  |  Branch (252:17): [True: 6, False: 312k]
  ------------------
  253|      6|                throw StaticError(var_id.location, "duplicate local var: " + var_id.data);
  254|   313k|        }
  255|  2.23M|        bool is_function = false;
  256|  2.23M|        ArgParams params;
  257|  2.23M|        bool trailing_comma = false;
  258|  2.23M|        Fodder fodder_l, fodder_r;
  259|  2.23M|        if (peek().kind == Token::PAREN_L) {
  ------------------
  |  Branch (259:13): [True: 648k, False: 1.58M]
  ------------------
  260|   648k|            Token paren_l = pop();
  261|   648k|            fodder_l = paren_l.fodder;
  262|   648k|            params = parseParams("function parameter", trailing_comma, fodder_r, current_depth);
  263|   648k|            is_function = true;
  264|   648k|        }
  265|  2.23M|        Token eq = popExpect(Token::OPERATOR, "=");
  266|  2.23M|        AST *body = parse(MAX_PRECEDENCE, current_depth + 1);
  267|  2.23M|        Token delim = pop();
  268|  2.23M|        binds.emplace_back(var_id.fodder,
  269|  2.23M|                           id,
  270|  2.23M|                           eq.fodder,
  271|  2.23M|                           body,
  272|  2.23M|                           is_function,
  273|  2.23M|                           fodder_l,
  274|  2.23M|                           params,
  275|  2.23M|                           trailing_comma,
  276|  2.23M|                           fodder_r,
  277|  2.23M|                           delim.fodder);
  278|  2.23M|        return delim;
  279|  2.23M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser28parseTerminalBracketsOrUnaryEj:
  627|  40.7M|    {
  628|  40.7M|        if (current_depth >= MAX_PARSER_DEPTH) {
  ------------------
  |  Branch (628:13): [True: 0, False: 40.7M]
  ------------------
  629|      0|            throw StaticError(peek().location, "Exceeded maximum parse depth limit.");
  630|      0|        }
  631|       |
  632|  40.7M|        Token tok = pop();
  633|  40.7M|        switch (tok.kind) {
  ------------------
  |  Branch (633:17): [True: 40.7M, False: 0]
  ------------------
  634|      0|            case Token::ASSERT:
  ------------------
  |  Branch (634:13): [True: 0, False: 40.7M]
  ------------------
  635|     10|            case Token::BRACE_R:
  ------------------
  |  Branch (635:13): [True: 10, False: 40.7M]
  ------------------
  636|     22|            case Token::BRACKET_R:
  ------------------
  |  Branch (636:13): [True: 12, False: 40.7M]
  ------------------
  637|     57|            case Token::COMMA:
  ------------------
  |  Branch (637:13): [True: 35, False: 40.7M]
  ------------------
  638|     77|            case Token::DOT:
  ------------------
  |  Branch (638:13): [True: 20, False: 40.7M]
  ------------------
  639|     78|            case Token::ELSE:
  ------------------
  |  Branch (639:13): [True: 1, False: 40.7M]
  ------------------
  640|     78|            case Token::ERROR:
  ------------------
  |  Branch (640:13): [True: 0, False: 40.7M]
  ------------------
  641|     79|            case Token::FOR:
  ------------------
  |  Branch (641:13): [True: 1, False: 40.7M]
  ------------------
  642|     79|            case Token::FUNCTION:
  ------------------
  |  Branch (642:13): [True: 0, False: 40.7M]
  ------------------
  643|     79|            case Token::IF:
  ------------------
  |  Branch (643:13): [True: 0, False: 40.7M]
  ------------------
  644|     83|            case Token::IN:
  ------------------
  |  Branch (644:13): [True: 4, False: 40.7M]
  ------------------
  645|     83|            case Token::IMPORT:
  ------------------
  |  Branch (645:13): [True: 0, False: 40.7M]
  ------------------
  646|     83|            case Token::IMPORTSTR:
  ------------------
  |  Branch (646:13): [True: 0, False: 40.7M]
  ------------------
  647|     83|            case Token::IMPORTBIN:
  ------------------
  |  Branch (647:13): [True: 0, False: 40.7M]
  ------------------
  648|     83|            case Token::LOCAL:
  ------------------
  |  Branch (648:13): [True: 0, False: 40.7M]
  ------------------
  649|     99|            case Token::PAREN_R:
  ------------------
  |  Branch (649:13): [True: 16, False: 40.7M]
  ------------------
  650|    110|            case Token::SEMICOLON:
  ------------------
  |  Branch (650:13): [True: 11, False: 40.7M]
  ------------------
  651|    111|            case Token::TAILSTRICT:
  ------------------
  |  Branch (651:13): [True: 1, False: 40.7M]
  ------------------
  652|    112|            case Token::THEN: throw unexpected(tok, "parsing terminal");
  ------------------
  |  Branch (652:13): [True: 1, False: 40.7M]
  ------------------
  653|       |
  654|    716|            case Token::END_OF_FILE: throw StaticError(tok.location, "unexpected end of file.");
  ------------------
  |  Branch (654:13): [True: 716, False: 40.7M]
  ------------------
  655|       |
  656|   555k|            case Token::OPERATOR: {
  ------------------
  |  Branch (656:13): [True: 555k, False: 40.1M]
  ------------------
  657|   555k|                UnaryOp uop;
  658|   555k|                if (!op_is_unary(tok.data, uop)) {
  ------------------
  |  Branch (658:21): [True: 195, False: 555k]
  ------------------
  659|    195|                    std::stringstream ss;
  660|    195|                    ss << "not a unary operator: " << tok.data;
  661|    195|                    throw StaticError(tok.location, ss.str());
  662|    195|                }
  663|   555k|                AST *expr = parse(UNARY_PRECEDENCE, current_depth + 1);
  664|   555k|                return alloc->make<Unary>(span(tok, expr), tok.fodder, uop, expr);
  665|   555k|            }
  666|   427k|            case Token::BRACE_L: {
  ------------------
  |  Branch (666:13): [True: 427k, False: 40.2M]
  ------------------
  667|   427k|                AST *obj;
  668|   427k|                parseObjectRemainder(obj, tok, current_depth + 1);
  669|   427k|                return obj;
  670|   555k|            }
  671|       |
  672|  1.22M|            case Token::BRACKET_L: {
  ------------------
  |  Branch (672:13): [True: 1.22M, False: 39.4M]
  ------------------
  673|  1.22M|                Token next = peek();
  674|  1.22M|                if (next.kind == Token::BRACKET_R) {
  ------------------
  |  Branch (674:21): [True: 199k, False: 1.02M]
  ------------------
  675|   199k|                    Token bracket_r = pop();
  676|   199k|                    return alloc->make<Array>(
  677|   199k|                        span(tok, next), tok.fodder, Array::Elements{}, false, bracket_r.fodder);
  678|   199k|                }
  679|  1.02M|                AST *first = parse(MAX_PRECEDENCE, current_depth + 1);
  680|  1.02M|                bool got_comma = false;
  681|  1.02M|                Fodder comma_fodder;
  682|  1.02M|                next = peek();
  683|  1.02M|                if (!got_comma && next.kind == Token::COMMA) {
  ------------------
  |  Branch (683:21): [True: 1.02M, False: 2.97k]
  |  Branch (683:35): [True: 156k, False: 869k]
  ------------------
  684|   156k|                    Token comma = pop();
  685|   156k|                    comma_fodder = comma.fodder;
  686|   156k|                    next = peek();
  687|   156k|                    got_comma = true;
  688|   156k|                }
  689|       |
  690|  1.02M|                if (next.kind == Token::FOR) {
  ------------------
  |  Branch (690:21): [True: 281k, False: 746k]
  ------------------
  691|       |                    // It's a comprehension
  692|   281k|                    Token for_token = pop();
  693|   281k|                    std::vector<ComprehensionSpec> specs;
  694|   281k|                    Token last = parseComprehensionSpecs(Token::BRACKET_R, for_token.fodder, specs, current_depth + 1);
  695|   281k|                    return alloc->make<ArrayComprehension>(span(tok, last),
  696|   281k|                                                           tok.fodder,
  697|   281k|                                                           first,
  698|   281k|                                                           comma_fodder,
  699|   281k|                                                           got_comma,
  700|   281k|                                                           specs,
  701|   281k|                                                           last.fodder);
  702|   281k|                }
  703|       |
  704|       |                // Not a comprehension: It can have more elements.
  705|   746k|                Array::Elements elements;
  706|   746k|                elements.emplace_back(first, comma_fodder);
  707|  2.96M|                do {
  708|  2.96M|                    if (next.kind == Token::BRACKET_R) {
  ------------------
  |  Branch (708:25): [True: 742k, False: 2.22M]
  ------------------
  709|   742k|                        Token bracket_r = pop();
  710|   742k|                        return alloc->make<Array>(
  711|   742k|                            span(tok, next), tok.fodder, elements, got_comma, bracket_r.fodder);
  712|   742k|                    }
  713|  2.22M|                    if (!got_comma) {
  ------------------
  |  Branch (713:25): [True: 256, False: 2.22M]
  ------------------
  714|    256|                        std::stringstream ss;
  715|    256|                        ss << "expected a comma before next array element.";
  716|    256|                        throw StaticError(next.location, ss.str());
  717|    256|                    }
  718|  2.22M|                    AST *expr = parse(MAX_PRECEDENCE, current_depth + 1);
  719|  2.22M|                    comma_fodder.clear();
  720|  2.22M|                    got_comma = false;
  721|  2.22M|                    next = peek();
  722|  2.22M|                    if (next.kind == Token::COMMA) {
  ------------------
  |  Branch (722:25): [True: 2.08M, False: 140k]
  ------------------
  723|  2.08M|                        Token comma = pop();
  724|  2.08M|                        comma_fodder = comma.fodder;
  725|  2.08M|                        next = peek();
  726|  2.08M|                        got_comma = true;
  727|  2.08M|                    }
  728|  2.22M|                    elements.emplace_back(expr, comma_fodder);
  729|  2.22M|                } while (true);
  ------------------
  |  Branch (729:26): [True: 2.21M, Folded]
  ------------------
  730|   746k|            }
  731|       |
  732|   443k|            case Token::PAREN_L: {
  ------------------
  |  Branch (732:13): [True: 439k, False: 40.2M]
  ------------------
  733|   443k|                auto *inner = parse(MAX_PRECEDENCE, current_depth + 1);
  734|   443k|                Token close = popExpect(Token::PAREN_R);
  735|   443k|                return alloc->make<Parens>(span(tok, close), tok.fodder, inner, close.fodder);
  736|   746k|            }
  737|       |
  738|       |            // Literals
  739|  5.49M|            case Token::NUMBER: return alloc->make<LiteralNumber>(span(tok), tok.fodder, tok.data);
  ------------------
  |  Branch (739:13): [True: 5.49M, False: 35.2M]
  ------------------
  740|       |
  741|  4.08M|            case Token::STRING_SINGLE:
  ------------------
  |  Branch (741:13): [True: 4.08M, False: 36.6M]
  ------------------
  742|  4.08M|                return alloc->make<LiteralString>(
  743|  4.08M|                    span(tok), tok.fodder, tok.data32(), LiteralString::SINGLE, "", "");
  744|   106k|            case Token::STRING_DOUBLE:
  ------------------
  |  Branch (744:13): [True: 106k, False: 40.5M]
  ------------------
  745|   106k|                return alloc->make<LiteralString>(
  746|   106k|                    span(tok), tok.fodder, tok.data32(), LiteralString::DOUBLE, "", "");
  747|  1.61k|            case Token::STRING_BLOCK:
  ------------------
  |  Branch (747:13): [True: 1.61k, False: 40.7M]
  ------------------
  748|  1.61k|                return alloc->make<LiteralString>(span(tok),
  749|  1.61k|                                                  tok.fodder,
  750|  1.61k|                                                  tok.data32(),
  751|  1.61k|                                                  LiteralString::BLOCK,
  752|  1.61k|                                                  tok.stringBlockIndent,
  753|  1.61k|                                                  tok.stringBlockTermIndent);
  754|    459|            case Token::VERBATIM_STRING_SINGLE:
  ------------------
  |  Branch (754:13): [True: 459, False: 40.7M]
  ------------------
  755|    459|                return alloc->make<LiteralString>(
  756|    459|                    span(tok), tok.fodder, tok.data32(), LiteralString::VERBATIM_SINGLE, "", "");
  757|    577|            case Token::VERBATIM_STRING_DOUBLE:
  ------------------
  |  Branch (757:13): [True: 577, False: 40.7M]
  ------------------
  758|    577|                return alloc->make<LiteralString>(
  759|    577|                    span(tok), tok.fodder, tok.data32(), LiteralString::VERBATIM_DOUBLE, "", "");
  760|       |
  761|   429k|            case Token::FALSE: return alloc->make<LiteralBoolean>(span(tok), tok.fodder, false);
  ------------------
  |  Branch (761:13): [True: 429k, False: 40.2M]
  ------------------
  762|       |
  763|   315k|            case Token::TRUE: return alloc->make<LiteralBoolean>(span(tok), tok.fodder, true);
  ------------------
  |  Branch (763:13): [True: 315k, False: 40.3M]
  ------------------
  764|       |
  765|   160k|            case Token::NULL_LIT: return alloc->make<LiteralNull>(span(tok), tok.fodder);
  ------------------
  |  Branch (765:13): [True: 160k, False: 40.5M]
  ------------------
  766|       |
  767|       |            // Variables
  768|  43.8k|            case Token::DOLLAR: return alloc->make<Dollar>(span(tok), tok.fodder);
  ------------------
  |  Branch (768:13): [True: 43.8k, False: 40.6M]
  ------------------
  769|       |
  770|  27.3M|            case Token::IDENTIFIER:
  ------------------
  |  Branch (770:13): [True: 27.3M, False: 13.3M]
  ------------------
  771|  27.3M|                return alloc->make<Var>(span(tok), tok.fodder, alloc->makeIdentifier(tok.data32()));
  772|       |
  773|  61.6k|            case Token::SELF: return alloc->make<Self>(span(tok), tok.fodder);
  ------------------
  |  Branch (773:13): [True: 61.6k, False: 40.6M]
  ------------------
  774|       |
  775|  1.73k|            case Token::SUPER: {
  ------------------
  |  Branch (775:13): [True: 1.73k, False: 40.7M]
  ------------------
  776|  1.73k|                Token next = pop();
  777|  1.73k|                AST *index = nullptr;
  778|  1.73k|                const Identifier *id = nullptr;
  779|  1.73k|                Fodder id_fodder;
  780|  1.73k|                switch (next.kind) {
  781|    983|                    case Token::DOT: {
  ------------------
  |  Branch (781:21): [True: 983, False: 754]
  ------------------
  782|    983|                        Token field_id = popExpect(Token::IDENTIFIER);
  783|    983|                        id_fodder = field_id.fodder;
  784|    983|                        id = alloc->makeIdentifier(field_id.data32());
  785|    983|                    } break;
  786|    752|                    case Token::BRACKET_L: {
  ------------------
  |  Branch (786:21): [True: 752, False: 985]
  ------------------
  787|    752|                        index = parse(MAX_PRECEDENCE, current_depth + 1);
  788|    752|                        Token bracket_r = popExpect(Token::BRACKET_R);
  789|    752|                        id_fodder = bracket_r.fodder;  // Not id_fodder, but use the same var.
  790|    752|                    } break;
  791|      2|                    default: throw StaticError(tok.location, "expected . or [ after super.");
  ------------------
  |  Branch (791:21): [True: 2, False: 1.73k]
  ------------------
  792|  1.73k|                }
  793|  1.53k|                return alloc->make<SuperIndex>(
  794|  1.53k|                    span(tok), tok.fodder, next.fodder, index, id_fodder, id);
  795|  1.73k|            }
  796|  40.7M|        }
  797|       |
  798|      0|        std::cerr << "INTERNAL ERROR: Unknown tok kind: " << tok.kind << std::endl;
  799|      0|        std::abort();
  800|      0|        return nullptr;  // Quiet, compiler.
  801|  40.7M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser10unexpectedERKNS0_5TokenERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  104|    365|    {
  105|    365|        std::stringstream ss;
  106|    365|        ss << "unexpected: " << tok.kind << " while " << while_;
  107|    365|        return StaticError(tok.location, ss.str());
  108|    365|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111op_is_unaryERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERNS0_7UnaryOpE:
   66|   555k|{
   67|   555k|    auto it = unary_map.find(op);
   68|   555k|    if (it == unary_map.end())
  ------------------
  |  Branch (68:9): [True: 195, False: 555k]
  ------------------
   69|    195|        return false;
   70|   555k|    uop = it->second;
   71|   555k|    return true;
   72|   555k|}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser20parseObjectRemainderERPNS0_3ASTERKNS0_5TokenEj:
  289|   542k|    {
  290|   542k|        if (current_depth >= MAX_PARSER_DEPTH) {
  ------------------
  |  Branch (290:13): [True: 2, False: 542k]
  ------------------
  291|      2|            throw StaticError(peek().location, "Exceeded maximum parse depth limit.");
  292|      2|        }
  293|       |
  294|   542k|        ObjectFields fields;
  295|   542k|        std::set<std::string> literal_fields;  // For duplicate fields detection.
  296|   542k|        std::set<const Identifier *> binds;    // For duplicate locals detection.
  297|       |
  298|   542k|        bool got_comma = false;
  299|   542k|        bool first = true;
  300|   542k|        Token next = pop();
  301|       |
  302|  2.80M|        do {
  303|  2.80M|            if (next.kind == Token::BRACE_R) {
  ------------------
  |  Branch (303:17): [True: 497k, False: 2.30M]
  ------------------
  304|   497k|                obj = alloc->make<Object>(
  305|   497k|                    span(tok, next), tok.fodder, fields, got_comma, next.fodder);
  306|   497k|                return next;
  307|       |
  308|  2.30M|            } else if (next.kind == Token::FOR) {
  ------------------
  |  Branch (308:24): [True: 39.2k, False: 2.26M]
  ------------------
  309|       |                // It's a comprehension
  310|  39.2k|                unsigned num_fields = 0;
  311|  39.2k|                unsigned num_asserts = 0;
  312|  39.2k|                const ObjectField *field_ptr = nullptr;
  313|  39.5k|                for (const auto &field : fields) {
  ------------------
  |  Branch (313:40): [True: 39.5k, False: 39.2k]
  ------------------
  314|  39.5k|                    if (field.kind == ObjectField::LOCAL)
  ------------------
  |  Branch (314:25): [True: 1, False: 39.5k]
  ------------------
  315|      1|                        continue;
  316|  39.5k|                    if (field.kind == ObjectField::ASSERT) {
  ------------------
  |  Branch (316:25): [True: 254, False: 39.2k]
  ------------------
  317|    254|                        num_asserts++;
  318|    254|                        continue;
  319|    254|                    }
  320|  39.2k|                    field_ptr = &field;
  321|  39.2k|                    num_fields++;
  322|  39.2k|                }
  323|  39.2k|                if (num_asserts > 0) {
  ------------------
  |  Branch (323:21): [True: 10, False: 39.2k]
  ------------------
  324|     10|                    auto msg = "object comprehension cannot have asserts.";
  325|     10|                    throw StaticError(next.location, msg);
  326|     10|                }
  327|  39.2k|                if (num_fields != 1) {
  ------------------
  |  Branch (327:21): [True: 4, False: 39.2k]
  ------------------
  328|      4|                    auto msg = "object comprehension can only have one field.";
  329|      4|                    throw StaticError(next.location, msg);
  330|      4|                }
  331|  39.2k|                const ObjectField &field = *field_ptr;
  332|       |
  333|  39.2k|                if (field.hide != ObjectField::INHERIT) {
  ------------------
  |  Branch (333:21): [True: 1, False: 39.2k]
  ------------------
  334|      1|                    auto msg = "object comprehensions cannot have hidden fields.";
  335|      1|                    throw StaticError(next.location, msg);
  336|      1|                }
  337|       |
  338|  39.2k|                if (field.kind != ObjectField::FIELD_EXPR) {
  ------------------
  |  Branch (338:21): [True: 1, False: 39.2k]
  ------------------
  339|      1|                    auto msg = "object comprehensions can only have [e] fields.";
  340|      1|                    throw StaticError(next.location, msg);
  341|      1|                }
  342|       |
  343|  39.2k|                std::vector<ComprehensionSpec> specs;
  344|  39.2k|                Token last = parseComprehensionSpecs(Token::BRACE_R, next.fodder, specs, current_depth + 1);
  345|  39.2k|                obj = alloc->make<ObjectComprehension>(
  346|  39.2k|                    span(tok, last), tok.fodder, fields, got_comma, specs, last.fodder);
  347|       |
  348|  39.2k|                return last;
  349|  39.2k|            }
  350|       |
  351|  2.26M|            if (!got_comma && !first)
  ------------------
  |  Branch (351:17): [True: 497k, False: 1.76M]
  |  Branch (351:31): [True: 107, False: 497k]
  ------------------
  352|    107|                throw StaticError(next.location, "expected a comma before next field.");
  353|       |
  354|  2.26M|            first = false;
  355|  2.26M|            got_comma = false;
  356|       |
  357|  2.26M|            switch (next.kind) {
  358|  43.9k|                case Token::BRACKET_L:
  ------------------
  |  Branch (358:17): [True: 43.9k, False: 2.22M]
  ------------------
  359|  2.03M|                case Token::IDENTIFIER:
  ------------------
  |  Branch (359:17): [True: 1.98M, False: 279k]
  ------------------
  360|  2.11M|                case Token::STRING_DOUBLE:
  ------------------
  |  Branch (360:17): [True: 81.8k, False: 2.18M]
  ------------------
  361|  2.14M|                case Token::STRING_SINGLE:
  ------------------
  |  Branch (361:17): [True: 35.4k, False: 2.23M]
  ------------------
  362|  2.15M|                case Token::STRING_BLOCK:
  ------------------
  |  Branch (362:17): [True: 2.47k, False: 2.26M]
  ------------------
  363|  2.15M|                case Token::VERBATIM_STRING_DOUBLE:
  ------------------
  |  Branch (363:17): [True: 836, False: 2.26M]
  ------------------
  364|  2.15M|                case Token::VERBATIM_STRING_SINGLE: {
  ------------------
  |  Branch (364:17): [True: 133, False: 2.26M]
  ------------------
  365|  2.15M|                    ObjectField::Kind kind;
  366|  2.15M|                    AST *expr1 = nullptr;
  367|  2.15M|                    const Identifier *id = nullptr;
  368|  2.15M|                    Fodder fodder1, fodder2;
  369|  2.15M|                    LocationRange idLocation;
  370|  2.15M|                    if (next.kind == Token::IDENTIFIER) {
  ------------------
  |  Branch (370:25): [True: 1.98M, False: 164k]
  ------------------
  371|  1.98M|                        fodder1 = next.fodder;
  372|  1.98M|                        kind = ObjectField::FIELD_ID;
  373|  1.98M|                        id = alloc->makeIdentifier(next.data32());
  374|  1.98M|                        idLocation = next.location;
  375|  1.98M|                    } else if (next.kind == Token::STRING_DOUBLE) {
  ------------------
  |  Branch (375:32): [True: 81.8k, False: 82.7k]
  ------------------
  376|  81.8k|                        kind = ObjectField::FIELD_STR;
  377|  81.8k|                        expr1 = alloc->make<LiteralString>(next.location,
  378|  81.8k|                                                           next.fodder,
  379|  81.8k|                                                           next.data32(),
  380|  81.8k|                                                           LiteralString::DOUBLE,
  381|  81.8k|                                                           "",
  382|  81.8k|                                                           "");
  383|  82.7k|                    } else if (next.kind == Token::STRING_SINGLE) {
  ------------------
  |  Branch (383:32): [True: 35.4k, False: 47.3k]
  ------------------
  384|  35.4k|                        kind = ObjectField::FIELD_STR;
  385|  35.4k|                        expr1 = alloc->make<LiteralString>(next.location,
  386|  35.4k|                                                           next.fodder,
  387|  35.4k|                                                           next.data32(),
  388|  35.4k|                                                           LiteralString::SINGLE,
  389|  35.4k|                                                           "",
  390|  35.4k|                                                           "");
  391|  47.3k|                    } else if (next.kind == Token::STRING_BLOCK) {
  ------------------
  |  Branch (391:32): [True: 2.47k, False: 44.8k]
  ------------------
  392|  2.47k|                        kind = ObjectField::FIELD_STR;
  393|  2.47k|                        expr1 = alloc->make<LiteralString>(next.location,
  394|  2.47k|                                                           next.fodder,
  395|  2.47k|                                                           next.data32(),
  396|  2.47k|                                                           LiteralString::BLOCK,
  397|  2.47k|                                                           next.stringBlockIndent,
  398|  2.47k|                                                           next.stringBlockTermIndent);
  399|  44.8k|                    } else if (next.kind == Token::VERBATIM_STRING_SINGLE) {
  ------------------
  |  Branch (399:32): [True: 133, False: 44.7k]
  ------------------
  400|    133|                        kind = ObjectField::FIELD_STR;
  401|    133|                        expr1 = alloc->make<LiteralString>(next.location,
  402|    133|                                                           next.fodder,
  403|    133|                                                           next.data32(),
  404|    133|                                                           LiteralString::VERBATIM_SINGLE,
  405|    133|                                                           "",
  406|    133|                                                           "");
  407|  44.7k|                    } else if (next.kind == Token::VERBATIM_STRING_DOUBLE) {
  ------------------
  |  Branch (407:32): [True: 836, False: 43.9k]
  ------------------
  408|    836|                        kind = ObjectField::FIELD_STR;
  409|    836|                        expr1 = alloc->make<LiteralString>(next.location,
  410|    836|                                                           next.fodder,
  411|    836|                                                           next.data32(),
  412|    836|                                                           LiteralString::VERBATIM_DOUBLE,
  413|    836|                                                           "",
  414|    836|                                                           "");
  415|  43.9k|                    } else {
  416|  43.9k|                        kind = ObjectField::FIELD_EXPR;
  417|  43.9k|                        fodder1 = next.fodder;
  418|  43.9k|                        expr1 = parse(MAX_PRECEDENCE, current_depth + 1);
  419|  43.9k|                        Token bracket_r = popExpect(Token::BRACKET_R);
  420|  43.9k|                        fodder2 = bracket_r.fodder;
  421|  43.9k|                    }
  422|       |
  423|  2.15M|                    bool is_method = false;
  424|  2.15M|                    bool meth_comma = false;
  425|  2.15M|                    ArgParams params;
  426|  2.15M|                    Fodder fodder_l;
  427|  2.15M|                    Fodder fodder_r;
  428|  2.15M|                    if (peek().kind == Token::PAREN_L) {
  ------------------
  |  Branch (428:25): [True: 1.09M, False: 1.05M]
  ------------------
  429|  1.09M|                        Token paren_l = pop();
  430|  1.09M|                        fodder_l = paren_l.fodder;
  431|  1.09M|                        params = parseParams("method parameter", meth_comma, fodder_r, current_depth);
  432|  1.09M|                        is_method = true;
  433|  1.09M|                    }
  434|       |
  435|  2.15M|                    bool plus_sugar = false;
  436|       |
  437|  2.15M|                    Token op = popExpect(Token::OPERATOR);
  438|  2.15M|                    const char *od = op.data.c_str();
  439|  2.15M|                    if (*od == '+') {
  ------------------
  |  Branch (439:25): [True: 18.8k, False: 2.13M]
  ------------------
  440|  18.8k|                        plus_sugar = true;
  441|  18.8k|                        od++;
  442|  18.8k|                    }
  443|  2.15M|                    unsigned colons = 0;
  444|  5.39M|                    for (; *od != '\0'; ++od) {
  ------------------
  |  Branch (444:28): [True: 3.24M, False: 2.15M]
  ------------------
  445|  3.24M|                        if (*od != ':') {
  ------------------
  |  Branch (445:29): [True: 19, False: 3.24M]
  ------------------
  446|     19|                            throw StaticError(
  447|     19|                                next.location,
  448|     19|                                "expected one of :, ::, :::, +:, +::, +:::, got: " + op.data);
  449|     19|                        }
  450|  3.24M|                        ++colons;
  451|  3.24M|                    }
  452|  2.15M|                    ObjectField::Hide field_hide;
  453|  2.15M|                    switch (colons) {
  454|  1.05M|                        case 1: field_hide = ObjectField::INHERIT; break;
  ------------------
  |  Branch (454:25): [True: 1.05M, False: 1.09M]
  ------------------
  455|       |
  456|  1.09M|                        case 2: field_hide = ObjectField::HIDDEN; break;
  ------------------
  |  Branch (456:25): [True: 1.09M, False: 1.05M]
  ------------------
  457|       |
  458|     14|                        case 3: field_hide = ObjectField::VISIBLE; break;
  ------------------
  |  Branch (458:25): [True: 14, False: 2.15M]
  ------------------
  459|       |
  460|      9|                        default:
  ------------------
  |  Branch (460:25): [True: 9, False: 2.15M]
  ------------------
  461|      9|                            throw StaticError(
  462|      9|                                next.location,
  463|      9|                                "expected one of :, ::, :::, +:, +::, +:::, got: " + op.data);
  464|  2.15M|                    }
  465|       |
  466|       |                    // Basic checks for invalid Jsonnet code.
  467|  2.14M|                    if (is_method && plus_sugar) {
  ------------------
  |  Branch (467:25): [True: 1.09M, False: 1.05M]
  |  Branch (467:38): [True: 1, False: 1.09M]
  ------------------
  468|      1|                        throw StaticError(next.location,
  469|      1|                                          "cannot use +: syntax sugar in a method: " + next.data);
  470|      1|                    }
  471|  2.14M|                    if (kind != ObjectField::FIELD_EXPR) {
  ------------------
  |  Branch (471:25): [True: 2.10M, False: 43.0k]
  ------------------
  472|  2.10M|                        if (!literal_fields.insert(next.data).second) {
  ------------------
  |  Branch (472:29): [True: 12, False: 2.10M]
  ------------------
  473|     12|                            throw StaticError(next.location, "duplicate field: " + next.data);
  474|     12|                        }
  475|  2.10M|                    }
  476|       |
  477|  2.14M|                    AST *body = parse(MAX_PRECEDENCE, current_depth + 1);
  478|       |
  479|  2.14M|                    Fodder comma_fodder;
  480|  2.14M|                    next = pop();
  481|  2.14M|                    if (next.kind == Token::COMMA) {
  ------------------
  |  Branch (481:25): [True: 1.78M, False: 367k]
  ------------------
  482|  1.78M|                        comma_fodder = next.fodder;
  483|  1.78M|                        next = pop();
  484|  1.78M|                        got_comma = true;
  485|  1.78M|                    }
  486|  2.14M|                    fields.emplace_back(kind,
  487|  2.14M|                                        fodder1,
  488|  2.14M|                                        fodder2,
  489|  2.14M|                                        fodder_l,
  490|  2.14M|                                        fodder_r,
  491|  2.14M|                                        field_hide,
  492|  2.14M|                                        plus_sugar,
  493|  2.14M|                                        is_method,
  494|  2.14M|                                        expr1,
  495|  2.14M|                                        id,
  496|  2.14M|                                        idLocation,
  497|  2.14M|                                        params,
  498|  2.14M|                                        meth_comma,
  499|  2.14M|                                        op.fodder,
  500|  2.14M|                                        body,
  501|  2.14M|                                        nullptr,
  502|  2.14M|                                        comma_fodder);
  503|  2.14M|                } break;
  504|       |
  505|  63.2k|                case Token::LOCAL: {
  ------------------
  |  Branch (505:17): [True: 63.2k, False: 2.20M]
  ------------------
  506|  63.2k|                    Fodder local_fodder = next.fodder;
  507|  63.2k|                    Token var_id = popExpect(Token::IDENTIFIER);
  508|  63.2k|                    auto *id = alloc->makeIdentifier(var_id.data32());
  509|       |
  510|  63.2k|                    if (binds.find(id) != binds.end()) {
  ------------------
  |  Branch (510:25): [True: 1, False: 63.2k]
  ------------------
  511|      1|                        throw StaticError(var_id.location, "duplicate local var: " + var_id.data);
  512|      1|                    }
  513|  63.2k|                    bool is_method = false;
  514|  63.2k|                    bool func_comma = false;
  515|  63.2k|                    ArgParams params;
  516|  63.2k|                    Fodder paren_l_fodder;
  517|  63.2k|                    Fodder paren_r_fodder;
  518|  63.2k|                    if (peek().kind == Token::PAREN_L) {
  ------------------
  |  Branch (518:25): [True: 9.88k, False: 53.3k]
  ------------------
  519|  9.88k|                        Token paren_l = pop();
  520|  9.88k|                        paren_l_fodder = paren_l.fodder;
  521|  9.88k|                        is_method = true;
  522|  9.88k|                        params = parseParams("function parameter", func_comma, paren_r_fodder, current_depth);
  523|  9.88k|                    }
  524|  63.2k|                    Token eq = popExpect(Token::OPERATOR, "=");
  525|  63.2k|                    AST *body = parse(MAX_PRECEDENCE, current_depth + 1);
  526|  63.2k|                    binds.insert(id);
  527|       |
  528|  63.2k|                    Fodder comma_fodder;
  529|  63.2k|                    next = pop();
  530|  63.2k|                    if (next.kind == Token::COMMA) {
  ------------------
  |  Branch (530:25): [True: 61.4k, False: 1.82k]
  ------------------
  531|  61.4k|                        comma_fodder = next.fodder;
  532|  61.4k|                        next = pop();
  533|  61.4k|                        got_comma = true;
  534|  61.4k|                    }
  535|  63.2k|                    fields.push_back(ObjectField::Local(local_fodder,
  536|  63.2k|                                                        var_id.fodder,
  537|  63.2k|                                                        paren_l_fodder,
  538|  63.2k|                                                        paren_r_fodder,
  539|  63.2k|                                                        is_method,
  540|  63.2k|                                                        id,
  541|  63.2k|                                                        params,
  542|  63.2k|                                                        func_comma,
  543|  63.2k|                                                        eq.fodder,
  544|  63.2k|                                                        body,
  545|  63.2k|                                                        comma_fodder));
  546|       |
  547|  63.2k|                } break;
  548|       |
  549|  51.3k|                case Token::ASSERT: {
  ------------------
  |  Branch (549:17): [True: 51.3k, False: 2.21M]
  ------------------
  550|  51.3k|                    Fodder assert_fodder = next.fodder;
  551|  51.3k|                    AST *cond = parse(MAX_PRECEDENCE, current_depth + 1);
  552|  51.3k|                    AST *msg = nullptr;
  553|  51.3k|                    Fodder colon_fodder;
  554|  51.3k|                    if (peek().kind == Token::OPERATOR && peek().data == ":") {
  ------------------
  |  Branch (554:25): [True: 40.2k, False: 11.0k]
  |  Branch (554:59): [True: 40.2k, False: 1]
  ------------------
  555|  40.2k|                        Token colon = pop();
  556|  40.2k|                        colon_fodder = colon.fodder;
  557|  40.2k|                        msg = parse(MAX_PRECEDENCE, current_depth + 1);
  558|  40.2k|                    }
  559|       |
  560|  51.3k|                    Fodder comma_fodder;
  561|  51.3k|                    next = pop();
  562|  51.3k|                    if (next.kind == Token::COMMA) {
  ------------------
  |  Branch (562:25): [True: 49.2k, False: 2.10k]
  ------------------
  563|  49.2k|                        comma_fodder = next.fodder;
  564|  49.2k|                        next = pop();
  565|  49.2k|                        got_comma = true;
  566|  49.2k|                    }
  567|  51.3k|                    fields.push_back(
  568|  51.3k|                        ObjectField::Assert(assert_fodder, cond, colon_fodder, msg, comma_fodder));
  569|  51.3k|                } break;
  570|       |
  571|     77|                default: throw unexpected(next, "parsing field definition");
  ------------------
  |  Branch (571:17): [True: 77, False: 2.26M]
  ------------------
  572|  2.26M|            }
  573|       |
  574|  2.26M|        } while (true);
  ------------------
  |  Branch (574:18): [True: 2.25M, Folded]
  ------------------
  575|   542k|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14spanERKNS0_5TokenES4_:
   89|  17.2M|{
   90|  17.2M|    return LocationRange(begin.location.file, begin.location.begin, end.location.end);
   91|  17.2M|}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser23parseComprehensionSpecsENS0_5Token4KindENSt3__16vectorINS0_13FodderElementENS5_9allocatorIS7_EEEERNS6_INS0_17ComprehensionSpecENS8_ISB_EEEEj:
  588|   320k|    {
  589|   320k|        if (current_depth >= MAX_PARSER_DEPTH) {
  ------------------
  |  Branch (589:13): [True: 0, False: 320k]
  ------------------
  590|      0|            throw StaticError(peek().location, "Exceeded maximum parse depth limit.");
  591|      0|        }
  592|       |
  593|   351k|        while (true) {
  ------------------
  |  Branch (593:16): [True: 350k, Folded]
  ------------------
  594|   350k|            LocationRange l;
  595|   350k|            Token id_token = popExpect(Token::IDENTIFIER);
  596|   350k|            const Identifier *id = alloc->makeIdentifier(id_token.data32());
  597|   350k|            Token in_token = popExpect(Token::IN);
  598|   350k|            AST *arr = parse(MAX_PRECEDENCE, current_depth + 1);
  599|   350k|            specs.emplace_back(
  600|   350k|                ComprehensionSpec::FOR, for_fodder, id_token.fodder, id, in_token.fodder, arr);
  601|       |
  602|   350k|            Token maybe_if = pop();
  603|   547k|            for (; maybe_if.kind == Token::IF; maybe_if = pop()) {
  ------------------
  |  Branch (603:20): [True: 197k, False: 350k]
  ------------------
  604|   197k|                AST *cond = parse(MAX_PRECEDENCE, current_depth + 1);
  605|   197k|                specs.emplace_back(
  606|   197k|                    ComprehensionSpec::IF, maybe_if.fodder, Fodder{}, nullptr, Fodder{}, cond);
  607|   197k|            }
  608|   350k|            if (maybe_if.kind == end) {
  ------------------
  |  Branch (608:17): [True: 319k, False: 30.4k]
  ------------------
  609|   319k|                return maybe_if;
  610|   319k|            }
  611|  30.4k|            if (maybe_if.kind != Token::FOR) {
  ------------------
  |  Branch (611:17): [True: 28, False: 30.3k]
  ------------------
  612|     28|                std::stringstream ss;
  613|     28|                ss << "expected for, if or " << end << " after for clause, got: " << maybe_if;
  614|     28|                throw StaticError(maybe_if.location, ss.str());
  615|     28|            }
  616|  30.3k|            for_fodder = maybe_if.fodder;
  617|  30.3k|        }
  618|   320k|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14spanERKNS0_5TokenE:
   84|  38.0M|{
   85|  38.0M|    return LocationRange(begin.location.file, begin.location.begin, begin.location.end);
   86|  38.0M|}
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_16Parser10parseInfixEPNS0_3ASTERKNS0_5TokenEjj:
 1009|  40.6M|    {
 1010|  40.6M|        if (current_depth >= MAX_PARSER_DEPTH) {
  ------------------
  |  Branch (1010:13): [True: 0, False: 40.6M]
  ------------------
 1011|      0|            throw StaticError(peek().location, "Exceeded maximum parse depth limit.");
 1012|      0|        }
 1013|       |
 1014|  63.3M|        while (true) {
  ------------------
  |  Branch (1014:16): [True: 63.3M, Folded]
  ------------------
 1015|       |
 1016|  63.3M|            BinaryOp bop = BOP_PLUS;
 1017|  63.3M|            unsigned op_precedence = 0;
 1018|       |
 1019|  63.3M|            switch (peek().kind) {
 1020|       |                // Logical / arithmetic binary operator.
 1021|  1.96k|                case Token::IN:
  ------------------
  |  Branch (1021:17): [True: 1.96k, False: 63.3M]
  ------------------
 1022|  9.70M|                case Token::OPERATOR:
  ------------------
  |  Branch (1022:17): [True: 9.69M, False: 53.6M]
  ------------------
 1023|       |                    // These occur if the outer statement was an assert or array slice.
 1024|       |                    // Either way, we terminate the parsing here.
 1025|  9.70M|                    if (peek().data == ":" || peek().data == "::") {
  ------------------
  |  Branch (1025:25): [True: 736k, False: 8.96M]
  |  Branch (1025:47): [True: 1.03k, False: 8.96M]
  ------------------
 1026|   737k|                        return lhs;
 1027|   737k|                    }
 1028|  8.96M|                    if (!op_is_binary(peek().data, bop)) {
  ------------------
  |  Branch (1028:25): [True: 154, False: 8.96M]
  ------------------
 1029|    154|                        std::stringstream ss;
 1030|    154|                        ss << "not a binary operator: " << peek().data;
 1031|    154|                        throw StaticError(peek().location, ss.str());
 1032|    154|                    }
 1033|  8.96M|                    op_precedence = precedence_map[bop];
 1034|  8.96M|                    break;
 1035|       |
 1036|       |                // Index, Apply
 1037|  6.29M|                case Token::DOT:
  ------------------
  |  Branch (1037:17): [True: 6.29M, False: 57.0M]
  ------------------
 1038|  7.82M|                case Token::BRACKET_L:
  ------------------
  |  Branch (1038:17): [True: 1.53M, False: 61.7M]
  ------------------
 1039|  14.9M|                case Token::PAREN_L:
  ------------------
  |  Branch (1039:17): [True: 7.11M, False: 56.2M]
  ------------------
 1040|  15.0M|                case Token::BRACE_L:
  ------------------
  |  Branch (1040:17): [True: 115k, False: 63.1M]
  ------------------
 1041|  15.0M|                    op_precedence = APPLY_PRECEDENCE;
 1042|  15.0M|                    break;
 1043|       |
 1044|  38.5M|                default:
  ------------------
  |  Branch (1044:17): [True: 38.5M, False: 24.7M]
  ------------------
 1045|       |                    // This happens when we reach EOF or the terminating token of an outer context.
 1046|  38.5M|                    return lhs;
 1047|  63.3M|            }
 1048|       |
 1049|       |            // If higher precedence than the outer recursive call, let that handle it.
 1050|  24.0M|            if (op_precedence >= max_precedence)
  ------------------
  |  Branch (1050:17): [True: 1.37M, False: 22.6M]
  ------------------
 1051|  1.37M|                return lhs;
 1052|       |
 1053|  22.6M|            Token op = pop();
 1054|       |
 1055|  22.6M|            switch (op.kind) {
 1056|  1.53M|                case Token::BRACKET_L: {
  ------------------
  |  Branch (1056:17): [True: 1.53M, False: 21.1M]
  ------------------
 1057|  1.53M|                    bool is_slice;
 1058|  1.53M|                    AST *first = nullptr;
 1059|  1.53M|                    Fodder second_fodder;
 1060|  1.53M|                    AST *second = nullptr;
 1061|  1.53M|                    Fodder third_fodder;
 1062|  1.53M|                    AST *third = nullptr;
 1063|       |
 1064|  1.53M|                    if (peek().kind == Token::BRACKET_R)
  ------------------
  |  Branch (1064:25): [True: 2, False: 1.53M]
  ------------------
 1065|      2|                        throw unexpected(pop(), "parsing index");
 1066|       |
 1067|  1.53M|                    if (peek().data != ":" && peek().data != "::") {
  ------------------
  |  Branch (1067:25): [True: 1.50M, False: 20.7k]
  |  Branch (1067:47): [True: 1.50M, False: 1.24k]
  ------------------
 1068|  1.50M|                        first = parse(MAX_PRECEDENCE, current_depth + 1);
 1069|  1.50M|                    }
 1070|       |
 1071|  1.53M|                    if (peek().kind == Token::OPERATOR && peek().data == "::") {
  ------------------
  |  Branch (1071:25): [True: 162k, False: 1.36M]
  |  Branch (1071:59): [True: 1.34k, False: 161k]
  ------------------
 1072|       |                        // Handle ::
 1073|  1.34k|                        is_slice = true;
 1074|  1.34k|                        Token joined = pop();
 1075|  1.34k|                        second_fodder = joined.fodder;
 1076|       |
 1077|  1.34k|                        if (peek().kind != Token::BRACKET_R)
  ------------------
  |  Branch (1077:29): [True: 1.03k, False: 308]
  ------------------
 1078|  1.03k|                            third = parse(MAX_PRECEDENCE, current_depth + 1);
 1079|       |
 1080|  1.52M|                    } else if (peek().kind != Token::BRACKET_R) {
  ------------------
  |  Branch (1080:32): [True: 161k, False: 1.36M]
  ------------------
 1081|   161k|                        is_slice = true;
 1082|   161k|                        Token delim = pop();
 1083|   161k|                        if (delim.data != ":")
  ------------------
  |  Branch (1083:29): [True: 129, False: 161k]
  ------------------
 1084|    129|                            throw unexpected(delim, "parsing slice");
 1085|       |
 1086|   161k|                        second_fodder = delim.fodder;
 1087|       |
 1088|   161k|                        if (peek().data != ":" && peek().kind != Token::BRACKET_R)
  ------------------
  |  Branch (1088:29): [True: 161k, False: 132]
  |  Branch (1088:51): [True: 71.9k, False: 89.3k]
  ------------------
 1089|  71.9k|                            second = parse(MAX_PRECEDENCE, current_depth + 1);
 1090|       |
 1091|   161k|                        if (peek().kind != Token::BRACKET_R) {
  ------------------
  |  Branch (1091:29): [True: 9.55k, False: 151k]
  ------------------
 1092|  9.55k|                            Token delim = pop();
 1093|  9.55k|                            if (delim.data != ":")
  ------------------
  |  Branch (1093:33): [True: 45, False: 9.51k]
  ------------------
 1094|     45|                                throw unexpected(delim, "parsing slice");
 1095|       |
 1096|  9.51k|                            third_fodder = delim.fodder;
 1097|       |
 1098|  9.51k|                            if (peek().kind != Token::BRACKET_R)
  ------------------
  |  Branch (1098:33): [True: 9.29k, False: 219]
  ------------------
 1099|  9.29k|                                third = parse(MAX_PRECEDENCE, current_depth + 1);
 1100|  9.51k|                        }
 1101|  1.36M|                    } else {
 1102|  1.36M|                        is_slice = false;
 1103|  1.36M|                    }
 1104|  1.53M|                    Token end = popExpect(Token::BRACKET_R);
 1105|  1.53M|                    lhs = alloc->make<Index>(span(begin, end),
 1106|  1.53M|                                             EMPTY_FODDER,
 1107|  1.53M|                                             lhs,
 1108|  1.53M|                                             op.fodder,
 1109|  1.53M|                                             is_slice,
 1110|  1.53M|                                             first,
 1111|  1.53M|                                             second_fodder,
 1112|  1.53M|                                             second,
 1113|  1.53M|                                             third_fodder,
 1114|  1.53M|                                             third,
 1115|  1.53M|                                             end.fodder);
 1116|  1.53M|                    break;
 1117|  1.53M|                }
 1118|  6.29M|                case Token::DOT: {
  ------------------
  |  Branch (1118:17): [True: 6.29M, False: 16.3M]
  ------------------
 1119|  6.29M|                    Token field_id = popExpect(Token::IDENTIFIER);
 1120|  6.29M|                    const Identifier *id = alloc->makeIdentifier(field_id.data32());
 1121|  6.29M|                    lhs = alloc->make<Index>(span(begin, field_id),
 1122|  6.29M|                                             EMPTY_FODDER,
 1123|  6.29M|                                             lhs,
 1124|  6.29M|                                             op.fodder,
 1125|  6.29M|                                             field_id.fodder,
 1126|  6.29M|                                             id);
 1127|  6.29M|                    break;
 1128|  1.53M|                }
 1129|  7.11M|                case Token::PAREN_L: {
  ------------------
  |  Branch (1129:17): [True: 7.11M, False: 15.5M]
  ------------------
 1130|  7.11M|                    ArgParams args;
 1131|  7.11M|                    bool got_comma;
 1132|  7.11M|                    Token end = parseArgs(args, "function argument", got_comma, current_depth);
 1133|  7.11M|                    bool got_named = false;
 1134|  11.9M|                    for (const auto& arg : args) {
  ------------------
  |  Branch (1134:42): [True: 11.9M, False: 7.11M]
  ------------------
 1135|  11.9M|                        if (arg.id != nullptr) {
  ------------------
  |  Branch (1135:29): [True: 26.5k, False: 11.9M]
  ------------------
 1136|  26.5k|                            got_named = true;
 1137|  11.9M|                        } else {
 1138|  11.9M|                            if (got_named) {
  ------------------
  |  Branch (1138:33): [True: 5, False: 11.9M]
  ------------------
 1139|      5|                                throw StaticError(arg.expr->location, "Positional argument after a named argument is not allowed");
 1140|      5|                            }
 1141|  11.9M|                        }
 1142|  11.9M|                    }
 1143|  7.11M|                    bool tailstrict = false;
 1144|  7.11M|                    Fodder tailstrict_fodder;
 1145|  7.11M|                    if (peek().kind == Token::TAILSTRICT) {
  ------------------
  |  Branch (1145:25): [True: 350k, False: 6.75M]
  ------------------
 1146|   350k|                        Token tailstrict_token = pop();
 1147|   350k|                        tailstrict_fodder = tailstrict_token.fodder;
 1148|   350k|                        tailstrict = true;
 1149|   350k|                    }
 1150|  7.11M|                    lhs = alloc->make<Apply>(span(begin, end),
 1151|  7.11M|                                             EMPTY_FODDER,
 1152|  7.11M|                                             lhs,
 1153|  7.11M|                                             op.fodder,
 1154|  7.11M|                                             args,
 1155|  7.11M|                                             got_comma,
 1156|  7.11M|                                             end.fodder,
 1157|  7.11M|                                             tailstrict_fodder,
 1158|  7.11M|                                             tailstrict);
 1159|  7.11M|                    break;
 1160|  7.11M|                }
 1161|   115k|                case Token::BRACE_L: {
  ------------------
  |  Branch (1161:17): [True: 115k, False: 22.5M]
  ------------------
 1162|   115k|                    AST *obj;
 1163|   115k|                    Token end = parseObjectRemainder(obj, op, current_depth + 1);
 1164|   115k|                    lhs = alloc->make<ApplyBrace>(span(begin, end), EMPTY_FODDER, lhs, obj);
 1165|   115k|                    break;
 1166|  7.11M|                }
 1167|       |
 1168|  1.63k|                case Token::IN: {
  ------------------
  |  Branch (1168:17): [True: 1.63k, False: 22.6M]
  ------------------
 1169|  1.63k|                    if (peek().kind == Token::SUPER) {
  ------------------
  |  Branch (1169:25): [True: 496, False: 1.14k]
  ------------------
 1170|    496|                        Token super = pop();
 1171|    496|                        lhs = alloc->make<InSuper>(
 1172|    496|                            span(begin, super), EMPTY_FODDER, lhs, op.fodder, super.fodder);
 1173|  1.14k|                    } else {
 1174|  1.14k|                        AST *rhs = parse(op_precedence, current_depth + 1);
 1175|  1.14k|                        lhs = alloc->make<Binary>(
 1176|  1.14k|                            span(begin, rhs), EMPTY_FODDER, lhs, op.fodder, bop, rhs);
 1177|  1.14k|                    }
 1178|  1.63k|                    break;
 1179|  7.11M|                }
 1180|       |
 1181|  7.58M|                case Token::OPERATOR: {
  ------------------
  |  Branch (1181:17): [True: 7.58M, False: 15.0M]
  ------------------
 1182|  7.58M|                    AST *rhs = parse(op_precedence, current_depth + 1);
 1183|  7.58M|                    lhs = alloc->make<Binary>(
 1184|  7.58M|                        span(begin, rhs), EMPTY_FODDER, lhs, op.fodder, bop, rhs);
 1185|  7.58M|                    break;
 1186|  7.11M|                }
 1187|       |
 1188|      0|                default: {
  ------------------
  |  Branch (1188:17): [True: 0, False: 22.6M]
  ------------------
 1189|      0|                    std::cerr << "Should not be here." << std::endl;
 1190|      0|                    abort();
 1191|  7.11M|                }
 1192|  22.6M|            }
 1193|  22.6M|        }
 1194|       |
 1195|       |        // (1 & ((1 + (1 * 1)) + 1)) & 1
 1196|       |        //
 1197|       |        //
 1198|       |
 1199|       |/*
 1200|       |        // Allocate this on the heap to control stack growth.
 1201|       |        std::unique_ptr<Token> begin_(new Token(peek()));
 1202|       |        const Token &begin = *begin_;
 1203|       |*/
 1204|  40.6M|    }
parser.cpp:_ZN7jsonnet8internal12_GLOBAL__N_112op_is_binaryERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERNS0_8BinaryOpE:
   75|  8.96M|{
   76|  8.96M|    auto it = binary_map.find(op);
   77|  8.96M|    if (it == binary_map.end())
  ------------------
  |  Branch (77:9): [True: 154, False: 8.96M]
  ------------------
   78|    154|        return false;
   79|  8.96M|    bop = it->second;
   80|  8.96M|    return true;
   81|  8.96M|}

_ZN7jsonnet8internal12CompilerPass6fodderERNSt3__16vectorINS0_13FodderElementENS2_9allocatorIS4_EEEE:
   22|  25.3M|{
   23|  25.3M|    for (auto &f : fodder)
  ------------------
  |  Branch (23:18): [True: 242k, False: 25.3M]
  ------------------
   24|   242k|        fodderElement(f);
   25|  25.3M|}
_ZN7jsonnet8internal12CompilerPass6paramsERNSt3__16vectorINS0_13FodderElementENS2_9allocatorIS4_EEEERNS3_INS0_8ArgParamENS5_IS9_EEEES8_:
   43|   538k|{
   44|   538k|    fodder(fodder_l);
   45|  1.21M|    for (auto &param : params) {
  ------------------
  |  Branch (45:22): [True: 1.21M, False: 538k]
  ------------------
   46|  1.21M|        fodder(param.idFodder);
   47|  1.21M|        if (param.expr) {
  ------------------
  |  Branch (47:13): [True: 615k, False: 603k]
  ------------------
   48|   615k|            fodder(param.eqFodder);
   49|   615k|            expr(param.expr);
   50|   615k|        }
   51|  1.21M|        fodder(param.commaFodder);
   52|  1.21M|    }
   53|   538k|    fodder(fodder_r);
   54|   538k|}
_ZN7jsonnet8internal12CompilerPass4exprERPNS0_3ASTE:
  110|  12.5M|{
  111|  12.5M|    fodder(ast_->openFodder);
  112|  12.5M|    visitExpr(ast_);
  113|  12.5M|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_5ApplyE:
  116|   342k|{
  117|   342k|    expr(ast->target);
  118|   342k|    params(ast->fodderL, ast->args, ast->fodderR);
  119|   342k|    if (ast->tailstrict) {
  ------------------
  |  Branch (119:9): [True: 209k, False: 133k]
  ------------------
  120|   209k|        fodder(ast->tailstrictFodder);
  121|   209k|    }
  122|   342k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_5ArrayE:
  131|   203k|{
  132|   233k|    for (auto &element : ast->elements) {
  ------------------
  |  Branch (132:24): [True: 233k, False: 203k]
  ------------------
  133|   233k|        expr(element.expr);
  134|   233k|        fodder(element.commaFodder);
  135|   233k|    }
  136|   203k|    fodder(ast->closeFodder);
  137|   203k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_6BinaryE:
  159|  1.11M|{
  160|  1.11M|    expr(ast->left);
  161|  1.11M|    fodder(ast->opFodder);
  162|  1.11M|    expr(ast->right);
  163|  1.11M|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_11ConditionalE:
  166|   603k|{
  167|   603k|    expr(ast->cond);
  168|   603k|    fodder(ast->thenFodder);
  169|   603k|    if (ast->branchFalse != nullptr) {
  ------------------
  |  Branch (169:9): [True: 603k, False: 0]
  ------------------
  170|   603k|        expr(ast->branchTrue);
  171|   603k|        fodder(ast->elseFodder);
  172|   603k|        expr(ast->branchFalse);
  173|   603k|    } else {
  174|      0|        expr(ast->branchTrue);
  175|      0|    }
  176|   603k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_5ErrorE:
  179|  97.5k|{
  180|  97.5k|    expr(ast->expr);
  181|  97.5k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_8FunctionE:
  184|   196k|{
  185|   196k|    params(ast->parenLeftFodder, ast->params, ast->parenRightFodder);
  186|   196k|    expr(ast->body);
  187|   196k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_6ImportE:
  190|  1.88k|{
  191|  1.88k|    visit(ast->file);
  192|  1.88k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_9ImportstrE:
  195|  9.79k|{
  196|  9.79k|    visit(ast->file);
  197|  9.79k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_9ImportbinE:
  200|  1.72k|{
  201|  1.72k|    visit(ast->file);
  202|  1.72k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_7InSuperE:
  205|   244k|{
  206|   244k|    expr(ast->element);
  207|   244k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_5IndexE:
  210|   395k|{
  211|   395k|    expr(ast->target);
  212|   395k|    if (ast->id != nullptr) {
  ------------------
  |  Branch (212:9): [True: 0, False: 395k]
  ------------------
  213|   395k|    } else {
  214|   395k|        if (ast->isSlice) {
  ------------------
  |  Branch (214:13): [True: 0, False: 395k]
  ------------------
  215|      0|            if (ast->index != nullptr)
  ------------------
  |  Branch (215:17): [True: 0, False: 0]
  ------------------
  216|      0|                expr(ast->index);
  217|      0|            if (ast->end != nullptr)
  ------------------
  |  Branch (217:17): [True: 0, False: 0]
  ------------------
  218|      0|                expr(ast->end);
  219|      0|            if (ast->step != nullptr)
  ------------------
  |  Branch (219:17): [True: 0, False: 0]
  ------------------
  220|      0|                expr(ast->step);
  221|   395k|        } else {
  222|   395k|            expr(ast->index);
  223|   395k|        }
  224|   395k|    }
  225|   395k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_5LocalE:
  228|   329k|{
  229|   329k|    assert(ast->binds.size() > 0);
  ------------------
  |  Branch (229:5): [True: 329k, False: 0]
  ------------------
  230|  1.89M|    for (auto &bind : ast->binds) {
  ------------------
  |  Branch (230:21): [True: 1.89M, False: 329k]
  ------------------
  231|  1.89M|        fodder(bind.varFodder);
  232|  1.89M|        if (bind.functionSugar) {
  ------------------
  |  Branch (232:13): [True: 0, False: 1.89M]
  ------------------
  233|      0|            params(bind.parenLeftFodder, bind.params, bind.parenRightFodder);
  234|      0|        }
  235|  1.89M|        fodder(bind.opFodder);
  236|  1.89M|        expr(bind.body);
  237|  1.89M|        fodder(bind.closeFodder);
  238|  1.89M|    }
  239|   329k|    expr(ast->body);
  240|   329k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_15DesugaredObjectE:
  249|  1.20M|{
  250|  1.20M|    for (AST *assert : ast->asserts) {
  ------------------
  |  Branch (250:22): [True: 14.6k, False: 1.20M]
  ------------------
  251|  14.6k|        expr(assert);
  252|  14.6k|    }
  253|  1.20M|    for (auto &field : ast->fields) {
  ------------------
  |  Branch (253:22): [True: 867k, False: 1.20M]
  ------------------
  254|   867k|        expr(field.name);
  255|   867k|        expr(field.body);
  256|   867k|    }
  257|  1.20M|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_25ObjectComprehensionSimpleE:
  267|  37.5k|{
  268|  37.5k|    expr(ast->field);
  269|  37.5k|    expr(ast->value);
  270|  37.5k|    expr(ast->array);
  271|  37.5k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_10SuperIndexE:
  280|   245k|{
  281|   245k|    if (ast->id != nullptr) {
  ------------------
  |  Branch (281:9): [True: 0, False: 245k]
  ------------------
  282|   245k|    } else {
  283|   245k|        expr(ast->index);
  284|   245k|    }
  285|   245k|}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_5UnaryE:
  288|  1.54M|{
  289|  1.54M|    expr(ast->expr);
  290|  1.54M|}
_ZN7jsonnet8internal12CompilerPass9visitExprERPNS0_3ASTE:
  300|  12.5M|{
  301|  12.5M|    switch(ast_->type) {
  302|   342k|        VISIT(ast_, AST_APPLY, Apply);
  ------------------
  |  |  293|   342k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 342k, False: 12.1M]
  |  |  ------------------
  |  |  294|   342k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   342k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   342k|     visit(ast); \
  |  |  297|   342k|   } break
  ------------------
  |  Branch (302:9): [True: 342k, False: 0]
  ------------------
  303|      0|        VISIT(ast_, AST_APPLY_BRACE, ApplyBrace);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 12.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  |  Branch (303:9): [True: 0, False: 0]
  ------------------
  304|   203k|        VISIT(ast_, AST_ARRAY, Array);
  ------------------
  |  |  293|   203k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 203k, False: 12.3M]
  |  |  ------------------
  |  |  294|   203k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   203k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   203k|     visit(ast); \
  |  |  297|   203k|   } break
  ------------------
  |  Branch (304:9): [True: 203k, False: 0]
  ------------------
  305|      0|        VISIT(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehension);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 12.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  |  Branch (305:9): [True: 0, False: 0]
  ------------------
  306|       |        // VISIT(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehensionSimple);
  307|      0|        VISIT(ast_, AST_ASSERT, Assert);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 12.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  |  Branch (307:9): [True: 0, False: 0]
  ------------------
  308|  1.11M|        VISIT(ast_, AST_BINARY, Binary);
  ------------------
  |  |  293|  1.11M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 1.11M, False: 11.3M]
  |  |  ------------------
  |  |  294|  1.11M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  1.11M|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  1.11M|     visit(ast); \
  |  |  297|  1.11M|   } break
  ------------------
  |  Branch (308:9): [True: 1.11M, False: 0]
  ------------------
  309|      0|        VISIT(ast_, AST_BUILTIN_FUNCTION, BuiltinFunction);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 12.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  |  Branch (309:9): [True: 0, False: 0]
  ------------------
  310|      0|        VISIT(ast_, AST_BUILTIN_FUNCTION_BODY, BuiltinFunctionBody);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 12.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  |  Branch (310:9): [True: 0, False: 0]
  ------------------
  311|   603k|        VISIT(ast_, AST_CONDITIONAL, Conditional);
  ------------------
  |  |  293|   603k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 603k, False: 11.9M]
  |  |  ------------------
  |  |  294|   603k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   603k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   603k|     visit(ast); \
  |  |  297|   603k|   } break
  ------------------
  |  Branch (311:9): [True: 603k, False: 0]
  ------------------
  312|  1.20M|        VISIT(ast_, AST_DESUGARED_OBJECT, DesugaredObject);
  ------------------
  |  |  293|  1.20M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 1.20M, False: 11.3M]
  |  |  ------------------
  |  |  294|  1.20M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  1.20M|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  1.20M|     visit(ast); \
  |  |  297|  1.20M|   } break
  ------------------
  |  Branch (312:9): [True: 1.20M, False: 0]
  ------------------
  313|      0|        VISIT(ast_, AST_DOLLAR, Dollar);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 12.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  |  Branch (313:9): [True: 0, False: 0]
  ------------------
  314|  97.5k|        VISIT(ast_, AST_ERROR, Error);
  ------------------
  |  |  293|  97.5k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 97.5k, False: 12.4M]
  |  |  ------------------
  |  |  294|  97.5k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  97.5k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  97.5k|     visit(ast); \
  |  |  297|  97.5k|   } break
  ------------------
  |  Branch (314:9): [True: 97.5k, False: 0]
  ------------------
  315|   196k|        VISIT(ast_, AST_FUNCTION, Function);
  ------------------
  |  |  293|   196k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 196k, False: 12.3M]
  |  |  ------------------
  |  |  294|   196k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   196k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   196k|     visit(ast); \
  |  |  297|   196k|   } break
  ------------------
  |  Branch (315:9): [True: 196k, False: 0]
  ------------------
  316|  1.88k|        VISIT(ast_, AST_IMPORT, Import);
  ------------------
  |  |  293|  1.88k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 1.88k, False: 12.5M]
  |  |  ------------------
  |  |  294|  1.88k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  1.88k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  1.88k|     visit(ast); \
  |  |  297|  1.88k|   } break
  ------------------
  |  Branch (316:9): [True: 1.88k, False: 0]
  ------------------
  317|  9.79k|        VISIT(ast_, AST_IMPORTSTR, Importstr);
  ------------------
  |  |  293|  9.79k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 9.79k, False: 12.5M]
  |  |  ------------------
  |  |  294|  9.79k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  9.79k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  9.79k|     visit(ast); \
  |  |  297|  9.79k|   } break
  ------------------
  |  Branch (317:9): [True: 9.79k, False: 0]
  ------------------
  318|  1.72k|        VISIT(ast_, AST_IMPORTBIN, Importbin);
  ------------------
  |  |  293|  1.72k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 1.72k, False: 12.5M]
  |  |  ------------------
  |  |  294|  1.72k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  1.72k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  1.72k|     visit(ast); \
  |  |  297|  1.72k|   } break
  ------------------
  |  Branch (318:9): [True: 1.72k, False: 0]
  ------------------
  319|   395k|        VISIT(ast_, AST_INDEX, Index);
  ------------------
  |  |  293|   395k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 395k, False: 12.1M]
  |  |  ------------------
  |  |  294|   395k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   395k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   395k|     visit(ast); \
  |  |  297|   395k|   } break
  ------------------
  |  Branch (319:9): [True: 395k, False: 0]
  ------------------
  320|   244k|        VISIT(ast_, AST_IN_SUPER, InSuper);
  ------------------
  |  |  293|   244k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 244k, False: 12.2M]
  |  |  ------------------
  |  |  294|   244k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   244k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   244k|     visit(ast); \
  |  |  297|   244k|   } break
  ------------------
  |  Branch (320:9): [True: 244k, False: 0]
  ------------------
  321|  15.0k|        VISIT(ast_, AST_LITERAL_BOOLEAN, LiteralBoolean);
  ------------------
  |  |  293|  15.0k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 15.0k, False: 12.4M]
  |  |  ------------------
  |  |  294|  15.0k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  15.0k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  15.0k|     visit(ast); \
  |  |  297|  15.0k|   } break
  ------------------
  |  Branch (321:9): [True: 15.0k, False: 0]
  ------------------
  322|  12.2k|        VISIT(ast_, AST_LITERAL_NULL, LiteralNull);
  ------------------
  |  |  293|  12.2k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 12.2k, False: 12.5M]
  |  |  ------------------
  |  |  294|  12.2k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  12.2k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  12.2k|     visit(ast); \
  |  |  297|  12.2k|   } break
  ------------------
  |  Branch (322:9): [True: 12.2k, False: 0]
  ------------------
  323|   671k|        VISIT(ast_, AST_LITERAL_NUMBER, LiteralNumber);
  ------------------
  |  |  293|   671k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 671k, False: 11.8M]
  |  |  ------------------
  |  |  294|   671k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   671k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   671k|     visit(ast); \
  |  |  297|   671k|   } break
  ------------------
  |  Branch (323:9): [True: 671k, False: 0]
  ------------------
  324|  1.94M|        VISIT(ast_, AST_LITERAL_STRING, LiteralString);
  ------------------
  |  |  293|  1.94M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 1.94M, False: 10.5M]
  |  |  ------------------
  |  |  294|  1.94M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  1.94M|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  1.94M|     visit(ast); \
  |  |  297|  1.94M|   } break
  ------------------
  |  Branch (324:9): [True: 1.94M, False: 0]
  ------------------
  325|   329k|        VISIT(ast_, AST_LOCAL, Local);
  ------------------
  |  |  293|   329k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 329k, False: 12.1M]
  |  |  ------------------
  |  |  294|   329k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   329k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   329k|     visit(ast); \
  |  |  297|   329k|   } break
  ------------------
  |  Branch (325:9): [True: 329k, False: 0]
  ------------------
  326|      0|        VISIT(ast_, AST_OBJECT, Object);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 12.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  |  Branch (326:9): [True: 0, False: 0]
  ------------------
  327|      0|        VISIT(ast_, AST_OBJECT_COMPREHENSION, ObjectComprehension);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 12.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  |  Branch (327:9): [True: 0, False: 0]
  ------------------
  328|  37.5k|        VISIT(ast_, AST_OBJECT_COMPREHENSION_SIMPLE, ObjectComprehensionSimple);
  ------------------
  |  |  293|  37.5k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 37.5k, False: 12.4M]
  |  |  ------------------
  |  |  294|  37.5k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  37.5k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  37.5k|     visit(ast); \
  |  |  297|  37.5k|   } break
  ------------------
  |  Branch (328:9): [True: 37.5k, False: 0]
  ------------------
  329|      0|        VISIT(ast_, AST_PARENS, Parens);
  ------------------
  |  |  293|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 0, False: 12.5M]
  |  |  ------------------
  |  |  294|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|      0|     visit(ast); \
  |  |  297|      0|   } break
  ------------------
  |  Branch (329:9): [True: 0, False: 0]
  ------------------
  330|  9.78k|        VISIT(ast_, AST_SELF, Self);
  ------------------
  |  |  293|  9.78k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 9.78k, False: 12.5M]
  |  |  ------------------
  |  |  294|  9.78k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  9.78k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  9.78k|     visit(ast); \
  |  |  297|  9.78k|   } break
  ------------------
  |  Branch (330:9): [True: 9.78k, False: 0]
  ------------------
  331|   245k|        VISIT(ast_, AST_SUPER_INDEX, SuperIndex);
  ------------------
  |  |  293|   245k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 245k, False: 12.2M]
  |  |  ------------------
  |  |  294|   245k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|   245k|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|   245k|     visit(ast); \
  |  |  297|   245k|   } break
  ------------------
  |  Branch (331:9): [True: 245k, False: 0]
  ------------------
  332|  1.54M|        VISIT(ast_, AST_UNARY, Unary);
  ------------------
  |  |  293|  1.54M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 1.54M, False: 10.9M]
  |  |  ------------------
  |  |  294|  1.54M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  1.54M|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  1.54M|     visit(ast); \
  |  |  297|  1.54M|   } break
  ------------------
  |  Branch (332:9): [True: 1.54M, False: 0]
  ------------------
  333|  3.28M|        VISIT(ast_, AST_VAR, Var);
  ------------------
  |  |  293|  3.28M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (293:4): [True: 3.28M, False: 9.23M]
  |  |  ------------------
  |  |  294|  3.28M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  295|  3.28M|     auto *ast = static_cast<astClass *>(var); \
  |  |  296|  3.28M|     visit(ast); \
  |  |  297|  3.28M|   } break
  ------------------
  |  Branch (333:9): [True: 3.28M, False: 0]
  ------------------
  334|      0|        default:
  ------------------
  |  Branch (334:9): [True: 0, False: 12.5M]
  ------------------
  335|      0|            std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl;
  336|      0|            std::abort();
  337|      0|            break;
  338|  12.5M|    }
  339|  12.5M|}
_ZN7jsonnet8internal9ClonePass4exprERPNS0_3ASTE:
  362|  11.0M|{
  363|  11.0M|    switch(ast_->type) {
  364|   294k|        CLONE(ast_, AST_APPLY, Apply);
  ------------------
  |  |  355|   294k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 294k, False: 10.7M]
  |  |  ------------------
  |  |  356|   294k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|   294k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|   294k|     var = alloc.clone(ast); \
  |  |  359|   294k|   } break
  ------------------
  |  Branch (364:9): [True: 294k, False: 0]
  ------------------
  365|      0|        CLONE(ast_, AST_APPLY_BRACE, ApplyBrace);
  ------------------
  |  |  355|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 0, False: 11.0M]
  |  |  ------------------
  |  |  356|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|      0|     var = alloc.clone(ast); \
  |  |  359|      0|   } break
  ------------------
  |  Branch (365:9): [True: 0, False: 0]
  ------------------
  366|   181k|        CLONE(ast_, AST_ARRAY, Array);
  ------------------
  |  |  355|   181k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 181k, False: 10.8M]
  |  |  ------------------
  |  |  356|   181k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|   181k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|   181k|     var = alloc.clone(ast); \
  |  |  359|   181k|   } break
  ------------------
  |  Branch (366:9): [True: 181k, False: 0]
  ------------------
  367|      0|        CLONE(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehension);
  ------------------
  |  |  355|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 0, False: 11.0M]
  |  |  ------------------
  |  |  356|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|      0|     var = alloc.clone(ast); \
  |  |  359|      0|   } break
  ------------------
  |  Branch (367:9): [True: 0, False: 0]
  ------------------
  368|       |        // CLONE(ast_, AST_ARRAY_COMPREHENSION, ArrayComprehensionSimple);
  369|      0|        CLONE(ast_, AST_ASSERT, Assert);
  ------------------
  |  |  355|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 0, False: 11.0M]
  |  |  ------------------
  |  |  356|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|      0|     var = alloc.clone(ast); \
  |  |  359|      0|   } break
  ------------------
  |  Branch (369:9): [True: 0, False: 0]
  ------------------
  370|   981k|        CLONE(ast_, AST_BINARY, Binary);
  ------------------
  |  |  355|   981k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 981k, False: 10.0M]
  |  |  ------------------
  |  |  356|   981k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|   981k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|   981k|     var = alloc.clone(ast); \
  |  |  359|   981k|   } break
  ------------------
  |  Branch (370:9): [True: 981k, False: 0]
  ------------------
  371|      0|        CLONE(ast_, AST_BUILTIN_FUNCTION, BuiltinFunction);
  ------------------
  |  |  355|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 0, False: 11.0M]
  |  |  ------------------
  |  |  356|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|      0|     var = alloc.clone(ast); \
  |  |  359|      0|   } break
  ------------------
  |  Branch (371:9): [True: 0, False: 0]
  ------------------
  372|   552k|        CLONE(ast_, AST_CONDITIONAL, Conditional);
  ------------------
  |  |  355|   552k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 552k, False: 10.5M]
  |  |  ------------------
  |  |  356|   552k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|   552k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|   552k|     var = alloc.clone(ast); \
  |  |  359|   552k|   } break
  ------------------
  |  Branch (372:9): [True: 552k, False: 0]
  ------------------
  373|  1.08M|        CLONE(ast_, AST_DESUGARED_OBJECT, DesugaredObject);
  ------------------
  |  |  355|  1.08M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 1.08M, False: 9.96M]
  |  |  ------------------
  |  |  356|  1.08M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|  1.08M|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|  1.08M|     var = alloc.clone(ast); \
  |  |  359|  1.08M|   } break
  ------------------
  |  Branch (373:9): [True: 1.08M, False: 0]
  ------------------
  374|      0|        CLONE(ast_, AST_DOLLAR, Dollar);
  ------------------
  |  |  355|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 0, False: 11.0M]
  |  |  ------------------
  |  |  356|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|      0|     var = alloc.clone(ast); \
  |  |  359|      0|   } break
  ------------------
  |  Branch (374:9): [True: 0, False: 0]
  ------------------
  375|  85.0k|        CLONE(ast_, AST_ERROR, Error);
  ------------------
  |  |  355|  85.0k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 85.0k, False: 10.9M]
  |  |  ------------------
  |  |  356|  85.0k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|  85.0k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|  85.0k|     var = alloc.clone(ast); \
  |  |  359|  85.0k|   } break
  ------------------
  |  Branch (375:9): [True: 85.0k, False: 0]
  ------------------
  376|   161k|        CLONE(ast_, AST_FUNCTION, Function);
  ------------------
  |  |  355|   161k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 161k, False: 10.8M]
  |  |  ------------------
  |  |  356|   161k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|   161k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|   161k|     var = alloc.clone(ast); \
  |  |  359|   161k|   } break
  ------------------
  |  Branch (376:9): [True: 161k, False: 0]
  ------------------
  377|  1.66k|        CLONE(ast_, AST_IMPORT, Import);
  ------------------
  |  |  355|  1.66k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 1.66k, False: 11.0M]
  |  |  ------------------
  |  |  356|  1.66k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|  1.66k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|  1.66k|     var = alloc.clone(ast); \
  |  |  359|  1.66k|   } break
  ------------------
  |  Branch (377:9): [True: 1.66k, False: 0]
  ------------------
  378|  7.67k|        CLONE(ast_, AST_IMPORTSTR, Importstr);
  ------------------
  |  |  355|  7.67k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 7.67k, False: 11.0M]
  |  |  ------------------
  |  |  356|  7.67k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|  7.67k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|  7.67k|     var = alloc.clone(ast); \
  |  |  359|  7.67k|   } break
  ------------------
  |  Branch (378:9): [True: 7.67k, False: 0]
  ------------------
  379|  1.15k|        CLONE(ast_, AST_IMPORTBIN, Importbin);
  ------------------
  |  |  355|  1.15k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 1.15k, False: 11.0M]
  |  |  ------------------
  |  |  356|  1.15k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|  1.15k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|  1.15k|     var = alloc.clone(ast); \
  |  |  359|  1.15k|   } break
  ------------------
  |  Branch (379:9): [True: 1.15k, False: 0]
  ------------------
  380|   338k|        CLONE(ast_, AST_INDEX, Index);
  ------------------
  |  |  355|   338k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 338k, False: 10.7M]
  |  |  ------------------
  |  |  356|   338k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|   338k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|   338k|     var = alloc.clone(ast); \
  |  |  359|   338k|   } break
  ------------------
  |  Branch (380:9): [True: 338k, False: 0]
  ------------------
  381|   244k|        CLONE(ast_, AST_IN_SUPER, InSuper);
  ------------------
  |  |  355|   244k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 244k, False: 10.8M]
  |  |  ------------------
  |  |  356|   244k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|   244k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|   244k|     var = alloc.clone(ast); \
  |  |  359|   244k|   } break
  ------------------
  |  Branch (381:9): [True: 244k, False: 0]
  ------------------
  382|  14.0k|        CLONE(ast_, AST_LITERAL_BOOLEAN, LiteralBoolean);
  ------------------
  |  |  355|  14.0k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 14.0k, False: 11.0M]
  |  |  ------------------
  |  |  356|  14.0k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|  14.0k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|  14.0k|     var = alloc.clone(ast); \
  |  |  359|  14.0k|   } break
  ------------------
  |  Branch (382:9): [True: 14.0k, False: 0]
  ------------------
  383|  9.76k|        CLONE(ast_, AST_LITERAL_NULL, LiteralNull);
  ------------------
  |  |  355|  9.76k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 9.76k, False: 11.0M]
  |  |  ------------------
  |  |  356|  9.76k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|  9.76k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|  9.76k|     var = alloc.clone(ast); \
  |  |  359|  9.76k|   } break
  ------------------
  |  Branch (383:9): [True: 9.76k, False: 0]
  ------------------
  384|   575k|        CLONE(ast_, AST_LITERAL_NUMBER, LiteralNumber);
  ------------------
  |  |  355|   575k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 575k, False: 10.4M]
  |  |  ------------------
  |  |  356|   575k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|   575k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|   575k|     var = alloc.clone(ast); \
  |  |  359|   575k|   } break
  ------------------
  |  Branch (384:9): [True: 575k, False: 0]
  ------------------
  385|  1.77M|        CLONE(ast_, AST_LITERAL_STRING, LiteralString);
  ------------------
  |  |  355|  1.77M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 1.77M, False: 9.28M]
  |  |  ------------------
  |  |  356|  1.77M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|  1.77M|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|  1.77M|     var = alloc.clone(ast); \
  |  |  359|  1.77M|   } break
  ------------------
  |  Branch (385:9): [True: 1.77M, False: 0]
  ------------------
  386|   306k|        CLONE(ast_, AST_LOCAL, Local);
  ------------------
  |  |  355|   306k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 306k, False: 10.7M]
  |  |  ------------------
  |  |  356|   306k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|   306k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|   306k|     var = alloc.clone(ast); \
  |  |  359|   306k|   } break
  ------------------
  |  Branch (386:9): [True: 306k, False: 0]
  ------------------
  387|      0|        CLONE(ast_, AST_OBJECT, Object);
  ------------------
  |  |  355|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 0, False: 11.0M]
  |  |  ------------------
  |  |  356|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|      0|     var = alloc.clone(ast); \
  |  |  359|      0|   } break
  ------------------
  |  Branch (387:9): [True: 0, False: 0]
  ------------------
  388|      0|        CLONE(ast_, AST_OBJECT_COMPREHENSION, ObjectComprehension);
  ------------------
  |  |  355|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 0, False: 11.0M]
  |  |  ------------------
  |  |  356|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|      0|     var = alloc.clone(ast); \
  |  |  359|      0|   } break
  ------------------
  |  Branch (388:9): [True: 0, False: 0]
  ------------------
  389|  31.4k|        CLONE(ast_, AST_OBJECT_COMPREHENSION_SIMPLE, ObjectComprehensionSimple);
  ------------------
  |  |  355|  31.4k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 31.4k, False: 11.0M]
  |  |  ------------------
  |  |  356|  31.4k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|  31.4k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|  31.4k|     var = alloc.clone(ast); \
  |  |  359|  31.4k|   } break
  ------------------
  |  Branch (389:9): [True: 31.4k, False: 0]
  ------------------
  390|      0|        CLONE(ast_, AST_PARENS, Parens);
  ------------------
  |  |  355|      0|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 0, False: 11.0M]
  |  |  ------------------
  |  |  356|      0|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|      0|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|      0|     var = alloc.clone(ast); \
  |  |  359|      0|   } break
  ------------------
  |  Branch (390:9): [True: 0, False: 0]
  ------------------
  391|  9.78k|        CLONE(ast_, AST_SELF, Self);
  ------------------
  |  |  355|  9.78k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 9.78k, False: 11.0M]
  |  |  ------------------
  |  |  356|  9.78k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|  9.78k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|  9.78k|     var = alloc.clone(ast); \
  |  |  359|  9.78k|   } break
  ------------------
  |  Branch (391:9): [True: 9.78k, False: 0]
  ------------------
  392|   245k|        CLONE(ast_, AST_SUPER_INDEX, SuperIndex);
  ------------------
  |  |  355|   245k|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 245k, False: 10.8M]
  |  |  ------------------
  |  |  356|   245k|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|   245k|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|   245k|     var = alloc.clone(ast); \
  |  |  359|   245k|   } break
  ------------------
  |  Branch (392:9): [True: 245k, False: 0]
  ------------------
  393|  1.31M|        CLONE(ast_, AST_UNARY, Unary);
  ------------------
  |  |  355|  1.31M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 1.31M, False: 9.73M]
  |  |  ------------------
  |  |  356|  1.31M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|  1.31M|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|  1.31M|     var = alloc.clone(ast); \
  |  |  359|  1.31M|   } break
  ------------------
  |  Branch (393:9): [True: 1.31M, False: 0]
  ------------------
  394|  2.83M|        CLONE(ast_, AST_VAR, Var);
  ------------------
  |  |  355|  2.83M|   case astType: { \
  |  |  ------------------
  |  |  |  Branch (355:4): [True: 2.83M, False: 8.21M]
  |  |  ------------------
  |  |  356|  2.83M|     assert(dynamic_cast<astClass *>(var)); \
  |  |  357|  2.83M|     auto *ast = static_cast<astClass *>(var); \
  |  |  358|  2.83M|     var = alloc.clone(ast); \
  |  |  359|  2.83M|   } break
  ------------------
  |  Branch (394:9): [True: 2.83M, False: 0]
  ------------------
  395|      0|        default:
  ------------------
  |  Branch (395:9): [True: 0, False: 11.0M]
  ------------------
  396|      0|            std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl;
  397|      0|            std::abort();
  398|      0|            break;
  399|  11.0M|    }
  400|       |
  401|  11.0M|    CompilerPass::expr(ast_);
  402|  11.0M|}
_ZN7jsonnet8internal9clone_astERNS0_9AllocatorEPNS0_3ASTE:
  405|  50.4k|{
  406|  50.4k|    AST *r = ast;
  407|  50.4k|    ClonePass(alloc).expr(r);
  408|  50.4k|    return r;
  409|  50.4k|}
_ZN7jsonnet8internal9ClonePassC2ERNS0_9AllocatorE:
  350|  50.4k|    ClonePass(Allocator &alloc) : CompilerPass(alloc) {}

_ZN7jsonnet8internal12CompilerPassC2ERNS0_9AllocatorE:
   32|  67.2k|    CompilerPass(Allocator &alloc) : alloc(alloc) {}
_ZN7jsonnet8internal12CompilerPass13fodderElementERNS0_13FodderElementE:
   34|   242k|    virtual void fodderElement(FodderElement &) {}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_14LiteralBooleanE:
   84|  15.0k|    virtual void visit(LiteralBoolean *) {}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_13LiteralNumberE:
   86|   671k|    virtual void visit(LiteralNumber *) {}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_11LiteralNullE:
   90|  12.2k|    virtual void visit(LiteralNull *) {}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_4SelfE:
  102|  9.78k|    virtual void visit(Self *) {}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_3VarE:
  108|  3.28M|    virtual void visit(Var *) {}
_ZN7jsonnet8internal12CompilerPass5visitEPNS0_13LiteralStringE:
   88|  1.95M|    virtual void visit(LiteralString *) {}

_ZN7jsonnet8internal32path_dir_with_trailing_separatorERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   31|     60|std::string path_dir_with_trailing_separator(const std::string &path) {
   32|     60|    size_t last_slash = path.find_last_of(DIR_SEPARATORS);
   33|     60|    if (last_slash != std::string::npos) {
  ------------------
  |  Branch (33:9): [True: 0, False: 60]
  ------------------
   34|      0|        return path.substr(0, last_slash + 1);
   35|      0|    }
   36|     60|    return "";
   37|     60|}

vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14HeapC2Ejd:
  346|  4.02k|        : gcTuneMinObjects(gc_tune_min_objects),
  347|  4.02k|          gcTuneGrowthTrigger(gc_tune_growth_trigger),
  348|  4.02k|          lastMark(0),
  349|  4.02k|          lastNumEntities(0),
  350|  4.02k|          numEntities(0)
  351|  4.02k|    {
  352|  4.02k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_18type_strENS1_5Value4TypeE:
   76|  1.47k|{
   77|  1.47k|    switch (t) {
   78|      3|        case Value::NULL_TYPE: return "null";
  ------------------
  |  Branch (78:9): [True: 3, False: 1.47k]
  ------------------
   79|    258|        case Value::BOOLEAN: return "boolean";
  ------------------
  |  Branch (79:9): [True: 258, False: 1.21k]
  ------------------
   80|    331|        case Value::NUMBER: return "number";
  ------------------
  |  Branch (80:9): [True: 331, False: 1.14k]
  ------------------
   81|     93|        case Value::ARRAY: return "array";
  ------------------
  |  Branch (81:9): [True: 93, False: 1.38k]
  ------------------
   82|      3|        case Value::FUNCTION: return "function";
  ------------------
  |  Branch (82:9): [True: 3, False: 1.47k]
  ------------------
   83|    174|        case Value::OBJECT: return "object";
  ------------------
  |  Branch (83:9): [True: 174, False: 1.29k]
  ------------------
   84|    611|        case Value::STRING: return "string";
  ------------------
  |  Branch (84:9): [True: 611, False: 862]
  ------------------
   85|      0|        default:
  ------------------
  |  Branch (85:9): [True: 0, False: 1.47k]
  ------------------
   86|      0|            std::cerr << "INTERNAL ERROR: Unknown type: " << t << std::endl;
   87|      0|            std::abort();
   88|      0|            return "";  // Quiet, compiler.
   89|  1.47k|    }
   90|  1.47k|}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_18type_strERKNS1_5ValueE:
   94|    472|{
   95|    472|    return type_str(v.t);
   96|    472|}
vm.cpp:_ZNK7jsonnet8internal12_GLOBAL__N_15Value6isHeapEv:
   69|  60.8M|    {
   70|  60.8M|        return t & 0x10;
   71|  60.8M|    }
vm.cpp:_ZNK7jsonnet8internal12_GLOBAL__N_111HeapClosure9isBuiltinEv:
  293|  28.8M|    bool isBuiltin() const { return !this->body || this->body->type == AST_BUILTIN_FUNCTION_BODY; }
  ------------------
  |  Branch (293:37): [True: 0, False: 28.8M]
  |  Branch (293:52): [True: 21.5M, False: 7.36M]
  ------------------
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_19HeapThunkC2EPKNS0_10IdentifierEPNS1_10HeapObjectEjPKNS0_3ASTE:
  140|  47.2M|        : HeapEntity(THUNK), filled(false), name(name), self(self), offset(offset), body(body)
  141|  47.2M|    {
  142|  47.2M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_110HeapEntityC2ENS2_4TypeE:
   43|   100M|    HeapEntity(Type type_) : type(type_) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_110HeapEntityD2Ev:
   44|   100M|    virtual ~HeapEntity() {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap9checkHeapEv:
  489|   100M|    {
  490|   100M|        return numEntities > gcTuneMinObjects &&
  ------------------
  |  Branch (490:16): [True: 41.8M, False: 58.2M]
  ------------------
  491|  41.8M|               numEntities > gcTuneGrowthTrigger * lastNumEntities;
  ------------------
  |  Branch (491:16): [True: 110k, False: 41.7M]
  ------------------
  492|   100M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap8markFromEPNS1_10HeapEntityE:
  369|  96.1M|    {
  370|  96.1M|        assert(from != nullptr);
  ------------------
  |  Branch (370:9): [True: 96.1M, False: 0]
  ------------------
  371|  96.1M|        const GarbageCollectionMark thisMark = lastMark + 1;
  372|  96.1M|        struct State {
  373|  96.1M|            HeapEntity *ent;
  374|  96.1M|            std::vector<HeapEntity *> children;
  375|  96.1M|            State(HeapEntity *ent) : ent(ent) {}
  376|  96.1M|        };
  377|       |
  378|  96.1M|        std::vector<State> stack;
  379|  96.1M|        stack.emplace_back(from);
  380|       |
  381|   403M|        while (stack.size() > 0) {
  ------------------
  |  Branch (381:16): [True: 307M, False: 96.1M]
  ------------------
  382|   307M|            size_t curr_index = stack.size() - 1;
  383|   307M|            State &s = stack[curr_index];
  384|   307M|            HeapEntity *curr = s.ent;
  385|   307M|            if (curr->mark != thisMark) {
  ------------------
  |  Branch (385:17): [True: 77.5M, False: 229M]
  ------------------
  386|  77.5M|                curr->mark = thisMark;
  387|       |
  388|  77.5M|                switch(curr->type) {
  389|  11.5M|                    case HeapEntity::SIMPLE_OBJECT: {
  ------------------
  |  Branch (389:21): [True: 11.5M, False: 65.9M]
  ------------------
  390|  11.5M|                        assert(dynamic_cast<HeapSimpleObject *>(curr));
  ------------------
  |  Branch (390:25): [True: 11.5M, False: 0]
  ------------------
  391|  11.5M|                        auto *obj = static_cast<HeapSimpleObject *>(curr);
  392|  11.5M|                        for (auto upv : obj->upValues)
  ------------------
  |  Branch (392:39): [True: 10.3M, False: 11.5M]
  ------------------
  393|  10.3M|                            addIfHeapEntity(upv.second, s.children);
  394|  11.5M|                        break;
  395|  11.5M|                    }
  396|  7.42M|                    case HeapEntity::EXTENDED_OBJECT: {
  ------------------
  |  Branch (396:21): [True: 7.42M, False: 70.0M]
  ------------------
  397|  7.42M|                        assert(dynamic_cast<HeapExtendedObject *>(curr));
  ------------------
  |  Branch (397:25): [True: 7.42M, False: 0]
  ------------------
  398|  7.42M|                        auto *obj = static_cast<HeapExtendedObject *>(curr);
  399|  7.42M|                        addIfHeapEntity(obj->left, s.children);
  400|  7.42M|                        addIfHeapEntity(obj->right, s.children);
  401|  7.42M|                        break;
  402|  7.42M|                    }
  403|      0|                    case HeapEntity::RESTRICTED_OBJECT: {
  ------------------
  |  Branch (403:21): [True: 0, False: 77.5M]
  ------------------
  404|      0|                        assert(dynamic_cast<HeapRestrictedObject *>(curr));
  ------------------
  |  Branch (404:25): [True: 0, False: 0]
  ------------------
  405|      0|                        auto *obj = static_cast<HeapRestrictedObject *>(curr);
  406|      0|                        addIfHeapEntity(obj->obj, s.children);
  407|      0|                        break;
  408|      0|                    }
  409|      0|                    case HeapEntity::COMPREHENSION_OBJECT: {
  ------------------
  |  Branch (409:21): [True: 0, False: 77.5M]
  ------------------
  410|      0|                        assert(dynamic_cast<HeapComprehensionObject *>(curr));
  ------------------
  |  Branch (410:25): [True: 0, False: 0]
  ------------------
  411|      0|                        auto *obj = static_cast<HeapComprehensionObject *>(curr);
  412|      0|                        for (auto upv : obj->upValues)
  ------------------
  |  Branch (412:39): [True: 0, False: 0]
  ------------------
  413|      0|                            addIfHeapEntity(upv.second, s.children);
  414|      0|                        for (auto upv : obj->compValues)
  ------------------
  |  Branch (414:39): [True: 0, False: 0]
  ------------------
  415|      0|                            addIfHeapEntity(upv.second, s.children);
  416|      0|                        break;
  417|      0|                    }
  418|  1.95M|                    case HeapEntity::ARRAY: {
  ------------------
  |  Branch (418:21): [True: 1.95M, False: 75.5M]
  ------------------
  419|  1.95M|                        assert(dynamic_cast<HeapArray *>(curr));
  ------------------
  |  Branch (419:25): [True: 1.95M, False: 0]
  ------------------
  420|  1.95M|                        auto *arr = static_cast<HeapArray *>(curr);
  421|  1.95M|                        for (auto el : arr->elements)
  ------------------
  |  Branch (421:38): [True: 19.5M, False: 1.95M]
  ------------------
  422|  19.5M|                            addIfHeapEntity(el, s.children);
  423|  1.95M|                        break;
  424|  1.95M|                    }
  425|  1.77M|                    case HeapEntity::CLOSURE: {
  ------------------
  |  Branch (425:21): [True: 1.77M, False: 75.7M]
  ------------------
  426|  1.77M|                        assert(dynamic_cast<HeapClosure *>(curr));
  ------------------
  |  Branch (426:25): [True: 1.77M, False: 0]
  ------------------
  427|  1.77M|                        auto *func = static_cast<HeapClosure *>(curr);
  428|  1.77M|                        for (auto upv : func->upValues)
  ------------------
  |  Branch (428:39): [True: 4.00M, False: 1.77M]
  ------------------
  429|  4.00M|                            addIfHeapEntity(upv.second, s.children);
  430|  1.77M|                        if (func->self)
  ------------------
  |  Branch (430:29): [True: 1.53M, False: 237k]
  ------------------
  431|  1.53M|                            addIfHeapEntity(func->self, s.children);
  432|  1.77M|                        break;
  433|  1.77M|                    }
  434|  53.4M|                    case HeapEntity::THUNK: {
  ------------------
  |  Branch (434:21): [True: 53.4M, False: 24.1M]
  ------------------
  435|  53.4M|                        assert(dynamic_cast<HeapThunk *>(curr));
  ------------------
  |  Branch (435:25): [True: 53.4M, False: 0]
  ------------------
  436|  53.4M|                        auto *thunk = static_cast<HeapThunk *>(curr);
  437|  53.4M|                        if (thunk->filled) {
  ------------------
  |  Branch (437:29): [True: 9.93M, False: 43.4M]
  ------------------
  438|  9.93M|                            if (thunk->content.isHeap())
  ------------------
  |  Branch (438:33): [True: 7.00M, False: 2.92M]
  ------------------
  439|  7.00M|                                addIfHeapEntity(thunk->content.v.h, s.children);
  440|  43.4M|                        } else {
  441|  43.4M|                            for (auto upv : thunk->upValues)
  ------------------
  |  Branch (441:43): [True: 7.10M, False: 43.4M]
  ------------------
  442|  7.10M|                                addIfHeapEntity(upv.second, s.children);
  443|  43.4M|                            if (thunk->self)
  ------------------
  |  Branch (443:33): [True: 41.1M, False: 2.34M]
  ------------------
  444|  41.1M|                                addIfHeapEntity(thunk->self, s.children);
  445|  43.4M|                        }
  446|  53.4M|                        break;
  447|  53.4M|                    }
  448|  1.38M|                    case HeapEntity::STRING:
  ------------------
  |  Branch (448:21): [True: 1.38M, False: 76.1M]
  ------------------
  449|  1.38M|                        assert(dynamic_cast<HeapString *>(curr));
  ------------------
  |  Branch (449:25): [True: 1.38M, False: 0]
  ------------------
  450|  1.38M|                        break;
  451|  1.38M|                    default:
  ------------------
  |  Branch (451:21): [True: 0, False: 77.5M]
  ------------------
  452|      0|                        assert(false);
  ------------------
  |  Branch (452:25): [Folded, False: 0]
  ------------------
  453|      0|                        break;
  454|  77.5M|                }
  455|  77.5M|            }
  456|       |
  457|   307M|            if (s.children.size() > 0) {
  ------------------
  |  Branch (457:17): [True: 105M, False: 201M]
  ------------------
  458|   105M|                HeapEntity *next = s.children[s.children.size() - 1];
  459|   105M|                s.children.pop_back();
  460|   105M|                stack.emplace_back(next);  // CAUTION: s invalidated here
  461|   201M|            } else {
  462|   201M|                stack.pop_back();  // CAUTION: s invalidated here
  463|   201M|            }
  464|   307M|        }
  465|  96.1M|    }
vm.cpp:_ZZN7jsonnet8internal12_GLOBAL__N_14Heap8markFromEPNS1_10HeapEntityEEN5StateC2ES4_:
  375|   201M|            State(HeapEntity *ent) : ent(ent) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap15addIfHeapEntityEPNS1_10HeapEntityERNSt3__16vectorIS4_NS5_9allocatorIS4_EEEE:
  340|   105M|    {
  341|   105M|        vec.push_back(v);
  342|   105M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap8markFromENS1_5ValueE:
  362|  50.4M|    {
  363|  50.4M|        if (v.isHeap())
  ------------------
  |  Branch (363:13): [True: 14.0M, False: 36.3M]
  ------------------
  364|  14.0M|            markFrom(v.v.h);
  365|  50.4M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap5sweepEv:
  469|   114k|    {
  470|   114k|        lastMark++;
  471|       |        // Heap shrinks during this loop.  Do not cache entities.size().
  472|   177M|        for (unsigned long i = 0; i < entities.size(); ++i) {
  ------------------
  |  Branch (472:35): [True: 177M, False: 114k]
  ------------------
  473|   177M|            HeapEntity *x = entities[i];
  474|   177M|            if (x->mark != lastMark) {
  ------------------
  |  Branch (474:17): [True: 100M, False: 77.5M]
  ------------------
  475|   100M|                delete x;
  476|   100M|                if (i != entities.size() - 1) {
  ------------------
  |  Branch (476:21): [True: 100M, False: 96.1k]
  ------------------
  477|       |                    // Swap it with the back.
  478|   100M|                    entities[i] = entities[entities.size() - 1];
  479|   100M|                }
  480|   100M|                entities.pop_back();
  481|   100M|                --i;
  482|   100M|            }
  483|   177M|        }
  484|   114k|        lastNumEntities = numEntities = entities.size();
  485|   114k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_19HeapThunk4fillERKNS1_5ValueE:
  145|  24.2M|    {
  146|  24.2M|        content = v;
  147|  24.2M|        filled = true;
  148|  24.2M|        self = nullptr;
  149|  24.2M|        upValues.clear();
  150|  24.2M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapArrayEJRKNSt3__16vectorIPNS1_9HeapThunkENS5_9allocatorIS8_EEEEEEEPT_DpOT0_:
  501|  1.65M|    {
  502|  1.65M|        T *r = new T(std::forward<Args>(args)...);
  503|  1.65M|        entities.push_back(r);
  504|  1.65M|        r->mark = lastMark;
  505|  1.65M|        numEntities = entities.size();
  506|  1.65M|        return r;
  507|  1.65M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_19HeapArrayC2ERKNSt3__16vectorIPNS1_9HeapThunkENS3_9allocatorIS6_EEEE:
  159|  1.65M|        : HeapEntity(ARRAY), elements(elements)
  160|  1.65M|    {
  161|  1.65M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_10HeapStringEJRKNSt3__112basic_stringIDiNS5_11char_traitsIDiEENS5_9allocatorIDiEEEEEEEPT_DpOT0_:
  501|  37.4M|    {
  502|  37.4M|        T *r = new T(std::forward<Args>(args)...);
  503|  37.4M|        entities.push_back(r);
  504|  37.4M|        r->mark = lastMark;
  505|  37.4M|        numEntities = entities.size();
  506|  37.4M|        return r;
  507|  37.4M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_110HeapStringC2ERKNSt3__112basic_stringIDiNS3_11char_traitsIDiEENS3_9allocatorIDiEEEE:
  299|  37.4M|    HeapString(const UString &value) : HeapEntity(STRING), value(value) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapThunkEJRPKNS0_10IdentifierEDniDnEEEPT_DpOT0_:
  501|   661k|    {
  502|   661k|        T *r = new T(std::forward<Args>(args)...);
  503|   661k|        entities.push_back(r);
  504|   661k|        r->mark = lastMark;
  505|   661k|        numEntities = entities.size();
  506|   661k|        return r;
  507|   661k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_114HeapLeafObjectC2ENS1_10HeapEntity4TypeE:
  166|  2.01M|    HeapLeafObject(Type type) : HeapObject(type) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_110HeapObjectC2ENS1_10HeapEntity4TypeE:
  109|  3.49M|    HeapObject(Type type) : HeapEntity(type) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111HeapClosure5ParamC2EPKNS0_10IdentifierEPKNS0_3ASTE:
  275|  17.0M|        Param(const Identifier *id, const AST *def) : id(id), def(def) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_11HeapClosureEJNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS5_4lessIS9_EENS5_9allocatorINS5_4pairIKS9_SB_EEEEEEDniRNS5_6vectorINS4_5ParamENSE_ISL_EEEERPKNS0_19BuiltinFunctionBodyERKNS5_12basic_stringIcNS5_11char_traitsIcEENSE_IcEEEEEEEPT_DpOT0_:
  501|  8.33M|    {
  502|  8.33M|        T *r = new T(std::forward<Args>(args)...);
  503|  8.33M|        entities.push_back(r);
  504|  8.33M|        r->mark = lastMark;
  505|  8.33M|        numEntities = entities.size();
  506|  8.33M|        return r;
  507|  8.33M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111HeapClosureC2ERKNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS3_4lessIS7_EENS3_9allocatorINS3_4pairIKS7_S9_EEEEEEPNS1_10HeapObjectEjRKNS3_6vectorINS2_5ParamENSC_ISN_EEEEPKNS0_3ASTERKNS3_12basic_stringIcNS3_11char_traitsIcEENSC_IcEEEE:
  283|  10.3M|        : HeapEntity(CLOSURE),
  284|  10.3M|          upValues(up_values),
  285|  10.3M|          self(self),
  286|  10.3M|          offset(offset),
  287|  10.3M|          params(params),
  288|  10.3M|          body(body),
  289|  10.3M|          builtinName(builtin_name)
  290|  10.3M|    {
  291|  10.3M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapThunkEJDnDniPKNS0_3ASTEEEEPT_DpOT0_:
  501|  4.02k|    {
  502|  4.02k|        T *r = new T(std::forward<Args>(args)...);
  503|  4.02k|        entities.push_back(r);
  504|  4.02k|        r->mark = lastMark;
  505|  4.02k|        numEntities = entities.size();
  506|  4.02k|        return r;
  507|  4.02k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapThunkEJPNS0_10IdentifierERPNS1_10HeapObjectEiRKPNS0_3ASTEEEEPT_DpOT0_:
  501|   647k|    {
  502|   647k|        T *r = new T(std::forward<Args>(args)...);
  503|   647k|        entities.push_back(r);
  504|   647k|        r->mark = lastMark;
  505|   647k|        numEntities = entities.size();
  506|   647k|        return r;
  507|   647k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14HeapD2Ev:
  355|  4.02k|    {
  356|       |        // Nothing is marked, everything will be collected.
  357|  4.02k|        sweep();
  358|  4.02k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapThunkEJRPKNS0_10IdentifierERPNS1_10HeapObjectERjRKPNS0_3ASTEEEEPT_DpOT0_:
  501|  25.3M|    {
  502|  25.3M|        T *r = new T(std::forward<Args>(args)...);
  503|  25.3M|        entities.push_back(r);
  504|  25.3M|        r->mark = lastMark;
  505|  25.3M|        numEntities = entities.size();
  506|  25.3M|        return r;
  507|  25.3M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_11HeapClosureEJRKNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS5_4lessIS9_EENS5_9allocatorINS5_4pairIKS9_SB_EEEEEERPNS1_10HeapObjectERjRKNS5_6vectorINS4_5ParamENSE_ISR_EEEERPNS0_3ASTERA1_KcEEEPT_DpOT0_:
  501|  2.00M|    {
  502|  2.00M|        T *r = new T(std::forward<Args>(args)...);
  503|  2.00M|        entities.push_back(r);
  504|  2.00M|        r->mark = lastMark;
  505|  2.00M|        numEntities = entities.size();
  506|  2.00M|        return r;
  507|  2.00M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapThunkEJRKPKNS0_10IdentifierERPNS1_10HeapObjectERjRKPNS0_3ASTEEEEPT_DpOT0_:
  501|  18.1M|    {
  502|  18.1M|        T *r = new T(std::forward<Args>(args)...);
  503|  18.1M|        entities.push_back(r);
  504|  18.1M|        r->mark = lastMark;
  505|  18.1M|        numEntities = entities.size();
  506|  18.1M|        return r;
  507|  18.1M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_16HeapSimpleObjectEJRNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS5_4lessIS9_EENS5_9allocatorINS5_4pairIKS9_SB_EEEEEERNS6_IS9_NS4_5FieldESD_NSE_INSF_ISG_SL_EEEEEERNS5_4listIPNS0_3ASTENSE_ISS_EEEEEEEPT_DpOT0_:
  501|  2.01M|    {
  502|  2.01M|        T *r = new T(std::forward<Args>(args)...);
  503|  2.01M|        entities.push_back(r);
  504|  2.01M|        r->mark = lastMark;
  505|  2.01M|        numEntities = entities.size();
  506|  2.01M|        return r;
  507|  2.01M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_116HeapSimpleObjectC2ERKNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS3_4lessIS7_EENS3_9allocatorINS3_4pairIKS7_S9_EEEEEENS4_IS7_NS2_5FieldESB_NSC_INSD_ISE_SK_EEEEEENS3_4listIPNS0_3ASTENSC_ISQ_EEEE:
  196|  2.01M|        : HeapLeafObject(SIMPLE_OBJECT), upValues(up_values), fields(fields), asserts(asserts)
  197|  2.01M|    {
  198|  2.01M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapThunkEJRPKNS0_10IdentifierERPNS1_10HeapObjectERjRKPKNS0_3ASTEEEEPT_DpOT0_:
  501|    131|    {
  502|    131|        T *r = new T(std::forward<Args>(args)...);
  503|    131|        entities.push_back(r);
  504|    131|        r->mark = lastMark;
  505|    131|        numEntities = entities.size();
  506|    131|        return r;
  507|    131|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_18HeapExtendedObjectEJRPNS1_10HeapObjectES7_EEEPT_DpOT0_:
  501|  1.47M|    {
  502|  1.47M|        T *r = new T(std::forward<Args>(args)...);
  503|  1.47M|        entities.push_back(r);
  504|  1.47M|        r->mark = lastMark;
  505|  1.47M|        numEntities = entities.size();
  506|  1.47M|        return r;
  507|  1.47M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_118HeapExtendedObjectC2EPNS1_10HeapObjectES4_:
  210|  1.47M|        : HeapObject(EXTENDED_OBJECT), left(left), right(right)
  211|  1.47M|    {
  212|  1.47M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_14Heap10makeEntityINS1_9HeapThunkEJRPKNS0_10IdentifierERPNS1_10HeapObjectERjRPNS0_3ASTEEEEPT_DpOT0_:
  501|  2.35M|    {
  502|  2.35M|        T *r = new T(std::forward<Args>(args)...);
  503|  2.35M|        entities.push_back(r);
  504|  2.35M|        r->mark = lastMark;
  505|  2.35M|        numEntities = entities.size();
  506|  2.35M|        return r;
  507|  2.35M|    }

_ZN7jsonnet8internal23jsonnet_static_analysisEPNS0_3ASTE:
  228|  8.76k|{
  229|  8.76k|    static_analysis(ast, false, IdSet{});
  230|  8.76k|}
static_analysis.cpp:_ZN7jsonnet8internalL15static_analysisEPNS0_3ASTEbRKNSt3__13setIPKNS0_10IdentifierENS3_4lessIS7_EENS3_9allocatorIS7_EEEE:
   41|   277M|{
   42|   277M|    IdSet r;
   43|       |
   44|   277M|    switch (ast_->type) {
   45|  24.7M|    case AST_APPLY: {
  ------------------
  |  Branch (45:5): [True: 24.7M, False: 253M]
  ------------------
   46|  24.7M|        assert(dynamic_cast<Apply *>(ast_));
  ------------------
  |  Branch (46:9): [True: 24.7M, False: 0]
  ------------------
   47|  24.7M|        auto* ast = static_cast<Apply *>(ast_);
   48|  24.7M|        append(r, static_analysis(ast->target, in_object, vars));
   49|  24.7M|        for (const auto &arg : ast->args)
  ------------------
  |  Branch (49:30): [True: 40.5M, False: 24.7M]
  ------------------
   50|  40.5M|            append(r, static_analysis(arg.expr, in_object, vars));
   51|  24.7M|    } break;
   52|      0|    case AST_APPLY_BRACE: {
  ------------------
  |  Branch (52:5): [True: 0, False: 277M]
  ------------------
   53|      0|        assert(dynamic_cast<ApplyBrace *>(ast_));
  ------------------
  |  Branch (53:9): [True: 0, False: 0]
  ------------------
   54|       |        // Nothing to do.
   55|      0|    } break;
   56|  5.74M|    case AST_ARRAY: {
  ------------------
  |  Branch (56:5): [True: 5.74M, False: 272M]
  ------------------
   57|  5.74M|        assert(dynamic_cast<Array *>(ast_));
  ------------------
  |  Branch (57:9): [True: 5.74M, False: 0]
  ------------------
   58|  5.74M|        auto* ast = static_cast<Array *>(ast_);
   59|  5.74M|        for (auto &el : ast->elements)
  ------------------
  |  Branch (59:23): [True: 8.33M, False: 5.74M]
  ------------------
   60|  8.33M|            append(r, static_analysis(el.expr, in_object, vars));
   61|  5.74M|    } break;
   62|  25.4M|    case AST_BINARY: {
  ------------------
  |  Branch (62:5): [True: 25.4M, False: 252M]
  ------------------
   63|  25.4M|        assert(dynamic_cast<Binary *>(ast_));
  ------------------
  |  Branch (63:9): [True: 25.4M, False: 0]
  ------------------
   64|  25.4M|        auto* ast = static_cast<Binary *>(ast_);
   65|  25.4M|        append(r, static_analysis(ast->left, in_object, vars));
   66|  25.4M|        append(r, static_analysis(ast->right, in_object, vars));
   67|  25.4M|    } break;
   68|   368k|    case AST_BUILTIN_FUNCTION: {
  ------------------
  |  Branch (68:5): [True: 368k, False: 277M]
  ------------------
   69|   368k|        assert(dynamic_cast<BuiltinFunction *>(ast_));
  ------------------
  |  Branch (69:9): [True: 368k, False: 0]
  ------------------
   70|       |        // Nothing to do.
   71|   368k|    } break;
   72|  10.2M|    case AST_CONDITIONAL: {
  ------------------
  |  Branch (72:5): [True: 10.2M, False: 267M]
  ------------------
   73|  10.2M|        assert(dynamic_cast<Conditional *>(ast_));
  ------------------
  |  Branch (73:9): [True: 10.2M, False: 0]
  ------------------
   74|  10.2M|        auto* ast = static_cast<Conditional *>(ast_);
   75|  10.2M|        append(r, static_analysis(ast->cond, in_object, vars));
   76|  10.2M|        append(r, static_analysis(ast->branchTrue, in_object, vars));
   77|  10.2M|        append(r, static_analysis(ast->branchFalse, in_object, vars));
   78|  10.2M|    } break;
   79|  5.35M|    case AST_ERROR: {
  ------------------
  |  Branch (79:5): [True: 5.35M, False: 272M]
  ------------------
   80|  5.35M|        assert(dynamic_cast<Error *>(ast_));
  ------------------
  |  Branch (80:9): [True: 5.35M, False: 0]
  ------------------
   81|  5.35M|        auto* ast = static_cast<Error *>(ast_);
   82|  5.35M|        append(r, static_analysis(ast->expr, in_object, vars));
   83|  5.35M|    } break;
   84|  6.36M|    case AST_FUNCTION: {
  ------------------
  |  Branch (84:5): [True: 6.36M, False: 271M]
  ------------------
   85|  6.36M|        assert(dynamic_cast<Function *>(ast_));
  ------------------
  |  Branch (85:9): [True: 6.36M, False: 0]
  ------------------
   86|  6.36M|        auto* ast = static_cast<Function *>(ast_);
   87|  6.36M|        auto new_vars = vars;
   88|  6.36M|        IdSet params;
   89|  11.7M|        for (const auto &p : ast->params) {
  ------------------
  |  Branch (89:28): [True: 11.7M, False: 6.36M]
  ------------------
   90|  11.7M|            if (params.find(p.id) != params.end()) {
  ------------------
  |  Branch (90:17): [True: 4, False: 11.7M]
  ------------------
   91|      4|                std::string msg = "Duplicate function parameter: " + encode_utf8(p.id->name);
   92|      4|                throw StaticError(ast_->location, msg);
   93|      4|            }
   94|  11.7M|            params.insert(p.id);
   95|  11.7M|            new_vars.insert(p.id);
   96|  11.7M|        }
   97|       |
   98|  6.36M|        auto fv = static_analysis(ast->body, in_object, new_vars);
   99|  11.7M|        for (const auto &p : ast->params) {
  ------------------
  |  Branch (99:28): [True: 11.7M, False: 6.36M]
  ------------------
  100|  11.7M|            if (p.expr != nullptr)
  ------------------
  |  Branch (100:17): [True: 187k, False: 11.5M]
  ------------------
  101|   187k|                append(fv, static_analysis(p.expr, in_object, new_vars));
  102|  11.7M|        }
  103|  6.36M|        for (const auto &p : ast->params)
  ------------------
  |  Branch (103:28): [True: 11.7M, False: 6.36M]
  ------------------
  104|  11.7M|            fv.erase(p.id);
  105|  6.36M|        append(r, fv);
  106|  6.36M|    } break;
  107|    289|    case AST_IMPORT: {
  ------------------
  |  Branch (107:5): [True: 289, False: 277M]
  ------------------
  108|    289|        assert(dynamic_cast<Import *>(ast_));
  ------------------
  |  Branch (108:9): [True: 289, False: 0]
  ------------------
  109|       |        // Nothing to do.
  110|    289|    } break;
  111|  1.76k|    case AST_IMPORTSTR: {
  ------------------
  |  Branch (111:5): [True: 1.76k, False: 277M]
  ------------------
  112|  1.76k|        assert(dynamic_cast<Importstr *>(ast_));
  ------------------
  |  Branch (112:9): [True: 1.76k, False: 0]
  ------------------
  113|       |        // Nothing to do.
  114|  1.76k|    } break;
  115|  1.76k|    case AST_IMPORTBIN: {
  ------------------
  |  Branch (115:5): [True: 578, False: 277M]
  ------------------
  116|    578|        assert(dynamic_cast<Importbin *>(ast_));
  ------------------
  |  Branch (116:9): [True: 578, False: 0]
  ------------------
  117|       |        // Nothing to do.
  118|    578|    } break;
  119|  94.0k|    case AST_IN_SUPER: {
  ------------------
  |  Branch (119:5): [True: 94.0k, False: 277M]
  ------------------
  120|  94.0k|        assert(dynamic_cast<const InSuper *>(ast_));
  ------------------
  |  Branch (120:9): [True: 94.0k, False: 0]
  ------------------
  121|  94.0k|        auto* ast = static_cast<const InSuper *>(ast_);
  122|  94.0k|        if (!in_object)
  ------------------
  |  Branch (122:13): [True: 27, False: 94.0k]
  ------------------
  123|     27|            throw StaticError(ast_->location, "Can't use super outside of an object.");
  124|  94.0k|        append(r, static_analysis(ast->element, in_object, vars));
  125|  94.0k|    } break;
  126|  27.0M|    case AST_INDEX: {
  ------------------
  |  Branch (126:5): [True: 27.0M, False: 250M]
  ------------------
  127|  27.0M|        assert(dynamic_cast<const Index *>(ast_));
  ------------------
  |  Branch (127:9): [True: 27.0M, False: 0]
  ------------------
  128|  27.0M|        auto* ast = static_cast<const Index *>(ast_);
  129|  27.0M|        append(r, static_analysis(ast->target, in_object, vars));
  130|  27.0M|        append(r, static_analysis(ast->index, in_object, vars));
  131|  27.0M|    } break;
  132|  13.1M|    case AST_LOCAL: {
  ------------------
  |  Branch (132:5): [True: 13.1M, False: 264M]
  ------------------
  133|  13.1M|        assert(dynamic_cast<const Local *>(ast_));
  ------------------
  |  Branch (133:9): [True: 13.1M, False: 0]
  ------------------
  134|  13.1M|        auto* ast = static_cast<const Local *>(ast_);
  135|  13.1M|        IdSet ast_vars;
  136|  22.5M|        for (const auto &bind : ast->binds) {
  ------------------
  |  Branch (136:31): [True: 22.5M, False: 13.1M]
  ------------------
  137|  22.5M|            ast_vars.insert(bind.var);
  138|  22.5M|        }
  139|  13.1M|        auto new_vars = vars;
  140|  13.1M|        append(new_vars, ast_vars);
  141|  13.1M|        IdSet fvs;
  142|  22.5M|        for (const auto &bind : ast->binds) {
  ------------------
  |  Branch (142:31): [True: 22.5M, False: 13.1M]
  ------------------
  143|  22.5M|            append(fvs, static_analysis(bind.body, in_object, new_vars));
  144|  22.5M|        }
  145|       |
  146|  13.1M|        append(fvs, static_analysis(ast->body, in_object, new_vars));
  147|       |
  148|  13.1M|        for (const auto &bind : ast->binds)
  ------------------
  |  Branch (148:31): [True: 22.5M, False: 13.1M]
  ------------------
  149|  22.5M|            fvs.erase(bind.var);
  150|       |
  151|  13.1M|        append(r, fvs);
  152|  13.1M|    } break;
  153|   767k|    case AST_LITERAL_BOOLEAN: {
  ------------------
  |  Branch (153:5): [True: 767k, False: 277M]
  ------------------
  154|   767k|        assert(dynamic_cast<const LiteralBoolean *>(ast_));
  ------------------
  |  Branch (154:9): [True: 767k, False: 0]
  ------------------
  155|       |        // Nothing to do.
  156|   767k|    } break;
  157|  18.3M|    case AST_LITERAL_NUMBER: {
  ------------------
  |  Branch (157:5): [True: 18.3M, False: 259M]
  ------------------
  158|  18.3M|        assert(dynamic_cast<const LiteralNumber *>(ast_));
  ------------------
  |  Branch (158:9): [True: 18.3M, False: 0]
  ------------------
  159|       |        // Nothing to do.
  160|  18.3M|    } break;
  161|  48.5M|    case AST_LITERAL_STRING: {
  ------------------
  |  Branch (161:5): [True: 48.5M, False: 229M]
  ------------------
  162|  48.5M|        assert(dynamic_cast<const LiteralString *>(ast_));
  ------------------
  |  Branch (162:9): [True: 48.5M, False: 0]
  ------------------
  163|       |        // Nothing to do.
  164|  48.5M|    } break;
  165|  48.5M|    case AST_LITERAL_NULL: {
  ------------------
  |  Branch (165:5): [True: 427k, False: 277M]
  ------------------
  166|   427k|        assert(dynamic_cast<const LiteralNull *>(ast_));
  ------------------
  |  Branch (166:9): [True: 427k, False: 0]
  ------------------
  167|       |        // Nothing to do.
  168|   427k|    } break;
  169|  2.13M|    case AST_DESUGARED_OBJECT: {
  ------------------
  |  Branch (169:5): [True: 2.13M, False: 275M]
  ------------------
  170|  2.13M|        assert(dynamic_cast<DesugaredObject *>(ast_));
  ------------------
  |  Branch (170:9): [True: 2.13M, False: 0]
  ------------------
  171|  2.13M|        auto* ast = static_cast<DesugaredObject *>(ast_);
  172|  7.94M|        for (auto &field : ast->fields) {
  ------------------
  |  Branch (172:26): [True: 7.94M, False: 2.13M]
  ------------------
  173|  7.94M|            append(r, static_analysis(field.name, in_object, vars));
  174|  7.94M|            append(r, static_analysis(field.body, true, vars));
  175|  7.94M|        }
  176|  2.13M|        for (AST *assert : ast->asserts) {
  ------------------
  |  Branch (176:26): [True: 57.7k, False: 2.13M]
  ------------------
  177|  57.7k|            append(r, static_analysis(assert, true, vars));
  178|  57.7k|        }
  179|  2.13M|    } break;
  180|  1.08M|    case AST_OBJECT_COMPREHENSION_SIMPLE: {
  ------------------
  |  Branch (180:5): [True: 1.08M, False: 276M]
  ------------------
  181|  1.08M|        assert(dynamic_cast<ObjectComprehensionSimple *>(ast_));
  ------------------
  |  Branch (181:9): [True: 1.08M, False: 0]
  ------------------
  182|  1.08M|        auto* ast = static_cast<ObjectComprehensionSimple *>(ast_);
  183|  1.08M|        auto new_vars = vars;
  184|  1.08M|        new_vars.insert(ast->id);
  185|  1.08M|        append(r, static_analysis(ast->field, false, new_vars));
  186|  1.08M|        append(r, static_analysis(ast->value, true, new_vars));
  187|  1.08M|        r.erase(ast->id);
  188|  1.08M|        append(r, static_analysis(ast->array, in_object, vars));
  189|  1.08M|    } break;
  190|  2.19M|    case AST_SELF: {
  ------------------
  |  Branch (190:5): [True: 2.19M, False: 275M]
  ------------------
  191|  2.19M|        assert(dynamic_cast<const Self *>(ast_));
  ------------------
  |  Branch (191:9): [True: 2.19M, False: 0]
  ------------------
  192|  2.19M|        if (!in_object)
  ------------------
  |  Branch (192:13): [True: 21, False: 2.19M]
  ------------------
  193|     21|            throw StaticError(ast_->location, "Can't use self outside of an object.");
  194|  2.19M|    } break;
  195|  2.19M|    case AST_SUPER_INDEX: {
  ------------------
  |  Branch (195:5): [True: 93.9k, False: 277M]
  ------------------
  196|  93.9k|        assert(dynamic_cast<const SuperIndex *>(ast_));
  ------------------
  |  Branch (196:9): [True: 93.9k, False: 0]
  ------------------
  197|  93.9k|        auto* ast = static_cast<const SuperIndex *>(ast_);
  198|  93.9k|        if (!in_object)
  ------------------
  |  Branch (198:13): [True: 6, False: 93.9k]
  ------------------
  199|      6|            throw StaticError(ast_->location, "Can't use super outside of an object.");
  200|  93.9k|        append(r, static_analysis(ast->index, in_object, vars));
  201|  93.9k|    } break;
  202|  1.45M|    case AST_UNARY: {
  ------------------
  |  Branch (202:5): [True: 1.45M, False: 276M]
  ------------------
  203|  1.45M|        assert(dynamic_cast<const Unary *>(ast_));
  ------------------
  |  Branch (203:9): [True: 1.45M, False: 0]
  ------------------
  204|  1.45M|        auto* ast = static_cast<const Unary *>(ast_);
  205|  1.45M|        append(r, static_analysis(ast->expr, in_object, vars));
  206|  1.45M|    } break;
  207|  84.2M|    case AST_VAR: {
  ------------------
  |  Branch (207:5): [True: 84.2M, False: 193M]
  ------------------
  208|  84.2M|        assert(dynamic_cast<const Var *>(ast_));
  ------------------
  |  Branch (208:9): [True: 84.2M, False: 0]
  ------------------
  209|  84.2M|        auto* ast = static_cast<const Var *>(ast_);
  210|  84.2M|        if (vars.find(ast->id) == vars.end()) {
  ------------------
  |  Branch (210:13): [True: 661, False: 84.2M]
  ------------------
  211|    661|            throw StaticError(ast->location, "Unknown variable: " + encode_utf8(ast->id->name));
  212|    661|        }
  213|  84.2M|        r.insert(ast->id);
  214|  84.2M|    } break;
  215|      0|    default:
  ------------------
  |  Branch (215:5): [True: 0, False: 277M]
  ------------------
  216|      0|        std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_ << std::endl;
  217|      0|        std::abort();
  218|      0|        break;
  219|   277M|    }
  220|       |
  221|   277M|    for (auto *id : r)
  ------------------
  |  Branch (221:19): [True: 384M, False: 277M]
  ------------------
  222|   384M|        ast_->freeVariables.push_back(id);
  223|       |
  224|   277M|    return r;
  225|   277M|}
static_analysis.cpp:_ZN7jsonnet8internalL6appendERNSt3__13setIPKNS0_10IdentifierENS1_4lessIS5_EENS1_9allocatorIS5_EEEERKSA_:
   29|   304M|{
   30|   304M|    r.insert(s.begin(), s.end());
   31|   304M|}

libjsonnet.cpp:_ZN7jsonnet8internallsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS0_11StaticErrorE:
  108|  4.29k|{
  109|  4.29k|    o << err.toString();
  110|  4.29k|    return o;
  111|  4.29k|}
_ZNK7jsonnet8internal11StaticError8toStringEv:
   97|  4.29k|    {
   98|  4.29k|        std::stringstream ss;
   99|  4.29k|        if (location.isSet()) {
  ------------------
  |  Branch (99:13): [True: 4.27k, False: 18]
  ------------------
  100|  4.27k|            ss << location << ":";
  101|  4.27k|        }
  102|  4.29k|        ss << " " << msg;
  103|  4.29k|        return ss.str();
  104|  4.29k|    }
_ZNK7jsonnet8internal13LocationRange5isSetEv:
   58|   437k|    {
   59|   437k|        return begin.isSet();
   60|   437k|    }
_ZNK7jsonnet8internal8Location5isSetEv:
   31|   437k|    {
   32|   437k|        return line != 0;
   33|   437k|    }
libjsonnet.cpp:_ZN7jsonnet8internallsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS0_13LocationRangeE:
   64|  29.4k|{
   65|  29.4k|    if (loc.file.length() > 0)
  ------------------
  |  Branch (65:9): [True: 12.3k, False: 17.0k]
  ------------------
   66|  12.3k|        o << loc.file;
   67|  29.4k|    if (loc.isSet()) {
  ------------------
  |  Branch (67:9): [True: 27.4k, False: 2.00k]
  ------------------
   68|  27.4k|        if (loc.file.length() > 0)
  ------------------
  |  Branch (68:13): [True: 10.4k, False: 16.9k]
  ------------------
   69|  10.4k|            o << ":";
   70|  27.4k|        if (loc.begin.line == loc.end.line) {
  ------------------
  |  Branch (70:13): [True: 23.7k, False: 3.66k]
  ------------------
   71|  23.7k|            if (loc.begin.column == loc.end.column - 1) {
  ------------------
  |  Branch (71:17): [True: 4.94k, False: 18.8k]
  ------------------
   72|  4.94k|                o << loc.begin;
   73|  18.8k|            } else {
   74|  18.8k|                o << loc.begin << "-" << loc.end.column;
   75|  18.8k|            }
   76|  23.7k|        } else {
   77|  3.66k|            o << "(" << loc.begin << ")-(" << loc.end << ")";
   78|  3.66k|        }
   79|  27.4k|    }
   80|  29.4k|    return o;
   81|  29.4k|}
libjsonnet.cpp:_ZN7jsonnet8internallsERNSt3__113basic_ostreamIcNS1_11char_traitsIcEEEERKNS0_8LocationE:
   41|  31.0k|{
   42|  31.0k|    o << loc.line << ":" << loc.column;
   43|  31.0k|    return o;
   44|  31.0k|}
_ZN7jsonnet8internal8LocationC2Ev:
   28|  5.31M|    Location(void) : line(0), column(0) {}
_ZN7jsonnet8internal8LocationC2Emm:
   29|   246M|    Location(unsigned long line, unsigned long column) : line(line), column(column) {}
_ZNK7jsonnet8internal8Location9successorEv:
   35|    580|    {
   36|    580|        return Location(this->line, this->column + 1);
   37|    580|    }
_ZN7jsonnet8internal13LocationRangeC2Ev:
   50|  2.64M|    LocationRange(void) {}
_ZN7jsonnet8internal13LocationRangeC2ERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE:
   52|  7.22k|    LocationRange(const std::string &msg) : file(msg) {}
_ZN7jsonnet8internal13LocationRangeC2ERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS0_8LocationESD_:
   54|   190M|        : file(file), begin(begin), end(end)
   55|   190M|    {
   56|   190M|    }
_ZN7jsonnet8internal11StaticErrorC2ERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEERKNS0_8LocationESA_:
   88|    580|        : location(filename, location, location.successor()), msg(msg)
   89|    580|    {
   90|    580|    }
_ZN7jsonnet8internal11StaticErrorC2ERKNS0_13LocationRangeERKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEE:
   92|  3.71k|        : location(location), msg(msg)
   93|  3.71k|    {
   94|  3.71k|    }

_ZN7jsonnet8internal22jsonnet_string_unparseERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEEb:
   25|   565k|{
   26|   565k|    UStringStream ss;
   27|   565k|    ss << (single ? U'\'' : U'\"');
  ------------------
  |  Branch (27:12): [True: 0, False: 565k]
  ------------------
   28|   565k|    ss << jsonnet_string_escape(str, single);
   29|   565k|    ss << (single ? U'\'' : U'\"');
  ------------------
  |  Branch (29:12): [True: 0, False: 565k]
  ------------------
   30|   565k|    return ss.str();
   31|   565k|}
_ZN7jsonnet8internal21jsonnet_string_escapeERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEEb:
   34|   565k|{
   35|   565k|    UStringStream ss;
   36|   825M|    for (std::size_t i = 0; i < str.length(); ++i) {
  ------------------
  |  Branch (36:29): [True: 824M, False: 565k]
  ------------------
   37|   824M|        char32_t c = str[i];
   38|   824M|        switch (c) {
   39|   520k|            case U'\"': ss << (single ? U"\"" : U"\\\""); break;
  ------------------
  |  Branch (39:13): [True: 520k, False: 824M]
  |  Branch (39:32): [True: 0, False: 520k]
  ------------------
   40|  1.03M|            case U'\'': ss << (single ? U"\\\'" : U"\'"); break;
  ------------------
  |  Branch (40:13): [True: 1.03M, False: 823M]
  |  Branch (40:32): [True: 0, False: 1.03M]
  ------------------
   41|   717M|            case U'\\': ss << U"\\\\"; break;
  ------------------
  |  Branch (41:13): [True: 717M, False: 106M]
  ------------------
   42|  1.58M|            case U'\b': ss << U"\\b"; break;
  ------------------
  |  Branch (42:13): [True: 1.58M, False: 823M]
  ------------------
   43|   237k|            case U'\f': ss << U"\\f"; break;
  ------------------
  |  Branch (43:13): [True: 237k, False: 824M]
  ------------------
   44|  8.40M|            case U'\n': ss << U"\\n"; break;
  ------------------
  |  Branch (44:13): [True: 8.40M, False: 816M]
  ------------------
   45|  98.6k|            case U'\r': ss << U"\\r"; break;
  ------------------
  |  Branch (45:13): [True: 98.6k, False: 824M]
  ------------------
   46|  1.03M|            case U'\t': ss << U"\\t"; break;
  ------------------
  |  Branch (46:13): [True: 1.03M, False: 823M]
  ------------------
   47|  59.7k|            case U'\0': ss << U"\\u0000"; break;
  ------------------
  |  Branch (47:13): [True: 59.7k, False: 824M]
  ------------------
   48|  93.8M|            default: {
  ------------------
  |  Branch (48:13): [True: 93.8M, False: 730M]
  ------------------
   49|  93.8M|                if (c < 0x20 || (c >= 0x7f && c <= 0x9f)) {
  ------------------
  |  Branch (49:21): [True: 7.78M, False: 86.1M]
  |  Branch (49:34): [True: 39.7M, False: 46.3M]
  |  Branch (49:47): [True: 1.59M, False: 38.1M]
  ------------------
   50|       |                    // Unprintable, use \u
   51|  9.37M|                    std::stringstream ss8;
   52|  9.37M|                    ss8 << "\\u" << std::hex << std::setfill('0') << std::setw(4)
   53|  9.37M|                        << (unsigned long)(c);
   54|  9.37M|                    ss << decode_utf8(ss8.str());
   55|  84.5M|                } else {
   56|       |                    // Printable, write verbatim
   57|  84.5M|                    ss << c;
   58|  84.5M|                }
   59|  93.8M|            }
   60|   824M|        }
   61|   824M|    }
   62|   565k|    return ss.str();
   63|   565k|}
_ZN7jsonnet8internal28jsonnet_string_parse_unicodeERKNS0_13LocationRangeEPKDi:
   66|  35.4k|{
   67|  35.4k|    unsigned long codepoint = 0;
   68|       |    // Expect 4 hex digits.
   69|   176k|    for (unsigned i = 0; i < 4; ++i) {
  ------------------
  |  Branch (69:26): [True: 141k, False: 35.3k]
  ------------------
   70|   141k|        auto x = (unsigned char)(c[i]);
   71|   141k|        unsigned digit;
   72|   141k|        if (x == '\0') {
  ------------------
  |  Branch (72:13): [True: 17, False: 141k]
  ------------------
   73|     17|            auto msg = "Truncated unicode escape sequence in string literal.";
   74|     17|            throw StaticError(loc, msg);
   75|   141k|        } else if (x >= '0' && x <= '9') {
  ------------------
  |  Branch (75:20): [True: 141k, False: 12]
  |  Branch (75:32): [True: 124k, False: 17.0k]
  ------------------
   76|   124k|            digit = x - '0';
   77|   124k|        } else if (x >= 'a' && x <= 'f') {
  ------------------
  |  Branch (77:20): [True: 3.23k, False: 13.7k]
  |  Branch (77:32): [True: 3.21k, False: 14]
  ------------------
   78|  3.21k|            digit = x - 'a' + 10;
   79|  13.7k|        } else if (x >= 'A' && x <= 'F') {
  ------------------
  |  Branch (79:20): [True: 13.7k, False: 17]
  |  Branch (79:32): [True: 13.7k, False: 25]
  ------------------
   80|  13.7k|            digit = x - 'A' + 10;
   81|  13.7k|        } else {
   82|     42|            std::stringstream ss;
   83|     42|            ss << "Malformed unicode escape character, "
   84|     42|               << "should be hex: '" << x << "'";
   85|     42|            throw StaticError(loc, ss.str());
   86|     42|        }
   87|   141k|        codepoint *= 16;
   88|   141k|        codepoint += digit;
   89|   141k|    }
   90|  35.3k|    return codepoint;
   91|  35.4k|}
_ZN7jsonnet8internal16is_bmp_codepointEm:
   94|  35.2k|{
   95|  35.2k|    return codepoint < 0xd800 || (codepoint >= 0xe000 && codepoint < 0x10000);
  ------------------
  |  Branch (95:12): [True: 34.1k, False: 1.06k]
  |  Branch (95:35): [True: 885, False: 178]
  |  Branch (95:58): [True: 885, False: 0]
  ------------------
   96|  35.2k|}
_ZN7jsonnet8internal23decode_utf16_surrogatesERKNS0_13LocationRangeEmm:
   99|    151|{
  100|    151|    if (high >= 0xd800 && high < 0xdc00 && low >= 0xdc00 && low < 0xe000) {
  ------------------
  |  Branch (100:9): [True: 151, False: 0]
  |  Branch (100:27): [True: 148, False: 3]
  |  Branch (100:44): [True: 140, False: 8]
  |  Branch (100:61): [True: 138, False: 2]
  ------------------
  101|    138|        return 0x10000 + ((high & 0x03ff) << 10) + (low & 0x03ff);
  102|    138|    } else {
  103|     13|        std::stringstream ss;
  104|     13|        ss << "Invalid UTF-16 bytes";
  105|     13|        throw StaticError(loc, ss.str());
  106|     13|    }
  107|    151|}
_ZN7jsonnet8internal23jsonnet_string_unescapeERKNS0_13LocationRangeERKNSt3__112basic_stringIDiNS4_11char_traitsIDiEENS4_9allocatorIDiEEEE:
  110|  4.28M|{
  111|  4.28M|    UString r;
  112|  4.28M|    const char32_t *s_ptr = s.c_str();
  113|  90.5M|    for (const char32_t *c = s_ptr; *c != U'\0'; ++c) {
  ------------------
  |  Branch (113:37): [True: 86.2M, False: 4.28M]
  ------------------
  114|  86.2M|        switch (*c) {
  115|   536k|            case '\\':
  ------------------
  |  Branch (115:13): [True: 536k, False: 85.6M]
  ------------------
  116|   536k|                switch (*(++c)) {
  117|  19.5k|                    case '"':
  ------------------
  |  Branch (117:21): [True: 19.5k, False: 516k]
  ------------------
  118|  31.0k|                    case '\'': r += *c; break;
  ------------------
  |  Branch (118:21): [True: 11.5k, False: 524k]
  ------------------
  119|       |
  120|  96.8k|                    case '\\': r += *c; break;
  ------------------
  |  Branch (120:21): [True: 96.8k, False: 439k]
  ------------------
  121|       |
  122|    516|                    case '/': r += *c; break;
  ------------------
  |  Branch (122:21): [True: 516, False: 535k]
  ------------------
  123|       |
  124|  11.2k|                    case 'b': r += '\b'; break;
  ------------------
  |  Branch (124:21): [True: 11.2k, False: 525k]
  ------------------
  125|       |
  126|  49.3k|                    case 'f': r += '\f'; break;
  ------------------
  |  Branch (126:21): [True: 49.3k, False: 487k]
  ------------------
  127|       |
  128|   249k|                    case 'n': r += '\n'; break;
  ------------------
  |  Branch (128:21): [True: 249k, False: 287k]
  ------------------
  129|       |
  130|  18.2k|                    case 'r': r += '\r'; break;
  ------------------
  |  Branch (130:21): [True: 18.2k, False: 518k]
  ------------------
  131|       |
  132|  44.5k|                    case 't': r += '\t'; break;
  ------------------
  |  Branch (132:21): [True: 44.5k, False: 491k]
  ------------------
  133|       |
  134|  35.2k|                    case 'u': {
  ------------------
  |  Branch (134:21): [True: 35.2k, False: 501k]
  ------------------
  135|  35.2k|                        ++c;  // Consume the 'u'.
  136|  35.2k|                        unsigned long codepoint = jsonnet_string_parse_unicode(loc, c);
  137|       |
  138|       |                        // Leave us on the last char, ready for the ++c at
  139|       |                        // the outer for loop.
  140|  35.2k|                        c += 3;
  141|  35.2k|                        if (!is_bmp_codepoint(codepoint)) {
  ------------------
  |  Branch (141:29): [True: 178, False: 35.0k]
  ------------------
  142|    178|                           if (*(++c) != '\\') {
  ------------------
  |  Branch (142:32): [True: 16, False: 162]
  ------------------
  143|     16|                                std::stringstream ss;
  144|     16|                                ss << "Invalid non-BMP Unicode escape in string literal";
  145|     16|                                throw StaticError(loc, ss.str());
  146|     16|                           }
  147|    162|                           if (*(++c) != 'u') {
  ------------------
  |  Branch (147:32): [True: 6, False: 156]
  ------------------
  148|      6|                                std::stringstream ss;
  149|      6|                                ss << "Invalid non-BMP Unicode escape in string literal";
  150|      6|                                throw StaticError(loc, ss.str());
  151|      6|                           }
  152|    156|                           ++c;
  153|    156|                           unsigned long codepoint2 = jsonnet_string_parse_unicode(loc, c);
  154|    156|                           c += 3;
  155|    156|                           codepoint = decode_utf16_surrogates(loc, codepoint, codepoint2);
  156|    156|                       }
  157|  35.2k|                       r += codepoint;
  158|  35.2k|                    } break;
  159|       |
  160|      2|                    case '\0': {
  ------------------
  |  Branch (160:21): [True: 2, False: 536k]
  ------------------
  161|      2|                        auto msg = "Truncated escape sequence in string literal.";
  162|      2|                        throw StaticError(loc, msg);
  163|  35.2k|                    }
  164|       |
  165|    154|                    default: {
  ------------------
  |  Branch (165:21): [True: 154, False: 536k]
  ------------------
  166|    154|                        std::stringstream ss;
  167|    154|                        std::string utf8;
  168|    154|                        encode_utf8(*c, utf8);
  169|    154|                        ss << "Unknown escape sequence in string literal: '" << utf8 << "'";
  170|    154|                        throw StaticError(loc, ss.str());
  171|  35.2k|                    }
  172|   536k|                }
  173|   536k|                break;
  174|       |
  175|  85.6M|            default:
  ------------------
  |  Branch (175:13): [True: 85.6M, False: 536k]
  ------------------
  176|       |                // Just a regular letter.
  177|  85.6M|                r += *c;
  178|  86.2M|        }
  179|  86.2M|    }
  180|  4.28M|    return r;
  181|  4.28M|}

_ZN7jsonnet8internal13UStringStreamlsERKNSt3__112basic_stringIDiNS2_11char_traitsIDiEENS2_9allocatorIDiEEEE:
  155|  22.5M|    {
  156|  22.5M|        buf.append(s);
  157|  22.5M|        return *this;
  158|  22.5M|    }
_ZN7jsonnet8internal13UStringStreamlsEPKDi:
  160|   737M|    {
  161|   737M|        buf.append(s);
  162|   737M|        return *this;
  163|   737M|    }
_ZN7jsonnet8internal13UStringStreamlsEDi:
  165|  85.6M|    {
  166|  85.6M|        buf.push_back(c);
  167|  85.6M|        return *this;
  168|  85.6M|    }
_ZN7jsonnet8internal13UStringStream3strEv:
  179|  6.75M|    {
  180|  6.75M|        return buf;
  181|  6.75M|    }
parser.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  140|  42.8M|{
  141|  42.8M|    UString r;
  142|   306M|    for (size_t i = 0; i < s.length(); ++i)
  ------------------
  |  Branch (142:24): [True: 263M, False: 42.8M]
  ------------------
  143|   263M|        r.push_back(decode_utf8(s, i));
  144|  42.8M|    return r;
  145|  42.8M|}
parser.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERm:
   75|   263M|{
   76|   263M|    char c0 = str[i];
   77|   263M|    if ((c0 & 0x80) == 0) {  // 0xxxxxxx
  ------------------
  |  Branch (77:9): [True: 252M, False: 10.7M]
  ------------------
   78|   252M|        return c0;
   79|   252M|    } else if ((c0 & 0xE0) == 0xC0) {  // 110yyyxx 10xxxxxx
  ------------------
  |  Branch (79:16): [True: 479k, False: 10.2M]
  ------------------
   80|   479k|        if (i + 1 >= str.length()) {
  ------------------
  |  Branch (80:13): [True: 3.65k, False: 476k]
  ------------------
   81|  3.65k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  3.65k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   82|  3.65k|        }
   83|   476k|        char c1 = str[++i];
   84|   476k|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (84:13): [True: 395k, False: 80.3k]
  ------------------
   85|   395k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|   395k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   86|   395k|        }
   87|  80.3k|        return ((c0 & 0x1F) << 6ul) | (c1 & 0x3F);
   88|  10.2M|    } else if ((c0 & 0xF0) == 0xE0) {  // 1110yyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (88:16): [True: 1.30M, False: 8.92M]
  ------------------
   89|  1.30M|        if (i + 2 >= str.length()) {
  ------------------
  |  Branch (89:13): [True: 1.43k, False: 1.30M]
  ------------------
   90|  1.43k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  1.43k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   91|  1.43k|        }
   92|  1.30M|        char c1 = str[++i];
   93|  1.30M|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (93:13): [True: 1.21M, False: 88.1k]
  ------------------
   94|  1.21M|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  1.21M|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   95|  1.21M|        }
   96|  88.1k|        char c2 = str[++i];
   97|  88.1k|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (97:13): [True: 28.2k, False: 59.8k]
  ------------------
   98|  28.2k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  28.2k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   99|  28.2k|        }
  100|  59.8k|        return ((c0 & 0xF) << 12ul) | ((c1 & 0x3F) << 6) | (c2 & 0x3F);
  101|  8.92M|    } else if ((c0 & 0xF8) == 0xF0) {  // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (101:16): [True: 304k, False: 8.61M]
  ------------------
  102|   304k|        if (i + 3 >= str.length()) {
  ------------------
  |  Branch (102:13): [True: 2.22k, False: 302k]
  ------------------
  103|  2.22k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  2.22k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  104|  2.22k|        }
  105|   302k|        char c1 = str[++i];
  106|   302k|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (106:13): [True: 239k, False: 63.0k]
  ------------------
  107|   239k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|   239k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  108|   239k|        }
  109|  63.0k|        char c2 = str[++i];
  110|  63.0k|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (110:13): [True: 5.56k, False: 57.4k]
  ------------------
  111|  5.56k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  5.56k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  112|  5.56k|        }
  113|  57.4k|        char c3 = str[++i];
  114|  57.4k|        if ((c3 & 0xC0) != 0x80) {
  ------------------
  |  Branch (114:13): [True: 17.3k, False: 40.1k]
  ------------------
  115|  17.3k|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  17.3k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  116|  17.3k|        }
  117|  40.1k|        return ((c0 & 0x7) << 18ul) | ((c1 & 0x3F) << 12ul) | ((c2 & 0x3F) << 6) | (c3 & 0x3F);
  118|  8.61M|    } else {
  119|  8.61M|        return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  8.61M|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  120|  8.61M|    }
  121|   263M|}
static_analysis.cpp:_ZN7jsonnet8internalL11encode_utf8ERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEE:
  133|    665|{
  134|    665|    std::string r;
  135|    665|    encode_utf8(s, r);
  136|    665|    return r;
  137|    665|}
static_analysis.cpp:_ZN7jsonnet8internalL11encode_utf8ERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEERNS2_IcNS3_IcEENS5_IcEEEE:
  127|    665|{
  128|    665|    for (char32_t cp : s)
  ------------------
  |  Branch (128:22): [True: 9.39M, False: 665]
  ------------------
  129|  9.39M|        encode_utf8(cp, r);
  130|    665|}
static_analysis.cpp:_ZN7jsonnet8internalL11encode_utf8EDiRNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   33|  9.39M|{
   34|  9.39M|    if (x >= JSONNET_CODEPOINT_MAX)
  ------------------
  |  |   22|  9.39M|#define JSONNET_CODEPOINT_MAX 0x110000
  ------------------
  |  Branch (34:9): [True: 0, False: 9.39M]
  ------------------
   35|      0|        x = JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   36|       |
   37|       |    // 00ZZZzzz 00zzYYYY 00Yyyyxx 00xxxxxx
   38|  9.39M|    long bytes = ((x & 0x1C0000) << 6) | ((x & 0x03F000) << 4) | ((x & 0x0FC0) << 2) | (x & 0x3F);
   39|       |
   40|  9.39M|    if (x < 0x80) {
  ------------------
  |  Branch (40:9): [True: 9.39M, False: 0]
  ------------------
   41|  9.39M|        s.push_back((char)x);
   42|  9.39M|        return 1;
   43|  9.39M|    } else if (x < 0x800) {  // note that capital 'Y' bits must be 0
  ------------------
  |  Branch (43:16): [True: 0, False: 0]
  ------------------
   44|      0|        bytes |= 0xC080;
   45|      0|        s.push_back((bytes >> 8) & 0xFF);
   46|      0|        s.push_back((bytes >> 0) & 0xFF);
   47|      0|        return 2;
   48|      0|    } else if (x < 0x10000) {  // note that 'z' bits must be 0
  ------------------
  |  Branch (48:16): [True: 0, False: 0]
  ------------------
   49|      0|        bytes |= 0xE08080;
   50|      0|        s.push_back((bytes >> 16) & 0xFF);
   51|      0|        s.push_back((bytes >> 8) & 0xFF);
   52|      0|        s.push_back((bytes >> 0) & 0xFF);
   53|      0|        return 3;
   54|      0|    } else if (x < 0x110000) {  // note that capital 'Z' bits must be 0
  ------------------
  |  Branch (54:16): [True: 0, False: 0]
  ------------------
   55|      0|        bytes |= 0xF0808080;
   56|      0|        s.push_back((bytes >> 24) & 0xFF);
   57|      0|        s.push_back((bytes >> 16) & 0xFF);
   58|      0|        s.push_back((bytes >> 8) & 0xFF);
   59|      0|        s.push_back((bytes >> 0) & 0xFF);
   60|      0|        return 4;
   61|      0|    } else {
   62|      0|        std::cerr << "Should never get here." << std::endl;
   63|      0|        abort();
   64|      0|    }
   65|  9.39M|}
string_utils.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  140|  9.37M|{
  141|  9.37M|    UString r;
  142|  65.6M|    for (size_t i = 0; i < s.length(); ++i)
  ------------------
  |  Branch (142:24): [True: 56.2M, False: 9.37M]
  ------------------
  143|  56.2M|        r.push_back(decode_utf8(s, i));
  144|  9.37M|    return r;
  145|  9.37M|}
string_utils.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERm:
   75|  56.2M|{
   76|  56.2M|    char c0 = str[i];
   77|  56.2M|    if ((c0 & 0x80) == 0) {  // 0xxxxxxx
  ------------------
  |  Branch (77:9): [True: 56.2M, False: 0]
  ------------------
   78|  56.2M|        return c0;
   79|  56.2M|    } else if ((c0 & 0xE0) == 0xC0) {  // 110yyyxx 10xxxxxx
  ------------------
  |  Branch (79:16): [True: 0, False: 0]
  ------------------
   80|      0|        if (i + 1 >= str.length()) {
  ------------------
  |  Branch (80:13): [True: 0, False: 0]
  ------------------
   81|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   82|      0|        }
   83|      0|        char c1 = str[++i];
   84|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (84:13): [True: 0, False: 0]
  ------------------
   85|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   86|      0|        }
   87|      0|        return ((c0 & 0x1F) << 6ul) | (c1 & 0x3F);
   88|      0|    } else if ((c0 & 0xF0) == 0xE0) {  // 1110yyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (88:16): [True: 0, False: 0]
  ------------------
   89|      0|        if (i + 2 >= str.length()) {
  ------------------
  |  Branch (89:13): [True: 0, False: 0]
  ------------------
   90|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   91|      0|        }
   92|      0|        char c1 = str[++i];
   93|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (93:13): [True: 0, False: 0]
  ------------------
   94|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   95|      0|        }
   96|      0|        char c2 = str[++i];
   97|      0|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (97:13): [True: 0, False: 0]
  ------------------
   98|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   99|      0|        }
  100|      0|        return ((c0 & 0xF) << 12ul) | ((c1 & 0x3F) << 6) | (c2 & 0x3F);
  101|      0|    } else if ((c0 & 0xF8) == 0xF0) {  // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (101:16): [True: 0, False: 0]
  ------------------
  102|      0|        if (i + 3 >= str.length()) {
  ------------------
  |  Branch (102:13): [True: 0, False: 0]
  ------------------
  103|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  104|      0|        }
  105|      0|        char c1 = str[++i];
  106|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (106:13): [True: 0, False: 0]
  ------------------
  107|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  108|      0|        }
  109|      0|        char c2 = str[++i];
  110|      0|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (110:13): [True: 0, False: 0]
  ------------------
  111|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  112|      0|        }
  113|      0|        char c3 = str[++i];
  114|      0|        if ((c3 & 0xC0) != 0x80) {
  ------------------
  |  Branch (114:13): [True: 0, False: 0]
  ------------------
  115|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  116|      0|        }
  117|      0|        return ((c0 & 0x7) << 18ul) | ((c1 & 0x3F) << 12ul) | ((c2 & 0x3F) << 6) | (c3 & 0x3F);
  118|      0|    } else {
  119|      0|        return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  120|      0|    }
  121|  56.2M|}
string_utils.cpp:_ZN7jsonnet8internalL11encode_utf8EDiRNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   33|    154|{
   34|    154|    if (x >= JSONNET_CODEPOINT_MAX)
  ------------------
  |  |   22|    154|#define JSONNET_CODEPOINT_MAX 0x110000
  ------------------
  |  Branch (34:9): [True: 1, False: 153]
  ------------------
   35|      1|        x = JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      1|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   36|       |
   37|       |    // 00ZZZzzz 00zzYYYY 00Yyyyxx 00xxxxxx
   38|    154|    long bytes = ((x & 0x1C0000) << 6) | ((x & 0x03F000) << 4) | ((x & 0x0FC0) << 2) | (x & 0x3F);
   39|       |
   40|    154|    if (x < 0x80) {
  ------------------
  |  Branch (40:9): [True: 86, False: 68]
  ------------------
   41|     86|        s.push_back((char)x);
   42|     86|        return 1;
   43|     86|    } else if (x < 0x800) {  // note that capital 'Y' bits must be 0
  ------------------
  |  Branch (43:16): [True: 9, False: 59]
  ------------------
   44|      9|        bytes |= 0xC080;
   45|      9|        s.push_back((bytes >> 8) & 0xFF);
   46|      9|        s.push_back((bytes >> 0) & 0xFF);
   47|      9|        return 2;
   48|     59|    } else if (x < 0x10000) {  // note that 'z' bits must be 0
  ------------------
  |  Branch (48:16): [True: 42, False: 17]
  ------------------
   49|     42|        bytes |= 0xE08080;
   50|     42|        s.push_back((bytes >> 16) & 0xFF);
   51|     42|        s.push_back((bytes >> 8) & 0xFF);
   52|     42|        s.push_back((bytes >> 0) & 0xFF);
   53|     42|        return 3;
   54|     42|    } else if (x < 0x110000) {  // note that capital 'Z' bits must be 0
  ------------------
  |  Branch (54:16): [True: 17, False: 0]
  ------------------
   55|     17|        bytes |= 0xF0808080;
   56|     17|        s.push_back((bytes >> 24) & 0xFF);
   57|     17|        s.push_back((bytes >> 16) & 0xFF);
   58|     17|        s.push_back((bytes >> 8) & 0xFF);
   59|     17|        s.push_back((bytes >> 0) & 0xFF);
   60|     17|        return 4;
   61|     17|    } else {
   62|      0|        std::cerr << "Should never get here." << std::endl;
   63|      0|        abort();
   64|      0|    }
   65|    154|}
vm.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  140|  3.62M|{
  141|  3.62M|    UString r;
  142|  13.9M|    for (size_t i = 0; i < s.length(); ++i)
  ------------------
  |  Branch (142:24): [True: 10.3M, False: 3.62M]
  ------------------
  143|  10.3M|        r.push_back(decode_utf8(s, i));
  144|  3.62M|    return r;
  145|  3.62M|}
vm.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERm:
   75|  10.3M|{
   76|  10.3M|    char c0 = str[i];
   77|  10.3M|    if ((c0 & 0x80) == 0) {  // 0xxxxxxx
  ------------------
  |  Branch (77:9): [True: 10.3M, False: 0]
  ------------------
   78|  10.3M|        return c0;
   79|  10.3M|    } else if ((c0 & 0xE0) == 0xC0) {  // 110yyyxx 10xxxxxx
  ------------------
  |  Branch (79:16): [True: 0, False: 0]
  ------------------
   80|      0|        if (i + 1 >= str.length()) {
  ------------------
  |  Branch (80:13): [True: 0, False: 0]
  ------------------
   81|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   82|      0|        }
   83|      0|        char c1 = str[++i];
   84|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (84:13): [True: 0, False: 0]
  ------------------
   85|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   86|      0|        }
   87|      0|        return ((c0 & 0x1F) << 6ul) | (c1 & 0x3F);
   88|      0|    } else if ((c0 & 0xF0) == 0xE0) {  // 1110yyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (88:16): [True: 0, False: 0]
  ------------------
   89|      0|        if (i + 2 >= str.length()) {
  ------------------
  |  Branch (89:13): [True: 0, False: 0]
  ------------------
   90|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   91|      0|        }
   92|      0|        char c1 = str[++i];
   93|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (93:13): [True: 0, False: 0]
  ------------------
   94|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   95|      0|        }
   96|      0|        char c2 = str[++i];
   97|      0|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (97:13): [True: 0, False: 0]
  ------------------
   98|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   99|      0|        }
  100|      0|        return ((c0 & 0xF) << 12ul) | ((c1 & 0x3F) << 6) | (c2 & 0x3F);
  101|      0|    } else if ((c0 & 0xF8) == 0xF0) {  // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (101:16): [True: 0, False: 0]
  ------------------
  102|      0|        if (i + 3 >= str.length()) {
  ------------------
  |  Branch (102:13): [True: 0, False: 0]
  ------------------
  103|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  104|      0|        }
  105|      0|        char c1 = str[++i];
  106|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (106:13): [True: 0, False: 0]
  ------------------
  107|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  108|      0|        }
  109|      0|        char c2 = str[++i];
  110|      0|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (110:13): [True: 0, False: 0]
  ------------------
  111|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  112|      0|        }
  113|      0|        char c3 = str[++i];
  114|      0|        if ((c3 & 0xC0) != 0x80) {
  ------------------
  |  Branch (114:13): [True: 0, False: 0]
  ------------------
  115|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  116|      0|        }
  117|      0|        return ((c0 & 0x7) << 18ul) | ((c1 & 0x3F) << 12ul) | ((c2 & 0x3F) << 6) | (c3 & 0x3F);
  118|      0|    } else {
  119|      0|        return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  120|      0|    }
  121|  10.3M|}
vm.cpp:_ZN7jsonnet8internalL11encode_utf8ERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEE:
  133|   781k|{
  134|   781k|    std::string r;
  135|   781k|    encode_utf8(s, r);
  136|   781k|    return r;
  137|   781k|}
vm.cpp:_ZN7jsonnet8internalL11encode_utf8ERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEERNS2_IcNS3_IcEENS5_IcEEEE:
  127|   781k|{
  128|   781k|    for (char32_t cp : s)
  ------------------
  |  Branch (128:22): [True: 601M, False: 781k]
  ------------------
  129|   601M|        encode_utf8(cp, r);
  130|   781k|}
vm.cpp:_ZN7jsonnet8internalL11encode_utf8EDiRNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   33|   601M|{
   34|   601M|    if (x >= JSONNET_CODEPOINT_MAX)
  ------------------
  |  |   22|   601M|#define JSONNET_CODEPOINT_MAX 0x110000
  ------------------
  |  Branch (34:9): [True: 1.48k, False: 601M]
  ------------------
   35|  1.48k|        x = JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|  1.48k|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   36|       |
   37|       |    // 00ZZZzzz 00zzYYYY 00Yyyyxx 00xxxxxx
   38|   601M|    long bytes = ((x & 0x1C0000) << 6) | ((x & 0x03F000) << 4) | ((x & 0x0FC0) << 2) | (x & 0x3F);
   39|       |
   40|   601M|    if (x < 0x80) {
  ------------------
  |  Branch (40:9): [True: 598M, False: 2.12M]
  ------------------
   41|   598M|        s.push_back((char)x);
   42|   598M|        return 1;
   43|   598M|    } else if (x < 0x800) {  // note that capital 'Y' bits must be 0
  ------------------
  |  Branch (43:16): [True: 8.38k, False: 2.12M]
  ------------------
   44|  8.38k|        bytes |= 0xC080;
   45|  8.38k|        s.push_back((bytes >> 8) & 0xFF);
   46|  8.38k|        s.push_back((bytes >> 0) & 0xFF);
   47|  8.38k|        return 2;
   48|  2.12M|    } else if (x < 0x10000) {  // note that 'z' bits must be 0
  ------------------
  |  Branch (48:16): [True: 2.11M, False: 9.98k]
  ------------------
   49|  2.11M|        bytes |= 0xE08080;
   50|  2.11M|        s.push_back((bytes >> 16) & 0xFF);
   51|  2.11M|        s.push_back((bytes >> 8) & 0xFF);
   52|  2.11M|        s.push_back((bytes >> 0) & 0xFF);
   53|  2.11M|        return 3;
   54|  2.11M|    } else if (x < 0x110000) {  // note that capital 'Z' bits must be 0
  ------------------
  |  Branch (54:16): [True: 9.98k, False: 0]
  ------------------
   55|  9.98k|        bytes |= 0xF0808080;
   56|  9.98k|        s.push_back((bytes >> 24) & 0xFF);
   57|  9.98k|        s.push_back((bytes >> 16) & 0xFF);
   58|  9.98k|        s.push_back((bytes >> 8) & 0xFF);
   59|  9.98k|        s.push_back((bytes >> 0) & 0xFF);
   60|  9.98k|        return 4;
   61|  9.98k|    } else {
   62|      0|        std::cerr << "Should never get here." << std::endl;
   63|      0|        abort();
   64|      0|    }
   65|   601M|}
_ZN7jsonnet8internal13UStringStreamlsIiEERS1_T_:
  171|  1.06M|    {
  172|  1.06M|        std::stringstream ss;
  173|  1.06M|        ss << c;
  174|  1.06M|        for (char c : ss.str())
  ------------------
  |  Branch (174:21): [True: 1.84M, False: 1.06M]
  ------------------
  175|  1.84M|            buf.push_back(char32_t(c));
  176|  1.06M|        return *this;
  177|  1.06M|    }
_ZN7jsonnet8internal13UStringStreamlsIjEERS1_T_:
  171|   287k|    {
  172|   287k|        std::stringstream ss;
  173|   287k|        ss << c;
  174|   287k|        for (char c : ss.str())
  ------------------
  |  Branch (174:21): [True: 896k, False: 287k]
  ------------------
  175|   896k|            buf.push_back(char32_t(c));
  176|   287k|        return *this;
  177|   287k|    }
desugarer.cpp:_ZN7jsonnet8internalL11encode_utf8ERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEE:
  133|   368k|{
  134|   368k|    std::string r;
  135|   368k|    encode_utf8(s, r);
  136|   368k|    return r;
  137|   368k|}
desugarer.cpp:_ZN7jsonnet8internalL11encode_utf8ERKNSt3__112basic_stringIDiNS1_11char_traitsIDiEENS1_9allocatorIDiEEEERNS2_IcNS3_IcEENS5_IcEEEE:
  127|   368k|{
  128|   368k|    for (char32_t cp : s)
  ------------------
  |  Branch (128:22): [True: 2.46M, False: 368k]
  ------------------
  129|  2.46M|        encode_utf8(cp, r);
  130|   368k|}
desugarer.cpp:_ZN7jsonnet8internalL11encode_utf8EDiRNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
   33|  2.46M|{
   34|  2.46M|    if (x >= JSONNET_CODEPOINT_MAX)
  ------------------
  |  |   22|  2.46M|#define JSONNET_CODEPOINT_MAX 0x110000
  ------------------
  |  Branch (34:9): [True: 0, False: 2.46M]
  ------------------
   35|      0|        x = JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   36|       |
   37|       |    // 00ZZZzzz 00zzYYYY 00Yyyyxx 00xxxxxx
   38|  2.46M|    long bytes = ((x & 0x1C0000) << 6) | ((x & 0x03F000) << 4) | ((x & 0x0FC0) << 2) | (x & 0x3F);
   39|       |
   40|  2.46M|    if (x < 0x80) {
  ------------------
  |  Branch (40:9): [True: 2.46M, False: 0]
  ------------------
   41|  2.46M|        s.push_back((char)x);
   42|  2.46M|        return 1;
   43|  2.46M|    } else if (x < 0x800) {  // note that capital 'Y' bits must be 0
  ------------------
  |  Branch (43:16): [True: 0, False: 0]
  ------------------
   44|      0|        bytes |= 0xC080;
   45|      0|        s.push_back((bytes >> 8) & 0xFF);
   46|      0|        s.push_back((bytes >> 0) & 0xFF);
   47|      0|        return 2;
   48|      0|    } else if (x < 0x10000) {  // note that 'z' bits must be 0
  ------------------
  |  Branch (48:16): [True: 0, False: 0]
  ------------------
   49|      0|        bytes |= 0xE08080;
   50|      0|        s.push_back((bytes >> 16) & 0xFF);
   51|      0|        s.push_back((bytes >> 8) & 0xFF);
   52|      0|        s.push_back((bytes >> 0) & 0xFF);
   53|      0|        return 3;
   54|      0|    } else if (x < 0x110000) {  // note that capital 'Z' bits must be 0
  ------------------
  |  Branch (54:16): [True: 0, False: 0]
  ------------------
   55|      0|        bytes |= 0xF0808080;
   56|      0|        s.push_back((bytes >> 24) & 0xFF);
   57|      0|        s.push_back((bytes >> 16) & 0xFF);
   58|      0|        s.push_back((bytes >> 8) & 0xFF);
   59|      0|        s.push_back((bytes >> 0) & 0xFF);
   60|      0|        return 4;
   61|      0|    } else {
   62|      0|        std::cerr << "Should never get here." << std::endl;
   63|      0|        abort();
   64|      0|    }
   65|  2.46M|}
desugarer.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
  140|  8.76k|{
  141|  8.76k|    UString r;
  142|  57.0k|    for (size_t i = 0; i < s.length(); ++i)
  ------------------
  |  Branch (142:24): [True: 48.2k, False: 8.76k]
  ------------------
  143|  48.2k|        r.push_back(decode_utf8(s, i));
  144|  8.76k|    return r;
  145|  8.76k|}
desugarer.cpp:_ZN7jsonnet8internalL11decode_utf8ERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEERm:
   75|  48.2k|{
   76|  48.2k|    char c0 = str[i];
   77|  48.2k|    if ((c0 & 0x80) == 0) {  // 0xxxxxxx
  ------------------
  |  Branch (77:9): [True: 48.2k, False: 0]
  ------------------
   78|  48.2k|        return c0;
   79|  48.2k|    } else if ((c0 & 0xE0) == 0xC0) {  // 110yyyxx 10xxxxxx
  ------------------
  |  Branch (79:16): [True: 0, False: 0]
  ------------------
   80|      0|        if (i + 1 >= str.length()) {
  ------------------
  |  Branch (80:13): [True: 0, False: 0]
  ------------------
   81|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   82|      0|        }
   83|      0|        char c1 = str[++i];
   84|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (84:13): [True: 0, False: 0]
  ------------------
   85|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   86|      0|        }
   87|      0|        return ((c0 & 0x1F) << 6ul) | (c1 & 0x3F);
   88|      0|    } else if ((c0 & 0xF0) == 0xE0) {  // 1110yyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (88:16): [True: 0, False: 0]
  ------------------
   89|      0|        if (i + 2 >= str.length()) {
  ------------------
  |  Branch (89:13): [True: 0, False: 0]
  ------------------
   90|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   91|      0|        }
   92|      0|        char c1 = str[++i];
   93|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (93:13): [True: 0, False: 0]
  ------------------
   94|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   95|      0|        }
   96|      0|        char c2 = str[++i];
   97|      0|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (97:13): [True: 0, False: 0]
  ------------------
   98|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
   99|      0|        }
  100|      0|        return ((c0 & 0xF) << 12ul) | ((c1 & 0x3F) << 6) | (c2 & 0x3F);
  101|      0|    } else if ((c0 & 0xF8) == 0xF0) {  // 11110zzz 10zzyyyy 10yyyyxx 10xxxxxx
  ------------------
  |  Branch (101:16): [True: 0, False: 0]
  ------------------
  102|      0|        if (i + 3 >= str.length()) {
  ------------------
  |  Branch (102:13): [True: 0, False: 0]
  ------------------
  103|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  104|      0|        }
  105|      0|        char c1 = str[++i];
  106|      0|        if ((c1 & 0xC0) != 0x80) {
  ------------------
  |  Branch (106:13): [True: 0, False: 0]
  ------------------
  107|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  108|      0|        }
  109|      0|        char c2 = str[++i];
  110|      0|        if ((c2 & 0xC0) != 0x80) {
  ------------------
  |  Branch (110:13): [True: 0, False: 0]
  ------------------
  111|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  112|      0|        }
  113|      0|        char c3 = str[++i];
  114|      0|        if ((c3 & 0xC0) != 0x80) {
  ------------------
  |  Branch (114:13): [True: 0, False: 0]
  ------------------
  115|      0|            return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  116|      0|        }
  117|      0|        return ((c0 & 0x7) << 18ul) | ((c1 & 0x3F) << 12ul) | ((c2 & 0x3F) << 6) | (c3 & 0x3F);
  118|      0|    } else {
  119|      0|        return JSONNET_CODEPOINT_ERROR;
  ------------------
  |  |   21|      0|#define JSONNET_CODEPOINT_ERROR 0xfffd
  ------------------
  120|      0|    }
  121|  48.2k|}

_ZN7jsonnet8internal24jsonnet_vm_execute_multiEPNS0_9AllocatorEPKNS0_3ASTERKNSt3__13mapINS6_12basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEENS0_5VmExtENS6_4lessISD_EENSB_INS6_4pairIKSD_SE_EEEEEEjddRKNS7_ISD_NS0_16VmNativeCallbackESG_NSB_INSH_ISI_SO_EEEEEEPFiPvPKcSW_PPcSY_PmESU_b:
 3520|  4.02k|{
 3521|  4.02k|    Interpreter vm(alloc,
 3522|  4.02k|                   ext_vars,
 3523|  4.02k|                   max_stack,
 3524|  4.02k|                   gc_min_objects,
 3525|  4.02k|                   gc_growth_trigger,
 3526|  4.02k|                   natives,
 3527|  4.02k|                   import_callback,
 3528|  4.02k|                   ctx);
 3529|  4.02k|    vm.evaluate(ast, 0);
 3530|  4.02k|    return vm.manifestMulti(string_output);
 3531|  4.02k|}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111InterpreterC2EPNS0_9AllocatorERKNSt3__13mapINS5_12basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEENS0_5VmExtENS5_4lessISC_EENSA_INS5_4pairIKSC_SD_EEEEEEjddRKNS6_ISC_NS0_16VmNativeCallbackESF_NSA_INSG_ISH_SN_EEEEEEPFiPvPKcSV_PPcSX_PmEST_:
  945|  4.02k|        : heap(gc_min_objects, gc_growth_trigger),
  946|  4.02k|          stack(max_stack),
  947|  4.02k|          alloc(alloc),
  948|  4.02k|          idImport(alloc->makeIdentifier(U"import")),
  949|  4.02k|          idArrayElement(alloc->makeIdentifier(U"array_element")),
  950|  4.02k|          idInvariant(alloc->makeIdentifier(U"object_assert")),
  951|  4.02k|          idInternal(alloc->makeIdentifier(U"__internal__")),
  952|  4.02k|          idJsonObjVar(alloc->makeIdentifier(U"_")),
  953|  4.02k|          idEmpty(alloc->makeIdentifier(U"")),
  954|  4.02k|          jsonObjVar(alloc->make<Var>(LocationRange(), Fodder{}, idJsonObjVar)),
  955|  4.02k|          externalVars(ext_vars),
  956|  4.02k|          importCallback(import_callback),
  957|  4.02k|          importCallbackContext(import_callback_context)
  958|  4.02k|    {
  959|  4.02k|        scratch = makeNull();
  960|       |        // Add a prefix to avoid conflicting with names from `native_callbacks`.
  961|  4.02k|        builtins["std:makeArray"] = &Interpreter::builtinMakeArray;
  962|  4.02k|        builtins["std:pow"] = &Interpreter::builtinPow;
  963|  4.02k|        builtins["std:floor"] = &Interpreter::builtinFloor;
  964|  4.02k|        builtins["std:ceil"] = &Interpreter::builtinCeil;
  965|  4.02k|        builtins["std:sqrt"] = &Interpreter::builtinSqrt;
  966|  4.02k|        builtins["std:sin"] = &Interpreter::builtinSin;
  967|  4.02k|        builtins["std:cos"] = &Interpreter::builtinCos;
  968|  4.02k|        builtins["std:tan"] = &Interpreter::builtinTan;
  969|  4.02k|        builtins["std:asin"] = &Interpreter::builtinAsin;
  970|  4.02k|        builtins["std:acos"] = &Interpreter::builtinAcos;
  971|  4.02k|        builtins["std:atan"] = &Interpreter::builtinAtan;
  972|  4.02k|        builtins["std:type"] = &Interpreter::builtinType;
  973|  4.02k|        builtins["std:filter"] = &Interpreter::builtinFilter;
  974|  4.02k|        builtins["std:objectHasEx"] = &Interpreter::builtinObjectHasEx;
  975|  4.02k|        builtins["std:length"] = &Interpreter::builtinLength;
  976|  4.02k|        builtins["std:objectFieldsEx"] = &Interpreter::builtinObjectFieldsEx;
  977|  4.02k|        builtins["std:objectRemoveKey"] = &Interpreter::builtinObjectRemoveKey;
  978|  4.02k|        builtins["std:codepoint"] = &Interpreter::builtinCodepoint;
  979|  4.02k|        builtins["std:char"] = &Interpreter::builtinChar;
  980|  4.02k|        builtins["std:log"] = &Interpreter::builtinLog;
  981|  4.02k|        builtins["std:exp"] = &Interpreter::builtinExp;
  982|  4.02k|        builtins["std:mantissa"] = &Interpreter::builtinMantissa;
  983|  4.02k|        builtins["std:exponent"] = &Interpreter::builtinExponent;
  984|  4.02k|        builtins["std:modulo"] = &Interpreter::builtinModulo;
  985|  4.02k|        builtins["std:extVar"] = &Interpreter::builtinExtVar;
  986|  4.02k|        builtins["std:primitiveEquals"] = &Interpreter::builtinPrimitiveEquals;
  987|  4.02k|        builtins["std:native"] = &Interpreter::builtinNative;
  988|  4.02k|        builtins["std:md5"] = &Interpreter::builtinMd5;
  989|  4.02k|        builtins["std:trace"] = &Interpreter::builtinTrace;
  990|  4.02k|        builtins["std:splitLimit"] = &Interpreter::builtinSplitLimit;
  991|  4.02k|        builtins["std:substr"] = &Interpreter::builtinSubstr;
  992|  4.02k|        builtins["std:range"] = &Interpreter::builtinRange;
  993|  4.02k|        builtins["std:strReplace"] = &Interpreter::builtinStrReplace;
  994|  4.02k|        builtins["std:asciiLower"] = &Interpreter::builtinAsciiLower;
  995|  4.02k|        builtins["std:asciiUpper"] = &Interpreter::builtinAsciiUpper;
  996|  4.02k|        builtins["std:join"] = &Interpreter::builtinJoin;
  997|  4.02k|        builtins["std:parseJson"] = &Interpreter::builtinParseJson;
  998|  4.02k|        builtins["std:parseYaml"] = &Interpreter::builtinParseYaml;
  999|  4.02k|        builtins["std:encodeUTF8"] = &Interpreter::builtinEncodeUTF8;
 1000|  4.02k|        builtins["std:decodeUTF8"] = &Interpreter::builtinDecodeUTF8;
 1001|  4.02k|        builtins["std:atan2"] = &Interpreter::builtinAtan2;
 1002|  4.02k|        builtins["std:hypot"] = &Interpreter::builtinHypot;
 1003|       |
 1004|       |        // Add a prefix `native:` to names of provided callbacks to ensure they can't clash with the builtins above.
 1005|       |        // Although we have separate lookup tables for them, the HeapClosure and BuiltinFunctionBody types just hold
 1006|       |        // function "name" as a std::string to identify the function.
 1007|  4.02k|        for (const auto& [name, cb] : native_callbacks) {
  ------------------
  |  Branch (1007:37): [True: 0, False: 4.02k]
  ------------------
 1008|      0|            nativeCallbacks.emplace("native:" + name, cb);
 1009|      0|        }
 1010|       |
 1011|  4.02k|        DesugaredObject *stdlib = makeStdlibAST(alloc, "__internal__");
 1012|  4.02k|        jsonnet_static_analysis(stdlib);
 1013|  4.02k|        stdlibAST = stdlib; // stdlibAST is const, so we need to do analysis before this assignment
 1014|  4.02k|        auto stdThunk = makeHeap<HeapThunk>(nullptr, nullptr, 0, static_cast<const AST*>(stdlibAST));
 1015|  4.02k|        stack.newCall(stdThunk->body->location, stdThunk, stdThunk->self, stdThunk->offset, stdThunk->upValues);
 1016|  4.02k|        evaluate(stdThunk->body, 0);
 1017|  4.02k|        stdObject = dynamic_cast<HeapObject*>(scratch.v.h);
 1018|  4.02k|        prepareSourceValThunks();
 1019|  4.02k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15StackC2Ej:
  258|  4.02k|    Stack(unsigned limit) : calls(0), limit(limit) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeNullEv:
  634|  32.7k|    {
  635|  32.7k|        Value r;
  636|  32.7k|        r.t = Value::NULL_TYPE;
  637|  32.7k|        return r;
  638|  32.7k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack3topEv:
  291|   562M|    {
  292|   562M|        return stack.back();
  293|   562M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter19validateBuiltinArgsERKNS0_13LocationRangeERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEERKNS6_6vectorINS1_5ValueENSA_ISG_EEEENSF_INSG_4TypeENSA_ISL_EEEE:
 1043|   201k|    {
 1044|   201k|        if (args.size() == params.size()) {
  ------------------
  |  Branch (1044:13): [True: 201k, False: 0]
  ------------------
 1045|   565k|            for (std::size_t i = 0; i < args.size(); ++i) {
  ------------------
  |  Branch (1045:37): [True: 364k, False: 201k]
  ------------------
 1046|   364k|                if (args[i].t != params[i])
  ------------------
  |  Branch (1046:21): [True: 0, False: 364k]
  ------------------
 1047|      0|                    goto bad;
 1048|   364k|            }
 1049|   201k|            return;
 1050|   201k|        }
 1051|      0|    bad:;
 1052|      0|        std::stringstream ss;
 1053|      0|        ss << "Builtin function " + name + " expected (";
 1054|      0|        const char *prefix = "";
 1055|      0|        for (auto p : params) {
  ------------------
  |  Branch (1055:21): [True: 0, False: 0]
  ------------------
 1056|      0|            ss << prefix << type_str(p);
 1057|      0|            prefix = ", ";
 1058|      0|        }
 1059|      0|        ss << ") but got (";
 1060|      0|        prefix = "";
 1061|      0|        for (auto a : args) {
  ------------------
  |  Branch (1061:21): [True: 0, False: 0]
  ------------------
 1062|      0|            ss << prefix << type_str(a);
 1063|      0|            prefix = ", ";
 1064|      0|        }
 1065|      0|        ss << ")";
 1066|      0|        throw makeError(loc, ss.str());
 1067|   201k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter9makeErrorERKNS0_13LocationRangeERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  567|  2.61k|    {
  568|  2.61k|        return stack.makeError(loc, msg);
  569|  2.61k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack9makeErrorERKNS0_13LocationRangeERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE:
  368|  3.37k|    {
  369|  3.37k|        std::vector<TraceFrame> stack_trace;
  370|  3.37k|        stack_trace.push_back(TraceFrame(loc));
  371|  1.19M|        for (int i = stack.size() - 1; i >= 0; --i) {
  ------------------
  |  Branch (371:40): [True: 1.18M, False: 3.37k]
  ------------------
  372|  1.18M|            const auto &f = stack[i];
  373|  1.18M|            if (f.isCall()) {
  ------------------
  |  Branch (373:17): [True: 403k, False: 785k]
  ------------------
  374|   403k|                if (f.context != nullptr) {
  ------------------
  |  Branch (374:21): [True: 403k, False: 0]
  ------------------
  375|       |                    // Give the last line a name.
  376|   403k|                    stack_trace[stack_trace.size() - 1].name = getName(i, f.context);
  377|   403k|                }
  378|   403k|                if (f.location.isSet() || f.location.file.length() > 0)
  ------------------
  |  Branch (378:21): [True: 326k, False: 77.3k]
  |  Branch (378:43): [True: 854, False: 76.4k]
  ------------------
  379|   327k|                    stack_trace.push_back(TraceFrame(f.location));
  380|   403k|            }
  381|  1.18M|        }
  382|  3.37k|        return RuntimeError(stack_trace, msg);
  383|  3.37k|    }
vm.cpp:_ZNK7jsonnet8internal12_GLOBAL__N_15Frame6isCallEv:
  241|   648M|    {
  242|   648M|        return kind == FRAME_CALL;
  243|   648M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack7getNameEjPKNS1_10HeapEntityE:
  313|   403k|    {
  314|   403k|        std::string name;
  315|  1.17M|        for (int i = from_here - 1; i >= 0; --i) {
  ------------------
  |  Branch (315:37): [True: 1.17M, False: 2.37k]
  ------------------
  316|  1.17M|            const auto &f = stack[i];
  317|  1.17M|            for (const auto &pair : f.bindings) {
  ------------------
  |  Branch (317:35): [True: 661k, False: 1.17M]
  ------------------
  318|   661k|                HeapThunk *thunk = pair.second;
  319|   661k|                if (!thunk->filled)
  ------------------
  |  Branch (319:21): [True: 195k, False: 465k]
  ------------------
  320|   195k|                    continue;
  321|   465k|                if (!thunk->content.isHeap())
  ------------------
  |  Branch (321:21): [True: 60.4k, False: 405k]
  ------------------
  322|  60.4k|                    continue;
  323|   405k|                if (e != thunk->content.v.h)
  ------------------
  |  Branch (323:21): [True: 357k, False: 47.9k]
  ------------------
  324|   357k|                    continue;
  325|  47.9k|                name = encode_utf8(pair.first->name);
  326|  47.9k|            }
  327|       |            // Do not go into the next call frame, keep local reasoning.
  328|  1.17M|            if (f.isCall())
  ------------------
  |  Branch (328:17): [True: 401k, False: 775k]
  ------------------
  329|   401k|                break;
  330|  1.17M|        }
  331|       |
  332|   403k|        if (name == "")
  ------------------
  |  Branch (332:13): [True: 355k, False: 47.9k]
  ------------------
  333|   355k|            name = "anonymous";
  334|   403k|        if (dynamic_cast<const HeapObject *>(e)) {
  ------------------
  |  Branch (334:13): [True: 258k, False: 145k]
  ------------------
  335|   258k|            return "object <" + name + ">";
  336|   258k|        } else if (auto *thunk = dynamic_cast<const HeapThunk *>(e)) {
  ------------------
  |  Branch (336:26): [True: 81.3k, False: 64.0k]
  ------------------
  337|  81.3k|            if (thunk->name == nullptr) {
  ------------------
  |  Branch (337:17): [True: 8.99k, False: 72.3k]
  ------------------
  338|  8.99k|                return "";  // Argument of builtin, or root (since top level functions).
  339|  72.3k|            } else {
  340|  72.3k|                return "thunk <" + encode_utf8(thunk->name->name) + ">";
  341|  72.3k|            }
  342|  81.3k|        } else {
  343|  64.0k|            const auto *func = static_cast<const HeapClosure *>(e);
  344|  64.0k|            if (func->isBuiltin()) {
  ------------------
  |  Branch (344:17): [True: 0, False: 64.0k]
  ------------------
  345|      0|                return "builtin function <" + func->builtinName + ">";
  346|      0|            }
  347|  64.0k|            return "function <" + name + ">";
  348|  64.0k|        }
  349|   403k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack4markERNS1_4HeapE:
  284|   110k|    {
  285|  25.1M|        for (const auto &f : stack) {
  ------------------
  |  Branch (285:28): [True: 25.1M, False: 110k]
  ------------------
  286|  25.1M|            f.mark(heap);
  287|  25.1M|        }
  288|   110k|    }
vm.cpp:_ZNK7jsonnet8internal12_GLOBAL__N_15Frame4markERNS1_4HeapE:
  225|  25.1M|    {
  226|  25.1M|        heap.markFrom(val);
  227|  25.1M|        heap.markFrom(val2);
  228|  25.1M|        if (context)
  ------------------
  |  Branch (228:13): [True: 17.8M, False: 7.27M]
  ------------------
  229|  17.8M|            heap.markFrom(context);
  230|  25.1M|        if (self)
  ------------------
  |  Branch (230:13): [True: 17.8M, False: 7.35M]
  ------------------
  231|  17.8M|            heap.markFrom(self);
  232|  25.1M|        for (const auto &bind : bindings)
  ------------------
  |  Branch (232:31): [True: 24.0M, False: 25.1M]
  ------------------
  233|  24.0M|            heap.markFrom(bind.second);
  234|  25.1M|        for (const auto &el : elements)
  ------------------
  |  Branch (234:29): [True: 0, False: 25.1M]
  ------------------
  235|      0|            heap.markFrom(el.second);
  236|  25.1M|        for (const auto &th : thunks)
  ------------------
  |  Branch (236:29): [True: 4.51M, False: 25.1M]
  ------------------
  237|  4.51M|            heap.markFrom(th);
  238|  25.1M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10makeNumberEd:
  615|  5.61M|    {
  616|  5.61M|        Value r;
  617|  5.61M|        r.t = Value::NUMBER;
  618|  5.61M|        r.v.d = v;
  619|  5.61M|        return r;
  620|  5.61M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter9makeArrayERKNSt3__16vectorIPNS1_9HeapThunkENS3_9allocatorIS6_EEEE:
  641|  1.65M|    {
  642|  1.65M|        Value r;
  643|  1.65M|        r.t = Value::ARRAY;
  644|  1.65M|        r.v.h = makeHeap<HeapArray>(v);
  645|  1.65M|        return r;
  646|  1.65M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapArrayEJRKNSt3__16vectorIPNS1_9HeapThunkENS5_9allocatorIS8_EEEEEEEPT_DpOT0_:
  577|  1.65M|    {
  578|  1.65M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  579|  1.65M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (579:13): [True: 3.02k, False: 1.65M]
  ------------------
  580|       |            // Avoid the object we just made being collected.
  581|  3.02k|            heap.markFrom(r);
  582|       |
  583|       |            // Mark from the stack.
  584|  3.02k|            stack.mark(heap);
  585|       |
  586|       |            // Mark from the scratch register
  587|  3.02k|            heap.markFrom(scratch);
  588|       |
  589|       |            // Mark from cached imports
  590|  3.02k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (590:35): [True: 0, False: 3.02k]
  ------------------
  591|      0|                HeapThunk *thunk = pair.second->thunk;
  592|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (592:21): [True: 0, False: 0]
  ------------------
  593|      0|                    heap.markFrom(thunk);
  594|      0|            }
  595|       |
  596|   486k|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (596:40): [True: 486k, False: 3.02k]
  ------------------
  597|   486k|                heap.markFrom(sourceVal.second);
  598|   486k|            }
  599|       |
  600|       |            // Delete unreachable objects.
  601|  3.02k|            heap.sweep();
  602|  3.02k|        }
  603|  1.65M|        return r;
  604|  1.65M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10builtinPowERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1103|  3.06k|    {
 1104|  3.06k|        validateBuiltinArgs(loc, "pow", args, {Value::NUMBER, Value::NUMBER});
 1105|  3.06k|        scratch = makeNumberCheck(loc, std::pow(args[0].v.d, args[1].v.d));
 1106|  3.06k|        return nullptr;
 1107|  3.06k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter15makeNumberCheckERKNS0_13LocationRangeEd:
  623|  4.85M|    {
  624|  4.85M|        if (std::isnan(v)) {
  ------------------
  |  Branch (624:13): [True: 0, False: 4.85M]
  ------------------
  625|      0|            throw makeError(loc, "not a number");
  626|      0|        }
  627|  4.85M|        if (std::isinf(v)) {
  ------------------
  |  Branch (627:13): [True: 35, False: 4.85M]
  ------------------
  628|     35|            throw makeError(loc, "overflow");
  629|     35|        }
  630|  4.85M|        return makeNumber(v);
  631|  4.85M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter12builtinFloorERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1110|  32.9k|    {
 1111|  32.9k|        validateBuiltinArgs(loc, "floor", args, {Value::NUMBER});
 1112|  32.9k|        scratch = makeNumberCheck(loc, std::floor(args[0].v.d));
 1113|  32.9k|        return nullptr;
 1114|  32.9k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter11builtinTypeERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1187|  2.82M|    {
 1188|  2.82M|        switch (args[0].t) {
  ------------------
  |  Branch (1188:17): [True: 2.82M, False: 0]
  ------------------
 1189|  30.0k|            case Value::NULL_TYPE: scratch = makeString(U"null"); return nullptr;
  ------------------
  |  Branch (1189:13): [True: 30.0k, False: 2.79M]
  ------------------
 1190|       |
 1191|   137k|            case Value::BOOLEAN: scratch = makeString(U"boolean"); return nullptr;
  ------------------
  |  Branch (1191:13): [True: 137k, False: 2.68M]
  ------------------
 1192|       |
 1193|   382k|            case Value::NUMBER: scratch = makeString(U"number"); return nullptr;
  ------------------
  |  Branch (1193:13): [True: 382k, False: 2.44M]
  ------------------
 1194|       |
 1195|   185k|            case Value::ARRAY: scratch = makeString(U"array"); return nullptr;
  ------------------
  |  Branch (1195:13): [True: 185k, False: 2.63M]
  ------------------
 1196|       |
 1197|     32|            case Value::FUNCTION: scratch = makeString(U"function"); return nullptr;
  ------------------
  |  Branch (1197:13): [True: 32, False: 2.82M]
  ------------------
 1198|       |
 1199|   125k|            case Value::OBJECT: scratch = makeString(U"object"); return nullptr;
  ------------------
  |  Branch (1199:13): [True: 125k, False: 2.69M]
  ------------------
 1200|       |
 1201|  1.96M|            case Value::STRING: scratch = makeString(U"string"); return nullptr;
  ------------------
  |  Branch (1201:13): [True: 1.96M, False: 860k]
  ------------------
 1202|  2.82M|        }
 1203|      0|        return nullptr;  // Quiet, compiler.
 1204|  2.82M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10makeStringERKNSt3__112basic_stringIDiNS3_11char_traitsIDiEENS3_9allocatorIDiEEEE:
  679|  37.4M|    {
  680|  37.4M|        Value r;
  681|  37.4M|        r.t = Value::STRING;
  682|  37.4M|        r.v.h = makeHeap<HeapString>(v);
  683|  37.4M|        return r;
  684|  37.4M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_10HeapStringEJRKNSt3__112basic_stringIDiNS5_11char_traitsIDiEENS5_9allocatorIDiEEEEEEEPT_DpOT0_:
  577|  37.4M|    {
  578|  37.4M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  579|  37.4M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (579:13): [True: 42.5k, False: 37.3M]
  ------------------
  580|       |            // Avoid the object we just made being collected.
  581|  42.5k|            heap.markFrom(r);
  582|       |
  583|       |            // Mark from the stack.
  584|  42.5k|            stack.mark(heap);
  585|       |
  586|       |            // Mark from the scratch register
  587|  42.5k|            heap.markFrom(scratch);
  588|       |
  589|       |            // Mark from cached imports
  590|  42.5k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (590:35): [True: 0, False: 42.5k]
  ------------------
  591|      0|                HeapThunk *thunk = pair.second->thunk;
  592|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (592:21): [True: 0, False: 0]
  ------------------
  593|      0|                    heap.markFrom(thunk);
  594|      0|            }
  595|       |
  596|  6.85M|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (596:40): [True: 6.85M, False: 42.5k]
  ------------------
  597|  6.85M|                heap.markFrom(sourceVal.second);
  598|  6.85M|            }
  599|       |
  600|       |            // Delete unreachable objects.
  601|  42.5k|            heap.sweep();
  602|  42.5k|        }
  603|  37.4M|        return r;
  604|  37.4M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter12objectFieldsEPKNS1_10HeapObjectEb:
  773|   681k|    {
  774|   681k|        std::set<const Identifier *> r;
  775|  1.44M|        for (const auto &pair : objectFieldsAux(obj_)) {
  ------------------
  |  Branch (775:31): [True: 1.44M, False: 681k]
  ------------------
  776|  1.44M|            if (!manifesting || pair.second != ObjectField::HIDDEN)
  ------------------
  |  Branch (776:17): [True: 0, False: 1.44M]
  |  Branch (776:33): [True: 1.44M, False: 3.23k]
  ------------------
  777|  1.44M|                r.insert(pair.first);
  778|  1.44M|        }
  779|   681k|        return r;
  780|   681k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter15objectFieldsAuxEPKNS1_10HeapObjectE:
  740|  41.7M|    {
  741|  41.7M|        IdHideMap r;
  742|  41.7M|        if (auto *obj = dynamic_cast<const HeapSimpleObject *>(obj_)) {
  ------------------
  |  Branch (742:19): [True: 21.2M, False: 20.5M]
  ------------------
  743|  21.2M|            for (const auto &f : obj->fields) {
  ------------------
  |  Branch (743:32): [True: 10.2M, False: 21.2M]
  ------------------
  744|  10.2M|                r[f.first] = f.second.hide;
  745|  10.2M|            }
  746|       |
  747|  21.2M|        } else if (auto *obj = dynamic_cast<const HeapRestrictedObject *>(obj_)) {
  ------------------
  |  Branch (747:26): [True: 0, False: 20.5M]
  ------------------
  748|      0|            return obj->retainedKeys;
  749|       |
  750|  20.5M|        } else if (auto *obj = dynamic_cast<const HeapExtendedObject *>(obj_)) {
  ------------------
  |  Branch (750:26): [True: 20.5M, False: 0]
  ------------------
  751|  20.5M|            r = objectFieldsAux(obj->right);
  752|  35.8M|            for (const auto &pair : objectFieldsAux(obj->left)) {
  ------------------
  |  Branch (752:35): [True: 35.8M, False: 20.5M]
  ------------------
  753|  35.8M|                auto it = r.find(pair.first);
  754|  35.8M|                if (it == r.end()) {
  ------------------
  |  Branch (754:21): [True: 27.0M, False: 8.76M]
  ------------------
  755|       |                    // First time it is seen
  756|  27.0M|                    r[pair.first] = pair.second;
  757|  27.0M|                } else if (it->second == ObjectField::INHERIT) {
  ------------------
  |  Branch (757:28): [True: 8.30M, False: 464k]
  ------------------
  758|       |                    // Seen before, but with inherited visibility so use new visibility
  759|  8.30M|                    r[pair.first] = pair.second;
  760|  8.30M|                }
  761|  35.8M|            }
  762|       |
  763|  20.5M|        } else if (auto *obj = dynamic_cast<const HeapComprehensionObject *>(obj_)) {
  ------------------
  |  Branch (763:26): [True: 0, False: 0]
  ------------------
  764|      0|            for (const auto &f : obj->compValues)
  ------------------
  |  Branch (764:32): [True: 0, False: 0]
  ------------------
  765|      0|                r[f.first] = ObjectField::INHERIT;
  766|      0|        }
  767|  41.7M|        return r;
  768|  41.7M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter11makeBooleanEb:
  607|  10.0M|    {
  608|  10.0M|        Value r;
  609|  10.0M|        r.t = Value::BOOLEAN;
  610|  10.0M|        r.v.b = v;
  611|  10.0M|        return r;
  612|  10.0M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter13builtinLengthERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1252|   594k|    {
 1253|   594k|        if (args.size() != 1) {
  ------------------
  |  Branch (1253:13): [True: 0, False: 594k]
  ------------------
 1254|      0|            throw makeError(loc, "length takes 1 parameter.");
 1255|      0|        }
 1256|   594k|        HeapEntity *e = args[0].v.h;
 1257|   594k|        switch (args[0].t) {
 1258|      0|            case Value::OBJECT: {
  ------------------
  |  Branch (1258:13): [True: 0, False: 594k]
  ------------------
 1259|      0|                auto fields = objectFields(static_cast<HeapObject *>(e), true);
 1260|      0|                scratch = makeNumber(fields.size());
 1261|      0|            } break;
 1262|       |
 1263|   311k|            case Value::ARRAY:
  ------------------
  |  Branch (1263:13): [True: 311k, False: 282k]
  ------------------
 1264|   311k|                scratch = makeNumber(static_cast<HeapArray *>(e)->elements.size());
 1265|   311k|                break;
 1266|       |
 1267|   282k|            case Value::STRING:
  ------------------
  |  Branch (1267:13): [True: 282k, False: 311k]
  ------------------
 1268|   282k|                scratch = makeNumber(static_cast<HeapString *>(e)->value.length());
 1269|   282k|                break;
 1270|       |
 1271|      0|            case Value::FUNCTION:
  ------------------
  |  Branch (1271:13): [True: 0, False: 594k]
  ------------------
 1272|      0|                scratch = makeNumber(static_cast<HeapClosure *>(e)->params.size());
 1273|      0|                break;
 1274|       |
 1275|     11|            default:
  ------------------
  |  Branch (1275:13): [True: 11, False: 594k]
  ------------------
 1276|     11|                throw makeError(loc,
 1277|     11|                                "length operates on strings, objects, "
 1278|     11|                                "and arrays, got " +
 1279|     11|                                    type_str(args[0]));
 1280|   594k|        }
 1281|   594k|        return nullptr;
 1282|   594k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter21builtinObjectFieldsExERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1285|   112k|    {
 1286|   112k|        validateBuiltinArgs(loc, "objectFieldsEx", args, {Value::OBJECT, Value::BOOLEAN});
 1287|   112k|        const auto *obj = static_cast<HeapObject *>(args[0].v.h);
 1288|   112k|        bool include_hidden = args[1].v.b;
 1289|       |        // Stash in a set first to sort them.
 1290|   112k|        std::set<UString> fields;
 1291|   661k|        for (const auto &field : objectFields(obj, !include_hidden)) {
  ------------------
  |  Branch (1291:32): [True: 661k, False: 112k]
  ------------------
 1292|   661k|            fields.insert(field->name);
 1293|   661k|        }
 1294|   112k|        scratch = makeArray({});
 1295|   112k|        auto &elements = static_cast<HeapArray *>(scratch.v.h)->elements;
 1296|   661k|        for (const auto &field : fields) {
  ------------------
  |  Branch (1296:32): [True: 661k, False: 112k]
  ------------------
 1297|   661k|            auto *th = makeHeap<HeapThunk>(idArrayElement, nullptr, 0, nullptr);
 1298|   661k|            elements.push_back(th);
 1299|   661k|            th->fill(makeString(field));
 1300|   661k|        }
 1301|   112k|        return nullptr;
 1302|   112k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapThunkEJRPKNS0_10IdentifierEDniDnEEEPT_DpOT0_:
  577|   661k|    {
  578|   661k|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  579|   661k|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (579:13): [True: 1.09k, False: 660k]
  ------------------
  580|       |            // Avoid the object we just made being collected.
  581|  1.09k|            heap.markFrom(r);
  582|       |
  583|       |            // Mark from the stack.
  584|  1.09k|            stack.mark(heap);
  585|       |
  586|       |            // Mark from the scratch register
  587|  1.09k|            heap.markFrom(scratch);
  588|       |
  589|       |            // Mark from cached imports
  590|  1.09k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (590:35): [True: 0, False: 1.09k]
  ------------------
  591|      0|                HeapThunk *thunk = pair.second->thunk;
  592|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (592:21): [True: 0, False: 0]
  ------------------
  593|      0|                    heap.markFrom(thunk);
  594|      0|            }
  595|       |
  596|   176k|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (596:40): [True: 176k, False: 1.09k]
  ------------------
  597|   176k|                heap.markFrom(sourceVal.second);
  598|   176k|            }
  599|       |
  600|       |            // Delete unreachable objects.
  601|  1.09k|            heap.sweep();
  602|  1.09k|        }
  603|   661k|        return r;
  604|   661k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter11builtinCharERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1335|  3.08k|    {
 1336|  3.08k|        validateBuiltinArgs(loc, "char", args, {Value::NUMBER});
 1337|  3.08k|        long l = long(args[0].v.d);
 1338|  3.08k|        if (l < 0) {
  ------------------
  |  Branch (1338:13): [True: 64, False: 3.01k]
  ------------------
 1339|     64|            std::stringstream ss;
 1340|     64|            ss << "codepoints must be >= 0, got " << l;
 1341|     64|            throw makeError(loc, ss.str());
 1342|     64|        }
 1343|  3.01k|        if (l >= JSONNET_CODEPOINT_MAX) {
  ------------------
  |  |   22|  3.01k|#define JSONNET_CODEPOINT_MAX 0x110000
  ------------------
  |  Branch (1343:13): [True: 44, False: 2.97k]
  ------------------
 1344|     44|            std::stringstream ss;
 1345|     44|            ss << "invalid unicode codepoint, got " << l;
 1346|     44|            throw makeError(loc, ss.str());
 1347|     44|        }
 1348|  2.97k|        char32_t c = l;
 1349|  2.97k|        scratch = makeString(UString(&c, 1));
 1350|  2.97k|        return nullptr;
 1351|  3.01k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10builtinLogERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1354|  4.05k|    {
 1355|  4.05k|        validateBuiltinArgs(loc, "log", args, {Value::NUMBER});
 1356|  4.05k|        scratch = makeNumberCheck(loc, std::log(args[0].v.d));
 1357|  4.05k|        return nullptr;
 1358|  4.05k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter13builtinModuloERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1386|  44.2k|    {
 1387|  44.2k|        validateBuiltinArgs(loc, "modulo", args, {Value::NUMBER, Value::NUMBER});
 1388|  44.2k|        double a = args[0].v.d;
 1389|  44.2k|        double b = args[1].v.d;
 1390|  44.2k|        if (b == 0)
  ------------------
  |  Branch (1390:13): [True: 22, False: 44.2k]
  ------------------
 1391|     22|            throw makeError(loc, "division by zero.");
 1392|  44.2k|        scratch = makeNumberCheck(loc, std::fmod(a, b));
 1393|  44.2k|        return nullptr;
 1394|  44.2k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack3popEv:
  301|   107M|    {
  302|   107M|        if (top().isCall())
  ------------------
  |  Branch (302:13): [True: 42.1M, False: 65.6M]
  ------------------
  303|  42.1M|            calls--;
  304|   107M|        stack.pop_back();
  305|   107M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter22builtinPrimitiveEqualsERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1422|  4.70M|    {
 1423|  4.70M|        if (args.size() != 2) {
  ------------------
  |  Branch (1423:13): [True: 0, False: 4.70M]
  ------------------
 1424|      0|            std::stringstream ss;
 1425|      0|            ss << "primitiveEquals takes 2 parameters, got " << args.size();
 1426|      0|            throw makeError(loc, ss.str());
 1427|      0|        }
 1428|  4.70M|        if (args[0].t != args[1].t) {
  ------------------
  |  Branch (1428:13): [True: 0, False: 4.70M]
  ------------------
 1429|      0|            scratch = makeBoolean(false);
 1430|      0|            return nullptr;
 1431|      0|        }
 1432|  4.70M|        bool r;
 1433|  4.70M|        switch (args[0].t) {
 1434|  42.8k|            case Value::BOOLEAN: r = args[0].v.b == args[1].v.b; break;
  ------------------
  |  Branch (1434:13): [True: 42.8k, False: 4.65M]
  ------------------
 1435|       |
 1436|   147k|            case Value::NUMBER: r = args[0].v.d == args[1].v.d; break;
  ------------------
  |  Branch (1436:13): [True: 147k, False: 4.55M]
  ------------------
 1437|       |
 1438|  4.50M|            case Value::STRING:
  ------------------
  |  Branch (1438:13): [True: 4.50M, False: 199k]
  ------------------
 1439|  4.50M|                r = static_cast<HeapString *>(args[0].v.h)->value ==
 1440|  4.50M|                    static_cast<HeapString *>(args[1].v.h)->value;
 1441|  4.50M|                break;
 1442|       |
 1443|  9.90k|            case Value::NULL_TYPE: r = true; break;
  ------------------
  |  Branch (1443:13): [True: 9.90k, False: 4.69M]
  ------------------
 1444|       |
 1445|      1|            case Value::FUNCTION: throw makeError(loc, "cannot test equality of functions"); break;
  ------------------
  |  Branch (1445:13): [True: 1, False: 4.70M]
  ------------------
 1446|       |
 1447|      0|            default:
  ------------------
  |  Branch (1447:13): [True: 0, False: 4.70M]
  ------------------
 1448|      0|                throw makeError(loc,
 1449|      0|                                "primitiveEquals operates on primitive "
 1450|      0|                                "types, got " +
 1451|      0|                                    type_str(args[0]));
 1452|  4.70M|        }
 1453|  4.70M|        scratch = makeBoolean(r);
 1454|  4.70M|        return nullptr;
 1455|  4.70M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter18makeBuiltinFromASTEPKNS0_19BuiltinFunctionBodyE:
  658|  8.33M|    {
  659|  8.33M|        HeapClosure::Params hc_params;
  660|  13.1M|        for (const auto p : body->params) {
  ------------------
  |  Branch (660:27): [True: 13.1M, False: 8.33M]
  ------------------
  661|  13.1M|            hc_params.emplace_back(p, nullptr);
  662|  13.1M|        }
  663|  8.33M|        Value r;
  664|  8.33M|        r.t = Value::FUNCTION;
  665|  8.33M|        r.v.h = makeHeap<HeapClosure>(BindingFrame(), nullptr, 0, hc_params, body, body->name);
  666|  8.33M|        return r;
  667|  8.33M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_11HeapClosureEJNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS5_4lessIS9_EENS5_9allocatorINS5_4pairIKS9_SB_EEEEEEDniRNS5_6vectorINS4_5ParamENSE_ISL_EEEERPKNS0_19BuiltinFunctionBodyERKNS5_12basic_stringIcNS5_11char_traitsIcEENSE_IcEEEEEEEPT_DpOT0_:
  577|  8.33M|    {
  578|  8.33M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  579|  8.33M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (579:13): [True: 8.70k, False: 8.32M]
  ------------------
  580|       |            // Avoid the object we just made being collected.
  581|  8.70k|            heap.markFrom(r);
  582|       |
  583|       |            // Mark from the stack.
  584|  8.70k|            stack.mark(heap);
  585|       |
  586|       |            // Mark from the scratch register
  587|  8.70k|            heap.markFrom(scratch);
  588|       |
  589|       |            // Mark from cached imports
  590|  8.70k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (590:35): [True: 0, False: 8.70k]
  ------------------
  591|      0|                HeapThunk *thunk = pair.second->thunk;
  592|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (592:21): [True: 0, False: 0]
  ------------------
  593|      0|                    heap.markFrom(thunk);
  594|      0|            }
  595|       |
  596|  1.40M|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (596:40): [True: 1.40M, False: 8.70k]
  ------------------
  597|  1.40M|                heap.markFrom(sourceVal.second);
  598|  1.40M|            }
  599|       |
  600|       |            // Delete unreachable objects.
  601|  8.70k|            heap.sweep();
  602|  8.70k|        }
  603|  8.33M|        return r;
  604|  8.33M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter13builtinSubstrERKNS0_13LocationRangeERKNSt3__16vectorINS1_5ValueENS6_9allocatorIS8_EEEE:
 1599|  1.44k|    {
 1600|  1.44k|        validateBuiltinArgs(loc, "substr", args, {Value::STRING, Value::NUMBER, Value::NUMBER});
 1601|  1.44k|        const auto *str = static_cast<const HeapString *>(args[0].v.h);
 1602|  1.44k|        long from = long(args[1].v.d);
 1603|  1.44k|        long len = long(args[2].v.d);
 1604|  1.44k|        if (from < 0) {
  ------------------
  |  Branch (1604:13): [True: 0, False: 1.44k]
  ------------------
 1605|      0|            std::stringstream ss;
 1606|      0|            ss << "substr second parameter should be greater than zero, got " << from;
 1607|      0|            throw makeError(loc, ss.str());
 1608|      0|        }
 1609|  1.44k|        if (len < 0) {
  ------------------
  |  Branch (1609:13): [True: 0, False: 1.44k]
  ------------------
 1610|      0|            std::stringstream ss;
 1611|      0|            ss << "substr third parameter should be greater than zero, got " << len;
 1612|      0|            throw makeError(loc, ss.str());
 1613|      0|        }
 1614|  1.44k|        if (static_cast<unsigned long>(from) > str->value.size()) {
  ------------------
  |  Branch (1614:13): [True: 0, False: 1.44k]
  ------------------
 1615|      0|            scratch = makeString(UString());
 1616|      0|            return nullptr;
 1617|      0|        }
 1618|  1.44k|        if (size_t(len + from) > str->value.size()) {
  ------------------
  |  Branch (1618:13): [True: 0, False: 1.44k]
  ------------------
 1619|      0|          len = str->value.size() - from;
 1620|      0|        }
 1621|  1.44k|        scratch = makeString(str->value.substr(from, len));
 1622|  1.44k|        return nullptr;
 1623|  1.44k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapThunkEJDnDniPKNS0_3ASTEEEEPT_DpOT0_:
  577|  4.02k|    {
  578|  4.02k|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  579|  4.02k|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (579:13): [True: 0, False: 4.02k]
  ------------------
  580|       |            // Avoid the object we just made being collected.
  581|      0|            heap.markFrom(r);
  582|       |
  583|       |            // Mark from the stack.
  584|      0|            stack.mark(heap);
  585|       |
  586|       |            // Mark from the scratch register
  587|      0|            heap.markFrom(scratch);
  588|       |
  589|       |            // Mark from cached imports
  590|      0|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (590:35): [True: 0, False: 0]
  ------------------
  591|      0|                HeapThunk *thunk = pair.second->thunk;
  592|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (592:21): [True: 0, False: 0]
  ------------------
  593|      0|                    heap.markFrom(thunk);
  594|      0|            }
  595|       |
  596|      0|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (596:40): [True: 0, False: 0]
  ------------------
  597|      0|                heap.markFrom(sourceVal.second);
  598|      0|            }
  599|       |
  600|       |            // Delete unreachable objects.
  601|      0|            heap.sweep();
  602|      0|        }
  603|  4.02k|        return r;
  604|  4.02k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack7newCallERKNS0_13LocationRangeEPNS1_10HeapEntityEPNS1_10HeapObjectEjRKNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENSA_4lessISE_EENSA_9allocatorINSA_4pairIKSE_SG_EEEEEE:
  418|  42.8M|    {
  419|  42.8M|        tailCallTrimStack();
  420|  42.8M|        if (calls >= limit) {
  ------------------
  |  Branch (420:13): [True: 767, False: 42.8M]
  ------------------
  421|    767|            throw makeError(loc, "max stack frames exceeded.");
  422|    767|        }
  423|  42.8M|        stack.emplace_back(FRAME_CALL, loc);
  424|  42.8M|        calls++;
  425|  42.8M|        top().context = context;
  426|  42.8M|        top().self = self;
  427|  42.8M|        top().offset = offset;
  428|  42.8M|        top().bindings = up_values;
  429|  42.8M|        top().tailCall = false;
  430|       |
  431|  42.8M|#ifndef NDEBUG
  432|  42.8M|        for (const auto &bind : up_values) {
  ------------------
  |  Branch (432:31): [True: 42.6M, False: 42.8M]
  ------------------
  433|  42.6M|            if (bind.second == nullptr) {
  ------------------
  |  Branch (433:17): [True: 0, False: 42.6M]
  ------------------
  434|      0|                std::cerr << "INTERNAL ERROR: No binding for variable "
  435|      0|                          << encode_utf8(bind.first->name) << std::endl;
  436|      0|                std::abort();
  437|      0|            }
  438|  42.6M|        }
  439|  42.8M|#endif
  440|  42.8M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack17tailCallTrimStackEv:
  394|  42.8M|    {
  395|  43.8M|        for (int i = stack.size() - 1; i >= 0; --i) {
  ------------------
  |  Branch (395:40): [True: 43.8M, False: 11.4k]
  ------------------
  396|  43.8M|            switch (stack[i].kind) {
  397|  13.1M|                case FRAME_CALL: {
  ------------------
  |  Branch (397:17): [True: 13.1M, False: 30.6M]
  ------------------
  398|  13.1M|                    if (!stack[i].tailCall || stack[i].thunks.size() > 0) {
  ------------------
  |  Branch (398:25): [True: 9.32M, False: 3.82M]
  |  Branch (398:47): [True: 3.51M, False: 307k]
  ------------------
  399|  12.8M|                        return;
  400|  12.8M|                    }
  401|       |                    // Remove all stack frames including this one.
  402|  1.23M|                    while (stack.size() > unsigned(i))
  ------------------
  |  Branch (402:28): [True: 924k, False: 307k]
  ------------------
  403|   924k|                        stack.pop_back();
  404|   307k|                    calls--;
  405|   307k|                    return;
  406|  13.1M|                } break;
  407|       |
  408|   961k|                case FRAME_LOCAL: break;
  ------------------
  |  Branch (408:17): [True: 961k, False: 42.8M]
  ------------------
  409|       |
  410|  29.7M|                default: return;
  ------------------
  |  Branch (410:17): [True: 29.7M, False: 14.1M]
  ------------------
  411|  43.8M|            }
  412|  43.8M|        }
  413|  42.8M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15FrameC2ERKNS1_9FrameKindERKNS0_13LocationRangeE:
  209|  53.8M|        : kind(kind),
  210|  53.8M|          ast(nullptr),
  211|  53.8M|          location(location),
  212|  53.8M|          tailCall(false),
  213|  53.8M|          elementId(0),
  214|  53.8M|          first(false),
  215|  53.8M|          context(NULL),
  216|  53.8M|          self(NULL),
  217|  53.8M|          offset(0)
  218|  53.8M|    {
  219|  53.8M|        val.t = Value::NULL_TYPE;
  220|  53.8M|        val2.t = Value::NULL_TYPE;
  221|  53.8M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter22prepareSourceValThunksEv:
  887|  4.02k|    void prepareSourceValThunks() {
  888|   647k|        for (const auto &field : stdlibAST->fields) {
  ------------------
  |  Branch (888:32): [True: 647k, False: 4.02k]
  ------------------
  889|   647k|            AST *nameAST = field.name;
  890|   647k|            if (nameAST->type != AST_LITERAL_STRING) {
  ------------------
  |  Branch (890:17): [True: 0, False: 647k]
  ------------------
  891|       |                // Skip any fields without a known name.
  892|      0|                continue;
  893|      0|            }
  894|   647k|            UString name = dynamic_cast<LiteralString *>(nameAST)->value;
  895|       |
  896|   647k|            sourceFuncIds.emplace_back(new Identifier(name));
  897|   647k|            auto *th = makeHeap<HeapThunk>(sourceFuncIds.back().get(), stdObject, 0, field.body);
  898|   647k|            sourceVals[encode_utf8(name)] = th;
  899|   647k|        }
  900|  4.02k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapThunkEJPNS0_10IdentifierERPNS1_10HeapObjectEiRKPNS0_3ASTEEEEPT_DpOT0_:
  577|   647k|    {
  578|   647k|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  579|   647k|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (579:13): [True: 0, False: 647k]
  ------------------
  580|       |            // Avoid the object we just made being collected.
  581|      0|            heap.markFrom(r);
  582|       |
  583|       |            // Mark from the stack.
  584|      0|            stack.mark(heap);
  585|       |
  586|       |            // Mark from the scratch register
  587|      0|            heap.markFrom(scratch);
  588|       |
  589|       |            // Mark from cached imports
  590|      0|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (590:35): [True: 0, False: 0]
  ------------------
  591|      0|                HeapThunk *thunk = pair.second->thunk;
  592|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (592:21): [True: 0, False: 0]
  ------------------
  593|      0|                    heap.markFrom(thunk);
  594|      0|            }
  595|       |
  596|      0|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (596:40): [True: 0, False: 0]
  ------------------
  597|      0|                heap.markFrom(sourceVal.second);
  598|      0|            }
  599|       |
  600|       |            // Delete unreachable objects.
  601|      0|            heap.sweep();
  602|      0|        }
  603|   647k|        return r;
  604|   647k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15StackD2Ev:
  260|  4.02k|    ~Stack(void) {}
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8evaluateEPKNS0_3ASTEj:
 2096|  4.30M|    {
 2097|   125M|    recurse:
 2098|       |
 2099|   125M|        switch (ast_->type) {
 2100|  10.6M|            case AST_APPLY: {
  ------------------
  |  Branch (2100:13): [True: 10.6M, False: 115M]
  ------------------
 2101|  10.6M|                const auto &ast = *static_cast<const Apply *>(ast_);
 2102|  10.6M|                stack.newFrame(FRAME_APPLY_TARGET, ast_);
 2103|  10.6M|                ast_ = ast.target;
 2104|  10.6M|                goto recurse;
 2105|      0|            } break;
 2106|       |
 2107|   922k|            case AST_ARRAY: {
  ------------------
  |  Branch (2107:13): [True: 922k, False: 124M]
  ------------------
 2108|   922k|                const auto &ast = *static_cast<const Array *>(ast_);
 2109|   922k|                HeapObject *self;
 2110|   922k|                unsigned offset;
 2111|   922k|                stack.getSelfBinding(self, offset);
 2112|   922k|                scratch = makeArray({});
 2113|   922k|                auto &elements = static_cast<HeapArray *>(scratch.v.h)->elements;
 2114|  7.14M|                for (const auto &el : ast.elements) {
  ------------------
  |  Branch (2114:37): [True: 7.14M, False: 922k]
  ------------------
 2115|  7.14M|                    auto *el_th = makeHeap<HeapThunk>(idArrayElement, self, offset, el.expr);
 2116|  7.14M|                    el_th->upValues = capture(el.expr->freeVariables);
 2117|  7.14M|                    elements.push_back(el_th);
 2118|  7.14M|                }
 2119|   922k|            } break;
 2120|       |
 2121|  4.91M|            case AST_BINARY: {
  ------------------
  |  Branch (2121:13): [True: 4.91M, False: 120M]
  ------------------
 2122|  4.91M|                const auto &ast = *static_cast<const Binary *>(ast_);
 2123|  4.91M|                stack.newFrame(FRAME_BINARY_LEFT, ast_);
 2124|  4.91M|                ast_ = ast.left;
 2125|  4.91M|                goto recurse;
 2126|      0|            } break;
 2127|       |
 2128|  8.33M|            case AST_BUILTIN_FUNCTION: {
  ------------------
  |  Branch (2128:13): [True: 8.33M, False: 117M]
  ------------------
 2129|  8.33M|                const auto &ast = *static_cast<const BuiltinFunction *>(ast_);
 2130|  8.33M|                scratch = makeBuiltinFromAST(ast.body);
 2131|  8.33M|            } break;
 2132|       |
 2133|      0|            case AST_BUILTIN_FUNCTION_BODY: {
  ------------------
  |  Branch (2133:13): [True: 0, False: 125M]
  ------------------
 2134|       |                // We can reach here if we end up evaluating a HeapThunk that was constructed
 2135|       |                // from a built-in function. Synthesize a FRAME_BUILTIN_FORCE_THUNKS to call it.
 2136|      0|                assert(stack.top().isCall());
  ------------------
  |  Branch (2136:17): [True: 0, False: 0]
  ------------------
 2137|      0|                const auto fbody = static_cast<const BuiltinFunctionBody*>(ast_);
 2138|       |
 2139|      0|                const BindingFrame up_values = stack.top().bindings;
 2140|      0|                std::vector<HeapThunk*> arg_thunks;
 2141|      0|                for (const auto &p : fbody->params) {
  ------------------
  |  Branch (2141:36): [True: 0, False: 0]
  ------------------
 2142|      0|                    const auto it = up_values.find(p);
 2143|      0|                    if (it != up_values.end()) {
  ------------------
  |  Branch (2143:25): [True: 0, False: 0]
  ------------------
 2144|      0|                        arg_thunks.push_back(it->second);
 2145|      0|                    } else {
 2146|      0|                        JSONNET_UNREACHABLE();
  ------------------
  |  |   53|      0|  do {                                                             \
  |  |   54|      0|    std::cerr << __FILE__ << ":" << __LINE__                       \
  |  |   55|      0|              << ": INTERNAL ERROR: reached unreachable code path" \
  |  |   56|      0|              << std::endl;                                        \
  |  |   57|      0|    abort();                                                       \
  |  |   58|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (58:12): [Folded, False: 0]
  |  |  ------------------
  ------------------
 2147|      0|                    }
 2148|      0|                }
 2149|      0|                const LocationRange &loc = stack.top().location;
 2150|       |
 2151|      0|                stack.newFrame(FRAME_BUILTIN_FORCE_THUNKS, loc);
 2152|      0|                stack.top().bindings = up_values;
 2153|      0|                stack.top().thunks = arg_thunks;
 2154|      0|                stack.top().val = makeBuiltinFromAST(fbody);
 2155|      0|            } break;
 2156|       |
 2157|  7.70M|            case AST_CONDITIONAL: {
  ------------------
  |  Branch (2157:13): [True: 7.70M, False: 118M]
  ------------------
 2158|  7.70M|                const auto &ast = *static_cast<const Conditional *>(ast_);
 2159|  7.70M|                stack.newFrame(FRAME_IF, ast_);
 2160|  7.70M|                ast_ = ast.cond;
 2161|  7.70M|                goto recurse;
 2162|      0|            } break;
 2163|       |
 2164|  5.47k|            case AST_ERROR: {
  ------------------
  |  Branch (2164:13): [True: 5.47k, False: 125M]
  ------------------
 2165|  5.47k|                const auto &ast = *static_cast<const Error *>(ast_);
 2166|  5.47k|                stack.newFrame(FRAME_ERROR, ast_);
 2167|  5.47k|                ast_ = ast.expr;
 2168|  5.47k|                goto recurse;
 2169|      0|            } break;
 2170|       |
 2171|  2.00M|            case AST_FUNCTION: {
  ------------------
  |  Branch (2171:13): [True: 2.00M, False: 123M]
  ------------------
 2172|  2.00M|                const auto &ast = *static_cast<const Function *>(ast_);
 2173|  2.00M|                auto env = capture(ast.freeVariables);
 2174|  2.00M|                HeapObject *self;
 2175|  2.00M|                unsigned offset;
 2176|  2.00M|                stack.getSelfBinding(self, offset);
 2177|  2.00M|                HeapClosure::Params params;
 2178|  2.00M|                params.reserve(ast.params.size());
 2179|  3.83M|                for (const auto &p : ast.params) {
  ------------------
  |  Branch (2179:36): [True: 3.83M, False: 2.00M]
  ------------------
 2180|  3.83M|                    params.emplace_back(p.id, p.expr);
 2181|  3.83M|                }
 2182|  2.00M|                scratch = makeClosure(env, self, offset, params, ast.body);
 2183|  2.00M|            } break;
 2184|       |
 2185|     39|            case AST_IMPORT: {
  ------------------
  |  Branch (2185:13): [True: 39, False: 125M]
  ------------------
 2186|     39|                const auto &ast = *static_cast<const Import *>(ast_);
 2187|     39|                HeapThunk *thunk = import(ast.location, ast.file);
 2188|     39|                if (thunk->filled) {
  ------------------
  |  Branch (2188:21): [True: 0, False: 39]
  ------------------
 2189|      0|                    scratch = thunk->content;
 2190|     39|                } else {
 2191|     39|                    stack.newCall(ast.location, thunk, thunk->self, thunk->offset, thunk->upValues);
 2192|     39|                    ast_ = thunk->body;
 2193|     39|                    goto recurse;
 2194|     39|                }
 2195|     39|            } break;
 2196|       |
 2197|     16|            case AST_IMPORTSTR: {
  ------------------
  |  Branch (2197:13): [True: 16, False: 125M]
  ------------------
 2198|     16|                const auto &ast = *static_cast<const Importstr *>(ast_);
 2199|     16|                const ImportCacheValue *value = importData(ast.location, ast.file);
 2200|     16|                scratch = makeString(decode_utf8(value->content));
 2201|     16|            } break;
 2202|       |
 2203|      5|            case AST_IMPORTBIN: {
  ------------------
  |  Branch (2203:13): [True: 5, False: 125M]
  ------------------
 2204|      5|                const auto &ast = *static_cast<const Importbin *>(ast_);
 2205|      5|                const ImportCacheValue *value = importData(ast.location, ast.file);
 2206|      5|                scratch = makeArray({});
 2207|      5|                auto &elements = static_cast<HeapArray *>(scratch.v.h)->elements;
 2208|      5|                elements.reserve(value->content.size());
 2209|      5|                for (const auto c : value->content) {
  ------------------
  |  Branch (2209:35): [True: 0, False: 5]
  ------------------
 2210|      0|                    auto *th = makeHeap<HeapThunk>(idArrayElement, nullptr, 0, nullptr);
 2211|      0|                    elements.push_back(th);
 2212|      0|                    th->fill(makeNumber(uint8_t(c)));
 2213|      0|                }
 2214|      5|            } break;
 2215|       |
 2216|  2.45M|            case AST_IN_SUPER: {
  ------------------
  |  Branch (2216:13): [True: 2.45M, False: 123M]
  ------------------
 2217|  2.45M|                const auto &ast = *static_cast<const InSuper *>(ast_);
 2218|  2.45M|                stack.newFrame(FRAME_IN_SUPER_ELEMENT, ast_);
 2219|  2.45M|                ast_ = ast.element;
 2220|  2.45M|                goto recurse;
 2221|     39|            } break;
 2222|       |
 2223|  10.8M|            case AST_INDEX: {
  ------------------
  |  Branch (2223:13): [True: 10.8M, False: 115M]
  ------------------
 2224|  10.8M|                const auto &ast = *static_cast<const Index *>(ast_);
 2225|  10.8M|                stack.newFrame(FRAME_INDEX_TARGET, ast_);
 2226|  10.8M|                ast_ = ast.target;
 2227|  10.8M|                goto recurse;
 2228|     39|            } break;
 2229|       |
 2230|  5.66M|            case AST_LOCAL: {
  ------------------
  |  Branch (2230:13): [True: 5.66M, False: 120M]
  ------------------
 2231|  5.66M|                const auto &ast = *static_cast<const Local *>(ast_);
 2232|  5.66M|                stack.newFrame(FRAME_LOCAL, ast_);
 2233|  5.66M|                Frame &f = stack.top();
 2234|       |                // First build all the thunks and bind them.
 2235|  5.66M|                HeapObject *self;
 2236|  5.66M|                unsigned offset;
 2237|  5.66M|                stack.getSelfBinding(self, offset);
 2238|  18.1M|                for (const auto &bind : ast.binds) {
  ------------------
  |  Branch (2238:39): [True: 18.1M, False: 5.66M]
  ------------------
 2239|       |                    // Note that these 2 lines must remain separate to avoid the GC running
 2240|       |                    // when bindings has a nullptr for key bind.first.
 2241|  18.1M|                    auto *th = makeHeap<HeapThunk>(bind.var, self, offset, bind.body);
 2242|  18.1M|                    f.bindings[bind.var] = th;
 2243|  18.1M|                }
 2244|       |                // Now capture the environment (including the new thunks, to make cycles).
 2245|  18.1M|                for (const auto &bind : ast.binds) {
  ------------------
  |  Branch (2245:39): [True: 18.1M, False: 5.66M]
  ------------------
 2246|  18.1M|                    auto *thunk = f.bindings[bind.var];
 2247|  18.1M|                    thunk->upValues = capture(bind.body->freeVariables);
 2248|  18.1M|                }
 2249|  5.66M|                ast_ = ast.body;
 2250|  5.66M|                goto recurse;
 2251|     39|            } break;
 2252|       |
 2253|   354k|            case AST_LITERAL_BOOLEAN: {
  ------------------
  |  Branch (2253:13): [True: 354k, False: 125M]
  ------------------
 2254|   354k|                const auto &ast = *static_cast<const LiteralBoolean *>(ast_);
 2255|   354k|                scratch = makeBoolean(ast.value);
 2256|   354k|            } break;
 2257|       |
 2258|  4.36M|            case AST_LITERAL_NUMBER: {
  ------------------
  |  Branch (2258:13): [True: 4.36M, False: 121M]
  ------------------
 2259|  4.36M|                const auto &ast = *static_cast<const LiteralNumber *>(ast_);
 2260|  4.36M|                scratch = makeNumberCheck(ast_->location, ast.value);
 2261|  4.36M|            } break;
 2262|       |
 2263|  32.3M|            case AST_LITERAL_STRING: {
  ------------------
  |  Branch (2263:13): [True: 32.3M, False: 93.5M]
  ------------------
 2264|  32.3M|                const auto &ast = *static_cast<const LiteralString *>(ast_);
 2265|  32.3M|                scratch = makeString(ast.value);
 2266|  32.3M|            } break;
 2267|       |
 2268|  28.7k|            case AST_LITERAL_NULL: {
  ------------------
  |  Branch (2268:13): [True: 28.7k, False: 125M]
  ------------------
 2269|  28.7k|                scratch = makeNull();
 2270|  28.7k|            } break;
 2271|       |
 2272|  2.01M|            case AST_DESUGARED_OBJECT: {
  ------------------
  |  Branch (2272:13): [True: 2.01M, False: 123M]
  ------------------
 2273|  2.01M|                const auto &ast = *static_cast<const DesugaredObject *>(ast_);
 2274|  2.01M|                if (ast.fields.empty()) {
  ------------------
  |  Branch (2274:21): [True: 1.15M, False: 858k]
  ------------------
 2275|  1.15M|                    auto env = capture(ast.freeVariables);
 2276|  1.15M|                    std::map<const Identifier *, HeapSimpleObject::Field> fields;
 2277|  1.15M|                    scratch = makeObject<HeapSimpleObject>(env, fields, ast.asserts);
 2278|  1.15M|                } else {
 2279|   858k|                    auto env = capture(ast.freeVariables);
 2280|   858k|                    stack.newFrame(FRAME_OBJECT, ast_);
 2281|   858k|                    auto fit = ast.fields.begin();
 2282|   858k|                    stack.top().fit = fit;
 2283|   858k|                    ast_ = fit->name;
 2284|   858k|                    goto recurse;
 2285|   858k|                }
 2286|  2.01M|            } break;
 2287|       |
 2288|  1.15M|            case AST_OBJECT_COMPREHENSION_SIMPLE: {
  ------------------
  |  Branch (2288:13): [True: 48, False: 125M]
  ------------------
 2289|     48|                const auto &ast = *static_cast<const ObjectComprehensionSimple *>(ast_);
 2290|     48|                stack.newFrame(FRAME_OBJECT_COMP_ARRAY, ast_);
 2291|     48|                ast_ = ast.array;
 2292|     48|                goto recurse;
 2293|  2.01M|            } break;
 2294|       |
 2295|  1.93M|            case AST_SELF: {
  ------------------
  |  Branch (2295:13): [True: 1.93M, False: 123M]
  ------------------
 2296|  1.93M|                scratch.t = Value::OBJECT;
 2297|  1.93M|                HeapObject *self;
 2298|  1.93M|                unsigned offset;
 2299|  1.93M|                stack.getSelfBinding(self, offset);
 2300|  1.93M|                scratch.v.h = self;
 2301|  1.93M|            } break;
 2302|       |
 2303|  2.23M|            case AST_SUPER_INDEX: {
  ------------------
  |  Branch (2303:13): [True: 2.23M, False: 123M]
  ------------------
 2304|  2.23M|                const auto &ast = *static_cast<const SuperIndex *>(ast_);
 2305|  2.23M|                stack.newFrame(FRAME_SUPER_INDEX, ast_);
 2306|  2.23M|                ast_ = ast.index;
 2307|  2.23M|                goto recurse;
 2308|  2.01M|            } break;
 2309|       |
 2310|  2.39M|            case AST_UNARY: {
  ------------------
  |  Branch (2310:13): [True: 2.39M, False: 123M]
  ------------------
 2311|  2.39M|                const auto &ast = *static_cast<const Unary *>(ast_);
 2312|  2.39M|                stack.newFrame(FRAME_UNARY, ast_);
 2313|  2.39M|                ast_ = ast.expr;
 2314|  2.39M|                goto recurse;
 2315|  2.01M|            } break;
 2316|       |
 2317|  26.7M|            case AST_VAR: {
  ------------------
  |  Branch (2317:13): [True: 26.7M, False: 99.1M]
  ------------------
 2318|  26.7M|                const auto &ast = *static_cast<const Var *>(ast_);
 2319|  26.7M|                auto *thunk = stack.lookUpVar(ast.id);
 2320|  26.7M|                if (thunk == nullptr) {
  ------------------
  |  Branch (2320:21): [True: 0, False: 26.7M]
  ------------------
 2321|      0|                    std::cerr << "INTERNAL ERROR: Could not bind variable: "
 2322|      0|                              << encode_utf8(ast.id->name) << " at "
 2323|      0|                              << ast.location << std::endl;
 2324|      0|                    std::abort();
 2325|      0|                }
 2326|  26.7M|                if (thunk->filled) {
  ------------------
  |  Branch (2326:21): [True: 19.9M, False: 6.77M]
  ------------------
 2327|  19.9M|                    scratch = thunk->content;
 2328|  19.9M|                } else {
 2329|  6.77M|                    stack.newCall(ast.location, thunk, thunk->self, thunk->offset, thunk->upValues);
 2330|  6.77M|                    ast_ = thunk->body;
 2331|  6.77M|                    goto recurse;
 2332|  6.77M|                }
 2333|  26.7M|            } break;
 2334|       |
 2335|  19.9M|            default:
  ------------------
  |  Branch (2335:13): [True: 0, False: 125M]
  ------------------
 2336|      0|                std::cerr << "INTERNAL ERROR: Unknown AST: " << ast_->type << std::endl;
 2337|      0|                std::abort();
 2338|   125M|        }
 2339|       |
 2340|       |        // To evaluate another AST, set ast to it, then goto recurse.
 2341|       |        // To pop, exit the switch or goto popframe
 2342|       |        // To change the frame and re-enter the switch, goto replaceframe
 2343|   144M|        while (stack.size() > initial_stack_size) {
  ------------------
  |  Branch (2343:16): [True: 139M, False: 4.27M]
  ------------------
 2344|   139M|            Frame &f = stack.top();
 2345|   139M|            switch (f.kind) {
 2346|  10.6M|                case FRAME_APPLY_TARGET: {
  ------------------
  |  Branch (2346:17): [True: 10.6M, False: 129M]
  ------------------
 2347|  10.6M|                    const auto &ast = *static_cast<const Apply *>(f.ast);
 2348|  10.6M|                    if (scratch.t != Value::FUNCTION) {
  ------------------
  |  Branch (2348:25): [True: 15, False: 10.6M]
  ------------------
 2349|     15|                        throw makeError(ast.location,
 2350|     15|                                        "only functions can be called, got " + type_str(scratch));
 2351|     15|                    }
 2352|  10.6M|                    auto *func = static_cast<HeapClosure *>(scratch.v.h);
 2353|       |
 2354|  10.6M|                    std::set<const Identifier *> params_needed;
 2355|  18.1M|                    for (const auto &param : func->params) {
  ------------------
  |  Branch (2355:44): [True: 18.1M, False: 10.6M]
  ------------------
 2356|  18.1M|                        params_needed.insert(param.id);
 2357|  18.1M|                    }
 2358|       |
 2359|       |                    // Create thunks for arguments.
 2360|  10.6M|                    std::vector<HeapThunk *> positional_args;
 2361|  10.6M|                    BindingFrame args;
 2362|  10.6M|                    bool got_named = false;
 2363|  28.8M|                    for (std::size_t i = 0; i < ast.args.size(); ++i) {
  ------------------
  |  Branch (2363:45): [True: 18.1M, False: 10.6M]
  ------------------
 2364|  18.1M|                        const auto &arg = ast.args[i];
 2365|       |
 2366|  18.1M|                        const Identifier *name;
 2367|  18.1M|                        if (arg.id != nullptr) {
  ------------------
  |  Branch (2367:29): [True: 0, False: 18.1M]
  ------------------
 2368|      0|                            got_named = true;
 2369|      0|                            name = arg.id;
 2370|  18.1M|                        } else {
 2371|  18.1M|                            if (got_named) {
  ------------------
  |  Branch (2371:33): [True: 0, False: 18.1M]
  ------------------
 2372|      0|                                std::stringstream ss;
 2373|      0|                                ss << "internal error: got positional param after named at index "
 2374|      0|                                   << i;
 2375|      0|                                throw makeError(ast.location, ss.str());
 2376|      0|                            }
 2377|  18.1M|                            if (i >= func->params.size()) {
  ------------------
  |  Branch (2377:33): [True: 0, False: 18.1M]
  ------------------
 2378|      0|                                std::stringstream ss;
 2379|      0|                                ss << "too many args, function has " << func->params.size()
 2380|      0|                                   << " parameter(s)";
 2381|      0|                                throw makeError(ast.location, ss.str());
 2382|      0|                            }
 2383|  18.1M|                            name = func->params[i].id;
 2384|  18.1M|                        }
 2385|       |                        // Special case for builtin functions -- leave identifier blank for
 2386|       |                        // them in the thunk.  This removes the thunk frame from the stacktrace.
 2387|  18.1M|                        const Identifier *name_ = func->isBuiltin() ? nullptr : name;
  ------------------
  |  Branch (2387:51): [True: 13.1M, False: 4.96M]
  ------------------
 2388|  18.1M|                        HeapObject *self;
 2389|  18.1M|                        unsigned offset;
 2390|  18.1M|                        stack.getSelfBinding(self, offset);
 2391|  18.1M|                        auto *thunk = makeHeap<HeapThunk>(name_, self, offset, arg.expr);
 2392|  18.1M|                        thunk->upValues = capture(arg.expr->freeVariables);
 2393|       |                        // While making the thunks, keep them in a frame to avoid premature garbage
 2394|       |                        // collection.
 2395|  18.1M|                        f.thunks.push_back(thunk);
 2396|  18.1M|                        if (args.find(name) != args.end()) {
  ------------------
  |  Branch (2396:29): [True: 0, False: 18.1M]
  ------------------
 2397|      0|                            std::stringstream ss;
 2398|      0|                            ss << "binding parameter a second time: " << encode_utf8(name->name);
 2399|      0|                            throw makeError(ast.location, ss.str());
 2400|      0|                        }
 2401|  18.1M|                        args[name] = thunk;
 2402|  18.1M|                        if (params_needed.find(name) == params_needed.end()) {
  ------------------
  |  Branch (2402:29): [True: 0, False: 18.1M]
  ------------------
 2403|      0|                            std::stringstream ss;
 2404|      0|                            ss << "function has no parameter " << encode_utf8(name->name);
 2405|      0|                            throw makeError(ast.location, ss.str());
 2406|      0|                        }
 2407|  18.1M|                    }
 2408|       |
 2409|       |                    // For any func params for which there was no arg, create a thunk for those and
 2410|       |                    // bind the default argument.  Allow default thunks to see other params.  If no
 2411|       |                    // default argument than raise an error.
 2412|       |
 2413|       |                    // Raise errors for unbound params, create thunks (but don't fill in upvalues).
 2414|       |                    // This is a subset of f.thunks, so will not get garbage collected.
 2415|  10.6M|                    std::vector<HeapThunk *> def_arg_thunks;
 2416|  18.1M|                    for (const auto &param : func->params) {
  ------------------
  |  Branch (2416:44): [True: 18.1M, False: 10.6M]
  ------------------
 2417|  18.1M|                        if (args.find(param.id) != args.end())
  ------------------
  |  Branch (2417:29): [True: 18.1M, False: 139]
  ------------------
 2418|  18.1M|                            continue;
 2419|    139|                        if (param.def == nullptr) {
  ------------------
  |  Branch (2419:29): [True: 8, False: 131]
  ------------------
 2420|      8|                            std::stringstream ss;
 2421|      8|                            ss << "function parameter " << encode_utf8(param.id->name)
 2422|      8|                               << " not bound in call.";
 2423|      8|                            throw makeError(ast.location, ss.str());
 2424|      8|                        }
 2425|       |
 2426|       |                        // Special case for builtin functions -- leave identifier blank for
 2427|       |                        // them in the thunk.  This removes the thunk frame from the stacktrace.
 2428|    131|                        const Identifier *name_ = func->isBuiltin() ? nullptr : param.id;
  ------------------
  |  Branch (2428:51): [True: 0, False: 131]
  ------------------
 2429|    131|                        auto *thunk =
 2430|    131|                            makeHeap<HeapThunk>(name_, func->self, func->offset, param.def);
 2431|    131|                        f.thunks.push_back(thunk);
 2432|    131|                        def_arg_thunks.push_back(thunk);
 2433|    131|                        args[param.id] = thunk;
 2434|    131|                    }
 2435|       |
 2436|  10.6M|                    BindingFrame up_values = func->upValues;
 2437|  10.6M|                    up_values.insert(args.begin(), args.end());
 2438|       |
 2439|       |                    // Fill in upvalues
 2440|  10.6M|                    for (HeapThunk *thunk : def_arg_thunks) {
  ------------------
  |  Branch (2440:43): [True: 107, False: 10.6M]
  ------------------
 2441|    107|                        thunk->upValues = up_values;
 2442|    107|                    }
 2443|       |
 2444|       |                    // Cache these, because pop will invalidate them.
 2445|  10.6M|                    std::vector<HeapThunk *> thunks_copy = f.thunks;
 2446|       |
 2447|  10.6M|                    const AST *f_ast = f.ast;
 2448|  10.6M|                    stack.pop();
 2449|       |
 2450|  10.6M|                    if (func->isBuiltin()) {
  ------------------
  |  Branch (2450:25): [True: 8.33M, False: 2.33M]
  ------------------
 2451|       |                        // Built-in function.
 2452|       |                        // Give nullptr for self because no one looking at this frame will
 2453|       |                        // attempt to bind to self (it's native code).
 2454|  8.33M|                        stack.newFrame(FRAME_BUILTIN_FORCE_THUNKS, f_ast);
 2455|  8.33M|                        assert(func->upValues.empty());
  ------------------
  |  Branch (2455:25): [True: 8.33M, False: 0]
  ------------------
 2456|  8.33M|                        stack.top().bindings = up_values;
 2457|  8.33M|                        stack.top().thunks = thunks_copy;
 2458|  8.33M|                        stack.top().val = scratch;
 2459|  8.33M|                        goto replaceframe;
 2460|  8.33M|                    } else {
 2461|       |                        // User defined function.
 2462|  2.33M|                        stack.newCall(ast.location, func, func->self, func->offset, up_values);
 2463|  2.33M|                        if (ast.tailstrict) {
  ------------------
  |  Branch (2463:29): [True: 1.52M, False: 804k]
  ------------------
 2464|  1.52M|                            stack.top().tailCall = true;
 2465|  1.52M|                            if (thunks_copy.size() == 0) {
  ------------------
  |  Branch (2465:33): [True: 0, False: 1.52M]
  ------------------
 2466|       |                                // No need to force thunks, proceed straight to body.
 2467|      0|                                ast_ = func->body;
 2468|      0|                                goto recurse;
 2469|  1.52M|                            } else {
 2470|       |                                // The check for args.size() > 0
 2471|  1.52M|                                stack.top().thunks = thunks_copy;
 2472|  1.52M|                                stack.top().val = scratch;
 2473|  1.52M|                                goto replaceframe;
 2474|  1.52M|                            }
 2475|  1.52M|                        } else {
 2476|   804k|                            ast_ = func->body;
 2477|   804k|                            goto recurse;
 2478|   804k|                        }
 2479|  2.33M|                    }
 2480|  10.6M|                } break;
 2481|       |
 2482|  4.80M|                case FRAME_BINARY_LEFT: {
  ------------------
  |  Branch (2482:17): [True: 4.80M, False: 135M]
  ------------------
 2483|  4.80M|                    const auto &ast = *static_cast<const Binary *>(f.ast);
 2484|  4.80M|                    const Value &lhs = scratch;
 2485|  4.80M|                    if (lhs.t == Value::BOOLEAN) {
  ------------------
  |  Branch (2485:25): [True: 177k, False: 4.63M]
  ------------------
 2486|       |                        // Handle short-cut semantics
 2487|   177k|                        switch (ast.op) {
 2488|  63.3k|                            case BOP_AND: {
  ------------------
  |  Branch (2488:29): [True: 63.3k, False: 114k]
  ------------------
 2489|  63.3k|                                if (!lhs.v.b) {
  ------------------
  |  Branch (2489:37): [True: 11.4k, False: 51.9k]
  ------------------
 2490|  11.4k|                                    scratch = makeBoolean(false);
 2491|  11.4k|                                    goto popframe;
 2492|  11.4k|                                }
 2493|  63.3k|                            } break;
 2494|       |
 2495|   112k|                            case BOP_OR: {
  ------------------
  |  Branch (2495:29): [True: 112k, False: 65.8k]
  ------------------
 2496|   112k|                                if (lhs.v.b) {
  ------------------
  |  Branch (2496:37): [True: 5.08k, False: 107k]
  ------------------
 2497|  5.08k|                                    scratch = makeBoolean(true);
 2498|  5.08k|                                    goto popframe;
 2499|  5.08k|                                }
 2500|   112k|                            } break;
 2501|       |
 2502|   107k|                            default:;
  ------------------
  |  Branch (2502:29): [True: 2.48k, False: 175k]
  ------------------
 2503|   177k|                        }
 2504|   177k|                    }
 2505|  4.79M|                    stack.top().kind = FRAME_BINARY_RIGHT;
 2506|  4.79M|                    stack.top().val = lhs;
 2507|  4.79M|                    ast_ = ast.right;
 2508|  4.79M|                    goto recurse;
 2509|  4.80M|                } break;
 2510|       |
 2511|  4.78M|                case FRAME_BINARY_RIGHT: {
  ------------------
  |  Branch (2511:17): [True: 4.78M, False: 135M]
  ------------------
 2512|  4.78M|                    stack.top().val2 = scratch;
 2513|  4.78M|                    stack.top().kind = FRAME_BINARY_OP;
 2514|  4.78M|                }
 2515|  4.78M|                [[fallthrough]];
 2516|  4.78M|                case FRAME_BINARY_OP: {
  ------------------
  |  Branch (2516:17): [True: 307, False: 139M]
  ------------------
 2517|  4.78M|                    const auto &ast = *static_cast<const Binary *>(f.ast);
 2518|  4.78M|                    const Value &lhs = stack.top().val;
 2519|  4.78M|                    const Value &rhs = stack.top().val2;
 2520|       |
 2521|       |                    // Handle cases where the LHS and RHS are not the same type.
 2522|  4.78M|                    if (lhs.t == Value::STRING || rhs.t == Value::STRING) {
  ------------------
  |  Branch (2522:25): [True: 1.42M, False: 3.36M]
  |  Branch (2522:51): [True: 16.3k, False: 3.34M]
  ------------------
 2523|  1.43M|                        if (ast.op == BOP_PLUS) {
  ------------------
  |  Branch (2523:29): [True: 1.38M, False: 56.0k]
  ------------------
 2524|       |                            // Handle co-ercions for string processing.
 2525|  1.38M|                            stack.top().kind = FRAME_STRING_CONCAT;
 2526|  1.38M|                            stack.top().val2 = rhs;
 2527|  1.38M|                            goto replaceframe;
 2528|  1.38M|                        }
 2529|  1.43M|                    }
 2530|  3.40M|                    switch (ast.op) {
 2531|       |                        // Equality can be used when the types don't match.
 2532|      0|                        case BOP_MANIFEST_EQUAL:
  ------------------
  |  Branch (2532:25): [True: 0, False: 3.40M]
  ------------------
 2533|      0|                            std::cerr << "INTERNAL ERROR: Equals not desugared" << std::endl;
 2534|      0|                            abort();
 2535|       |
 2536|       |                        // Equality can be used when the types don't match.
 2537|      0|                        case BOP_MANIFEST_UNEQUAL:
  ------------------
  |  Branch (2537:25): [True: 0, False: 3.40M]
  ------------------
 2538|      0|                            std::cerr << "INTERNAL ERROR: Notequals not desugared" << std::endl;
 2539|      0|                            abort();
 2540|       |
 2541|       |                        // e in e
 2542|    413|                        case BOP_IN: {
  ------------------
  |  Branch (2542:25): [True: 413, False: 3.40M]
  ------------------
 2543|    413|                            if (lhs.t != Value::STRING) {
  ------------------
  |  Branch (2543:33): [True: 4, False: 409]
  ------------------
 2544|      4|                                throw makeError(ast.location,
 2545|      4|                                                "the left hand side of the 'in' operator should be "
 2546|      4|                                                "a string,  got " +
 2547|      4|                                                    type_str(lhs));
 2548|      4|                            }
 2549|    409|                            auto *field = static_cast<HeapString *>(lhs.v.h);
 2550|    409|                            switch (rhs.t) {
 2551|    407|                                case Value::OBJECT: {
  ------------------
  |  Branch (2551:33): [True: 407, False: 2]
  ------------------
 2552|    407|                                    auto *obj = static_cast<HeapObject *>(rhs.v.h);
 2553|    407|                                    auto *fid = alloc->makeIdentifier(field->value);
 2554|    407|                                    unsigned unused_found_at = 0;
 2555|    407|                                    bool in = findObject(fid, obj, 0, unused_found_at);
 2556|    407|                                    scratch = makeBoolean(in);
 2557|    407|                                } break;
 2558|       |
 2559|      2|                                default:
  ------------------
  |  Branch (2559:33): [True: 2, False: 407]
  ------------------
 2560|      2|                                    throw makeError(
 2561|      2|                                        ast.location,
 2562|      2|                                        "the right hand side of the 'in' operator should be"
 2563|      2|                                        " an object, got " +
 2564|      2|                                            type_str(rhs));
 2565|    409|                            }
 2566|    407|                            goto popframe;
 2567|    409|                        }
 2568|       |
 2569|  3.40M|                        default:;
  ------------------
  |  Branch (2569:25): [True: 3.40M, False: 413]
  ------------------
 2570|  3.40M|                    }
 2571|       |                    // Everything else requires matching types.
 2572|  3.40M|                    if (lhs.t != rhs.t) {
  ------------------
  |  Branch (2572:25): [True: 98, False: 3.40M]
  ------------------
 2573|     98|                        throw makeError(ast.location,
 2574|     98|                                        "binary operator " + bop_string(ast.op) +
 2575|     98|                                            " requires "
 2576|     98|                                            "matching types, got " +
 2577|     98|                                            type_str(lhs) + " and " + type_str(rhs) + ".");
 2578|     98|                    }
 2579|  3.40M|                    switch (lhs.t) {
  ------------------
  |  Branch (2579:29): [True: 3.40M, False: 0]
  ------------------
 2580|   651k|                        case Value::ARRAY:
  ------------------
  |  Branch (2580:25): [True: 651k, False: 2.75M]
  ------------------
 2581|   651k|                            if (ast.op == BOP_PLUS) {
  ------------------
  |  Branch (2581:33): [True: 619k, False: 32.7k]
  ------------------
 2582|   619k|                                auto *arr_l = static_cast<HeapArray *>(lhs.v.h);
 2583|   619k|                                auto *arr_r = static_cast<HeapArray *>(rhs.v.h);
 2584|   619k|                                std::vector<HeapThunk *> elements;
 2585|   619k|                                for (auto *el : arr_l->elements)
  ------------------
  |  Branch (2585:47): [True: 60.3M, False: 619k]
  ------------------
 2586|  60.3M|                                    elements.push_back(el);
 2587|   619k|                                for (auto *el : arr_r->elements)
  ------------------
  |  Branch (2587:47): [True: 1.65M, False: 619k]
  ------------------
 2588|  1.65M|                                    elements.push_back(el);
 2589|   619k|                                scratch = makeArray(elements);
 2590|   619k|                            } else if (ast.op == BOP_LESS || ast.op == BOP_LESS_EQ || ast.op == BOP_GREATER || ast.op == BOP_GREATER_EQ) {
  ------------------
  |  Branch (2590:40): [True: 8.23k, False: 24.5k]
  |  Branch (2590:62): [True: 18.9k, False: 5.62k]
  |  Branch (2590:87): [True: 2.01k, False: 3.61k]
  |  Branch (2590:112): [True: 3.61k, False: 7]
  ------------------
 2591|  32.7k|                                HeapThunk *func;
 2592|  32.7k|                                switch(ast.op) {
 2593|  8.23k|                                case BOP_LESS:
  ------------------
  |  Branch (2593:33): [True: 8.23k, False: 24.5k]
  ------------------
 2594|  8.23k|                                    func = sourceVals["__array_less"];
 2595|  8.23k|                                    break;
 2596|  18.9k|                                case BOP_LESS_EQ:
  ------------------
  |  Branch (2596:33): [True: 18.9k, False: 13.8k]
  ------------------
 2597|  18.9k|                                    func = sourceVals["__array_less_or_equal"];
 2598|  18.9k|                                    break;
 2599|  2.01k|                                case BOP_GREATER:
  ------------------
  |  Branch (2599:33): [True: 2.01k, False: 30.7k]
  ------------------
 2600|  2.01k|                                    func = sourceVals["__array_greater"];
 2601|  2.01k|                                    break;
 2602|  3.61k|                                case BOP_GREATER_EQ:
  ------------------
  |  Branch (2602:33): [True: 3.61k, False: 29.1k]
  ------------------
 2603|  3.61k|                                    func = sourceVals["__array_greater_or_equal"];
 2604|  3.61k|                                    break;
 2605|      0|                                default:
  ------------------
  |  Branch (2605:33): [True: 0, False: 32.7k]
  ------------------
 2606|      0|                                    JSONNET_UNREACHABLE();
  ------------------
  |  |   53|      0|  do {                                                             \
  |  |   54|      0|    std::cerr << __FILE__ << ":" << __LINE__                       \
  |  |   55|      0|              << ": INTERNAL ERROR: reached unreachable code path" \
  |  |   56|      0|              << std::endl;                                        \
  |  |   57|      0|    abort();                                                       \
  |  |   58|      0|  } while (0)
  |  |  ------------------
  |  |  |  Branch (58:12): [Folded, False: 0]
  |  |  ------------------
  ------------------
 2607|  32.7k|                                }
 2608|  32.7k|                                if (!func->filled) {
  ------------------
  |  Branch (2608:37): [True: 307, False: 32.4k]
  ------------------
 2609|    307|                                    stack.newCall(ast.location, func, func->self, func->offset, func->upValues);
 2610|    307|                                    ast_ = func->body;
 2611|    307|                                    goto recurse;
 2612|    307|                                }
 2613|  32.4k|                                auto *lhs_th = makeHeap<HeapThunk>(idInternal, f.self, f.offset, ast.left);
 2614|  32.4k|                                lhs_th->fill(lhs);
 2615|  32.4k|                                f.thunks.push_back(lhs_th);
 2616|  32.4k|                                auto *rhs_th = makeHeap<HeapThunk>(idInternal, f.self, f.offset, ast.right);
 2617|  32.4k|                                rhs_th->fill(rhs);
 2618|  32.4k|                                f.thunks.push_back(rhs_th);
 2619|  32.4k|                                const AST *orig_ast = ast_;
 2620|  32.4k|                                stack.pop();
 2621|  32.4k|                                ast_ = callSourceVal(orig_ast, func, {lhs_th, rhs_th});
 2622|  32.4k|                                goto recurse;
 2623|  32.7k|                            } else {
 2624|      7|                                throw makeError(ast.location,
 2625|      7|                                                "binary operator " + bop_string(ast.op) +
 2626|      7|                                                    " does not operate on arrays.");
 2627|      7|                            }
 2628|   619k|                            break;
 2629|       |
 2630|   619k|                        case Value::BOOLEAN:
  ------------------
  |  Branch (2630:25): [True: 158k, False: 3.24M]
  ------------------
 2631|   158k|                            switch (ast.op) {
 2632|  51.7k|                                case BOP_AND: scratch = makeBoolean(lhs.v.b && rhs.v.b); break;
  ------------------
  |  Branch (2632:33): [True: 51.7k, False: 107k]
  |  Branch (2632:69): [True: 51.7k, False: 0]
  |  Branch (2632:80): [True: 44.3k, False: 7.42k]
  ------------------
 2633|       |
 2634|   107k|                                case BOP_OR: scratch = makeBoolean(lhs.v.b || rhs.v.b); break;
  ------------------
  |  Branch (2634:33): [True: 107k, False: 51.7k]
  |  Branch (2634:68): [True: 0, False: 107k]
  |  Branch (2634:79): [True: 4.26k, False: 102k]
  ------------------
 2635|       |
 2636|     29|                                default:
  ------------------
  |  Branch (2636:33): [True: 29, False: 158k]
  ------------------
 2637|     29|                                    throw makeError(ast.location,
 2638|     29|                                                    "binary operator " + bop_string(ast.op) +
 2639|     29|                                                        " does not operate on booleans.");
 2640|   158k|                            }
 2641|   158k|                            break;
 2642|       |
 2643|  1.05M|                        case Value::NUMBER:
  ------------------
  |  Branch (2643:25): [True: 1.05M, False: 2.34M]
  ------------------
 2644|  1.05M|                            switch (ast.op) {
 2645|   291k|                                case BOP_PLUS:
  ------------------
  |  Branch (2645:33): [True: 291k, False: 766k]
  ------------------
 2646|   291k|                                    scratch = makeNumberCheck(ast.location, lhs.v.d + rhs.v.d);
 2647|   291k|                                    break;
 2648|       |
 2649|  45.4k|                                case BOP_MINUS:
  ------------------
  |  Branch (2649:33): [True: 45.4k, False: 1.01M]
  ------------------
 2650|  45.4k|                                    scratch = makeNumberCheck(ast.location, lhs.v.d - rhs.v.d);
 2651|  45.4k|                                    break;
 2652|       |
 2653|  7.85k|                                case BOP_MULT:
  ------------------
  |  Branch (2653:33): [True: 7.85k, False: 1.04M]
  ------------------
 2654|  7.85k|                                    scratch = makeNumberCheck(ast.location, lhs.v.d * rhs.v.d);
 2655|  7.85k|                                    break;
 2656|       |
 2657|  68.3k|                                case BOP_DIV:
  ------------------
  |  Branch (2657:33): [True: 68.3k, False: 989k]
  ------------------
 2658|  68.3k|                                    if (rhs.v.d == 0)
  ------------------
  |  Branch (2658:41): [True: 1, False: 68.3k]
  ------------------
 2659|      1|                                        throw makeError(ast.location, "division by zero.");
 2660|  68.3k|                                    scratch = makeNumberCheck(ast.location, lhs.v.d / rhs.v.d);
 2661|  68.3k|                                    break;
 2662|       |
 2663|       |                                    // No need to check doubles made from longs
 2664|       |
 2665|    533|                                case BOP_SHIFT_L: {
  ------------------
  |  Branch (2665:33): [True: 533, False: 1.05M]
  ------------------
 2666|    533|                                    if (rhs.v.d < 0)
  ------------------
  |  Branch (2666:41): [True: 1, False: 532]
  ------------------
 2667|      1|                                        throw makeError(ast.location, "shift by negative exponent.");
 2668|       |
 2669|    532|                                    int64_t long_l = safeDoubleToInt64(lhs.v.d, ast.location);
 2670|    532|                                    int64_t long_r = safeDoubleToInt64(rhs.v.d, ast.location);
 2671|    532|                                    long_r = long_r % 64;
 2672|       |
 2673|       |                                    // Additional safety check for left shifts to prevent undefined behavior.
 2674|       |                                    // Left-shift that would move the highest set bit into the sign bit position is undefined.
 2675|    532|                                    if (long_r >= 1 && abs(long_l) >= (1LL << (63 - long_r))) {
  ------------------
  |  Branch (2675:41): [True: 342, False: 190]
  |  Branch (2675:56): [True: 51, False: 291]
  ------------------
 2676|     51|                                        throw makeError(ast.location,
 2677|     51|                                            "numeric value outside safe integer range for bitwise operation.");
 2678|     51|                                    }
 2679|       |
 2680|       |                                    // Left-shift of a negative number is undefined until C++20.
 2681|       |                                    // Perform the shift on unsigned int to avoid that.
 2682|    481|                                    scratch = makeNumber(static_cast<int64_t>(static_cast<uint64_t>(long_l) << long_r));
 2683|    481|                                } break;
 2684|       |
 2685|     37|                                case BOP_SHIFT_R: {
  ------------------
  |  Branch (2685:33): [True: 37, False: 1.05M]
  ------------------
 2686|     37|                                    if (rhs.v.d < 0)
  ------------------
  |  Branch (2686:41): [True: 1, False: 36]
  ------------------
 2687|      1|                                        throw makeError(ast.location, "shift by negative exponent.");
 2688|       |
 2689|     36|                                    int64_t long_l = safeDoubleToInt64(lhs.v.d, ast.location);
 2690|     36|                                    int64_t long_r = safeDoubleToInt64(rhs.v.d, ast.location);
 2691|     36|                                    long_r = long_r % 64;
 2692|     36|                                    scratch = makeNumber(long_l >> long_r);
 2693|     36|                                } break;
 2694|       |
 2695|  15.7k|                                case BOP_BITWISE_AND: {
  ------------------
  |  Branch (2695:33): [True: 15.7k, False: 1.04M]
  ------------------
 2696|  15.7k|                                    int64_t long_l = safeDoubleToInt64(lhs.v.d, ast.location);
 2697|  15.7k|                                    int64_t long_r = safeDoubleToInt64(rhs.v.d, ast.location);
 2698|  15.7k|                                    scratch = makeNumber(long_l & long_r);
 2699|  15.7k|                                } break;
 2700|       |
 2701|  12.4k|                                case BOP_BITWISE_XOR: {
  ------------------
  |  Branch (2701:33): [True: 12.4k, False: 1.04M]
  ------------------
 2702|  12.4k|                                    int64_t long_l = safeDoubleToInt64(lhs.v.d, ast.location);
 2703|  12.4k|                                    int64_t long_r = safeDoubleToInt64(rhs.v.d, ast.location);
 2704|  12.4k|                                    scratch = makeNumber(long_l ^ long_r);
 2705|  12.4k|                                } break;
 2706|       |
 2707|  6.72k|                                case BOP_BITWISE_OR: {
  ------------------
  |  Branch (2707:33): [True: 6.72k, False: 1.05M]
  ------------------
 2708|  6.72k|                                    int64_t long_l = safeDoubleToInt64(lhs.v.d, ast.location);
 2709|  6.72k|                                    int64_t long_r = safeDoubleToInt64(rhs.v.d, ast.location);
 2710|  6.72k|                                    scratch = makeNumber(long_l | long_r);
 2711|  6.72k|                                } break;
 2712|       |
 2713|  45.5k|                                case BOP_LESS_EQ: scratch = makeBoolean(lhs.v.d <= rhs.v.d); break;
  ------------------
  |  Branch (2713:33): [True: 45.5k, False: 1.01M]
  ------------------
 2714|       |
 2715|   365k|                                case BOP_GREATER_EQ:
  ------------------
  |  Branch (2715:33): [True: 365k, False: 691k]
  ------------------
 2716|   365k|                                    scratch = makeBoolean(lhs.v.d >= rhs.v.d);
 2717|   365k|                                    break;
 2718|       |
 2719|   177k|                                case BOP_LESS: scratch = makeBoolean(lhs.v.d < rhs.v.d); break;
  ------------------
  |  Branch (2719:33): [True: 177k, False: 880k]
  ------------------
 2720|       |
 2721|  21.0k|                                case BOP_GREATER: scratch = makeBoolean(lhs.v.d > rhs.v.d); break;
  ------------------
  |  Branch (2721:33): [True: 21.0k, False: 1.03M]
  ------------------
 2722|       |
 2723|      8|                                default:
  ------------------
  |  Branch (2723:33): [True: 8, False: 1.05M]
  ------------------
 2724|      8|                                    throw makeError(ast.location,
 2725|      8|                                                    "binary operator " + bop_string(ast.op) +
 2726|      8|                                                        " does not operate on numbers.");
 2727|  1.05M|                            }
 2728|  1.05M|                            break;
 2729|       |
 2730|  1.05M|                        case Value::FUNCTION:
  ------------------
  |  Branch (2730:25): [True: 2, False: 3.40M]
  ------------------
 2731|      2|                            throw makeError(ast.location,
 2732|      2|                                            "binary operator " + bop_string(ast.op) +
 2733|      2|                                                " does not operate on functions.");
 2734|       |
 2735|      1|                        case Value::NULL_TYPE:
  ------------------
  |  Branch (2735:25): [True: 1, False: 3.40M]
  ------------------
 2736|      1|                            throw makeError(ast.location,
 2737|      1|                                            "binary operator " + bop_string(ast.op) +
 2738|      1|                                                " does not operate on null.");
 2739|       |
 2740|  1.47M|                        case Value::OBJECT: {
  ------------------
  |  Branch (2740:25): [True: 1.47M, False: 1.92M]
  ------------------
 2741|  1.47M|                            if (ast.op != BOP_PLUS) {
  ------------------
  |  Branch (2741:33): [True: 4, False: 1.47M]
  ------------------
 2742|      4|                                throw makeError(ast.location,
 2743|      4|                                                "binary operator " + bop_string(ast.op) +
 2744|      4|                                                    " does not operate on objects.");
 2745|      4|                            }
 2746|  1.47M|                            auto *lhs_obj = static_cast<HeapObject *>(lhs.v.h);
 2747|  1.47M|                            auto *rhs_obj = static_cast<HeapObject *>(rhs.v.h);
 2748|  1.47M|                            scratch = makeObject<HeapExtendedObject>(lhs_obj, rhs_obj);
 2749|  1.47M|                        } break;
 2750|       |
 2751|  55.5k|                        case Value::STRING: {
  ------------------
  |  Branch (2751:25): [True: 55.5k, False: 3.34M]
  ------------------
 2752|  55.5k|                            const UString &lhs_str = static_cast<HeapString *>(lhs.v.h)->value;
 2753|  55.5k|                            const UString &rhs_str = static_cast<HeapString *>(rhs.v.h)->value;
 2754|  55.5k|                            switch (ast.op) {
 2755|      0|                                case BOP_PLUS: scratch = makeString(lhs_str + rhs_str); break;
  ------------------
  |  Branch (2755:33): [True: 0, False: 55.5k]
  ------------------
 2756|       |
 2757|  12.2k|                                case BOP_LESS_EQ: scratch = makeBoolean(lhs_str <= rhs_str); break;
  ------------------
  |  Branch (2757:33): [True: 12.2k, False: 43.3k]
  ------------------
 2758|       |
 2759|  34.6k|                                case BOP_GREATER_EQ:
  ------------------
  |  Branch (2759:33): [True: 34.6k, False: 20.9k]
  ------------------
 2760|  34.6k|                                    scratch = makeBoolean(lhs_str >= rhs_str);
 2761|  34.6k|                                    break;
 2762|       |
 2763|  3.18k|                                case BOP_LESS: scratch = makeBoolean(lhs_str < rhs_str); break;
  ------------------
  |  Branch (2763:33): [True: 3.18k, False: 52.4k]
  ------------------
 2764|       |
 2765|  5.47k|                                case BOP_GREATER: scratch = makeBoolean(lhs_str > rhs_str); break;
  ------------------
  |  Branch (2765:33): [True: 5.47k, False: 50.1k]
  ------------------
 2766|       |
 2767|     30|                                default:
  ------------------
  |  Branch (2767:33): [True: 30, False: 55.5k]
  ------------------
 2768|     30|                                    throw makeError(ast.location,
 2769|     30|                                                    "binary operator " + bop_string(ast.op) +
 2770|     30|                                                        " does not operate on strings.");
 2771|  55.5k|                            }
 2772|  55.5k|                        } break;
 2773|  3.40M|                    }
 2774|  3.40M|                } break;
 2775|       |
 2776|  3.36M|                case FRAME_BUILTIN_FILTER: {
  ------------------
  |  Branch (2776:17): [True: 0, False: 139M]
  ------------------
 2777|      0|                    const auto &ast = *static_cast<const Apply *>(f.ast);
 2778|      0|                    auto *func = static_cast<HeapClosure *>(f.val.v.h);
 2779|      0|                    auto *arr = static_cast<HeapArray *>(f.val2.v.h);
 2780|      0|                    if (scratch.t != Value::BOOLEAN) {
  ------------------
  |  Branch (2780:25): [True: 0, False: 0]
  ------------------
 2781|      0|                        throw makeError(
 2782|      0|                            ast.location,
 2783|      0|                            "filter function must return boolean, got: " + type_str(scratch));
 2784|      0|                    }
 2785|      0|                    if (scratch.v.b)
  ------------------
  |  Branch (2785:25): [True: 0, False: 0]
  ------------------
 2786|      0|                        f.thunks.push_back(arr->elements[f.elementId]);
 2787|      0|                    f.elementId++;
 2788|       |                    // Iterate through arr, calling the function on each.
 2789|      0|                    if (f.elementId == arr->elements.size()) {
  ------------------
  |  Branch (2789:25): [True: 0, False: 0]
  ------------------
 2790|      0|                        scratch = makeArray(f.thunks);
 2791|      0|                    } else {
 2792|      0|                        auto *thunk = arr->elements[f.elementId];
 2793|      0|                        BindingFrame bindings = func->upValues;
 2794|      0|                        bindings[func->params[0].id] = thunk;
 2795|      0|                        stack.newCall(ast.location, func, func->self, func->offset, bindings);
 2796|      0|                        ast_ = func->body;
 2797|      0|                        goto recurse;
 2798|      0|                    }
 2799|      0|                } break;
 2800|       |
 2801|  21.5M|                case FRAME_BUILTIN_FORCE_THUNKS: {
  ------------------
  |  Branch (2801:17): [True: 21.5M, False: 118M]
  ------------------
 2802|  21.5M|                    const auto &location = f.location;
 2803|  21.5M|                    auto *func = static_cast<HeapClosure *>(f.val.v.h);
 2804|  21.5M|                    if (f.elementId == f.thunks.size()) {
  ------------------
  |  Branch (2804:25): [True: 8.32M, False: 13.1M]
  ------------------
 2805|       |                        // All thunks forced, now the builtin implementations.
 2806|  8.32M|                        const std::string &builtin_name = func->builtinName;
 2807|  8.32M|                        std::vector<Value> args;
 2808|  13.1M|                        for (const auto &p : func->params) {
  ------------------
  |  Branch (2808:44): [True: 13.1M, False: 8.32M]
  ------------------
 2809|  13.1M|                            const auto it = f.bindings.find(p.id);
 2810|  13.1M|                            if (it != f.bindings.end()) {
  ------------------
  |  Branch (2810:33): [True: 13.1M, False: 0]
  ------------------
 2811|  13.1M|                                assert(it->second->filled);
  ------------------
  |  Branch (2811:33): [True: 13.1M, False: 0]
  ------------------
 2812|  13.1M|                                args.push_back(it->second->content);
 2813|  13.1M|                            } else {
 2814|      0|                                std::stringstream ss;
 2815|      0|                                ss << "function parameter " << encode_utf8(p.id->name)
 2816|      0|                                    << " not bound in call.";
 2817|      0|                                throw makeError(location, ss.str());
 2818|      0|                            }
 2819|  13.1M|                        }
 2820|       |
 2821|  8.32M|                        BuiltinMap::const_iterator bit = builtins.find(builtin_name);
 2822|  8.32M|                        if (bit != builtins.end()) {
  ------------------
  |  Branch (2822:29): [True: 8.32M, False: 0]
  ------------------
 2823|  8.32M|                            const AST *new_ast = (this->*bit->second)(location, args);
 2824|  8.32M|                            if (new_ast != nullptr) {
  ------------------
  |  Branch (2824:33): [True: 0, False: 8.32M]
  ------------------
 2825|      0|                                ast_ = new_ast;
 2826|      0|                                goto recurse;
 2827|      0|                            }
 2828|  8.32M|                            break;
 2829|  8.32M|                        }
 2830|      0|                        VmNativeCallbackMap::const_iterator nit =
 2831|      0|                            nativeCallbacks.find(builtin_name);
 2832|       |                        // TODO(dcunnin): Support arrays.
 2833|       |                        // TODO(dcunnin): Support objects.
 2834|      0|                        std::vector<JsonnetJsonValue> args2;
 2835|      0|                        for (const Value &arg : args) {
  ------------------
  |  Branch (2835:47): [True: 0, False: 0]
  ------------------
 2836|      0|                            switch (arg.t) {
 2837|      0|                                case Value::STRING:
  ------------------
  |  Branch (2837:33): [True: 0, False: 0]
  ------------------
 2838|      0|                                    args2.emplace_back(
 2839|      0|                                        JsonnetJsonValue::STRING,
 2840|      0|                                        encode_utf8(static_cast<HeapString *>(arg.v.h)->value),
 2841|      0|                                        0);
 2842|      0|                                    break;
 2843|       |
 2844|      0|                                case Value::BOOLEAN:
  ------------------
  |  Branch (2844:33): [True: 0, False: 0]
  ------------------
 2845|      0|                                    args2.emplace_back(
 2846|      0|                                        JsonnetJsonValue::BOOL, "", arg.v.b ? 1.0 : 0.0);
  ------------------
  |  Branch (2846:69): [True: 0, False: 0]
  ------------------
 2847|      0|                                    break;
 2848|       |
 2849|      0|                                case Value::NUMBER:
  ------------------
  |  Branch (2849:33): [True: 0, False: 0]
  ------------------
 2850|      0|                                    args2.emplace_back(JsonnetJsonValue::NUMBER, "", arg.v.d);
 2851|      0|                                    break;
 2852|       |
 2853|      0|                                case Value::NULL_TYPE:
  ------------------
  |  Branch (2853:33): [True: 0, False: 0]
  ------------------
 2854|      0|                                    args2.emplace_back(JsonnetJsonValue::NULL_KIND, "", 0);
 2855|      0|                                    break;
 2856|       |
 2857|      0|                                default:
  ------------------
  |  Branch (2857:33): [True: 0, False: 0]
  ------------------
 2858|      0|                                    throw makeError(location,
 2859|      0|                                                    "native extensions can only take primitives.");
 2860|      0|                            }
 2861|      0|                        }
 2862|      0|                        std::vector<const JsonnetJsonValue *> args3;
 2863|      0|                        for (size_t i = 0; i < args2.size(); ++i) {
  ------------------
  |  Branch (2863:44): [True: 0, False: 0]
  ------------------
 2864|      0|                            args3.push_back(&args2[i]);
 2865|      0|                        }
 2866|      0|                        if (nit == nativeCallbacks.end()) {
  ------------------
  |  Branch (2866:29): [True: 0, False: 0]
  ------------------
 2867|      0|                            throw makeError(location,
 2868|      0|                                            "unrecognized builtin name: " + builtin_name);
 2869|      0|                        }
 2870|      0|                        const VmNativeCallback &cb = nit->second;
 2871|       |
 2872|      0|                        int succ;
 2873|      0|                        std::unique_ptr<JsonnetJsonValue> r(cb.cb(cb.ctx, args3.data(), &succ));
 2874|       |
 2875|      0|                        if (succ) {
  ------------------
  |  Branch (2875:29): [True: 0, False: 0]
  ------------------
 2876|      0|                            bool unused;
 2877|      0|                            jsonToHeap(r, unused, scratch);
 2878|      0|                        } else {
 2879|      0|                            if (r->kind != JsonnetJsonValue::STRING) {
  ------------------
  |  Branch (2879:33): [True: 0, False: 0]
  ------------------
 2880|      0|                                throw makeError(
 2881|      0|                                    location,
 2882|      0|                                    "native extension returned an error that was not a string.");
 2883|      0|                            }
 2884|      0|                            std::string rs = r->string;
 2885|      0|                            throw makeError(location, rs);
 2886|      0|                        }
 2887|       |
 2888|  13.1M|                    } else {
 2889|       |                        // Not all arguments forced yet.
 2890|  13.1M|                        HeapThunk *th = f.thunks[f.elementId++];
 2891|  13.1M|                        if (!th->filled) {
  ------------------
  |  Branch (2891:29): [True: 13.1M, False: 0]
  ------------------
 2892|  13.1M|                            stack.newCall(location, th, th->self, th->offset, th->upValues);
 2893|  13.1M|                            ast_ = th->body;
 2894|  13.1M|                            goto recurse;
 2895|  13.1M|                        } else {
 2896|       |                            // Otherwise loop back around to force the next thunk.
 2897|      0|                            goto replaceframe;
 2898|      0|                        }
 2899|  13.1M|                    }
 2900|  21.5M|                } break;
 2901|       |
 2902|  43.1M|                case FRAME_CALL: {
  ------------------
  |  Branch (2902:17): [True: 43.1M, False: 96.8M]
  ------------------
 2903|  43.1M|                    if (auto *thunk = dynamic_cast<HeapThunk *>(f.context)) {
  ------------------
  |  Branch (2903:31): [True: 23.5M, False: 19.6M]
  ------------------
 2904|       |                        // If we called a thunk, cache result.
 2905|  23.5M|                        thunk->fill(scratch);
 2906|  23.5M|                    } else if (auto *closure = dynamic_cast<HeapClosure *>(f.context)) {
  ------------------
  |  Branch (2906:38): [True: 7.01M, False: 12.5M]
  ------------------
 2907|  7.01M|                        if (f.elementId < f.thunks.size()) {
  ------------------
  |  Branch (2907:29): [True: 3.51M, False: 3.50M]
  ------------------
 2908|       |                            // If tailstrict, force thunks
 2909|  3.51M|                            HeapThunk *th = f.thunks[f.elementId++];
 2910|  3.51M|                            if (!th->filled) {
  ------------------
  |  Branch (2910:33): [True: 3.51M, False: 0]
  ------------------
 2911|  3.51M|                                stack.newCall(f.location, th, th->self, th->offset, th->upValues);
 2912|  3.51M|                                ast_ = th->body;
 2913|  3.51M|                                goto recurse;
 2914|  3.51M|                            }
 2915|  3.51M|                        } else if (f.thunks.size() == 0) {
  ------------------
  |  Branch (2915:36): [True: 1.99M, False: 1.51M]
  ------------------
 2916|       |                            // Body has now been executed
 2917|  1.99M|                        } else {
 2918|       |                            // Execute the body
 2919|  1.51M|                            f.thunks.clear();
 2920|  1.51M|                            f.elementId = 0;
 2921|  1.51M|                            ast_ = closure->body;
 2922|  1.51M|                            goto recurse;
 2923|  1.51M|                        }
 2924|  7.01M|                    }
 2925|       |                    // Result of call is in scratch, just pop.
 2926|  43.1M|                } break;
 2927|       |
 2928|  38.1M|                case FRAME_ERROR: {
  ------------------
  |  Branch (2928:17): [True: 3.20k, False: 139M]
  ------------------
 2929|  3.20k|                    const auto &ast = *static_cast<const Error *>(f.ast);
 2930|  3.20k|                    UString msg;
 2931|  3.20k|                    if (scratch.t == Value::STRING) {
  ------------------
  |  Branch (2931:25): [True: 462, False: 2.74k]
  ------------------
 2932|    462|                        msg = static_cast<HeapString *>(scratch.v.h)->value;
 2933|  2.74k|                    } else {
 2934|  2.74k|                        msg = toString(ast.location);
 2935|  2.74k|                    }
 2936|  3.20k|                    throw makeError(ast.location, encode_utf8(msg));
 2937|  43.1M|                } break;
 2938|       |
 2939|  7.67M|                case FRAME_IF: {
  ------------------
  |  Branch (2939:17): [True: 7.67M, False: 132M]
  ------------------
 2940|  7.67M|                    const auto &ast = *static_cast<const Conditional *>(f.ast);
 2941|  7.67M|                    if (scratch.t != Value::BOOLEAN) {
  ------------------
  |  Branch (2941:25): [True: 70, False: 7.67M]
  ------------------
 2942|     70|                        throw makeError(
 2943|     70|                            ast.location,
 2944|     70|                            "condition must be boolean, got " + type_str(scratch) + ".");
 2945|     70|                    }
 2946|  7.67M|                    ast_ = scratch.v.b ? ast.branchTrue : ast.branchFalse;
  ------------------
  |  Branch (2946:28): [True: 2.88M, False: 4.79M]
  ------------------
 2947|  7.67M|                    stack.pop();
 2948|  7.67M|                    goto recurse;
 2949|  7.67M|                } break;
 2950|       |
 2951|  2.23M|                case FRAME_SUPER_INDEX: {
  ------------------
  |  Branch (2951:17): [True: 2.23M, False: 137M]
  ------------------
 2952|  2.23M|                    const auto &ast = *static_cast<const SuperIndex *>(f.ast);
 2953|  2.23M|                    HeapObject *self;
 2954|  2.23M|                    unsigned offset;
 2955|  2.23M|                    stack.getSelfBinding(self, offset);
 2956|  2.23M|                    offset++;
 2957|  2.23M|                    if (offset >= countLeaves(self)) {
  ------------------
  |  Branch (2957:25): [True: 1, False: 2.23M]
  ------------------
 2958|      1|                        throw makeError(ast.location,
 2959|      1|                                        "attempt to use super when there is no super class.");
 2960|      1|                    }
 2961|  2.23M|                    if (scratch.t != Value::STRING) {
  ------------------
  |  Branch (2961:25): [True: 0, False: 2.23M]
  ------------------
 2962|      0|                        throw makeError(
 2963|      0|                            ast.location,
 2964|      0|                            "super index must be string, got " + type_str(scratch) + ".");
 2965|      0|                    }
 2966|       |
 2967|  2.23M|                    const UString &index_name = static_cast<HeapString *>(scratch.v.h)->value;
 2968|  2.23M|                    auto *fid = alloc->makeIdentifier(index_name);
 2969|  2.23M|                    stack.pop();
 2970|  2.23M|                    ast_ = objectIndex(ast.location, self, fid, offset);
 2971|  2.23M|                    goto recurse;
 2972|  2.23M|                } break;
 2973|       |
 2974|  2.45M|                case FRAME_IN_SUPER_ELEMENT: {
  ------------------
  |  Branch (2974:17): [True: 2.45M, False: 137M]
  ------------------
 2975|  2.45M|                    const auto &ast = *static_cast<const InSuper *>(f.ast);
 2976|  2.45M|                    HeapObject *self;
 2977|  2.45M|                    unsigned offset;
 2978|  2.45M|                    stack.getSelfBinding(self, offset);
 2979|  2.45M|                    offset++;
 2980|  2.45M|                    if (scratch.t != Value::STRING) {
  ------------------
  |  Branch (2980:25): [True: 2, False: 2.45M]
  ------------------
 2981|      2|                        throw makeError(ast.location,
 2982|      2|                                        "left hand side of e in super must be string, got " +
 2983|      2|                                            type_str(scratch) + ".");
 2984|      2|                    }
 2985|  2.45M|                    if (offset >= countLeaves(self)) {
  ------------------
  |  Branch (2985:25): [True: 162k, False: 2.29M]
  ------------------
 2986|       |                        // There is no super object.
 2987|   162k|                        scratch = makeBoolean(false);
 2988|  2.29M|                    } else {
 2989|  2.29M|                        const UString &element_name = static_cast<HeapString *>(scratch.v.h)->value;
 2990|  2.29M|                        auto *fid = alloc->makeIdentifier(element_name);
 2991|  2.29M|                        unsigned unused_found_at = 0;
 2992|  2.29M|                        bool in = findObject(fid, self, offset, unused_found_at);
 2993|  2.29M|                        scratch = makeBoolean(in);
 2994|  2.29M|                    }
 2995|  2.45M|                } break;
 2996|       |
 2997|  10.8M|                case FRAME_INDEX_INDEX: {
  ------------------
  |  Branch (2997:17): [True: 10.8M, False: 129M]
  ------------------
 2998|  10.8M|                    const auto &ast = *static_cast<const Index *>(f.ast);
 2999|  10.8M|                    const Value &target = f.val;
 3000|  10.8M|                    if (target.t == Value::ARRAY) {
  ------------------
  |  Branch (3000:25): [True: 162k, False: 10.6M]
  ------------------
 3001|   162k|                        const auto *array = static_cast<HeapArray *>(target.v.h);
 3002|   162k|                        if (scratch.t == Value::STRING) {
  ------------------
  |  Branch (3002:29): [True: 72, False: 162k]
  ------------------
 3003|     72|                            const UString &str = static_cast<HeapString *>(scratch.v.h)->value;
 3004|     72|                            throw makeError(
 3005|     72|                                ast.location,
 3006|     72|                                "attempted index an array with string \""
 3007|     72|                                + encode_utf8(jsonnet_string_escape(str, false)) + "\".");
 3008|     72|                        }
 3009|   162k|                        if (scratch.t != Value::NUMBER) {
  ------------------
  |  Branch (3009:29): [True: 7, False: 162k]
  ------------------
 3010|      7|                            throw makeError(
 3011|      7|                                ast.location,
 3012|      7|                                "array index must be number, got " + type_str(scratch) + ".");
 3013|      7|                        }
 3014|   162k|                        double index = ::floor(scratch.v.d);
 3015|   162k|                        long sz = array->elements.size();
 3016|   162k|                        if (index < 0 || index >= sz) {
  ------------------
  |  Branch (3016:29): [True: 1, False: 162k]
  |  Branch (3016:42): [True: 10, False: 162k]
  ------------------
 3017|     11|                            std::stringstream ss;
 3018|     11|                            ss << "array bounds error: " << index << " not within [0, " << sz
 3019|     11|                               << ")";
 3020|     11|                            throw makeError(ast.location, ss.str());
 3021|     11|                        }
 3022|   162k|                        if (scratch.v.d != index) {
  ------------------
  |  Branch (3022:29): [True: 1, False: 162k]
  ------------------
 3023|      1|                            std::stringstream ss;
 3024|      1|                            ss << "array index was not integer: " << scratch.v.d;
 3025|      1|                            throw makeError(ast.location, ss.str());
 3026|      1|                        }
 3027|       |                        // index < sz <= SIZE_T_MAX
 3028|   162k|                        auto *thunk = array->elements[size_t(index)];
 3029|   162k|                        if (thunk->filled) {
  ------------------
  |  Branch (3029:29): [True: 70.5k, False: 91.7k]
  ------------------
 3030|  70.5k|                            scratch = thunk->content;
 3031|  91.7k|                        } else {
 3032|  91.7k|                            stack.pop();
 3033|  91.7k|                            stack.newCall(
 3034|  91.7k|                                ast.location, thunk, thunk->self, thunk->offset, thunk->upValues);
 3035|  91.7k|                            ast_ = thunk->body;
 3036|  91.7k|                            goto recurse;
 3037|  91.7k|                        }
 3038|  10.6M|                    } else if (target.t == Value::OBJECT) {
  ------------------
  |  Branch (3038:32): [True: 10.4M, False: 257k]
  ------------------
 3039|  10.4M|                        auto *obj = static_cast<HeapObject *>(target.v.h);
 3040|  10.4M|                        assert(obj != nullptr);
  ------------------
  |  Branch (3040:25): [True: 10.4M, False: 0]
  ------------------
 3041|  10.4M|                        if (scratch.t != Value::STRING) {
  ------------------
  |  Branch (3041:29): [True: 8, False: 10.4M]
  ------------------
 3042|      8|                            throw makeError(
 3043|      8|                                ast.location,
 3044|      8|                                "object index must be string, got " + type_str(scratch) + ".");
 3045|      8|                        }
 3046|  10.4M|                        const UString &index_name = static_cast<HeapString *>(scratch.v.h)->value;
 3047|  10.4M|                        auto *fid = alloc->makeIdentifier(index_name);
 3048|  10.4M|                        stack.pop();
 3049|  10.4M|                        ast_ = objectIndex(ast.location, obj, fid, 0);
 3050|  10.4M|                        goto recurse;
 3051|  10.4M|                    } else if (target.t == Value::STRING) {
  ------------------
  |  Branch (3051:32): [True: 257k, False: 0]
  ------------------
 3052|   257k|                        auto *obj = static_cast<HeapString *>(target.v.h);
 3053|   257k|                        assert(obj != nullptr);
  ------------------
  |  Branch (3053:25): [True: 257k, False: 0]
  ------------------
 3054|   257k|                        if (scratch.t != Value::NUMBER) {
  ------------------
  |  Branch (3054:29): [True: 6, False: 257k]
  ------------------
 3055|      6|                            throw makeError(
 3056|      6|                                ast.location,
 3057|      6|                                "string index must be a number, got " + type_str(scratch) + ".");
 3058|      6|                        }
 3059|   257k|                        long sz = obj->value.length();
 3060|   257k|                        long i = (long)scratch.v.d;
 3061|   257k|                        if (i < 0 || i >= sz) {
  ------------------
  |  Branch (3061:29): [True: 56, False: 257k]
  |  Branch (3061:38): [True: 55, False: 257k]
  ------------------
 3062|    111|                            std::stringstream ss;
 3063|    111|                            ss << "string bounds error: " << i << " not within [0, " << sz << ")";
 3064|    111|                            throw makeError(ast.location, ss.str());
 3065|    111|                        }
 3066|   257k|                        char32_t ch[] = {obj->value[i], U'\0'};
 3067|   257k|                        scratch = makeString(ch);
 3068|   257k|                    } else {
 3069|      0|                        std::cerr << "INTERNAL ERROR: not object / array / string." << std::endl;
 3070|      0|                        abort();
 3071|      0|                    }
 3072|  10.8M|                } break;
 3073|       |
 3074|  10.8M|                case FRAME_INDEX_TARGET: {
  ------------------
  |  Branch (3074:17): [True: 10.8M, False: 129M]
  ------------------
 3075|  10.8M|                    const auto &ast = *static_cast<const Index *>(f.ast);
 3076|  10.8M|                    if (scratch.t != Value::ARRAY && scratch.t != Value::OBJECT &&
  ------------------
  |  Branch (3076:25): [True: 10.6M, False: 162k]
  |  Branch (3076:54): [True: 257k, False: 10.4M]
  ------------------
 3077|   257k|                        scratch.t != Value::STRING) {
  ------------------
  |  Branch (3077:25): [True: 7, False: 257k]
  ------------------
 3078|      7|                        throw makeError(ast.location,
 3079|      7|                                        "can only index objects, strings, and arrays, got " +
 3080|      7|                                            type_str(scratch) + ".");
 3081|      7|                    }
 3082|  10.8M|                    f.val = scratch;
 3083|  10.8M|                    f.kind = FRAME_INDEX_INDEX;
 3084|  10.8M|                    if (scratch.t == Value::OBJECT) {
  ------------------
  |  Branch (3084:25): [True: 10.4M, False: 420k]
  ------------------
 3085|  10.4M|                        auto *self = static_cast<HeapObject *>(scratch.v.h);
 3086|  10.4M|                        if (!stack.alreadyExecutingInvariants(self)) {
  ------------------
  |  Branch (3086:29): [True: 10.4M, False: 12.1k]
  ------------------
 3087|  10.4M|                            stack.newFrame(FRAME_INVARIANTS, ast.location);
 3088|  10.4M|                            Frame &f2 = stack.top();
 3089|  10.4M|                            f2.self = self;
 3090|  10.4M|                            unsigned counter = 0;
 3091|  10.4M|                            objectInvariants(self, self, counter, f2.thunks);
 3092|  10.4M|                            if (f2.thunks.size() > 0) {
  ------------------
  |  Branch (3092:33): [True: 351, False: 10.4M]
  ------------------
 3093|    351|                                auto *thunk = f2.thunks[0];
 3094|    351|                                f2.elementId = 1;
 3095|    351|                                stack.newCall(ast.location,
 3096|    351|                                              thunk,
 3097|    351|                                              thunk->self,
 3098|    351|                                              thunk->offset,
 3099|    351|                                              thunk->upValues);
 3100|    351|                                ast_ = thunk->body;
 3101|    351|                                goto recurse;
 3102|    351|                            }
 3103|  10.4M|                        }
 3104|  10.4M|                    }
 3105|  10.8M|                    ast_ = ast.index;
 3106|  10.8M|                    goto recurse;
 3107|  10.8M|                } break;
 3108|       |
 3109|  10.4M|                case FRAME_INVARIANTS: {
  ------------------
  |  Branch (3109:17): [True: 10.4M, False: 129M]
  ------------------
 3110|  10.4M|                    if (f.elementId >= f.thunks.size()) {
  ------------------
  |  Branch (3110:25): [True: 10.4M, False: 8.85k]
  ------------------
 3111|  10.4M|                        if (stack.size() == initial_stack_size + 1) {
  ------------------
  |  Branch (3111:29): [True: 6.85k, False: 10.4M]
  ------------------
 3112|       |                            // Just pop, evaluate was invoked by runInvariants.
 3113|  6.85k|                            break;
 3114|  6.85k|                        }
 3115|  10.4M|                        stack.pop();
 3116|  10.4M|                        Frame &f2 = stack.top();
 3117|  10.4M|                        const auto &ast = *static_cast<const Index *>(f2.ast);
 3118|  10.4M|                        ast_ = ast.index;
 3119|  10.4M|                        goto recurse;
 3120|  10.4M|                    }
 3121|  8.85k|                    auto *thunk = f.thunks[f.elementId++];
 3122|  8.85k|                    stack.newCall(f.location, thunk, thunk->self, thunk->offset, thunk->upValues);
 3123|  8.85k|                    ast_ = thunk->body;
 3124|  8.85k|                    goto recurse;
 3125|  10.4M|                } break;
 3126|       |
 3127|  4.98M|                case FRAME_LOCAL: {
  ------------------
  |  Branch (3127:17): [True: 4.98M, False: 135M]
  ------------------
 3128|       |                    // Result of execution is in scratch already.
 3129|  4.98M|                } break;
 3130|       |
 3131|  2.39M|                case FRAME_OBJECT: {
  ------------------
  |  Branch (3131:17): [True: 2.39M, False: 137M]
  ------------------
 3132|  2.39M|                    const auto &ast = *static_cast<const DesugaredObject *>(f.ast);
 3133|  2.39M|                    if (scratch.t != Value::NULL_TYPE) {
  ------------------
  |  Branch (3133:25): [True: 2.39M, False: 0]
  ------------------
 3134|  2.39M|                        if (scratch.t != Value::STRING) {
  ------------------
  |  Branch (3134:29): [True: 21, False: 2.39M]
  ------------------
 3135|     21|                            throw makeError(ast.location, "field name was not a string.");
 3136|     21|                        }
 3137|  2.39M|                        const auto &fname = static_cast<const HeapString *>(scratch.v.h)->value;
 3138|  2.39M|                        const Identifier *fid = alloc->makeIdentifier(fname);
 3139|  2.39M|                        if (f.objectFields.find(fid) != f.objectFields.end()) {
  ------------------
  |  Branch (3139:29): [True: 3, False: 2.39M]
  ------------------
 3140|      3|                            std::string msg =
 3141|      3|                                "duplicate field name: \"" + encode_utf8(fname) + "\"";
 3142|      3|                            throw makeError(ast.location, msg);
 3143|      3|                        }
 3144|  2.39M|                        f.objectFields[fid].hide = f.fit->hide;
 3145|  2.39M|                        f.objectFields[fid].body = f.fit->body;
 3146|  2.39M|                    }
 3147|  2.39M|                    f.fit++;
 3148|  2.39M|                    if (f.fit != ast.fields.end()) {
  ------------------
  |  Branch (3148:25): [True: 1.53M, False: 858k]
  ------------------
 3149|  1.53M|                        ast_ = f.fit->name;
 3150|  1.53M|                        goto recurse;
 3151|  1.53M|                    } else {
 3152|   858k|                        auto env = capture(ast.freeVariables);
 3153|   858k|                        scratch = makeObject<HeapSimpleObject>(env, f.objectFields, ast.asserts);
 3154|   858k|                    }
 3155|  2.39M|                } break;
 3156|       |
 3157|   858k|                case FRAME_OBJECT_COMP_ARRAY: {
  ------------------
  |  Branch (3157:17): [True: 0, False: 139M]
  ------------------
 3158|      0|                    const auto &ast = *static_cast<const ObjectComprehensionSimple *>(f.ast);
 3159|      0|                    const Value &arr_v = scratch;
 3160|      0|                    if (scratch.t != Value::ARRAY) {
  ------------------
  |  Branch (3160:25): [True: 0, False: 0]
  ------------------
 3161|      0|                        throw makeError(ast.location,
 3162|      0|                                        "object comprehension needs array, got " + type_str(arr_v));
 3163|      0|                    }
 3164|      0|                    const auto *arr = static_cast<const HeapArray *>(arr_v.v.h);
 3165|      0|                    if (arr->elements.size() == 0) {
  ------------------
  |  Branch (3165:25): [True: 0, False: 0]
  ------------------
 3166|       |                        // Degenerate case.  Just create the object now.
 3167|      0|                        scratch = makeObject<HeapComprehensionObject>(
 3168|      0|                            BindingFrame{}, ast.value, ast.id, BindingFrame{});
 3169|      0|                    } else {
 3170|      0|                        f.kind = FRAME_OBJECT_COMP_ELEMENT;
 3171|      0|                        f.val = scratch;
 3172|      0|                        f.bindings[ast.id] = arr->elements[0];
 3173|      0|                        f.elementId = 0;
 3174|      0|                        ast_ = ast.field;
 3175|      0|                        goto recurse;
 3176|      0|                    }
 3177|      0|                } break;
 3178|       |
 3179|      0|                case FRAME_OBJECT_COMP_ELEMENT: {
  ------------------
  |  Branch (3179:17): [True: 0, False: 139M]
  ------------------
 3180|      0|                    const auto &ast = *static_cast<const ObjectComprehensionSimple *>(f.ast);
 3181|      0|                    const auto *arr = static_cast<const HeapArray *>(f.val.v.h);
 3182|      0|                    if (scratch.t != Value::NULL_TYPE) {
  ------------------
  |  Branch (3182:25): [True: 0, False: 0]
  ------------------
 3183|      0|                        if (scratch.t != Value::STRING) {
  ------------------
  |  Branch (3183:29): [True: 0, False: 0]
  ------------------
 3184|      0|                            std::stringstream ss;
 3185|      0|                            ss << "field must be string, got: " << type_str(scratch);
 3186|      0|                            throw makeError(ast.location, ss.str());
 3187|      0|                        }
 3188|      0|                        const auto &fname = static_cast<const HeapString *>(scratch.v.h)->value;
 3189|      0|                        const Identifier *fid = alloc->makeIdentifier(fname);
 3190|      0|                        if (f.elements.find(fid) != f.elements.end()) {
  ------------------
  |  Branch (3190:29): [True: 0, False: 0]
  ------------------
 3191|      0|                            throw makeError(ast.location,
 3192|      0|                                            "duplicate field name: \"" + encode_utf8(fname) + "\"");
 3193|      0|                        }
 3194|      0|                        f.elements[fid] = arr->elements[f.elementId];
 3195|      0|                    }
 3196|      0|                    f.elementId++;
 3197|       |
 3198|      0|                    if (f.elementId == arr->elements.size()) {
  ------------------
  |  Branch (3198:25): [True: 0, False: 0]
  ------------------
 3199|      0|                        auto env = capture(ast.freeVariables);
 3200|      0|                        scratch =
 3201|      0|                            makeObject<HeapComprehensionObject>(env, ast.value, ast.id, f.elements);
 3202|      0|                    } else {
 3203|      0|                        f.bindings[ast.id] = arr->elements[f.elementId];
 3204|      0|                        ast_ = ast.field;
 3205|      0|                        goto recurse;
 3206|      0|                    }
 3207|      0|                } break;
 3208|       |
 3209|  1.38M|                case FRAME_STRING_CONCAT: {
  ------------------
  |  Branch (3209:17): [True: 1.38M, False: 138M]
  ------------------
 3210|  1.38M|                    const auto &ast = *static_cast<const Binary *>(f.ast);
 3211|  1.38M|                    const Value &lhs = stack.top().val;
 3212|  1.38M|                    UString output;
 3213|  1.38M|                    if (lhs.t == Value::STRING) {
  ------------------
  |  Branch (3213:25): [True: 1.36M, False: 16.3k]
  ------------------
 3214|  1.36M|                        output.append(static_cast<const HeapString *>(lhs.v.h)->value);
 3215|  1.36M|                    } else {
 3216|  16.3k|                        scratch = lhs;
 3217|  16.3k|                        output.append(toString(ast.left->location));
 3218|  16.3k|                    }
 3219|  1.38M|                    const Value &rhs = stack.top().val2;
 3220|  1.38M|                    if (rhs.t == Value::STRING) {
  ------------------
  |  Branch (3220:25): [True: 1.16M, False: 221k]
  ------------------
 3221|  1.16M|                        output.append(static_cast<const HeapString *>(rhs.v.h)->value);
 3222|  1.16M|                    } else {
 3223|   221k|                        scratch = rhs;
 3224|   221k|                        output.append(toString(ast.right->location));
 3225|   221k|                    }
 3226|  1.38M|                    scratch = makeString(output);
 3227|  1.38M|                } break;
 3228|       |
 3229|  1.85M|                case FRAME_UNARY: {
  ------------------
  |  Branch (3229:17): [True: 1.85M, False: 138M]
  ------------------
 3230|  1.85M|                    const auto &ast = *static_cast<const Unary *>(f.ast);
 3231|  1.85M|                    switch (scratch.t) {
 3232|  1.71M|                        case Value::BOOLEAN:
  ------------------
  |  Branch (3232:25): [True: 1.71M, False: 142k]
  ------------------
 3233|  1.71M|                            if (ast.op == UOP_NOT) {
  ------------------
  |  Branch (3233:33): [True: 1.71M, False: 2]
  ------------------
 3234|  1.71M|                                scratch = makeBoolean(!scratch.v.b);
 3235|  1.71M|                            } else {
 3236|      2|                                throw makeError(ast.location,
 3237|      2|                                                "unary operator " + uop_string(ast.op) +
 3238|      2|                                                    " does not operate on booleans.");
 3239|      2|                            }
 3240|  1.71M|                            break;
 3241|       |
 3242|  1.71M|                        case Value::NUMBER:
  ------------------
  |  Branch (3242:25): [True: 141k, False: 1.71M]
  ------------------
 3243|   141k|                            switch (ast.op) {
 3244|  15.2k|                                case UOP_PLUS: break;
  ------------------
  |  Branch (3244:33): [True: 15.2k, False: 126k]
  ------------------
 3245|       |
 3246|   105k|                                case UOP_MINUS: scratch = makeNumber(-scratch.v.d); break;
  ------------------
  |  Branch (3246:33): [True: 105k, False: 36.1k]
  ------------------
 3247|       |
 3248|  20.8k|                                case UOP_BITWISE_NOT:
  ------------------
  |  Branch (3248:33): [True: 20.8k, False: 121k]
  ------------------
 3249|  20.8k|                                    scratch = makeNumber(~(long)(scratch.v.d));
 3250|  20.8k|                                    break;
 3251|       |
 3252|     34|                                default:
  ------------------
  |  Branch (3252:33): [True: 34, False: 141k]
  ------------------
 3253|     34|                                    throw makeError(ast.location,
 3254|     34|                                                    "unary operator " + uop_string(ast.op) +
 3255|     34|                                                        " does not operate on numbers.");
 3256|   141k|                            }
 3257|   141k|                            break;
 3258|       |
 3259|   141k|                        default:
  ------------------
  |  Branch (3259:25): [True: 144, False: 1.85M]
  ------------------
 3260|    144|                            throw makeError(ast.location,
 3261|    144|                                            "unary operator " + uop_string(ast.op) +
 3262|    144|                                                " does not operate on type " + type_str(scratch));
 3263|  1.85M|                    }
 3264|  1.85M|                } break;
 3265|       |
 3266|  1.85M|                case FRAME_BUILTIN_JOIN_STRINGS: {
  ------------------
  |  Branch (3266:17): [True: 0, False: 139M]
  ------------------
 3267|      0|                    joinString(f.first, f.str, f.val, f.elementId, scratch);
 3268|      0|                    f.elementId++;
 3269|      0|                    auto *ast = joinStrings();
 3270|      0|                    if (ast != nullptr) {
  ------------------
  |  Branch (3270:25): [True: 0, False: 0]
  ------------------
 3271|      0|                        ast_ = ast;
 3272|      0|                        goto recurse;
 3273|      0|                    }
 3274|      0|                } break;
 3275|       |
 3276|      0|                case FRAME_BUILTIN_JOIN_ARRAYS: {
  ------------------
  |  Branch (3276:17): [True: 0, False: 139M]
  ------------------
 3277|      0|                    joinArray(f.first, f.thunks, f.val, f.elementId, scratch);
 3278|      0|                    f.elementId++;
 3279|      0|                    auto *ast = joinArrays();
 3280|      0|                    if (ast != nullptr) {
  ------------------
  |  Branch (3280:25): [True: 0, False: 0]
  ------------------
 3281|      0|                        ast_ = ast;
 3282|      0|                        goto recurse;
 3283|      0|                    }
 3284|      0|                } break;
 3285|       |
 3286|      0|                 case FRAME_BUILTIN_DECODE_UTF8: {
  ------------------
  |  Branch (3286:18): [True: 0, False: 139M]
  ------------------
 3287|      0|                    auto *ast = decodeUTF8();
 3288|      0|                    if (ast != nullptr) {
  ------------------
  |  Branch (3288:25): [True: 0, False: 0]
  ------------------
 3289|      0|                        ast_ = ast;
 3290|      0|                        goto recurse;
 3291|      0|                    }
 3292|      0|                } break;
 3293|       |
 3294|      0|                default:
  ------------------
  |  Branch (3294:17): [True: 0, False: 139M]
  ------------------
 3295|      0|                    std::cerr << "INTERNAL ERROR: Unknown FrameKind:  " << f.kind << std::endl;
 3296|      0|                    std::abort();
 3297|   139M|            }
 3298|       |
 3299|  61.6M|        popframe:;
 3300|       |
 3301|  61.6M|            stack.pop();
 3302|       |
 3303|  72.9M|        replaceframe:;
 3304|  72.9M|        }
 3305|  71.3M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack8newFrameIJNS1_9FrameKindEPKNS0_3ASTEEEEvDpT_:
  388|  56.0M|    {
  389|  56.0M|        stack.emplace_back(args...);
  390|  56.0M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15FrameC2ERKNS1_9FrameKindEPKNS0_3ASTE:
  194|  56.0M|        : kind(kind),
  195|  56.0M|          ast(ast),
  196|  56.0M|          location(ast->location),
  197|  56.0M|          tailCall(false),
  198|  56.0M|          elementId(0),
  199|  56.0M|          first(false),
  200|  56.0M|          context(NULL),
  201|  56.0M|          self(NULL),
  202|  56.0M|          offset(0)
  203|  56.0M|    {
  204|  56.0M|        val.t = Value::NULL_TYPE;
  205|  56.0M|        val2.t = Value::NULL_TYPE;
  206|  56.0M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack14getSelfBindingERPNS1_10HeapObjectERj:
  444|  33.3M|    {
  445|  33.3M|        self = nullptr;
  446|  33.3M|        offset = 0;
  447|   111M|        for (int i = stack.size() - 1; i >= 0; --i) {
  ------------------
  |  Branch (447:40): [True: 111M, False: 20.1k]
  ------------------
  448|   111M|            if (stack[i].isCall()) {
  ------------------
  |  Branch (448:17): [True: 33.3M, False: 78.2M]
  ------------------
  449|  33.3M|                self = stack[i].self;
  450|  33.3M|                offset = stack[i].offset;
  451|  33.3M|                return;
  452|  33.3M|            }
  453|   111M|        }
  454|  33.3M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapThunkEJRPKNS0_10IdentifierERPNS1_10HeapObjectERjRKPNS0_3ASTEEEEPT_DpOT0_:
  577|  25.3M|    {
  578|  25.3M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  579|  25.3M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (579:13): [True: 23.6k, False: 25.3M]
  ------------------
  580|       |            // Avoid the object we just made being collected.
  581|  23.6k|            heap.markFrom(r);
  582|       |
  583|       |            // Mark from the stack.
  584|  23.6k|            stack.mark(heap);
  585|       |
  586|       |            // Mark from the scratch register
  587|  23.6k|            heap.markFrom(scratch);
  588|       |
  589|       |            // Mark from cached imports
  590|  23.6k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (590:35): [True: 0, False: 23.6k]
  ------------------
  591|      0|                HeapThunk *thunk = pair.second->thunk;
  592|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (592:21): [True: 0, False: 0]
  ------------------
  593|      0|                    heap.markFrom(thunk);
  594|      0|            }
  595|       |
  596|  3.79M|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (596:40): [True: 3.79M, False: 23.6k]
  ------------------
  597|  3.79M|                heap.markFrom(sourceVal.second);
  598|  3.79M|            }
  599|       |
  600|       |            // Delete unreachable objects.
  601|  23.6k|            heap.sweep();
  602|  23.6k|        }
  603|  25.3M|        return r;
  604|  25.3M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter7captureERKNSt3__16vectorIPKNS0_10IdentifierENS3_9allocatorIS7_EEEE:
  861|  48.3M|    {
  862|  48.3M|        BindingFrame env;
  863|   982M|        for (auto fv : free_vars) {
  ------------------
  |  Branch (863:22): [True: 982M, False: 48.3M]
  ------------------
  864|   982M|            auto *th = stack.lookUpVar(fv);
  865|   982M|            env[fv] = th;
  866|   982M|        }
  867|  48.3M|        return env;
  868|  48.3M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack8newFrameIJNS1_9FrameKindENS0_13LocationRangeEEEEvDpT_:
  388|  10.9M|    {
  389|  10.9M|        stack.emplace_back(args...);
  390|  10.9M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter11makeClosureERKNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS3_4lessIS7_EENS3_9allocatorINS3_4pairIKS7_S9_EEEEEEPNS1_10HeapObjectEjRKNS3_6vectorINS1_11HeapClosure5ParamENSC_ISO_EEEEPNS0_3ASTE:
  650|  2.00M|    {
  651|  2.00M|        Value r;
  652|  2.00M|        r.t = Value::FUNCTION;
  653|  2.00M|        r.v.h = makeHeap<HeapClosure>(env, self, offset, params, body, "");
  654|  2.00M|        return r;
  655|  2.00M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_11HeapClosureEJRKNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS5_4lessIS9_EENS5_9allocatorINS5_4pairIKS9_SB_EEEEEERPNS1_10HeapObjectERjRKNS5_6vectorINS4_5ParamENSE_ISR_EEEERPNS0_3ASTERA1_KcEEEPT_DpOT0_:
  577|  2.00M|    {
  578|  2.00M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  579|  2.00M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (579:13): [True: 4.66k, False: 2.00M]
  ------------------
  580|       |            // Avoid the object we just made being collected.
  581|  4.66k|            heap.markFrom(r);
  582|       |
  583|       |            // Mark from the stack.
  584|  4.66k|            stack.mark(heap);
  585|       |
  586|       |            // Mark from the scratch register
  587|  4.66k|            heap.markFrom(scratch);
  588|       |
  589|       |            // Mark from cached imports
  590|  4.66k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (590:35): [True: 0, False: 4.66k]
  ------------------
  591|      0|                HeapThunk *thunk = pair.second->thunk;
  592|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (592:21): [True: 0, False: 0]
  ------------------
  593|      0|                    heap.markFrom(thunk);
  594|      0|            }
  595|       |
  596|   751k|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (596:40): [True: 751k, False: 4.66k]
  ------------------
  597|   751k|                heap.markFrom(sourceVal.second);
  598|   751k|            }
  599|       |
  600|       |            // Delete unreachable objects.
  601|  4.66k|            heap.sweep();
  602|  4.66k|        }
  603|  2.00M|        return r;
  604|  2.00M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter6importERKNS0_13LocationRangeEPKNS0_13LiteralStringE:
  792|     39|    {
  793|     39|        ImportCacheValue *input = importData(loc, file);
  794|     39|        if (input->thunk == nullptr) {
  ------------------
  |  Branch (794:13): [True: 0, False: 39]
  ------------------
  795|      0|            Tokens tokens = jsonnet_lex(input->foundHere, input->content.c_str());
  796|      0|            AST *expr = jsonnet_parse(alloc, tokens);
  797|      0|            jsonnet_desugar(alloc, expr, nullptr);
  798|      0|            jsonnet_static_analysis(expr);
  799|       |            // If no errors then populate cache.
  800|      0|            auto *thunk = makeHeap<HeapThunk>(idImport, nullptr, 0, expr);
  801|      0|            input->thunk = thunk;
  802|      0|        }
  803|     39|        return input->thunk;
  804|     39|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10importDataERKNS0_13LocationRangeEPKNS0_13LiteralStringE:
  816|     60|    {
  817|       |        // `dir` is passed to the importCallback, which may be externally defined.
  818|       |        // For backwards compatibility, we need to keep the trailing directory separator.
  819|       |        // For example, the default callback in libjsonnet.cpp joins paths with simple
  820|       |        // string concatenation. Other (external) implementations might do the same.
  821|     60|        std::string dir = path_dir_with_trailing_separator(loc.file);
  822|       |
  823|     60|        const UString &path = file->value;
  824|       |
  825|     60|        std::pair<std::string, UString> key(dir, path);
  826|     60|        ImportCacheValue *cached_value = cachedImports[key];
  827|     60|        if (cached_value != nullptr)
  ------------------
  |  Branch (827:13): [True: 0, False: 60]
  ------------------
  828|      0|            return cached_value;
  829|       |
  830|     60|        char *found_here_cptr;
  831|     60|        char *buf = NULL;
  832|     60|        size_t buflen = 0;
  833|     60|        int result = importCallback(importCallbackContext,
  834|     60|                                    dir.c_str(),
  835|     60|                                    encode_utf8(path).c_str(),
  836|     60|                                    &found_here_cptr,
  837|     60|                                    &buf,
  838|     60|                                    &buflen);
  839|       |
  840|     60|        std::string input(buf, buflen);
  841|     60|        ::free(buf);
  842|       |
  843|     60|        if (result == 1) {  // failure
  ------------------
  |  Branch (843:13): [True: 60, False: 0]
  ------------------
  844|     60|            std::string epath = encode_utf8(jsonnet_string_escape(path, false));
  845|     60|            std::string msg = "couldn't open import \"" + epath + "\": ";
  846|     60|            msg += input;
  847|     60|            throw makeError(loc, msg);
  848|     60|        }
  849|       |
  850|      0|        auto *input_ptr = new ImportCacheValue();
  851|      0|        input_ptr->foundHere = found_here_cptr;
  852|      0|        input_ptr->content = input;
  853|      0|        input_ptr->thunk = nullptr;  // May be filled in later by import().
  854|      0|        ::free(found_here_cptr);
  855|      0|        cachedImports[key] = input_ptr;
  856|      0|        return input_ptr;
  857|     60|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapThunkEJRKPKNS0_10IdentifierERPNS1_10HeapObjectERjRKPNS0_3ASTEEEEPT_DpOT0_:
  577|  18.1M|    {
  578|  18.1M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  579|  18.1M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (579:13): [True: 23.0k, False: 18.1M]
  ------------------
  580|       |            // Avoid the object we just made being collected.
  581|  23.0k|            heap.markFrom(r);
  582|       |
  583|       |            // Mark from the stack.
  584|  23.0k|            stack.mark(heap);
  585|       |
  586|       |            // Mark from the scratch register
  587|  23.0k|            heap.markFrom(scratch);
  588|       |
  589|       |            // Mark from cached imports
  590|  23.0k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (590:35): [True: 0, False: 23.0k]
  ------------------
  591|      0|                HeapThunk *thunk = pair.second->thunk;
  592|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (592:21): [True: 0, False: 0]
  ------------------
  593|      0|                    heap.markFrom(thunk);
  594|      0|            }
  595|       |
  596|  3.70M|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (596:40): [True: 3.70M, False: 23.0k]
  ------------------
  597|  3.70M|                heap.markFrom(sourceVal.second);
  598|  3.70M|            }
  599|       |
  600|       |            // Delete unreachable objects.
  601|  23.0k|            heap.sweep();
  602|  23.0k|        }
  603|  18.1M|        return r;
  604|  18.1M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10makeObjectINS1_16HeapSimpleObjectEJNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS5_4lessIS9_EENS5_9allocatorINS5_4pairIKS9_SB_EEEEEENS6_IS9_NS4_5FieldESD_NSE_INSF_ISG_SK_EEEEEENS5_4listIPNS0_3ASTENSE_ISQ_EEEEEEENS1_5ValueEDpT0_:
  671|  2.01M|    {
  672|  2.01M|        Value r;
  673|  2.01M|        r.t = Value::OBJECT;
  674|  2.01M|        r.v.h = makeHeap<T>(args...);
  675|  2.01M|        return r;
  676|  2.01M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_16HeapSimpleObjectEJRNSt3__13mapIPKNS0_10IdentifierEPNS1_9HeapThunkENS5_4lessIS9_EENS5_9allocatorINS5_4pairIKS9_SB_EEEEEERNS6_IS9_NS4_5FieldESD_NSE_INSF_ISG_SL_EEEEEERNS5_4listIPNS0_3ASTENSE_ISS_EEEEEEEPT_DpOT0_:
  577|  2.01M|    {
  578|  2.01M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  579|  2.01M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (579:13): [True: 2.12k, False: 2.01M]
  ------------------
  580|       |            // Avoid the object we just made being collected.
  581|  2.12k|            heap.markFrom(r);
  582|       |
  583|       |            // Mark from the stack.
  584|  2.12k|            stack.mark(heap);
  585|       |
  586|       |            // Mark from the scratch register
  587|  2.12k|            heap.markFrom(scratch);
  588|       |
  589|       |            // Mark from cached imports
  590|  2.12k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (590:35): [True: 0, False: 2.12k]
  ------------------
  591|      0|                HeapThunk *thunk = pair.second->thunk;
  592|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (592:21): [True: 0, False: 0]
  ------------------
  593|      0|                    heap.markFrom(thunk);
  594|      0|            }
  595|       |
  596|   341k|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (596:40): [True: 341k, False: 2.12k]
  ------------------
  597|   341k|                heap.markFrom(sourceVal.second);
  598|   341k|            }
  599|       |
  600|       |            // Delete unreachable objects.
  601|  2.12k|            heap.sweep();
  602|  2.12k|        }
  603|  2.01M|        return r;
  604|  2.01M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack9lookUpVarEPKNS0_10IdentifierE:
  269|  1.00G|    {
  270|  1.43G|        for (int i = stack.size() - 1; i >= 0; --i) {
  ------------------
  |  Branch (270:40): [True: 1.43G, False: 0]
  ------------------
  271|  1.43G|            const auto &binds = stack[i].bindings;
  272|  1.43G|            auto it = binds.find(id);
  273|  1.43G|            if (it != binds.end()) {
  ------------------
  |  Branch (273:17): [True: 1.00G, False: 426M]
  ------------------
  274|  1.00G|                return it->second;
  275|  1.00G|            }
  276|   426M|            if (stack[i].isCall())
  ------------------
  |  Branch (276:17): [True: 0, False: 426M]
  ------------------
  277|      0|                break;
  278|   426M|        }
  279|      0|        return nullptr;
  280|  1.00G|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack4sizeEv:
  263|   159M|    {
  264|   159M|        return stack.size();
  265|   159M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapThunkEJRPKNS0_10IdentifierERPNS1_10HeapObjectERjRKPKNS0_3ASTEEEEPT_DpOT0_:
  577|    131|    {
  578|    131|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  579|    131|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (579:13): [True: 0, False: 131]
  ------------------
  580|       |            // Avoid the object we just made being collected.
  581|      0|            heap.markFrom(r);
  582|       |
  583|       |            // Mark from the stack.
  584|      0|            stack.mark(heap);
  585|       |
  586|       |            // Mark from the scratch register
  587|      0|            heap.markFrom(scratch);
  588|       |
  589|       |            // Mark from cached imports
  590|      0|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (590:35): [True: 0, False: 0]
  ------------------
  591|      0|                HeapThunk *thunk = pair.second->thunk;
  592|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (592:21): [True: 0, False: 0]
  ------------------
  593|      0|                    heap.markFrom(thunk);
  594|      0|            }
  595|       |
  596|      0|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (596:40): [True: 0, False: 0]
  ------------------
  597|      0|                heap.markFrom(sourceVal.second);
  598|      0|            }
  599|       |
  600|       |            // Delete unreachable objects.
  601|      0|            heap.sweep();
  602|      0|        }
  603|    131|        return r;
  604|    131|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10findObjectEPKNS0_10IdentifierEPNS1_10HeapObjectEjRj:
  698|   916M|    {
  699|   916M|        if (auto *ext = dynamic_cast<HeapExtendedObject *>(curr)) {
  ------------------
  |  Branch (699:19): [True: 453M, False: 463M]
  ------------------
  700|   453M|            auto *r = findObject(f, ext->right, start_from, counter);
  701|   453M|            if (r)
  ------------------
  |  Branch (701:17): [True: 5.33M, False: 448M]
  ------------------
  702|  5.33M|                return r;
  703|   448M|            auto *l = findObject(f, ext->left, start_from, counter);
  704|   448M|            if (l)
  ------------------
  |  Branch (704:17): [True: 340M, False: 107M]
  ------------------
  705|   340M|                return l;
  706|   463M|        } else if (auto *ext = dynamic_cast<HeapRestrictedObject *>(curr)) {
  ------------------
  |  Branch (706:26): [True: 0, False: 463M]
  ------------------
  707|       |            // The RestrictedObject is on the 'right', that is it is checked/counted first.
  708|      0|            if (counter >= start_from) {
  ------------------
  |  Branch (708:17): [True: 0, False: 0]
  ------------------
  709|      0|                if (ext->retainedKeys.find(f) == ext->retainedKeys.end()) {
  ------------------
  |  Branch (709:21): [True: 0, False: 0]
  ------------------
  710|      0|                    counter += 1 + countLeaves(ext->obj);
  711|      0|                    return nullptr;
  712|      0|                }
  713|      0|            }
  714|      0|            ++counter;
  715|      0|            return findObject(f, ext->obj, start_from, counter);
  716|   463M|        } else {
  717|   463M|            if (counter >= start_from) {
  ------------------
  |  Branch (717:17): [True: 38.5M, False: 425M]
  ------------------
  718|  38.5M|                if (auto *simp = dynamic_cast<HeapSimpleObject *>(curr)) {
  ------------------
  |  Branch (718:27): [True: 38.5M, False: 0]
  ------------------
  719|  38.5M|                    auto it = simp->fields.find(f);
  720|  38.5M|                    if (it != simp->fields.end()) {
  ------------------
  |  Branch (720:25): [True: 15.6M, False: 22.8M]
  ------------------
  721|  15.6M|                        return simp;
  722|  15.6M|                    }
  723|  38.5M|                } else if (auto *comp = dynamic_cast<HeapComprehensionObject *>(curr)) {
  ------------------
  |  Branch (723:34): [True: 0, False: 0]
  ------------------
  724|      0|                    auto it = comp->compValues.find(f);
  725|      0|                    if (it != comp->compValues.end()) {
  ------------------
  |  Branch (725:25): [True: 0, False: 0]
  ------------------
  726|      0|                        return comp;
  727|      0|                    }
  728|      0|                }
  729|  38.5M|            }
  730|   448M|            counter++;
  731|   448M|        }
  732|   555M|        return nullptr;
  733|   916M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter13callSourceValEPKNS0_3ASTEPNS1_9HeapThunkENSt3__16vectorIS7_NS8_9allocatorIS7_EEEE:
 2070|  32.4k|    const AST *callSourceVal(const AST *ast, HeapThunk *sourceVal, std::vector<HeapThunk*> args) {
 2071|  32.4k|        assert(sourceVal != nullptr);
  ------------------
  |  Branch (2071:9): [True: 32.4k, False: 0]
  ------------------
 2072|  32.4k|        assert(sourceVal->filled);
  ------------------
  |  Branch (2072:9): [True: 32.4k, False: 0]
  ------------------
 2073|  32.4k|        assert(sourceVal->content.t == Value::FUNCTION);
  ------------------
  |  Branch (2073:9): [True: 32.4k, False: 0]
  ------------------
 2074|  32.4k|        auto *func = static_cast<HeapClosure *>(sourceVal->content.v.h);
 2075|  32.4k|        BindingFrame up_values = func->upValues;
 2076|  97.4k|        for (size_t i = 0; i < args.size(); ++i) {
  ------------------
  |  Branch (2076:28): [True: 64.9k, False: 32.4k]
  ------------------
 2077|  64.9k|            up_values.insert({func->params[i].id, args[i]});
 2078|  64.9k|        }
 2079|  32.4k|        stack.newCall(ast->location, func, func->self, func->offset, up_values);
 2080|  32.4k|        return func->body;
 2081|  32.4k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter17safeDoubleToInt64EdRKNS0_13LocationRangeE:
  919|  70.8k|    int64_t safeDoubleToInt64(double value, const internal::LocationRange& loc) {
  920|  70.8k|        if (std::isnan(value) || std::isinf(value)) {
  ------------------
  |  Branch (920:13): [True: 0, False: 70.8k]
  |  Branch (920:34): [True: 0, False: 70.8k]
  ------------------
  921|      0|            throw internal::StaticError(loc, "numeric value is not finite");
  922|      0|        }
  923|       |
  924|       |        // Constants for safe double-to-int conversion
  925|       |        // Jsonnet uses IEEE 754 doubles, which precisely represent integers in the range [-2^53 + 1, 2^53 - 1].
  926|  70.8k|        constexpr int64_t DOUBLE_MAX_SAFE_INTEGER = (1LL << 53) - 1;
  927|  70.8k|        constexpr int64_t DOUBLE_MIN_SAFE_INTEGER = -((1LL << 53) - 1);
  928|       |
  929|       |        // Check if the value is within the safe integer range
  930|  70.8k|        if (value < DOUBLE_MIN_SAFE_INTEGER || value > DOUBLE_MAX_SAFE_INTEGER) {
  ------------------
  |  Branch (930:13): [True: 1, False: 70.8k]
  |  Branch (930:48): [True: 4, False: 70.8k]
  ------------------
  931|      5|            throw makeError(loc, "numeric value outside safe integer range for bitwise operation.");
  932|      5|        }
  933|  70.8k|        return static_cast<int64_t>(value);
  934|  70.8k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter10makeObjectINS1_18HeapExtendedObjectEJPNS1_10HeapObjectES6_EEENS1_5ValueEDpT0_:
  671|  1.47M|    {
  672|  1.47M|        Value r;
  673|  1.47M|        r.t = Value::OBJECT;
  674|  1.47M|        r.v.h = makeHeap<T>(args...);
  675|  1.47M|        return r;
  676|  1.47M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_18HeapExtendedObjectEJRPNS1_10HeapObjectES7_EEEPT_DpOT0_:
  577|  1.47M|    {
  578|  1.47M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  579|  1.47M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (579:13): [True: 1.22k, False: 1.47M]
  ------------------
  580|       |            // Avoid the object we just made being collected.
  581|  1.22k|            heap.markFrom(r);
  582|       |
  583|       |            // Mark from the stack.
  584|  1.22k|            stack.mark(heap);
  585|       |
  586|       |            // Mark from the scratch register
  587|  1.22k|            heap.markFrom(scratch);
  588|       |
  589|       |            // Mark from cached imports
  590|  1.22k|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (590:35): [True: 0, False: 1.22k]
  ------------------
  591|      0|                HeapThunk *thunk = pair.second->thunk;
  592|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (592:21): [True: 0, False: 0]
  ------------------
  593|      0|                    heap.markFrom(thunk);
  594|      0|            }
  595|       |
  596|   197k|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (596:40): [True: 197k, False: 1.22k]
  ------------------
  597|   197k|                heap.markFrom(sourceVal.second);
  598|   197k|            }
  599|       |
  600|       |            // Delete unreachable objects.
  601|  1.22k|            heap.sweep();
  602|  1.22k|        }
  603|  1.47M|        return r;
  604|  1.47M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8toStringERKNS0_13LocationRangeE:
 1979|   236k|    {
 1980|   236k|        return manifestJson(loc, false, U"");
 1981|   236k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter11countLeavesEPNS1_10HeapObjectE:
  876|  2.16G|    {
  877|  2.16G|        if (auto *ext = dynamic_cast<HeapExtendedObject *>(obj)) {
  ------------------
  |  Branch (877:19): [True: 1.07G, False: 1.08G]
  ------------------
  878|  1.07G|            return countLeaves(ext->left) + countLeaves(ext->right);
  879|  1.08G|        } else if (auto *ext = dynamic_cast<HeapRestrictedObject *>(obj)) {
  ------------------
  |  Branch (879:26): [True: 0, False: 1.08G]
  ------------------
  880|      0|            return countLeaves(ext->obj) + 1;
  881|  1.08G|        } else {
  882|       |            // Must be a HeapLeafObject.
  883|  1.08G|            return 1;
  884|  1.08G|        }
  885|  2.16G|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter11objectIndexERKNS0_13LocationRangeEPNS1_10HeapObjectEPKNS0_10IdentifierEj:
 2018|  13.3M|    {
 2019|  13.3M|        unsigned found_at = 0;
 2020|  13.3M|        HeapObject *self = obj;
 2021|  13.3M|        HeapLeafObject *found = findObject(f, obj, offset, found_at);
 2022|  13.3M|        if (found == nullptr) {
  ------------------
  |  Branch (2022:13): [True: 11, False: 13.3M]
  ------------------
 2023|     11|            throw makeError(loc, "field does not exist: " + encode_utf8(f->name));
 2024|     11|        }
 2025|  13.3M|        if (auto *simp = dynamic_cast<HeapSimpleObject *>(found)) {
  ------------------
  |  Branch (2025:19): [True: 13.3M, False: 0]
  ------------------
 2026|  13.3M|            auto it = simp->fields.find(f);
 2027|  13.3M|            const AST *body = it->second.body;
 2028|       |
 2029|  13.3M|            stack.newCall(loc, simp, self, found_at, simp->upValues);
 2030|  13.3M|            return body;
 2031|  13.3M|        } else {
 2032|       |            // If a HeapLeafObject is not HeapSimpleObject, it must be HeapComprehensionObject.
 2033|      0|            auto *comp = static_cast<HeapComprehensionObject *>(found);
 2034|      0|            auto it = comp->compValues.find(f);
 2035|      0|            auto *th = it->second;
 2036|      0|            BindingFrame binds = comp->upValues;
 2037|      0|            binds[comp->id] = th;
 2038|      0|            stack.newCall(loc, comp, self, found_at, binds);
 2039|      0|            return comp->value;
 2040|      0|        }
 2041|  13.3M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_15Stack26alreadyExecutingInvariantsEPNS1_10HeapObjectE:
  458|  10.9M|    {
  459|  2.85G|        for (int i = stack.size() - 1; i >= 0; --i) {
  ------------------
  |  Branch (459:40): [True: 2.84G, False: 10.9M]
  ------------------
  460|  2.84G|            if (stack[i].kind == FRAME_INVARIANTS) {
  ------------------
  |  Branch (460:17): [True: 10.5M, False: 2.83G]
  ------------------
  461|  10.5M|                if (stack[i].self == self)
  ------------------
  |  Branch (461:21): [True: 13.8k, False: 10.4M]
  ------------------
  462|  13.8k|                    return true;
  463|  10.5M|            }
  464|  2.84G|        }
  465|  10.9M|        return false;
  466|  10.9M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter16objectInvariantsEPNS1_10HeapObjectES4_RjRNSt3__16vectorIPNS1_9HeapThunkENS6_9allocatorIS9_EEEE:
 1992|  53.2M|    {
 1993|  53.2M|        if (auto *ext = dynamic_cast<HeapExtendedObject *>(curr)) {
  ------------------
  |  Branch (1993:19): [True: 21.1M, False: 32.1M]
  ------------------
 1994|  21.1M|            objectInvariants(ext->right, self, counter, thunks);
 1995|  21.1M|            objectInvariants(ext->left, self, counter, thunks);
 1996|  32.1M|        } else if (auto *ext = dynamic_cast<HeapRestrictedObject *>(curr)) {
  ------------------
  |  Branch (1996:26): [True: 0, False: 32.1M]
  ------------------
 1997|      0|            objectInvariants(ext->obj, self, counter, thunks);
 1998|  32.1M|        } else {
 1999|  32.1M|            if (auto *simp = dynamic_cast<HeapSimpleObject *>(curr)) {
  ------------------
  |  Branch (1999:23): [True: 32.1M, False: 0]
  ------------------
 2000|  32.1M|                for (AST *assert : simp->asserts) {
  ------------------
  |  Branch (2000:34): [True: 2.35M, False: 32.1M]
  ------------------
 2001|  2.35M|                    auto *el_th = makeHeap<HeapThunk>(idInvariant, self, counter, assert);
 2002|  2.35M|                    el_th->upValues = simp->upValues;
 2003|  2.35M|                    thunks.push_back(el_th);
 2004|  2.35M|                }
 2005|  32.1M|            }
 2006|  32.1M|            counter++;
 2007|  32.1M|        }
 2008|  53.2M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter8makeHeapINS1_9HeapThunkEJRPKNS0_10IdentifierERPNS1_10HeapObjectERjRPNS0_3ASTEEEEPT_DpOT0_:
  577|  2.35M|    {
  578|  2.35M|        T *r = heap.makeEntity<T, Args...>(std::forward<Args>(args)...);
  579|  2.35M|        if (heap.checkHeap()) {  // Do a GC cycle?
  ------------------
  |  Branch (579:13): [True: 190, False: 2.35M]
  ------------------
  580|       |            // Avoid the object we just made being collected.
  581|    190|            heap.markFrom(r);
  582|       |
  583|       |            // Mark from the stack.
  584|    190|            stack.mark(heap);
  585|       |
  586|       |            // Mark from the scratch register
  587|    190|            heap.markFrom(scratch);
  588|       |
  589|       |            // Mark from cached imports
  590|    190|            for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (590:35): [True: 0, False: 190]
  ------------------
  591|      0|                HeapThunk *thunk = pair.second->thunk;
  592|      0|                if (thunk != nullptr)
  ------------------
  |  Branch (592:21): [True: 0, False: 0]
  ------------------
  593|      0|                    heap.markFrom(thunk);
  594|      0|            }
  595|       |
  596|  30.5k|            for (const auto &sourceVal : sourceVals) {
  ------------------
  |  Branch (596:40): [True: 30.5k, False: 190]
  ------------------
  597|  30.5k|                heap.markFrom(sourceVal.second);
  598|  30.5k|            }
  599|       |
  600|       |            // Delete unreachable objects.
  601|    190|            heap.sweep();
  602|    190|        }
  603|  2.35M|        return r;
  604|  2.35M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter12manifestJsonERKNS0_13LocationRangeEbRKNSt3__112basic_stringIDiNS6_11char_traitsIDiEENS6_9allocatorIDiEEEE:
 3315|  4.50M|    {
 3316|       |        // Printing fields means evaluating and binding them, which can trigger
 3317|       |        // garbage collection.
 3318|       |
 3319|  4.50M|        UStringStream ss;
 3320|  4.50M|        switch (scratch.t) {
  ------------------
  |  Branch (3320:17): [True: 4.50M, False: 0]
  ------------------
 3321|   156k|            case Value::ARRAY: {
  ------------------
  |  Branch (3321:13): [True: 156k, False: 4.34M]
  ------------------
 3322|   156k|                HeapArray *arr = static_cast<HeapArray *>(scratch.v.h);
 3323|   156k|                if (arr->elements.size() == 0) {
  ------------------
  |  Branch (3323:21): [True: 35.3k, False: 121k]
  ------------------
 3324|  35.3k|                    ss << U"[ ]";
 3325|   121k|                } else {
 3326|   121k|                    const char32_t *prefix = multiline ? U"[\n" : U"[";
  ------------------
  |  Branch (3326:46): [True: 88.5k, False: 32.5k]
  ------------------
 3327|   121k|                    UString indent2 = multiline ? indent + U"   " : indent;
  ------------------
  |  Branch (3327:39): [True: 88.5k, False: 32.5k]
  ------------------
 3328|  3.56M|                    for (auto *thunk : arr->elements) {
  ------------------
  |  Branch (3328:38): [True: 3.56M, False: 121k]
  ------------------
 3329|  3.56M|                        LocationRange tloc = thunk->body == nullptr ? loc : thunk->body->location;
  ------------------
  |  Branch (3329:46): [True: 0, False: 3.56M]
  ------------------
 3330|  3.56M|                        if (thunk->filled) {
  ------------------
  |  Branch (3330:29): [True: 0, False: 3.56M]
  ------------------
 3331|      0|                            stack.newCall(loc, thunk, nullptr, 0, BindingFrame{});
 3332|       |                            // Keep arr alive when scratch is overwritten
 3333|      0|                            stack.top().val = scratch;
 3334|      0|                            scratch = thunk->content;
 3335|  3.56M|                        } else {
 3336|  3.56M|                            stack.newCall(loc, thunk, thunk->self, thunk->offset, thunk->upValues);
 3337|       |                            // Keep arr alive when scratch is overwritten
 3338|  3.56M|                            stack.top().val = scratch;
 3339|  3.56M|                            evaluate(thunk->body, stack.size());
 3340|  3.56M|                        }
 3341|  3.56M|                        auto element = manifestJson(tloc, multiline, indent2);
 3342|       |                        // Restore scratch
 3343|  3.56M|                        scratch = stack.top().val;
 3344|  3.56M|                        stack.pop();
 3345|  3.56M|                        ss << prefix << indent2 << element;
 3346|  3.56M|                        prefix = multiline ? U",\n" : U", ";
  ------------------
  |  Branch (3346:34): [True: 1.80M, False: 1.76M]
  ------------------
 3347|  3.56M|                    }
 3348|   121k|                    ss << (multiline ? U"\n" : U"") << indent << U"]";
  ------------------
  |  Branch (3348:28): [True: 67.8k, False: 53.2k]
  ------------------
 3349|   121k|                }
 3350|   156k|            } break;
 3351|       |
 3352|  83.7k|            case Value::BOOLEAN: ss << (scratch.v.b ? U"true" : U"false"); break;
  ------------------
  |  Branch (3352:13): [True: 83.7k, False: 4.41M]
  |  Branch (3352:41): [True: 34.8k, False: 48.8k]
  ------------------
 3353|       |
 3354|  3.62M|            case Value::NUMBER: ss << decode_utf8(jsonnet_unparse_number(scratch.v.d)); break;
  ------------------
  |  Branch (3354:13): [True: 3.62M, False: 870k]
  ------------------
 3355|       |
 3356|     27|            case Value::FUNCTION:
  ------------------
  |  Branch (3356:13): [True: 27, False: 4.50M]
  ------------------
 3357|     27|                throw makeError(loc, "couldn't manifest function in JSON output.");
 3358|       |
 3359|  3.41k|            case Value::NULL_TYPE: ss << U"null"; break;
  ------------------
  |  Branch (3359:13): [True: 3.41k, False: 4.49M]
  ------------------
 3360|       |
 3361|   572k|            case Value::OBJECT: {
  ------------------
  |  Branch (3361:13): [True: 572k, False: 3.92M]
  ------------------
 3362|   572k|                auto *obj = static_cast<HeapObject *>(scratch.v.h);
 3363|   572k|                runInvariants(loc, obj);
 3364|       |                // Using std::map has the useful side-effect of ordering the fields
 3365|       |                // alphabetically.
 3366|   572k|                std::map<UString, const Identifier *> fields;
 3367|   773k|                for (const auto &f : objectFields(obj, true)) {
  ------------------
  |  Branch (3367:36): [True: 773k, False: 572k]
  ------------------
 3368|   773k|                    fields[f->name] = f;
 3369|   773k|                }
 3370|   572k|                if (fields.size() == 0) {
  ------------------
  |  Branch (3370:21): [True: 117k, False: 455k]
  ------------------
 3371|   117k|                    ss << U"{ }";
 3372|   455k|                } else {
 3373|   455k|                    UString indent2 = multiline ? indent + U"   " : indent;
  ------------------
  |  Branch (3373:39): [True: 193k, False: 262k]
  ------------------
 3374|   455k|                    const char32_t *prefix = multiline ? U"{\n" : U"{";
  ------------------
  |  Branch (3374:46): [True: 193k, False: 262k]
  ------------------
 3375|   709k|                    for (const auto &f : fields) {
  ------------------
  |  Branch (3375:40): [True: 709k, False: 455k]
  ------------------
 3376|       |                        // pushes FRAME_CALL
 3377|   709k|                        const AST *body = objectIndex(loc, obj, f.second, 0);
 3378|   709k|                        stack.top().val = scratch;
 3379|   709k|                        evaluate(body, stack.size());
 3380|   709k|                        auto vstr = manifestJson(body->location, multiline, indent2);
 3381|       |                        // Reset scratch so that the object we're manifesting doesn't
 3382|       |                        // get GC'd.
 3383|   709k|                        scratch = stack.top().val;
 3384|   709k|                        stack.pop();
 3385|   709k|                        ss << prefix << indent2 << jsonnet_string_unparse(f.first, false) << U": "
 3386|   709k|                           << vstr;
 3387|   709k|                        prefix = multiline ? U",\n" : U", ";
  ------------------
  |  Branch (3387:34): [True: 263k, False: 445k]
  ------------------
 3388|   709k|                    }
 3389|   455k|                    ss << (multiline ? U"\n" : U"") << indent << U"}";
  ------------------
  |  Branch (3389:28): [True: 60.7k, False: 394k]
  ------------------
 3390|   455k|                }
 3391|   572k|            } break;
 3392|       |
 3393|  54.2k|            case Value::STRING: {
  ------------------
  |  Branch (3393:13): [True: 54.2k, False: 4.44M]
  ------------------
 3394|  54.2k|                const UString &str = static_cast<HeapString *>(scratch.v.h)->value;
 3395|  54.2k|                ss << jsonnet_string_unparse(str, false);
 3396|  54.2k|            } break;
 3397|  4.50M|        }
 3398|  4.27M|        return ss.str();
 3399|  4.50M|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter13runInvariantsERKNS0_13LocationRangeEPNS1_10HeapObjectE:
 2044|   574k|    {
 2045|   574k|        if (stack.alreadyExecutingInvariants(self))
  ------------------
  |  Branch (2045:13): [True: 1.62k, False: 572k]
  ------------------
 2046|  1.62k|            return;
 2047|       |
 2048|   572k|        unsigned counter = 0;
 2049|   572k|        unsigned initial_stack_size = stack.size();
 2050|   572k|        stack.newFrame(FRAME_INVARIANTS, loc);
 2051|   572k|        std::vector<HeapThunk *> &thunks = stack.top().thunks;
 2052|   572k|        objectInvariants(self, self, counter, thunks);
 2053|   572k|        if (thunks.size() == 0) {
  ------------------
  |  Branch (2053:13): [True: 560k, False: 12.5k]
  ------------------
 2054|   560k|            stack.pop();
 2055|   560k|            return;
 2056|   560k|        }
 2057|  12.5k|        HeapThunk *thunk = thunks[0];
 2058|  12.5k|        stack.top().elementId = 1;
 2059|  12.5k|        stack.top().self = self;
 2060|  12.5k|        stack.newCall(loc, thunk, thunk->self, thunk->offset, thunk->upValues);
 2061|  12.5k|        evaluate(thunk->body, initial_stack_size);
 2062|  12.5k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111InterpreterD2Ev:
 1024|  4.02k|    {
 1025|  4.02k|        for (const auto &pair : cachedImports) {
  ------------------
  |  Branch (1025:31): [True: 60, False: 4.02k]
  ------------------
 1026|     60|            delete pair.second;
 1027|     60|        }
 1028|  4.02k|    }
vm.cpp:_ZN7jsonnet8internal12_GLOBAL__N_111Interpreter13manifestMultiEb:
 3412|  2.48k|    {
 3413|  2.48k|        StrMap r;
 3414|  2.48k|        LocationRange loc("During manifestation");
 3415|  2.48k|        if (scratch.t != Value::OBJECT) {
  ------------------
  |  Branch (3415:13): [True: 1.00k, False: 1.48k]
  ------------------
 3416|  1.00k|            std::stringstream ss;
 3417|  1.00k|            ss << "multi mode: top-level object was a " << type_str(scratch.t) << ", "
 3418|  1.00k|               << "should be an object whose keys are filenames and values hold "
 3419|  1.00k|               << "the JSON for that file.";
 3420|  1.00k|            throw makeError(loc, ss.str());
 3421|  1.00k|        }
 3422|  1.48k|        auto *obj = static_cast<HeapObject *>(scratch.v.h);
 3423|  1.48k|        runInvariants(loc, obj);
 3424|  1.48k|        std::map<UString, const Identifier *> fields;
 3425|  7.94k|        for (const auto &f : objectFields(obj, true)) {
  ------------------
  |  Branch (3425:28): [True: 7.94k, False: 1.48k]
  ------------------
 3426|  7.94k|            fields[f->name] = f;
 3427|  7.94k|        }
 3428|  7.39k|        for (const auto &f : fields) {
  ------------------
  |  Branch (3428:28): [True: 7.39k, False: 1.48k]
  ------------------
 3429|       |            // pushes FRAME_CALL
 3430|  7.39k|            const AST *body = objectIndex(loc, obj, f.second, 0);
 3431|  7.39k|            stack.top().val = scratch;
 3432|  7.39k|            evaluate(body, stack.size());
 3433|  7.39k|            auto vstr =
 3434|  7.39k|                string ? manifestString(body->location) : manifestJson(body->location, true, U"");
  ------------------
  |  Branch (3434:17): [True: 0, False: 7.39k]
  ------------------
 3435|       |            // Reset scratch so that the object we're manifesting doesn't
 3436|       |            // get GC'd.
 3437|  7.39k|            scratch = stack.top().val;
 3438|  7.39k|            stack.pop();
 3439|  7.39k|            r[encode_utf8(f.first)] = encode_utf8(vstr);
 3440|  7.39k|        }
 3441|  1.48k|        return r;
 3442|  2.48k|    }

_ZN7jsonnet8internal10TraceFrameC2ERKNS0_13LocationRangeERKNSt3__112basic_stringIcNS5_11char_traitsIcEENS5_9allocatorIcEEEE:
   33|   330k|        : location(location), name(name)
   34|   330k|    {
   35|   330k|    }
_ZN7jsonnet8internal12RuntimeErrorC2ENSt3__16vectorINS0_10TraceFrameENS2_9allocatorIS4_EEEERKNS2_12basic_stringIcNS2_11char_traitsIcEENS5_IcEEEE:
   45|  3.37k|        : stackTrace(stack_trace), msg(msg)
   46|  3.37k|    {
   47|  3.37k|    }

_ZN2c43yml9CallbacksC2Ev:
31979|      2|    m_user_data(nullptr),
31980|       |    #ifndef RYML_NO_DEFAULT_CALLBACKS
31981|      2|    m_allocate(allocate_impl),
31982|      2|    m_free(free_impl),
31983|      2|    m_error(error_impl)
31984|       |    #else
31985|       |    m_allocate(nullptr),
31986|       |    m_free(nullptr),
31987|       |    m_error(nullptr)
31988|       |    #endif
31989|      2|{
31990|      2|}

