// Copyright 2014 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "fxjs/xfa/cfxjse_formcalc_context.h"

#include <ctype.h>
#include <math.h>
#include <stdint.h>
#include <stdlib.h>

#include <algorithm>
#include <limits>
#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include "core/fxcrt/cfx_datetime.h"
#include "core/fxcrt/code_point_view.h"
#include "core/fxcrt/data_vector.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_random.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/span_util.h"
#include "core/fxcrt/widetext_buffer.h"
#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_class.h"
#include "fxjs/xfa/cfxjse_context.h"
#include "fxjs/xfa/cfxjse_engine.h"
#include "fxjs/xfa/cfxjse_value.h"
#include "fxjs/xfa/cjx_object.h"
#include "third_party/base/check_op.h"
#include "third_party/base/numerics/safe_conversions.h"
#include "v8/include/v8-container.h"
#include "v8/include/v8-function-callback.h"
#include "v8/include/v8-local-handle.h"
#include "v8/include/v8-object.h"
#include "v8/include/v8-primitive.h"
#include "xfa/fgas/crt/cfgas_decimal.h"
#include "xfa/fxfa/cxfa_ffnotify.h"
#include "xfa/fxfa/formcalc/cxfa_fmparser.h"
#include "xfa/fxfa/formcalc/cxfa_fmtojavascriptdepth.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_localevalue.h"
#include "xfa/fxfa/parser/cxfa_node.h"
#include "xfa/fxfa/parser/cxfa_thisproxy.h"
#include "xfa/fxfa/parser/cxfa_timezoneprovider.h"
#include "xfa/fxfa/parser/gced_locale_iface.h"
#include "xfa/fxfa/parser/xfa_utils.h"

using pdfium::fxjse::kClassTag;
using pdfium::fxjse::kFuncTag;

namespace {

// Maximum number of characters Acrobat can fit in a text box.
constexpr int kMaxCharCount = 15654908;

const double kFinancialPrecision = 0.00000001;

const wchar_t kStrCode[] = L"0123456789abcdef";

struct XFA_FMHtmlReserveCode {
  uint16_t m_uCode;
  // Inline string data reduces size for small strings.
  const char m_htmlReserve[10];
};

// Sorted by |m_htmlReserve|.
const XFA_FMHtmlReserveCode kReservesForDecode[] = {
    {198, "AElig"},   {193, "Aacute"},   {194, "Acirc"},    {192, "Agrave"},
    {913, "Alpha"},   {197, "Aring"},    {195, "Atilde"},   {196, "Auml"},
    {914, "Beta"},    {199, "Ccedil"},   {935, "Chi"},      {8225, "Dagger"},
    {916, "Delta"},   {208, "ETH"},      {201, "Eacute"},   {202, "Ecirc"},
    {200, "Egrave"},  {917, "Epsilon"},  {919, "Eta"},      {203, "Euml"},
    {915, "Gamma"},   {922, "Kappa"},    {923, "Lambda"},   {924, "Mu"},
    {209, "Ntilde"},  {925, "Nu"},       {338, "OElig"},    {211, "Oacute"},
    {212, "Ocirc"},   {210, "Ograve"},   {937, "Omega"},    {927, "Omicron"},
    {216, "Oslash"},  {213, "Otilde"},   {214, "Ouml"},     {934, "Phi"},
    {928, "Pi"},      {936, "Psi"},      {929, "Rho"},      {352, "Scaron"},
    {931, "Sigma"},   {222, "THORN"},    {932, "Tau"},      {920, "Theta"},
    {218, "Uacute"},  {219, "Ucirc"},    {217, "Ugrave"},   {933, "Upsilon"},
    {220, "Uuml"},    {926, "Xi"},       {221, "Yacute"},   {376, "Yuml"},
    {918, "Zeta"},    {225, "aacute"},   {226, "acirc"},    {180, "acute"},
    {230, "aelig"},   {224, "agrave"},   {8501, "alefsym"}, {945, "alpha"},
    {38, "amp"},      {8743, "and"},     {8736, "ang"},     {39, "apos"},
    {229, "aring"},   {8776, "asymp"},   {227, "atilde"},   {228, "auml"},
    {8222, "bdquo"},  {946, "beta"},     {166, "brvbar"},   {8226, "bull"},
    {8745, "cap"},    {231, "ccedil"},   {184, "cedil"},    {162, "cent"},
    {967, "chi"},     {710, "circ"},     {9827, "clubs"},   {8773, "cong"},
    {169, "copy"},    {8629, "crarr"},   {8746, "cup"},     {164, "current"},
    {8659, "dArr"},   {8224, "dagger"},  {8595, "darr"},    {176, "deg"},
    {948, "delta"},   {9830, "diams"},   {247, "divide"},   {233, "eacute"},
    {234, "ecirc"},   {232, "egrave"},   {8709, "empty"},   {8195, "emsp"},
    {8194, "ensp"},   {949, "epsilon"},  {8801, "equiv"},   {951, "eta"},
    {240, "eth"},     {235, "euml"},     {8364, "euro"},    {8707, "exist"},
    {402, "fnof"},    {8704, "forall"},  {189, "frac12"},   {188, "frac14"},
    {190, "frac34"},  {8260, "frasl"},   {947, "gamma"},    {8805, "ge"},
    {62, "gt"},       {8660, "hArr"},    {8596, "harr"},    {9829, "hearts"},
    {8230, "hellip"}, {237, "iacute"},   {238, "icirc"},    {161, "iexcl"},
    {236, "igrave"},  {8465, "image"},   {8734, "infin"},   {8747, "int"},
    {953, "iota"},    {191, "iquest"},   {8712, "isin"},    {239, "iuml"},
    {954, "kappa"},   {8656, "lArr"},    {205, "lacute"},   {955, "lambda"},
    {9001, "lang"},   {171, "laquo"},    {8592, "larr"},    {8968, "lceil"},
    {206, "lcirc"},   {8220, "ldquo"},   {8804, "le"},      {8970, "lfloor"},
    {204, "lgrave"},  {921, "lota"},     {8727, "lowast"},  {9674, "loz"},
    {8206, "lrm"},    {8249, "lsaquo"},  {8216, "lsquo"},   {60, "lt"},
    {207, "luml"},    {175, "macr"},     {8212, "mdash"},   {181, "micro"},
    {183, "middot"},  {8722, "minus"},   {956, "mu"},       {8711, "nabla"},
    {160, "nbsp"},    {8211, "ndash"},   {8800, "ne"},      {8715, "ni"},
    {172, "not"},     {8713, "notin"},   {8836, "nsub"},    {241, "ntilde"},
    {957, "nu"},      {243, "oacute"},   {244, "ocirc"},    {339, "oelig"},
    {242, "ograve"},  {8254, "oline"},   {969, "omega"},    {959, "omicron"},
    {8853, "oplus"},  {8744, "or"},      {170, "ordf"},     {186, "ordm"},
    {248, "oslash"},  {245, "otilde"},   {8855, "otimes"},  {246, "ouml"},
    {182, "para"},    {8706, "part"},    {8240, "permil"},  {8869, "perp"},
    {966, "phi"},     {960, "pi"},       {982, "piv"},      {177, "plusmn"},
    {8242, "prime"},  {8719, "prod"},    {8733, "prop"},    {968, "psi"},
    {163, "pund"},    {34, "quot"},      {8658, "rArr"},    {8730, "radic"},
    {9002, "rang"},   {187, "raquo"},    {8594, "rarr"},    {8969, "rceil"},
    {8476, "real"},   {174, "reg"},      {8971, "rfloor"},  {961, "rho"},
    {8207, "rlm"},    {8250, "rsaquo"},  {8217, "rsquo"},   {353, "saron"},
    {8218, "sbquo"},  {8901, "sdot"},    {167, "sect"},     {173, "shy"},
    {963, "sigma"},   {962, "sigmaf"},   {8764, "sim"},     {9824, "spades"},
    {8834, "sub"},    {8838, "sube"},    {8721, "sum"},     {8835, "sup"},
    {185, "sup1"},    {178, "sup2"},     {179, "sup3"},     {8839, "supe"},
    {223, "szlig"},   {964, "tau"},      {8221, "tdquo"},   {8756, "there4"},
    {952, "theta"},   {977, "thetasym"}, {8201, "thinsp"},  {254, "thorn"},
    {732, "tilde"},   {215, "times"},    {8482, "trade"},   {8657, "uArr"},
    {250, "uacute"},  {8593, "uarr"},    {251, "ucirc"},    {249, "ugrave"},
    {168, "uml"},     {978, "upsih"},    {965, "upsilon"},  {252, "uuml"},
    {8472, "weierp"}, {958, "xi"},       {253, "yacute"},   {165, "yen"},
    {255, "yuml"},    {950, "zeta"},     {8205, "zwj"},     {8204, "zwnj"},
};

// Sorted by |m_uCode|.
const XFA_FMHtmlReserveCode kReservesForEncode[] = {
    {34, "quot"},     {38, "amp"},      {39, "apos"},      {60, "lt"},
    {62, "gt"},       {160, "nbsp"},    {161, "iexcl"},    {162, "cent"},
    {163, "pund"},    {164, "current"}, {165, "yen"},      {166, "brvbar"},
    {167, "sect"},    {168, "uml"},     {169, "copy"},     {170, "ordf"},
    {171, "laquo"},   {172, "not"},     {173, "shy"},      {174, "reg"},
    {175, "macr"},    {176, "deg"},     {177, "plusmn"},   {178, "sup2"},
    {179, "sup3"},    {180, "acute"},   {181, "micro"},    {182, "para"},
    {183, "middot"},  {184, "cedil"},   {185, "sup1"},     {186, "ordm"},
    {187, "raquo"},   {188, "frac14"},  {189, "frac12"},   {190, "frac34"},
    {191, "iquest"},  {192, "Agrave"},  {193, "Aacute"},   {194, "Acirc"},
    {195, "Atilde"},  {196, "Auml"},    {197, "Aring"},    {198, "AElig"},
    {199, "Ccedil"},  {200, "Egrave"},  {201, "Eacute"},   {202, "Ecirc"},
    {203, "Euml"},    {204, "lgrave"},  {205, "lacute"},   {206, "lcirc"},
    {207, "luml"},    {208, "ETH"},     {209, "Ntilde"},   {210, "Ograve"},
    {211, "Oacute"},  {212, "Ocirc"},   {213, "Otilde"},   {214, "Ouml"},
    {215, "times"},   {216, "Oslash"},  {217, "Ugrave"},   {218, "Uacute"},
    {219, "Ucirc"},   {220, "Uuml"},    {221, "Yacute"},   {222, "THORN"},
    {223, "szlig"},   {224, "agrave"},  {225, "aacute"},   {226, "acirc"},
    {227, "atilde"},  {228, "auml"},    {229, "aring"},    {230, "aelig"},
    {231, "ccedil"},  {232, "egrave"},  {233, "eacute"},   {234, "ecirc"},
    {235, "euml"},    {236, "igrave"},  {237, "iacute"},   {238, "icirc"},
    {239, "iuml"},    {240, "eth"},     {241, "ntilde"},   {242, "ograve"},
    {243, "oacute"},  {244, "ocirc"},   {245, "otilde"},   {246, "ouml"},
    {247, "divide"},  {248, "oslash"},  {249, "ugrave"},   {250, "uacute"},
    {251, "ucirc"},   {252, "uuml"},    {253, "yacute"},   {254, "thorn"},
    {255, "yuml"},    {338, "OElig"},   {339, "oelig"},    {352, "Scaron"},
    {353, "saron"},   {376, "Yuml"},    {402, "fnof"},     {710, "circ"},
    {732, "tilde"},   {913, "Alpha"},   {914, "Beta"},     {915, "Gamma"},
    {916, "Delta"},   {917, "Epsilon"}, {918, "Zeta"},     {919, "Eta"},
    {920, "Theta"},   {921, "lota"},    {922, "Kappa"},    {923, "Lambda"},
    {924, "Mu"},      {925, "Nu"},      {926, "Xi"},       {927, "Omicron"},
    {928, "Pi"},      {929, "Rho"},     {931, "Sigma"},    {932, "Tau"},
    {933, "Upsilon"}, {934, "Phi"},     {935, "Chi"},      {936, "Psi"},
    {937, "Omega"},   {945, "alpha"},   {946, "beta"},     {947, "gamma"},
    {948, "delta"},   {949, "epsilon"}, {950, "zeta"},     {951, "eta"},
    {952, "theta"},   {953, "iota"},    {954, "kappa"},    {955, "lambda"},
    {956, "mu"},      {957, "nu"},      {958, "xi"},       {959, "omicron"},
    {960, "pi"},      {961, "rho"},     {962, "sigmaf"},   {963, "sigma"},
    {964, "tau"},     {965, "upsilon"}, {966, "phi"},      {967, "chi"},
    {968, "psi"},     {969, "omega"},   {977, "thetasym"}, {978, "upsih"},
    {982, "piv"},     {8194, "ensp"},   {8195, "emsp"},    {8201, "thinsp"},
    {8204, "zwnj"},   {8205, "zwj"},    {8206, "lrm"},     {8207, "rlm"},
    {8211, "ndash"},  {8212, "mdash"},  {8216, "lsquo"},   {8217, "rsquo"},
    {8218, "sbquo"},  {8220, "ldquo"},  {8221, "tdquo"},   {8222, "bdquo"},
    {8224, "dagger"}, {8225, "Dagger"}, {8226, "bull"},    {8230, "hellip"},
    {8240, "permil"}, {8242, "prime"},  {8249, "lsaquo"},  {8250, "rsaquo"},
    {8254, "oline"},  {8260, "frasl"},  {8364, "euro"},    {8465, "image"},
    {8472, "weierp"}, {8476, "real"},   {8482, "trade"},   {8501, "alefsym"},
    {8592, "larr"},   {8593, "uarr"},   {8594, "rarr"},    {8595, "darr"},
    {8596, "harr"},   {8629, "crarr"},  {8656, "lArr"},    {8657, "uArr"},
    {8658, "rArr"},   {8659, "dArr"},   {8660, "hArr"},    {8704, "forall"},
    {8706, "part"},   {8707, "exist"},  {8709, "empty"},   {8711, "nabla"},
    {8712, "isin"},   {8713, "notin"},  {8715, "ni"},      {8719, "prod"},
    {8721, "sum"},    {8722, "minus"},  {8727, "lowast"},  {8730, "radic"},
    {8733, "prop"},   {8734, "infin"},  {8736, "ang"},     {8743, "and"},
    {8744, "or"},     {8745, "cap"},    {8746, "cup"},     {8747, "int"},
    {8756, "there4"}, {8764, "sim"},    {8773, "cong"},    {8776, "asymp"},
    {8800, "ne"},     {8801, "equiv"},  {8804, "le"},      {8805, "ge"},
    {8834, "sub"},    {8835, "sup"},    {8836, "nsub"},    {8838, "sube"},
    {8839, "supe"},   {8853, "oplus"},  {8855, "otimes"},  {8869, "perp"},
    {8901, "sdot"},   {8968, "lceil"},  {8969, "rceil"},   {8970, "lfloor"},
    {8971, "rfloor"}, {9001, "lang"},   {9002, "rang"},    {9674, "loz"},
    {9824, "spades"}, {9827, "clubs"},  {9829, "hearts"},  {9830, "diams"},
};

const FXJSE_FUNCTION_DESCRIPTOR kFormCalcFunctions[] = {
    {kFuncTag, "Abs", CFXJSE_FormCalcContext::Abs},
    {kFuncTag, "Avg", CFXJSE_FormCalcContext::Avg},
    {kFuncTag, "Ceil", CFXJSE_FormCalcContext::Ceil},
    {kFuncTag, "Count", CFXJSE_FormCalcContext::Count},
    {kFuncTag, "Floor", CFXJSE_FormCalcContext::Floor},
    {kFuncTag, "Max", CFXJSE_FormCalcContext::Max},
    {kFuncTag, "Min", CFXJSE_FormCalcContext::Min},
    {kFuncTag, "Mod", CFXJSE_FormCalcContext::Mod},
    {kFuncTag, "Round", CFXJSE_FormCalcContext::Round},
    {kFuncTag, "Sum", CFXJSE_FormCalcContext::Sum},
    {kFuncTag, "Date", CFXJSE_FormCalcContext::Date},
    {kFuncTag, "Date2Num", CFXJSE_FormCalcContext::Date2Num},
    {kFuncTag, "DateFmt", CFXJSE_FormCalcContext::DateFmt},
    {kFuncTag, "IsoDate2Num", CFXJSE_FormCalcContext::IsoDate2Num},
    {kFuncTag, "IsoTime2Num", CFXJSE_FormCalcContext::IsoTime2Num},
    {kFuncTag, "LocalDateFmt", CFXJSE_FormCalcContext::LocalDateFmt},
    {kFuncTag, "LocalTimeFmt", CFXJSE_FormCalcContext::LocalTimeFmt},
    {kFuncTag, "Num2Date", CFXJSE_FormCalcContext::Num2Date},
    {kFuncTag, "Num2GMTime", CFXJSE_FormCalcContext::Num2GMTime},
    {kFuncTag, "Num2Time", CFXJSE_FormCalcContext::Num2Time},
    {kFuncTag, "Time", CFXJSE_FormCalcContext::Time},
    {kFuncTag, "Time2Num", CFXJSE_FormCalcContext::Time2Num},
    {kFuncTag, "TimeFmt", CFXJSE_FormCalcContext::TimeFmt},
    {kFuncTag, "Apr", CFXJSE_FormCalcContext::Apr},
    {kFuncTag, "Cterm", CFXJSE_FormCalcContext::CTerm},
    {kFuncTag, "FV", CFXJSE_FormCalcContext::FV},
    {kFuncTag, "Ipmt", CFXJSE_FormCalcContext::IPmt},
    {kFuncTag, "NPV", CFXJSE_FormCalcContext::NPV},
    {kFuncTag, "Pmt", CFXJSE_FormCalcContext::Pmt},
    {kFuncTag, "PPmt", CFXJSE_FormCalcContext::PPmt},
    {kFuncTag, "PV", CFXJSE_FormCalcContext::PV},
    {kFuncTag, "Rate", CFXJSE_FormCalcContext::Rate},
    {kFuncTag, "Term", CFXJSE_FormCalcContext::Term},
    {kFuncTag, "Choose", CFXJSE_FormCalcContext::Choose},
    {kFuncTag, "Exists", CFXJSE_FormCalcContext::Exists},
    {kFuncTag, "HasValue", CFXJSE_FormCalcContext::HasValue},
    {kFuncTag, "Oneof", CFXJSE_FormCalcContext::Oneof},
    {kFuncTag, "Within", CFXJSE_FormCalcContext::Within},
    {kFuncTag, "If", CFXJSE_FormCalcContext::If},
    {kFuncTag, "Eval", CFXJSE_FormCalcContext::Eval},
    {kFuncTag, "Translate", CFXJSE_FormCalcContext::eval_translation},
    {kFuncTag, "Ref", CFXJSE_FormCalcContext::Ref},
    {kFuncTag, "UnitType", CFXJSE_FormCalcContext::UnitType},
    {kFuncTag, "UnitValue", CFXJSE_FormCalcContext::UnitValue},
    {kFuncTag, "At", CFXJSE_FormCalcContext::At},
    {kFuncTag, "Concat", CFXJSE_FormCalcContext::Concat},
    {kFuncTag, "Decode", CFXJSE_FormCalcContext::Decode},
    {kFuncTag, "Encode", CFXJSE_FormCalcContext::Encode},
    {kFuncTag, "Format", CFXJSE_FormCalcContext::Format},
    {kFuncTag, "Left", CFXJSE_FormCalcContext::Left},
    {kFuncTag, "Len", CFXJSE_FormCalcContext::Len},
    {kFuncTag, "Lower", CFXJSE_FormCalcContext::Lower},
    {kFuncTag, "Ltrim", CFXJSE_FormCalcContext::Ltrim},
    {kFuncTag, "Parse", CFXJSE_FormCalcContext::Parse},
    {kFuncTag, "Replace", CFXJSE_FormCalcContext::Replace},
    {kFuncTag, "Right", CFXJSE_FormCalcContext::Right},
    {kFuncTag, "Rtrim", CFXJSE_FormCalcContext::Rtrim},
    {kFuncTag, "Space", CFXJSE_FormCalcContext::Space},
    {kFuncTag, "Str", CFXJSE_FormCalcContext::Str},
    {kFuncTag, "Stuff", CFXJSE_FormCalcContext::Stuff},
    {kFuncTag, "Substr", CFXJSE_FormCalcContext::Substr},
    {kFuncTag, "Uuid", CFXJSE_FormCalcContext::Uuid},
    {kFuncTag, "Upper", CFXJSE_FormCalcContext::Upper},
    {kFuncTag, "WordNum", CFXJSE_FormCalcContext::WordNum},
    {kFuncTag, "Get", CFXJSE_FormCalcContext::Get},
    {kFuncTag, "Post", CFXJSE_FormCalcContext::Post},
    {kFuncTag, "Put", CFXJSE_FormCalcContext::Put},
    {kFuncTag, "pos_op", CFXJSE_FormCalcContext::positive_operator},
    {kFuncTag, "neg_op", CFXJSE_FormCalcContext::negative_operator},
    {kFuncTag, "log_or_op", CFXJSE_FormCalcContext::logical_or_operator},
    {kFuncTag, "log_and_op", CFXJSE_FormCalcContext::logical_and_operator},
    {kFuncTag, "log_not_op", CFXJSE_FormCalcContext::logical_not_operator},
    {kFuncTag, "eq_op", CFXJSE_FormCalcContext::equality_operator},
    {kFuncTag, "neq_op", CFXJSE_FormCalcContext::notequality_operator},
    {kFuncTag, "lt_op", CFXJSE_FormCalcContext::less_operator},
    {kFuncTag, "le_op", CFXJSE_FormCalcContext::lessequal_operator},
    {kFuncTag, "gt_op", CFXJSE_FormCalcContext::greater_operator},
    {kFuncTag, "ge_op", CFXJSE_FormCalcContext::greaterequal_operator},
    {kFuncTag, "plus_op", CFXJSE_FormCalcContext::plus_operator},
    {kFuncTag, "minus_op", CFXJSE_FormCalcContext::minus_operator},
    {kFuncTag, "mul_op", CFXJSE_FormCalcContext::multiple_operator},
    {kFuncTag, "div_op", CFXJSE_FormCalcContext::divide_operator},
    {kFuncTag, "asgn_val_op", CFXJSE_FormCalcContext::assign_value_operator},
    {kFuncTag, "dot_acc", CFXJSE_FormCalcContext::dot_accessor},
    {kFuncTag, "dotdot_acc", CFXJSE_FormCalcContext::dotdot_accessor},
    {kFuncTag, "concat_obj", CFXJSE_FormCalcContext::concat_fm_object},
    {kFuncTag, "is_obj", CFXJSE_FormCalcContext::is_fm_object},
    {kFuncTag, "is_ary", CFXJSE_FormCalcContext::is_fm_array},
    {kFuncTag, "get_val", CFXJSE_FormCalcContext::get_fm_value},
    {kFuncTag, "get_jsobj", CFXJSE_FormCalcContext::get_fm_jsobj},
    {kFuncTag, "var_filter", CFXJSE_FormCalcContext::fm_var_filter},
};

const uint8_t kAltTableDate[] = {
    255, 255, 255, 3,   9,   255, 255, 255, 255, 255, 255,
    255, 2,   255, 255, 255, 255, 255, 255, 255, 255, 255,
    255, 255, 1,   255, 255, 255, 255, 255, 255, 255, 255,
};
static_assert(std::size(kAltTableDate) == L'a' - L'A' + 1,
              "Invalid kAltTableDate size.");

const uint8_t kAltTableTime[] = {
    14,  255, 255, 3,   9,   255, 255, 15,  255, 255, 255,
    255, 6,   255, 255, 255, 255, 255, 7,   255, 255, 255,
    255, 255, 1,   17,  255, 255, 255, 255, 255, 255, 255,
};
static_assert(std::size(kAltTableTime) == L'a' - L'A' + 1,
              "Invalid kAltTableTime size.");

void AlternateDateTimeSymbols(WideString* pPattern,
                              const WideString& wsAltSymbols,
                              bool bIsDate) {
  const uint8_t* pAltTable = bIsDate ? kAltTableDate : kAltTableTime;
  int32_t nLength = pPattern->GetLength();
  bool bInConstRange = false;
  bool bEscape = false;
  int32_t i = 0;
  while (i < nLength) {
    wchar_t wc = (*pPattern)[i];
    if (wc == L'\'') {
      bInConstRange = !bInConstRange;
      if (bEscape) {
        i++;
      } else {
        pPattern->Delete(i);
        nLength--;
      }
      bEscape = !bEscape;
      continue;
    }
    if (!bInConstRange && wc >= L'A' && wc <= L'a') {
      uint8_t nAlt = pAltTable[wc - L'A'];
      if (nAlt != 255)
        pPattern->SetAt(i, wsAltSymbols[nAlt]);
    }
    i++;
    bEscape = false;
  }
}

std::pair<bool, CXFA_LocaleValue::ValueType> PatternStringType(
    ByteStringView bsPattern) {
  WideString wsPattern = WideString::FromUTF8(bsPattern);
  if (L"datetime" == wsPattern.First(8))
    return {true, CXFA_LocaleValue::ValueType::kDateTime};
  if (L"date" == wsPattern.First(4)) {
    auto pos = wsPattern.Find(L"time");
    if (pos.has_value() && pos.value() != 0)
      return {true, CXFA_LocaleValue::ValueType::kDateTime};
    return {true, CXFA_LocaleValue::ValueType::kDate};
  }
  if (L"time" == wsPattern.First(4))
    return {true, CXFA_LocaleValue::ValueType::kTime};
  if (L"text" == wsPattern.First(4))
    return {true, CXFA_LocaleValue::ValueType::kText};
  if (L"num" == wsPattern.First(3)) {
    if (L"integer" == wsPattern.Substr(4, 7))
      return {true, CXFA_LocaleValue::ValueType::kInteger};
    if (L"decimal" == wsPattern.Substr(4, 7))
      return {true, CXFA_LocaleValue::ValueType::kDecimal};
    if (L"currency" == wsPattern.Substr(4, 8))
      return {true, CXFA_LocaleValue::ValueType::kFloat};
    if (L"percent" == wsPattern.Substr(4, 7))
      return {true, CXFA_LocaleValue::ValueType::kFloat};
    return {true, CXFA_LocaleValue::ValueType::kFloat};
  }

  CXFA_LocaleValue::ValueType type = CXFA_LocaleValue::ValueType::kNull;
  wsPattern.MakeLower();
  const wchar_t* pData = wsPattern.c_str();
  int32_t iLength = wsPattern.GetLength();
  int32_t iIndex = 0;
  bool bSingleQuotation = false;
  while (iIndex < iLength) {
    wchar_t wsPatternChar = pData[iIndex];
    if (wsPatternChar == 0x27) {
      bSingleQuotation = !bSingleQuotation;
      iIndex++;
      continue;
    }
    if (bSingleQuotation) {
      iIndex++;
      continue;
    }

    if (wsPatternChar == 'h' || wsPatternChar == 'k')
      return {false, CXFA_LocaleValue::ValueType::kTime};
    if (wsPatternChar == 'x' || wsPatternChar == 'o' || wsPatternChar == '0')
      return {false, CXFA_LocaleValue::ValueType::kText};
    if (wsPatternChar == 'v' || wsPatternChar == '8' || wsPatternChar == '$')
      return {false, CXFA_LocaleValue::ValueType::kFloat};
    if (wsPatternChar == 'y' || wsPatternChar == 'j') {
      iIndex++;
      wchar_t timePatternChar;
      while (iIndex < iLength) {
        timePatternChar = pData[iIndex];
        if (timePatternChar == 0x27) {
          bSingleQuotation = !bSingleQuotation;
          iIndex++;
          continue;
        }
        if (!bSingleQuotation && timePatternChar == 't')
          return {false, CXFA_LocaleValue::ValueType::kDateTime};
        iIndex++;
      }
      return {false, CXFA_LocaleValue::ValueType::kDate};
    }

    if (wsPatternChar == 'a') {
      type = CXFA_LocaleValue::ValueType::kText;
    } else if (wsPatternChar == 'z' || wsPatternChar == 's' ||
               wsPatternChar == 'e' || wsPatternChar == ',' ||
               wsPatternChar == '.') {
      type = CXFA_LocaleValue::ValueType::kFloat;
    }
    iIndex++;
  }
  return {false, type};
}

CFXJSE_FormCalcContext* ToFormCalcContext(CFXJSE_HostObject* pHostObj) {
  return pHostObj ? pHostObj->AsFormCalcContext() : nullptr;
}

GCedLocaleIface* LocaleFromString(CXFA_Document* pDoc,
                                  CXFA_LocaleMgr* pMgr,
                                  ByteStringView bsLocale) {
  if (!bsLocale.IsEmpty())
    return pMgr->GetLocaleByName(WideString::FromUTF8(bsLocale));

  CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
  return pThisNode->GetLocale();
}

WideString FormatFromString(LocaleIface* pLocale, ByteStringView bsFormat) {
  if (!bsFormat.IsEmpty())
    return WideString::FromUTF8(bsFormat);

  return pLocale->GetDatePattern(LocaleIface::DateTimeSubcategory::kDefault);
}

LocaleIface::DateTimeSubcategory SubCategoryFromInt(int32_t iStyle) {
  switch (iStyle) {
    case 1:
      return LocaleIface::DateTimeSubcategory::kShort;
    case 3:
      return LocaleIface::DateTimeSubcategory::kLong;
    case 4:
      return LocaleIface::DateTimeSubcategory::kFull;
    case 0:
    case 2:
    default:
      return LocaleIface::DateTimeSubcategory::kMedium;
  }
}

ByteString GetLocalDateTimeFormat(CXFA_Document* pDoc,
                                  int32_t iStyle,
                                  ByteStringView bsLocale,
                                  bool bStandard,
                                  bool bIsDate) {
  CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
  LocaleIface* pLocale = LocaleFromString(pDoc, pMgr, bsLocale);
  if (!pLocale)
    return ByteString();

  LocaleIface::DateTimeSubcategory category = SubCategoryFromInt(iStyle);
  WideString wsLocal = bIsDate ? pLocale->GetDatePattern(category)
                               : pLocale->GetTimePattern(category);
  if (!bStandard)
    AlternateDateTimeSymbols(&wsLocal, pLocale->GetDateTimeSymbols(), bIsDate);
  return wsLocal.ToUTF8();
}

bool IsWhitespace(char c) {
  return c == 0x20 || c == 0x09 || c == 0x0B || c == 0x0C || c == 0x0A ||
         c == 0x0D;
}

bool IsPartOfNumber(char ch) {
  return isdigit(ch) || ch == '-' || ch == '.';
}

bool IsPartOfNumberW(wchar_t ch) {
  return FXSYS_IsDecimalDigit(ch) || ch == L'-' || ch == L'.';
}

ByteString GUIDString(bool bSeparator) {
  uint8_t data[16];
  auto random_span = pdfium::make_span(data);
  FX_Random_GenerateMT(fxcrt::reinterpret_span<uint32_t>(random_span));
  data[6] = (data[6] & 0x0F) | 0x40;

  ByteString bsGUID;
  {
    // Span's lifetime must end before ReleaseBuffer() below.
    pdfium::span<char> pBuf = bsGUID.GetBuffer(40);
    size_t out_index = 0;
    for (size_t i = 0; i < 16; ++i, out_index += 2) {
      if (bSeparator && (i == 4 || i == 6 || i == 8 || i == 10))
        pBuf[out_index++] = L'-';

      FXSYS_IntToTwoHexChars(data[i], &pBuf[out_index]);
    }
  }
  bsGUID.ReleaseBuffer(bSeparator ? 36 : 32);
  return bsGUID;
}

void GetLocalTimeZone(int32_t* pHour, int32_t* pMin, int32_t* pSec) {
  time_t now;
  FXSYS_time(&now);

  struct tm* pGmt = gmtime(&now);
  struct tm* pLocal = FXSYS_localtime(&now);
  *pHour = pLocal->tm_hour - pGmt->tm_hour;
  *pMin = pLocal->tm_min - pGmt->tm_min;
  *pSec = pLocal->tm_sec - pGmt->tm_sec;
}

bool HTMLSTR2Code(const WideString& pData, uint32_t* iCode) {
  auto cmpFunc = [](const XFA_FMHtmlReserveCode& iter, ByteStringView val) {
    return strcmp(val.unterminated_c_str(), iter.m_htmlReserve) > 0;
  };
  if (!pData.IsASCII())
    return false;
  ByteString temp = pData.ToASCII();
  const XFA_FMHtmlReserveCode* result = std::lower_bound(
      std::begin(kReservesForDecode), std::end(kReservesForDecode),
      temp.AsStringView(), cmpFunc);
  if (result != std::end(kReservesForDecode) &&
      !strcmp(temp.c_str(), result->m_htmlReserve)) {
    *iCode = result->m_uCode;
    return true;
  }
  return false;
}

bool HTMLCode2STR(uint32_t iCode, WideString* wsHTMLReserve) {
  auto cmpFunc = [](const XFA_FMHtmlReserveCode iter, const uint32_t& val) {
    return iter.m_uCode < val;
  };
  const XFA_FMHtmlReserveCode* result =
      std::lower_bound(std::begin(kReservesForEncode),
                       std::end(kReservesForEncode), iCode, cmpFunc);
  if (result != std::end(kReservesForEncode) && result->m_uCode == iCode) {
    *wsHTMLReserve = WideString::FromASCII(result->m_htmlReserve);
    return true;
  }
  return false;
}

WideString DecodeURL(const WideString& wsURL) {
  const wchar_t* pData = wsURL.c_str();
  size_t iLen = wsURL.GetLength();
  WideTextBuffer wsResultBuf;
  for (size_t i = 0; i < iLen; ++i) {
    wchar_t ch = pData[i];
    if ('%' != ch) {
      wsResultBuf.AppendChar(ch);
      continue;
    }

    wchar_t chTemp = 0;
    int32_t iCount = 0;
    while (iCount < 2) {
      if (++i >= iLen)
        break;
      chTemp *= 16;
      ch = pData[i];
      if (!FXSYS_IsWideHexDigit(ch))
        return WideString();
      chTemp += FXSYS_WideHexCharToInt(ch);
      ++iCount;
    }
    wsResultBuf.AppendChar(chTemp);
  }
  return wsResultBuf.MakeString();
}

WideString DecodeMLInternal(const WideString& wsHTML, bool bIsHTML) {
  const wchar_t* pData = wsHTML.c_str();
  size_t iLen = wsHTML.GetLength();
  WideTextBuffer wsResultBuf;
  for (size_t i = 0; i < iLen; ++i) {
    wchar_t ch = pData[i];
    if (ch != '&') {
      wsResultBuf.AppendChar(ch);
      continue;
    }

    if (++i >= iLen)
      break;
    ch = pData[i];
    if (ch == '#') {
      if (++i >= iLen)
        break;
      ch = pData[i];
      if (ch != 'x' && ch != 'X')
        return WideString();
      if (++i >= iLen)
        break;
      ch = pData[i];
      uint32_t iCode = 0;
      while (ch != ';' && i < iLen) {
        iCode *= 16;
        if (!FXSYS_IsWideHexDigit(ch))
          return WideString();
        iCode += FXSYS_WideHexCharToInt(ch);
        if (++i >= iLen)
          break;
        ch = pData[i];
      }
      wsResultBuf.AppendChar(iCode);
      continue;
    }

    wchar_t szBuffer[9];
    size_t iStrIndex = 0;
    while (ch != ';' && i < iLen) {
      if (iStrIndex < 8)
        szBuffer[iStrIndex++] = ch;
      if (++i >= iLen)
        break;
      ch = pData[i];
    }
    szBuffer[iStrIndex] = 0;
    if (bIsHTML) {
      uint32_t iData = 0;
      if (HTMLSTR2Code(szBuffer, &iData))
        wsResultBuf.AppendChar((wchar_t)iData);
    } else {
      if (wcscmp(szBuffer, L"quot") == 0)
        wsResultBuf.AppendChar('"');
      else if (wcscmp(szBuffer, L"amp") == 0)
        wsResultBuf.AppendChar('&');
      else if (wcscmp(szBuffer, L"apos") == 0)
        wsResultBuf.AppendChar('\'');
      else if (wcscmp(szBuffer, L"lt") == 0)
        wsResultBuf.AppendChar('<');
      else if (wcscmp(szBuffer, L"gt") == 0)
        wsResultBuf.AppendChar('>');
    }
  }
  return wsResultBuf.MakeString();
}

WideString DecodeHTML(const WideString& wsHTML) {
  return DecodeMLInternal(wsHTML, true);
}

WideString DecodeXML(const WideString& wsXML) {
  return DecodeMLInternal(wsXML, false);
}

WideString EncodeURL(const ByteString& bsURL) {
  static constexpr char32_t kStrUnsafe[] = {' ', '<', '>', '"', '#',
                                            '%', '{', '}', '|', '\\',
                                            '^', '~', '[', ']', '`'};
  static constexpr char32_t kStrReserved[] = {';', '/', '?', ':',
                                              '@', '=', '&'};
  static constexpr char32_t kStrSpecial[] = {'$',  '-', '+', '!', '*',
                                             '\'', '(', ')', ','};

  WideString wsURL = WideString::FromUTF8(bsURL.AsStringView());
  WideTextBuffer wsResultBuf;
  wchar_t encode_buffer[3];
  encode_buffer[0] = '%';
  for (char32_t ch : pdfium::CodePointView(wsURL.AsStringView())) {
    size_t i = 0;
    size_t iCount = std::size(kStrUnsafe);
    while (i < iCount) {
      if (ch == kStrUnsafe[i]) {
        int32_t iIndex = ch / 16;
        encode_buffer[1] = kStrCode[iIndex];
        encode_buffer[2] = kStrCode[ch - iIndex * 16];
        wsResultBuf << WideStringView(encode_buffer, 3);
        break;
      }
      ++i;
    }
    if (i < iCount)
      continue;

    i = 0;
    iCount = std::size(kStrReserved);
    while (i < iCount) {
      if (ch == kStrReserved[i]) {
        int32_t iIndex = ch / 16;
        encode_buffer[1] = kStrCode[iIndex];
        encode_buffer[2] = kStrCode[ch - iIndex * 16];
        wsResultBuf << WideStringView(encode_buffer, 3);
        break;
      }
      ++i;
    }
    if (i < iCount)
      continue;

    i = 0;
    iCount = std::size(kStrSpecial);
    while (i < iCount) {
      if (ch == kStrSpecial[i]) {
        wsResultBuf.AppendChar(ch);
        break;
      }
      ++i;
    }
    if (i < iCount)
      continue;

    if ((ch >= 0x80 && ch <= 0xff) || ch <= 0x1f || ch == 0x7f) {
      int32_t iIndex = ch / 16;
      encode_buffer[1] = kStrCode[iIndex];
      encode_buffer[2] = kStrCode[ch - iIndex * 16];
      wsResultBuf << WideStringView(encode_buffer, 3);
    } else if (ch >= 0x20 && ch <= 0x7e) {
      wsResultBuf.AppendChar(ch);
    } else {
      const wchar_t iRadix = 16;
      WideString wsBuffer;
      while (ch >= iRadix) {
        wchar_t tmp = kStrCode[ch % iRadix];
        ch /= iRadix;
        wsBuffer += tmp;
      }
      wsBuffer += kStrCode[ch];
      int32_t iLen = wsBuffer.GetLength();
      if (iLen < 2)
        break;

      int32_t iIndex = 0;
      if (iLen % 2 != 0) {
        encode_buffer[1] = '0';
        encode_buffer[2] = wsBuffer[iLen - 1];
        iIndex = iLen - 2;
      } else {
        encode_buffer[1] = wsBuffer[iLen - 1];
        encode_buffer[2] = wsBuffer[iLen - 2];
        iIndex = iLen - 3;
      }
      wsResultBuf << WideStringView(encode_buffer, 3);
      while (iIndex > 0) {
        encode_buffer[1] = wsBuffer[iIndex];
        encode_buffer[2] = wsBuffer[iIndex - 1];
        iIndex -= 2;
        wsResultBuf << WideStringView(encode_buffer, 3);
      }
    }
  }
  return wsResultBuf.MakeString();
}

WideString EncodeHTML(const ByteString& bsHTML) {
  WideString wsHTML = WideString::FromUTF8(bsHTML.AsStringView());
  wchar_t encode_buffer[8];
  encode_buffer[0] = '&';
  encode_buffer[1] = '#';
  encode_buffer[2] = 'x';
  WideTextBuffer wsResultBuf;
  for (char32_t ch : pdfium::CodePointView(wsHTML.AsStringView())) {
    WideString htmlReserve;
    if (HTMLCode2STR(ch, &htmlReserve)) {
      wsResultBuf.AppendChar(L'&');
      wsResultBuf << htmlReserve;
      wsResultBuf.AppendChar(L';');
    } else if (ch >= 32 && ch <= 126) {
      wsResultBuf.AppendChar(static_cast<wchar_t>(ch));
    } else if (ch < 256) {
      int32_t iIndex = ch / 16;
      encode_buffer[3] = kStrCode[iIndex];
      encode_buffer[4] = kStrCode[ch - iIndex * 16];
      encode_buffer[5] = ';';
      wsResultBuf << WideStringView(encode_buffer, 6);
    } else if (ch < 65536) {
      int32_t iBigByte = ch / 256;
      int32_t iLittleByte = ch % 256;
      encode_buffer[3] = kStrCode[iBigByte / 16];
      encode_buffer[4] = kStrCode[iBigByte % 16];
      encode_buffer[5] = kStrCode[iLittleByte / 16];
      encode_buffer[6] = kStrCode[iLittleByte % 16];
      encode_buffer[7] = ';';
      wsResultBuf << WideStringView(encode_buffer, 8);
    } else {
      // TODO(tsepez): Handle codepoint not in BMP.
    }
  }
  return wsResultBuf.MakeString();
}

WideString EncodeXML(const ByteString& bsXML) {
  WideString wsXML = WideString::FromUTF8(bsXML.AsStringView());
  WideTextBuffer wsResultBuf;
  wchar_t encode_buffer[8];
  encode_buffer[0] = '&';
  encode_buffer[1] = '#';
  encode_buffer[2] = 'x';
  for (char32_t ch : pdfium::CodePointView(wsXML.AsStringView())) {
    switch (ch) {
      case '"':
        wsResultBuf.AppendChar('&');
        wsResultBuf << WideStringView(L"quot");
        wsResultBuf.AppendChar(';');
        break;
      case '&':
        wsResultBuf.AppendChar('&');
        wsResultBuf << WideStringView(L"amp");
        wsResultBuf.AppendChar(';');
        break;
      case '\'':
        wsResultBuf.AppendChar('&');
        wsResultBuf << WideStringView(L"apos");
        wsResultBuf.AppendChar(';');
        break;
      case '<':
        wsResultBuf.AppendChar('&');
        wsResultBuf << WideStringView(L"lt");
        wsResultBuf.AppendChar(';');
        break;
      case '>':
        wsResultBuf.AppendChar('&');
        wsResultBuf << WideStringView(L"gt");
        wsResultBuf.AppendChar(';');
        break;
      default: {
        if (ch >= 32 && ch <= 126) {
          wsResultBuf.AppendChar(static_cast<wchar_t>(ch));
        } else if (ch < 256) {
          int32_t iIndex = ch / 16;
          encode_buffer[3] = kStrCode[iIndex];
          encode_buffer[4] = kStrCode[ch - iIndex * 16];
          encode_buffer[5] = ';';
          wsResultBuf << WideStringView(encode_buffer, 6);
        } else if (ch < 65536) {
          int32_t iBigByte = ch / 256;
          int32_t iLittleByte = ch % 256;
          encode_buffer[3] = kStrCode[iBigByte / 16];
          encode_buffer[4] = kStrCode[iBigByte % 16];
          encode_buffer[5] = kStrCode[iLittleByte / 16];
          encode_buffer[6] = kStrCode[iLittleByte % 16];
          encode_buffer[7] = ';';
          wsResultBuf << WideStringView(encode_buffer, 8);
        } else {
          // TODO(tsepez): Handle codepoint not in BMP.
        }
        break;
      }
    }
  }
  return wsResultBuf.MakeString();
}

ByteString TrillionUS(ByteStringView bsData) {
  static const char kUnits[][6] = {"zero", "one", "two",   "three", "four",
                                   "five", "six", "seven", "eight", "nine"};
  static const char kCapUnits[][6] = {"Zero", "One", "Two",   "Three", "Four",
                                      "Five", "Six", "Seven", "Eight", "Nine"};
  static const char kTens[][10] = {
      "Ten",     "Eleven",  "Twelve",    "Thirteen", "Fourteen",
      "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
  static const char kLastTens[][8] = {"Twenty", "Thirty",  "Forty",  "Fifty",
                                      "Sixty",  "Seventy", "Eighty", "Ninety"};
  static const char kComm[][11] = {" Hundred ", " Thousand ", " Million ",
                                   " Billion ", "Trillion"};
  const char* pData = bsData.unterminated_c_str();
  int32_t iLength = bsData.GetLength();
  int32_t iComm = 0;
  if (iLength > 12)
    iComm = 4;
  else if (iLength > 9)
    iComm = 3;
  else if (iLength > 6)
    iComm = 2;
  else if (iLength > 3)
    iComm = 1;

  int32_t iFirstCount = iLength % 3;
  if (iFirstCount == 0)
    iFirstCount = 3;

  ByteString strBuf;
  int32_t iIndex = 0;
  if (iFirstCount == 3) {
    if (pData[iIndex] != '0') {
      strBuf += kCapUnits[pData[iIndex] - '0'];
      strBuf += kComm[0];
    }
    if (pData[iIndex + 1] == '0') {
      strBuf += kCapUnits[pData[iIndex + 2] - '0'];
    } else {
      if (pData[iIndex + 1] > '1') {
        strBuf += kLastTens[pData[iIndex + 1] - '2'];
        strBuf += "-";
        strBuf += kUnits[pData[iIndex + 2] - '0'];
      } else if (pData[iIndex + 1] == '1') {
        strBuf += kTens[pData[iIndex + 2] - '0'];
      } else if (pData[iIndex + 1] == '0') {
        strBuf += kCapUnits[pData[iIndex + 2] - '0'];
      }
    }
    iIndex += 3;
  } else if (iFirstCount == 2) {
    if (pData[iIndex] == '0') {
      strBuf += kCapUnits[pData[iIndex + 1] - '0'];
    } else {
      if (pData[iIndex] > '1') {
        strBuf += kLastTens[pData[iIndex] - '2'];
        strBuf += "-";
        strBuf += kUnits[pData[iIndex + 1] - '0'];
      } else if (pData[iIndex] == '1') {
        strBuf += kTens[pData[iIndex + 1] - '0'];
      } else if (pData[iIndex] == '0') {
        strBuf += kCapUnits[pData[iIndex + 1] - '0'];
      }
    }
    iIndex += 2;
  } else if (iFirstCount == 1) {
    strBuf += kCapUnits[pData[iIndex] - '0'];
    ++iIndex;
  }
  if (iLength > 3 && iFirstCount > 0) {
    strBuf += kComm[iComm];
    --iComm;
  }
  while (iIndex < iLength) {
    if (pData[iIndex] != '0') {
      strBuf += kCapUnits[pData[iIndex] - '0'];
      strBuf += kComm[0];
    }
    if (pData[iIndex + 1] == '0') {
      strBuf += kCapUnits[pData[iIndex + 2] - '0'];
    } else {
      if (pData[iIndex + 1] > '1') {
        strBuf += kLastTens[pData[iIndex + 1] - '2'];
        strBuf += "-";
        strBuf += kUnits[pData[iIndex + 2] - '0'];
      } else if (pData[iIndex + 1] == '1') {
        strBuf += kTens[pData[iIndex + 2] - '0'];
      } else if (pData[iIndex + 1] == '0') {
        strBuf += kCapUnits[pData[iIndex + 2] - '0'];
      }
    }
    if (iIndex < iLength - 3) {
      strBuf += kComm[iComm];
      --iComm;
    }
    iIndex += 3;
  }
  return strBuf;
}

ByteString WordUS(ByteStringView bsData, int32_t iStyle) {
  if (iStyle < 0 || iStyle > 2)
    return ByteString();

  int32_t iLength = bsData.GetLength();
  ByteString strBuf;
  int32_t iIndex = 0;
  while (iIndex < iLength) {
    if (bsData[iIndex] == '.')
      break;
    ++iIndex;
  }
  int32_t iInteger = iIndex;
  iIndex = 0;
  while (iIndex < iInteger) {
    int32_t iCount = (iInteger - iIndex) % 12;
    if (!iCount && iInteger - iIndex > 0)
      iCount = 12;

    strBuf += TrillionUS(bsData.Substr(iIndex, iCount));
    iIndex += iCount;
    if (iIndex < iInteger)
      strBuf += " Trillion ";
  }

  if (iStyle > 0)
    strBuf += " Dollars";

  if (iStyle > 1 && iInteger < iLength) {
    strBuf += " And ";
    iIndex = iInteger + 1;
    while (iIndex < iLength) {
      int32_t iCount = (iLength - iIndex) % 12;
      if (!iCount && iLength - iIndex > 0)
        iCount = 12;

      strBuf += TrillionUS(bsData.Substr(iIndex, iCount));
      iIndex += iCount;
      if (iIndex < iLength)
        strBuf += " Trillion ";
    }
    strBuf += " Cents";
  }
  return strBuf;
}

v8::Local<v8::Value> GetObjectDefaultValue(v8::Isolate* pIsolate,
                                           v8::Local<v8::Object> pObject) {
  CXFA_Node* pNode = ToNode(CFXJSE_Engine::ToObject(pIsolate, pObject));
  if (!pNode)
    return fxv8::NewNullHelper(pIsolate);

  v8::Local<v8::Value> value;
  pNode->JSObject()->ScriptSomDefaultValue(pIsolate, &value, false,
                                           XFA_Attribute::Unknown);
  return value;
}

bool SetObjectDefaultValue(v8::Isolate* pIsolate,
                           v8::Local<v8::Object> pObject,
                           v8::Local<v8::Value> hNewValue) {
  CXFA_Node* pNode = ToNode(CFXJSE_Engine::ToObject(pIsolate, pObject));
  if (!pNode)
    return false;

  pNode->JSObject()->ScriptSomDefaultValue(pIsolate, &hNewValue, true,
                                           XFA_Attribute::Unknown);
  return true;
}

v8::Local<v8::Value> GetExtractedValue(v8::Isolate* pIsolate,
                                       v8::Local<v8::Value> pValue) {
  if (pValue.IsEmpty())
    return v8::Local<v8::Value>();

  if (fxv8::IsArray(pValue)) {
    v8::Local<v8::Array> arr = pValue.As<v8::Array>();
    uint32_t iLength = fxv8::GetArrayLengthHelper(arr);
    if (iLength < 3)
      return fxv8::NewUndefinedHelper(pIsolate);

    v8::Local<v8::Value> propertyValue =
        fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, 1);
    v8::Local<v8::Value> jsValue =
        fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, 2);
    if (!fxv8::IsObject(jsValue))
      return fxv8::NewUndefinedHelper(pIsolate);

    v8::Local<v8::Object> jsObjectValue = jsValue.As<v8::Object>();
    if (fxv8::IsNull(propertyValue))
      return GetObjectDefaultValue(pIsolate, jsObjectValue);

    ByteString bsName =
        fxv8::ReentrantToByteStringHelper(pIsolate, propertyValue);
    return fxv8::ReentrantGetObjectPropertyHelper(pIsolate, jsObjectValue,
                                                  bsName.AsStringView());
  }

  if (fxv8::IsObject(pValue))
    return GetObjectDefaultValue(pIsolate, pValue.As<v8::Object>());

  return pValue;
}

v8::Local<v8::Value> GetSimpleValue(
    const v8::FunctionCallbackInfo<v8::Value>& info,
    uint32_t index) {
  DCHECK(index < static_cast<uint32_t>(info.Length()));
  return GetExtractedValue(info.GetIsolate(), info[index]);
}

bool ValueIsNull(v8::Isolate* pIsolate, v8::Local<v8::Value> arg) {
  v8::Local<v8::Value> extracted = GetExtractedValue(pIsolate, arg);
  return extracted.IsEmpty() || fxv8::IsNull(extracted);
}

int32_t ValueToInteger(v8::Isolate* pIsolate, v8::Local<v8::Value> arg) {
  v8::Local<v8::Value> extracted = GetExtractedValue(pIsolate, arg);
  if (extracted.IsEmpty())
    return 0;

  if (fxv8::IsObject(extracted) || fxv8::IsArray(extracted))
    return ValueToInteger(pIsolate, extracted);

  if (fxv8::IsString(extracted)) {
    ByteString bsValue = fxv8::ReentrantToByteStringHelper(pIsolate, extracted);
    return FXSYS_atoi(bsValue.c_str());
  }

  return fxv8::ReentrantToInt32Helper(pIsolate, extracted);
}

float ValueToFloat(v8::Isolate* pIsolate, v8::Local<v8::Value> arg) {
  v8::Local<v8::Value> extracted = GetExtractedValue(pIsolate, arg);
  if (extracted.IsEmpty())
    return 0.0f;

  if (fxv8::IsUndefined(extracted))
    return 0.0f;

  if (fxv8::IsObject(extracted) || fxv8::IsArray(extracted))
    return ValueToFloat(pIsolate, extracted);

  if (fxv8::IsString(extracted)) {
    ByteString bsValue = fxv8::ReentrantToByteStringHelper(pIsolate, extracted);
    return strtof(bsValue.c_str(), nullptr);
  }

  return fxv8::ReentrantToFloatHelper(pIsolate, extracted);
}

double ValueToDouble(v8::Isolate* pIsolate, v8::Local<v8::Value> arg) {
  v8::Local<v8::Value> extracted = GetExtractedValue(pIsolate, arg);
  if (extracted.IsEmpty())
    return 0.0;

  if (fxv8::IsUndefined(extracted))
    return 0.0;

  if (fxv8::IsObject(extracted) || fxv8::IsArray(extracted))
    return ValueToDouble(pIsolate, extracted);

  if (fxv8::IsString(extracted)) {
    ByteString bsValue = fxv8::ReentrantToByteStringHelper(pIsolate, extracted);
    return strtod(bsValue.c_str(), nullptr);
  }

  return fxv8::ReentrantToDoubleHelper(pIsolate, extracted);
}

std::optional<double> ExtractDouble(v8::Isolate* pIsolate,
                                    v8::Local<v8::Value> src) {
  if (src.IsEmpty())
    return 0.0;

  if (!fxv8::IsArray(src))
    return ValueToDouble(pIsolate, src);

  v8::Local<v8::Array> arr = src.As<v8::Array>();
  uint32_t iLength = fxv8::GetArrayLengthHelper(arr);
  if (iLength < 3)
    return std::nullopt;

  v8::Local<v8::Value> propertyValue =
      fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, 1);
  v8::Local<v8::Value> jsValue =
      fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, 2);
  if (fxv8::IsNull(propertyValue) || !fxv8::IsObject(jsValue))
    return ValueToDouble(pIsolate, jsValue);

  ByteString bsName =
      fxv8::ReentrantToByteStringHelper(pIsolate, propertyValue);
  return ValueToDouble(
      pIsolate, fxv8::ReentrantGetObjectPropertyHelper(
                    pIsolate, jsValue.As<v8::Object>(), bsName.AsStringView()));
}

ByteString ValueToUTF8String(v8::Isolate* pIsolate, v8::Local<v8::Value> arg) {
  if (arg.IsEmpty())
    return ByteString();

  if (fxv8::IsNull(arg) || fxv8::IsUndefined(arg))
    return ByteString();

  if (fxv8::IsBoolean(arg))
    return fxv8::ReentrantToBooleanHelper(pIsolate, arg) ? "1" : "0";

  return fxv8::ReentrantToByteStringHelper(pIsolate, arg);
}

bool SimpleValueCompare(v8::Isolate* pIsolate,
                        v8::Local<v8::Value> firstValue,
                        v8::Local<v8::Value> secondValue) {
  if (firstValue.IsEmpty())
    return false;

  if (fxv8::IsString(firstValue)) {
    const ByteString first = ValueToUTF8String(pIsolate, firstValue);
    const ByteString second = ValueToUTF8String(pIsolate, secondValue);
    return first == second;
  }
  if (fxv8::IsNumber(firstValue)) {
    const float first = ValueToFloat(pIsolate, firstValue);
    const float second = ValueToFloat(pIsolate, secondValue);
    return first == second;
  }
  if (fxv8::IsBoolean(firstValue)) {
    const bool first = fxv8::ReentrantToBooleanHelper(pIsolate, firstValue);
    const bool second = fxv8::ReentrantToBooleanHelper(pIsolate, secondValue);
    return first == second;
  }
  return fxv8::IsNull(firstValue) && fxv8::IsNull(secondValue);
}

v8::LocalVector<v8::Value> UnfoldArgs(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  v8::LocalVector<v8::Value> results(info.GetIsolate());
  v8::Isolate* pIsolate = info.GetIsolate();
  for (int i = 1; i < info.Length(); ++i) {
    v8::Local<v8::Value> arg = info[i];
    if (fxv8::IsArray(arg)) {
      v8::Local<v8::Array> arr = arg.As<v8::Array>();
      uint32_t iLength = fxv8::GetArrayLengthHelper(arr);
      if (iLength < 3)
        continue;

      v8::Local<v8::Value> propertyValue =
          fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, 1);

      for (uint32_t j = 2; j < iLength; j++) {
        v8::Local<v8::Value> jsValue =
            fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, j);

        if (!fxv8::IsObject(jsValue)) {
          results.push_back(fxv8::NewUndefinedHelper(pIsolate));
        } else if (fxv8::IsNull(propertyValue)) {
          results.push_back(
              GetObjectDefaultValue(pIsolate, jsValue.As<v8::Object>()));
        } else {
          ByteString bsName =
              fxv8::ReentrantToByteStringHelper(pIsolate, propertyValue);
          results.push_back(fxv8::ReentrantGetObjectPropertyHelper(
              pIsolate, jsValue.As<v8::Object>(), bsName.AsStringView()));
        }
      }
    } else if (fxv8::IsObject(arg)) {
      results.push_back(GetObjectDefaultValue(pIsolate, arg.As<v8::Object>()));
    } else {
      results.push_back(arg);
    }
  }
  return results;
}

// Returns empty value on failure.
v8::Local<v8::Value> GetObjectForName(CFXJSE_HostObject* pHostObject,
                                      ByteStringView bsAccessorName) {
  CXFA_Document* pDoc = ToFormCalcContext(pHostObject)->GetDocument();
  if (!pDoc)
    return v8::Local<v8::Value>();

  CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
  std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
      pScriptContext->ResolveObjects(
          pScriptContext->GetThisObject(),
          WideString::FromUTF8(bsAccessorName).AsStringView(),
          Mask<XFA_ResolveFlag>{
              XFA_ResolveFlag::kChildren, XFA_ResolveFlag::kProperties,
              XFA_ResolveFlag::kSiblings, XFA_ResolveFlag::kParent});
  if (!maybeResult.has_value() ||
      maybeResult.value().type != CFXJSE_Engine::ResolveResult::Type::kNodes ||
      maybeResult.value().objects.empty()) {
    return v8::Local<v8::Value>();
  }
  return pScriptContext->GetOrCreateJSBindingFromMap(
      maybeResult.value().objects.front().Get());
}

std::optional<CFXJSE_Engine::ResolveResult> ResolveObjects(
    CFXJSE_HostObject* pHostObject,
    v8::Local<v8::Value> pRefValue,
    ByteStringView bsSomExp,
    bool bDotAccessor,
    bool bHasNoResolveName) {
  CXFA_Document* pDoc = ToFormCalcContext(pHostObject)->GetDocument();
  if (!pDoc)
    return std::nullopt;

  v8::Isolate* pIsolate = ToFormCalcContext(pHostObject)->GetIsolate();
  WideString wsSomExpression = WideString::FromUTF8(bsSomExp);
  CFXJSE_Engine* pScriptContext = pDoc->GetScriptContext();
  CXFA_Object* pNode = nullptr;
  Mask<XFA_ResolveFlag> dwFlags;
  if (bDotAccessor) {
    if (fxv8::IsNull(pRefValue)) {
      pNode = pScriptContext->GetThisObject();
      dwFlags = {XFA_ResolveFlag::kSiblings, XFA_ResolveFlag::kParent};
    } else {
      pNode = CFXJSE_Engine::ToObject(pIsolate, pRefValue);
      if (!pNode)
        return std::nullopt;

      if (bHasNoResolveName) {
        WideString wsName;
        if (CXFA_Node* pXFANode = pNode->AsNode()) {
          std::optional<WideString> ret =
              pXFANode->JSObject()->TryAttribute(XFA_Attribute::Name, false);
          if (ret.has_value())
            wsName = ret.value();
        }
        if (wsName.IsEmpty())
          wsName = L"#" + WideString::FromASCII(pNode->GetClassName());

        wsSomExpression = wsName + wsSomExpression;
        dwFlags = XFA_ResolveFlag::kSiblings;
      } else {
        dwFlags = (bsSomExp == "*")
                      ? Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kChildren}
                      : Mask<XFA_ResolveFlag>{XFA_ResolveFlag::kChildren,
                                              XFA_ResolveFlag::kAttributes,
                                              XFA_ResolveFlag::kProperties};
      }
    }
  } else {
    pNode = CFXJSE_Engine::ToObject(pIsolate, pRefValue);
    dwFlags = XFA_ResolveFlag::kAnyChild;
  }
  return pScriptContext->ResolveObjects(pNode, wsSomExpression.AsStringView(),
                                        dwFlags);
}

v8::LocalVector<v8::Value> ParseResolveResult(
    CFXJSE_HostObject* pHostObject,
    const CFXJSE_Engine::ResolveResult& resolveNodeRS,
    v8::Local<v8::Value> pParentValue,
    bool* bAttribute) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pHostObject);
  v8::Isolate* pIsolate = pContext->GetIsolate();
  v8::LocalVector<v8::Value> resultValues(pIsolate);

  if (resolveNodeRS.type == CFXJSE_Engine::ResolveResult::Type::kNodes) {
    *bAttribute = false;
    CFXJSE_Engine* pScriptContext = pContext->GetDocument()->GetScriptContext();
    for (auto& pObject : resolveNodeRS.objects) {
      resultValues.push_back(
          pScriptContext->GetOrCreateJSBindingFromMap(pObject.Get()));
    }
    return resultValues;
  }

  *bAttribute = true;
  if (resolveNodeRS.script_attribute.callback &&
      resolveNodeRS.script_attribute.eValueType == XFA_ScriptType::Object) {
    for (auto& pObject : resolveNodeRS.objects) {
      v8::Local<v8::Value> pValue;
      CJX_Object* jsObject = pObject->JSObject();
      (*resolveNodeRS.script_attribute.callback)(
          pIsolate, jsObject, &pValue, false,
          resolveNodeRS.script_attribute.attribute);
      resultValues.push_back(pValue);
      *bAttribute = false;
    }
  }
  if (*bAttribute && fxv8::IsObject(pParentValue))
    resultValues.push_back(pParentValue);

  return resultValues;
}

// Returns 0 if the provided `arg` is an invalid payment period count.
int GetValidatedPaymentPeriods(v8::Isolate* isolate, v8::Local<v8::Value> arg) {
  double periods = ValueToDouble(isolate, arg);
  if (periods < 1 ||
      periods > static_cast<double>(std::numeric_limits<int32_t>::max())) {
    return 0;
  }

  return static_cast<int>(periods);
}

}  // namespace

const FXJSE_CLASS_DESCRIPTOR kFormCalcDescriptor = {
    kClassTag,                      // tag
    "XFA_FormCalcClass",            // name
    kFormCalcFunctions,             // methods
    std::size(kFormCalcFunctions),  // number of methods
    nullptr,                        // dynamic prop type
    nullptr,                        // dynamic prop getter
    nullptr,                        // dynamic prop setter
    nullptr,                        // dynamic prop method call
};

// static
void CFXJSE_FormCalcContext::Abs(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Abs");
    return;
  }

  if (ValueIsNull(info.GetIsolate(), info[0])) {
    info.GetReturnValue().SetNull();
    return;
  }
  double dValue = ValueToDouble(info.GetIsolate(), info[0]);
  if (dValue < 0)
    dValue = -dValue;

  info.GetReturnValue().Set(dValue);
}

// static
void CFXJSE_FormCalcContext::Avg(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  uint32_t uCount = 0;
  double dSum = 0.0;
  auto fn = [&uCount, &dSum](v8::Isolate* pIsolate,
                             v8::Local<v8::Value> pValue) {
    dSum += ValueToDouble(pIsolate, pValue);
    uCount++;
  };
  if (!ToFormCalcContext(pThis)->ApplyToExpansion(fn, info, /*bStrict=*/false))
    return;

  if (uCount == 0) {
    info.GetReturnValue().SetNull();
    return;
  }
  info.GetReturnValue().Set(dSum / uCount);
}

// static
void CFXJSE_FormCalcContext::Ceil(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Ceil");
    return;
  }

  v8::Local<v8::Value> argValue = GetSimpleValue(info, 0);
  if (ValueIsNull(info.GetIsolate(), argValue)) {
    info.GetReturnValue().SetNull();
    return;
  }

  info.GetReturnValue().Set(ceil(ValueToFloat(info.GetIsolate(), argValue)));
}

// static
void CFXJSE_FormCalcContext::Count(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  uint32_t iCount = 0;
  auto fn = [&iCount](v8::Isolate* pIsolate, v8::Local<v8::Value> pvalue) {
    ++iCount;
  };
  if (!ToFormCalcContext(pThis)->ApplyToExpansion(fn, info, /*bStrict=*/true))
    return;

  info.GetReturnValue().Set(iCount);
}

// static
void CFXJSE_FormCalcContext::Floor(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Floor");
    return;
  }

  v8::Local<v8::Value> argValue = GetSimpleValue(info, 0);
  if (ValueIsNull(info.GetIsolate(), argValue)) {
    info.GetReturnValue().SetNull();
    return;
  }

  info.GetReturnValue().Set(floor(ValueToFloat(info.GetIsolate(), argValue)));
}

// static
void CFXJSE_FormCalcContext::Max(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  uint32_t uCount = 0;
  double dMaxValue = 0.0;
  auto fn = [&uCount, &dMaxValue](v8::Isolate* pIsolate,
                                  v8::Local<v8::Value> pValue) {
    ++uCount;
    double dValue = ValueToDouble(pIsolate, pValue);
    dMaxValue = uCount == 1 ? dValue : std::max(dMaxValue, dValue);
  };
  if (!ToFormCalcContext(pThis)->ApplyToExpansion(fn, info, /*bStrict=*/true))
    return;

  if (uCount == 0) {
    info.GetReturnValue().SetNull();
    return;
  }
  info.GetReturnValue().Set(dMaxValue);
}

// static
void CFXJSE_FormCalcContext::Min(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  uint32_t uCount = 0;
  double dMinValue = 0.0;
  auto fn = [&uCount, &dMinValue](v8::Isolate* pIsolate,
                                  v8::Local<v8::Value> pValue) {
    ++uCount;
    double dValue = ValueToDouble(pIsolate, pValue);
    dMinValue = uCount == 1 ? dValue : std::min(dMinValue, dValue);
  };
  if (!ToFormCalcContext(pThis)->ApplyToExpansion(fn, info, /*bStrict=*/true))
    return;

  if (uCount == 0) {
    info.GetReturnValue().SetNull();
    return;
  }
  info.GetReturnValue().Set(dMinValue);
}

// static
void CFXJSE_FormCalcContext::Mod(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 2) {
    pContext->ThrowParamCountMismatchException("Mod");
    return;
  }

  if (fxv8::IsNull(info[0]) || fxv8::IsNull(info[1])) {
    info.GetReturnValue().SetNull();
    return;
  }

  std::optional<double> maybe_dividend =
      ExtractDouble(info.GetIsolate(), info[0]);
  std::optional<double> maybe_divisor =
      ExtractDouble(info.GetIsolate(), info[1]);
  if (!maybe_dividend.has_value() || !maybe_divisor.has_value()) {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  double dividend = maybe_dividend.value();
  double divisor = maybe_divisor.value();
  if (divisor == 0.0) {
    pContext->ThrowDivideByZeroException();
    return;
  }

  info.GetReturnValue().Set(dividend -
                            divisor * static_cast<int32_t>(dividend / divisor));
}

// static
void CFXJSE_FormCalcContext::Round(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  int32_t argc = info.Length();
  if (argc < 1 || argc > 2) {
    pContext->ThrowParamCountMismatchException("Round");
    return;
  }

  if (fxv8::IsNull(info[0])) {
    info.GetReturnValue().SetNull();
    return;
  }

  std::optional<double> maybe_value = ExtractDouble(info.GetIsolate(), info[0]);
  if (!maybe_value.has_value()) {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  double dValue = maybe_value.value();
  uint8_t uPrecision = 0;
  if (argc > 1) {
    if (fxv8::IsNull(info[1])) {
      info.GetReturnValue().SetNull();
      return;
    }
    std::optional<double> maybe_precision =
        ExtractDouble(info.GetIsolate(), info[1]);
    if (!maybe_precision.has_value()) {
      pContext->ThrowArgumentMismatchException();
      return;
    }
    double dPrecision = maybe_precision.value();
    uPrecision = static_cast<uint8_t>(std::clamp(dPrecision, 0.0, 12.0));
  }

  CFGAS_Decimal decimalValue(static_cast<float>(dValue), uPrecision);
  info.GetReturnValue().Set(decimalValue.ToDouble());
}

// static
void CFXJSE_FormCalcContext::Sum(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  uint32_t uCount = 0;
  double dSum = 0.0;
  auto fn = [&uCount, &dSum](v8::Isolate* pIsolate,
                             v8::Local<v8::Value> pValue) {
    ++uCount;
    dSum += ValueToDouble(pIsolate, pValue);
  };
  if (!ToFormCalcContext(pThis)->ApplyToExpansion(fn, info, /*bStrict=*/true))
    return;

  if (uCount == 0) {
    info.GetReturnValue().SetNull();
    return;
  }
  info.GetReturnValue().Set(dSum);
}

// static
void CFXJSE_FormCalcContext::Date(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 0) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Date");
    return;
  }

  time_t currentTime;
  FXSYS_time(&currentTime);
  struct tm* pTmStruct = gmtime(&currentTime);

  info.GetReturnValue().Set(DateString2Num(
      ByteString::Format("%d%02d%02d", pTmStruct->tm_year + 1900,
                         pTmStruct->tm_mon + 1, pTmStruct->tm_mday)
          .AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Date2Num(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 1 || argc > 3) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Date2Num");
    return;
  }

  v8::Local<v8::Value> dateValue = GetSimpleValue(info, 0);
  if (ValueIsNull(info.GetIsolate(), dateValue)) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsDate = ValueToUTF8String(info.GetIsolate(), dateValue);
  ByteString bsFormat;
  if (argc > 1) {
    v8::Local<v8::Value> formatValue = GetSimpleValue(info, 1);
    if (ValueIsNull(info.GetIsolate(), formatValue)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsFormat = ValueToUTF8String(info.GetIsolate(), formatValue);
  }

  ByteString bsLocale;
  if (argc > 2) {
    v8::Local<v8::Value> localeValue = GetSimpleValue(info, 2);
    if (ValueIsNull(info.GetIsolate(), localeValue)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsLocale = ValueToUTF8String(info.GetIsolate(), localeValue);
  }

  ByteString bsIsoDate =
      Local2IsoDate(pThis, bsDate.AsStringView(), bsFormat.AsStringView(),
                    bsLocale.AsStringView());
  info.GetReturnValue().Set(DateString2Num(bsIsoDate.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::DateFmt(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc > 2) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Date2Num");
    return;
  }

  int32_t iStyle = 0;
  if (argc > 0) {
    v8::Local<v8::Value> infotyle = GetSimpleValue(info, 0);
    if (fxv8::IsNull(infotyle)) {
      info.GetReturnValue().SetNull();
      return;
    }

    iStyle = static_cast<int32_t>(ValueToFloat(info.GetIsolate(), infotyle));
    if (iStyle < 0 || iStyle > 4)
      iStyle = 0;
  }

  ByteString bsLocale;
  if (argc > 1) {
    v8::Local<v8::Value> argLocale = GetSimpleValue(info, 1);
    if (fxv8::IsNull(argLocale)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsLocale = ValueToUTF8String(info.GetIsolate(), argLocale);
  }

  ByteString bsFormat =
      GetStandardDateFormat(pThis, iStyle, bsLocale.AsStringView());
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), bsFormat.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::IsoDate2Num(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("IsoDate2Num");
    return;
  }
  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  if (fxv8::IsNull(argOne)) {
    info.GetReturnValue().SetNull();
    return;
  }
  ByteString bsArg = ValueToUTF8String(info.GetIsolate(), argOne);
  info.GetReturnValue().Set(DateString2Num(bsArg.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::IsoTime2Num(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 1) {
    pContext->ThrowParamCountMismatchException("IsoTime2Num");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  if (ValueIsNull(info.GetIsolate(), argOne)) {
    info.GetReturnValue().SetNull();
    return;
  }

  CXFA_Document* pDoc = pContext->GetDocument();
  CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
  ByteString bsArg = ValueToUTF8String(info.GetIsolate(), argOne);
  auto pos = bsArg.Find('T', 0);
  if (!pos.has_value() || pos.value() == bsArg.GetLength() - 1) {
    info.GetReturnValue().Set(0);
    return;
  }
  bsArg = bsArg.Last(bsArg.GetLength() - (pos.value() + 1));

  CXFA_LocaleValue timeValue(CXFA_LocaleValue::ValueType::kTime,
                             WideString::FromUTF8(bsArg.AsStringView()), pMgr);
  if (!timeValue.IsValid()) {
    info.GetReturnValue().Set(0);
    return;
  }

  CFX_DateTime uniTime = timeValue.GetTime();
  int32_t hour = uniTime.GetHour();
  int32_t min = uniTime.GetMinute();
  int32_t second = uniTime.GetSecond();
  int32_t milSecond = uniTime.GetMillisecond();

  // TODO(dsinclair): See if there is other time conversion code in pdfium and
  //   consolidate.
  int32_t mins = hour * 60 + min;
  mins -= pMgr->GetDefLocale()->GetTimeZoneInMinutes();
  while (mins > 1440)
    mins -= 1440;
  while (mins < 0)
    mins += 1440;
  hour = mins / 60;
  min = mins % 60;

  info.GetReturnValue().Set(hour * 3600000 + min * 60000 + second * 1000 +
                            milSecond + 1);
}

// static
void CFXJSE_FormCalcContext::LocalDateFmt(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc > 2) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("LocalDateFmt");
    return;
  }

  int32_t iStyle = 0;
  if (argc > 0) {
    v8::Local<v8::Value> infotyle = GetSimpleValue(info, 0);
    if (fxv8::IsNull(infotyle)) {
      info.GetReturnValue().SetNull();
      return;
    }
    iStyle = static_cast<int32_t>(ValueToFloat(info.GetIsolate(), infotyle));
    if (iStyle > 4 || iStyle < 0)
      iStyle = 0;
  }

  ByteString bsLocale;
  if (argc > 1) {
    v8::Local<v8::Value> argLocale = GetSimpleValue(info, 1);
    if (fxv8::IsNull(argLocale)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsLocale = ValueToUTF8String(info.GetIsolate(), argLocale);
  }

  ByteString bsFormat =
      GetLocalDateFormat(pThis, iStyle, bsLocale.AsStringView(), false);
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), bsFormat.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::LocalTimeFmt(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc > 2) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("LocalTimeFmt");
    return;
  }

  int32_t iStyle = 0;
  if (argc > 0) {
    v8::Local<v8::Value> infotyle = GetSimpleValue(info, 0);
    if (fxv8::IsNull(infotyle)) {
      info.GetReturnValue().SetNull();
      return;
    }
    iStyle = static_cast<int32_t>(ValueToFloat(info.GetIsolate(), infotyle));
    if (iStyle > 4 || iStyle < 0)
      iStyle = 0;
  }

  ByteString bsLocale;
  if (argc > 1) {
    v8::Local<v8::Value> argLocale = GetSimpleValue(info, 1);
    if (fxv8::IsNull(argLocale)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsLocale = ValueToUTF8String(info.GetIsolate(), argLocale);
  }

  ByteString bsFormat =
      GetLocalTimeFormat(pThis, iStyle, bsLocale.AsStringView(), false);
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), bsFormat.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Num2Date(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 1 || argc > 3) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Num2Date");
    return;
  }

  v8::Local<v8::Value> dateValue = GetSimpleValue(info, 0);
  if (ValueIsNull(info.GetIsolate(), dateValue)) {
    info.GetReturnValue().SetNull();
    return;
  }
  int32_t dDate =
      static_cast<int32_t>(ValueToFloat(info.GetIsolate(), dateValue));
  if (dDate < 1) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsFormat;
  if (argc > 1) {
    v8::Local<v8::Value> formatValue = GetSimpleValue(info, 1);
    if (ValueIsNull(info.GetIsolate(), formatValue)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsFormat = ValueToUTF8String(info.GetIsolate(), formatValue);
  }

  ByteString bsLocale;
  if (argc > 2) {
    v8::Local<v8::Value> localeValue = GetSimpleValue(info, 2);
    if (ValueIsNull(info.GetIsolate(), localeValue)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsLocale = ValueToUTF8String(info.GetIsolate(), localeValue);
  }

  int32_t iYear = 1900;
  int32_t iMonth = 1;
  int32_t iDay = 1;
  int32_t i = 0;
  while (dDate > 0) {
    if (iMonth == 2) {
      if ((!((iYear + i) % 4) && ((iYear + i) % 100)) || !((iYear + i) % 400)) {
        if (dDate > 29) {
          ++iMonth;
          if (iMonth > 12) {
            iMonth = 1;
            ++i;
          }
          iDay = 1;
          dDate -= 29;
        } else {
          iDay += static_cast<int32_t>(dDate) - 1;
          dDate = 0;
        }
      } else {
        if (dDate > 28) {
          ++iMonth;
          if (iMonth > 12) {
            iMonth = 1;
            ++i;
          }
          iDay = 1;
          dDate -= 28;
        } else {
          iDay += static_cast<int32_t>(dDate) - 1;
          dDate = 0;
        }
      }
    } else if (iMonth < 8) {
      if ((iMonth % 2 == 0)) {
        if (dDate > 30) {
          ++iMonth;
          if (iMonth > 12) {
            iMonth = 1;
            ++i;
          }
          iDay = 1;
          dDate -= 30;
        } else {
          iDay += static_cast<int32_t>(dDate) - 1;
          dDate = 0;
        }
      } else {
        if (dDate > 31) {
          ++iMonth;
          if (iMonth > 12) {
            iMonth = 1;
            ++i;
          }
          iDay = 1;
          dDate -= 31;
        } else {
          iDay += static_cast<int32_t>(dDate) - 1;
          dDate = 0;
        }
      }
    } else {
      if (iMonth % 2 != 0) {
        if (dDate > 30) {
          ++iMonth;
          if (iMonth > 12) {
            iMonth = 1;
            ++i;
          }
          iDay = 1;
          dDate -= 30;
        } else {
          iDay += static_cast<int32_t>(dDate) - 1;
          dDate = 0;
        }
      } else {
        if (dDate > 31) {
          ++iMonth;
          if (iMonth > 12) {
            iMonth = 1;
            ++i;
          }
          iDay = 1;
          dDate -= 31;
        } else {
          iDay += static_cast<int32_t>(dDate) - 1;
          dDate = 0;
        }
      }
    }
  }

  ByteString bsLocalDate = IsoDate2Local(
      pThis,
      ByteString::Format("%d%02d%02d", iYear + i, iMonth, iDay).AsStringView(),
      bsFormat.AsStringView(), bsLocale.AsStringView());
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), bsLocalDate.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Num2GMTime(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 1 || argc > 3) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Num2GMTime");
    return;
  }

  v8::Local<v8::Value> timeValue = GetSimpleValue(info, 0);
  if (fxv8::IsNull(timeValue)) {
    info.GetReturnValue().SetNull();
    return;
  }
  int32_t iTime =
      static_cast<int32_t>(ValueToFloat(info.GetIsolate(), timeValue));
  if (abs(iTime) < 1.0) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsFormat;
  if (argc > 1) {
    v8::Local<v8::Value> formatValue = GetSimpleValue(info, 1);
    if (fxv8::IsNull(formatValue)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsFormat = ValueToUTF8String(info.GetIsolate(), formatValue);
  }

  ByteString bsLocale;
  if (argc > 2) {
    v8::Local<v8::Value> localeValue = GetSimpleValue(info, 2);
    if (fxv8::IsNull(localeValue)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsLocale = ValueToUTF8String(info.GetIsolate(), localeValue);
  }

  ByteString bsGMTTime = Num2AllTime(pThis, iTime, bsFormat.AsStringView(),
                                     bsLocale.AsStringView(), true);
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), bsGMTTime.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Num2Time(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 1 || argc > 3) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Num2Time");
    return;
  }

  v8::Local<v8::Value> timeValue = GetSimpleValue(info, 0);
  if (fxv8::IsNull(timeValue)) {
    info.GetReturnValue().SetNull();
    return;
  }
  float fTime = ValueToFloat(info.GetIsolate(), timeValue);
  if (fabs(fTime) < 1.0) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsFormat;
  if (argc > 1) {
    v8::Local<v8::Value> formatValue = GetSimpleValue(info, 1);
    if (fxv8::IsNull(formatValue)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsFormat = ValueToUTF8String(info.GetIsolate(), formatValue);
  }

  ByteString bsLocale;
  if (argc > 2) {
    v8::Local<v8::Value> localeValue = GetSimpleValue(info, 2);
    if (fxv8::IsNull(localeValue)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsLocale = ValueToUTF8String(info.GetIsolate(), localeValue);
  }

  ByteString bsLocalTime =
      Num2AllTime(pThis, static_cast<int32_t>(fTime), bsFormat.AsStringView(),
                  bsLocale.AsStringView(), false);
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), bsLocalTime.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Time(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 0) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Time");
    return;
  }

  time_t now;
  FXSYS_time(&now);
  struct tm* pGmt = gmtime(&now);
  info.GetReturnValue().Set(
      (pGmt->tm_hour * 3600 + pGmt->tm_min * 60 + pGmt->tm_sec) * 1000);
}

// static
void CFXJSE_FormCalcContext::Time2Num(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 1 || argc > 3) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Time2Num");
    return;
  }

  ByteString bsTime;
  v8::Local<v8::Value> timeValue = GetSimpleValue(info, 0);
  if (ValueIsNull(info.GetIsolate(), timeValue)) {
    info.GetReturnValue().SetNull();
    return;
  }
  bsTime = ValueToUTF8String(info.GetIsolate(), timeValue);

  ByteString bsFormat;
  if (argc > 1) {
    v8::Local<v8::Value> formatValue = GetSimpleValue(info, 1);
    if (ValueIsNull(info.GetIsolate(), formatValue)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsFormat = ValueToUTF8String(info.GetIsolate(), formatValue);
  }

  ByteString bsLocale;
  if (argc > 2) {
    v8::Local<v8::Value> localeValue = GetSimpleValue(info, 2);
    if (ValueIsNull(info.GetIsolate(), localeValue)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsLocale = ValueToUTF8String(info.GetIsolate(), localeValue);
  }

  CXFA_Document* pDoc = ToFormCalcContext(pThis)->GetDocument();
  CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
  GCedLocaleIface* pLocale = nullptr;
  if (!bsLocale.IsEmpty()) {
    pLocale =
        pMgr->GetLocaleByName(WideString::FromUTF8(bsLocale.AsStringView()));
  }
  if (!pLocale) {
    CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
    pLocale = pThisNode->GetLocale();
  }

  WideString wsFormat;
  if (bsFormat.IsEmpty()) {
    wsFormat =
        pLocale->GetTimePattern(LocaleIface::DateTimeSubcategory::kDefault);
  } else {
    wsFormat = WideString::FromUTF8(bsFormat.AsStringView());
  }
  wsFormat = L"time{" + wsFormat + L"}";
  CXFA_LocaleValue localeValue(CXFA_LocaleValue::ValueType::kTime,
                               WideString::FromUTF8(bsTime.AsStringView()),
                               wsFormat, pLocale, pMgr);
  if (!localeValue.IsValid()) {
    info.GetReturnValue().Set(0);
    return;
  }

  CFX_DateTime uniTime = localeValue.GetTime();
  int32_t hour = uniTime.GetHour();
  int32_t minute = uniTime.GetMinute();
  const int32_t second = uniTime.GetSecond();
  const int32_t millisecond = uniTime.GetMillisecond();

  constexpr int kMinutesInDay = 24 * 60;
  int32_t minutes_with_tz =
      hour * 60 + minute - CXFA_TimeZoneProvider().GetTimeZoneInMinutes();
  minutes_with_tz %= kMinutesInDay;
  if (minutes_with_tz < 0)
    minutes_with_tz += kMinutesInDay;

  hour = minutes_with_tz / 60;
  minute = minutes_with_tz % 60;
  info.GetReturnValue().Set(hour * 3600000 + minute * 60000 + second * 1000 +
                            millisecond + 1);
}

// static
void CFXJSE_FormCalcContext::TimeFmt(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc > 2) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("TimeFmt");
    return;
  }

  int32_t iStyle = 0;
  if (argc > 0) {
    v8::Local<v8::Value> infotyle = GetSimpleValue(info, 0);
    if (fxv8::IsNull(infotyle)) {
      info.GetReturnValue().SetNull();
      return;
    }
    iStyle = static_cast<int32_t>(ValueToFloat(info.GetIsolate(), infotyle));
    if (iStyle > 4 || iStyle < 0)
      iStyle = 0;
  }

  ByteString bsLocale;
  if (argc > 1) {
    v8::Local<v8::Value> argLocale = GetSimpleValue(info, 1);
    if (fxv8::IsNull(argLocale)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsLocale = ValueToUTF8String(info.GetIsolate(), argLocale);
  }

  ByteString bsFormat =
      GetStandardTimeFormat(pThis, iStyle, bsLocale.AsStringView());
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), bsFormat.AsStringView()));
}

// static
ByteString CFXJSE_FormCalcContext::Local2IsoDate(CFXJSE_HostObject* pThis,
                                                 ByteStringView bsDate,
                                                 ByteStringView bsFormat,
                                                 ByteStringView bsLocale) {
  CXFA_Document* pDoc = ToFormCalcContext(pThis)->GetDocument();
  if (!pDoc)
    return ByteString();

  CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
  GCedLocaleIface* pLocale = LocaleFromString(pDoc, pMgr, bsLocale);
  if (!pLocale)
    return ByteString();

  WideString wsFormat = FormatFromString(pLocale, bsFormat);
  CFX_DateTime dt =
      CXFA_LocaleValue(CXFA_LocaleValue::ValueType::kDate,
                       WideString::FromUTF8(bsDate), wsFormat, pLocale, pMgr)
          .GetDate();

  return ByteString::Format("%4d-%02d-%02d", dt.GetYear(), dt.GetMonth(),
                            dt.GetDay());
}

// static
ByteString CFXJSE_FormCalcContext::IsoDate2Local(CFXJSE_HostObject* pThis,
                                                 ByteStringView bsDate,
                                                 ByteStringView bsFormat,
                                                 ByteStringView bsLocale) {
  CXFA_Document* pDoc = ToFormCalcContext(pThis)->GetDocument();
  if (!pDoc)
    return ByteString();

  CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
  GCedLocaleIface* pLocale = LocaleFromString(pDoc, pMgr, bsLocale);
  if (!pLocale)
    return ByteString();

  WideString wsFormat = FormatFromString(pLocale, bsFormat);
  WideString wsRet;
  CXFA_LocaleValue(CXFA_LocaleValue::ValueType::kDate,
                   WideString::FromUTF8(bsDate), pMgr)
      .FormatPatterns(wsRet, wsFormat, pLocale, XFA_ValuePicture::kDisplay);
  return wsRet.ToUTF8();
}

// static
ByteString CFXJSE_FormCalcContext::IsoTime2Local(CFXJSE_HostObject* pThis,
                                                 ByteStringView bsTime,
                                                 ByteStringView bsFormat,
                                                 ByteStringView bsLocale) {
  CXFA_Document* pDoc = ToFormCalcContext(pThis)->GetDocument();
  if (!pDoc)
    return ByteString();

  CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
  GCedLocaleIface* pLocale = LocaleFromString(pDoc, pMgr, bsLocale);
  if (!pLocale)
    return ByteString();

  WideString wsFormat = {
      L"time{", FormatFromString(pLocale, bsFormat).AsStringView(), L"}"};
  CXFA_LocaleValue widgetValue(CXFA_LocaleValue::ValueType::kTime,
                               WideString::FromUTF8(bsTime), pMgr);
  WideString wsRet;
  widgetValue.FormatPatterns(wsRet, wsFormat, pLocale,
                             XFA_ValuePicture::kDisplay);
  return wsRet.ToUTF8();
}

// static
ByteString CFXJSE_FormCalcContext::GetLocalDateFormat(CFXJSE_HostObject* pThis,
                                                      int32_t iStyle,
                                                      ByteStringView bsLocale,
                                                      bool bStandard) {
  CXFA_Document* pDoc = ToFormCalcContext(pThis)->GetDocument();
  if (!pDoc)
    return ByteString();

  return GetLocalDateTimeFormat(pDoc, iStyle, bsLocale, bStandard,
                                /*bIsDate=*/true);
}

// static
ByteString CFXJSE_FormCalcContext::GetLocalTimeFormat(CFXJSE_HostObject* pThis,
                                                      int32_t iStyle,
                                                      ByteStringView bsLocale,
                                                      bool bStandard) {
  CXFA_Document* pDoc = ToFormCalcContext(pThis)->GetDocument();
  if (!pDoc)
    return ByteString();

  return GetLocalDateTimeFormat(pDoc, iStyle, bsLocale, bStandard,
                                /*bIsDate=*/false);
}

// static
ByteString CFXJSE_FormCalcContext::GetStandardDateFormat(
    CFXJSE_HostObject* pThis,
    int32_t iStyle,
    ByteStringView bsLocale) {
  return GetLocalDateFormat(pThis, iStyle, bsLocale, true);
}

// static
ByteString CFXJSE_FormCalcContext::GetStandardTimeFormat(
    CFXJSE_HostObject* pThis,
    int32_t iStyle,
    ByteStringView bsLocale) {
  return GetLocalTimeFormat(pThis, iStyle, bsLocale, true);
}

// static
ByteString CFXJSE_FormCalcContext::Num2AllTime(CFXJSE_HostObject* pThis,
                                               int32_t iTime,
                                               ByteStringView bsFormat,
                                               ByteStringView bsLocale,
                                               bool bGM) {
  int32_t iHour = 0;
  int32_t iMin = 0;
  int32_t iSec = 0;
  iHour = static_cast<int>(iTime) / 3600000;
  iMin = (static_cast<int>(iTime) - iHour * 3600000) / 60000;
  iSec = (static_cast<int>(iTime) - iHour * 3600000 - iMin * 60000) / 1000;

  if (!bGM) {
    int32_t iZoneHour;
    int32_t iZoneMin;
    int32_t iZoneSec;
    GetLocalTimeZone(&iZoneHour, &iZoneMin, &iZoneSec);
    iHour += iZoneHour;
    iMin += iZoneMin;
    iSec += iZoneSec;
  }

  return IsoTime2Local(
      pThis,
      ByteString::Format("%02d:%02d:%02d", iHour, iMin, iSec).AsStringView(),
      bsFormat, bsLocale);
}

// static
void CFXJSE_FormCalcContext::Apr(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 3) {
    pContext->ThrowParamCountMismatchException("Apr");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
  if (ValueIsNull(info.GetIsolate(), argOne) ||
      ValueIsNull(info.GetIsolate(), argTwo) ||
      ValueIsNull(info.GetIsolate(), argThree)) {
    info.GetReturnValue().SetNull();
    return;
  }

  double nPrincipal = ValueToDouble(info.GetIsolate(), argOne);
  double nPayment = ValueToDouble(info.GetIsolate(), argTwo);
  int nPeriods = GetValidatedPaymentPeriods(info.GetIsolate(), argThree);
  if (nPrincipal <= 0 || nPayment <= 0 || nPeriods == 0) {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  double r = 2 * (nPeriods * nPayment - nPrincipal) / (nPeriods * nPrincipal);
  double nTemp = 1;
  for (int32_t i = 0; i < nPeriods; ++i)
    nTemp *= (1 + r);

  double nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
  while (fabs(nRet) > kFinancialPrecision) {
    double nDerivative =
        ((nTemp + r * nPeriods * (nTemp / (1 + r))) * (nTemp - 1) -
         (r * nTemp * nPeriods * (nTemp / (1 + r)))) /
        ((nTemp - 1) * (nTemp - 1));
    if (nDerivative == 0) {
      info.GetReturnValue().SetNull();
      return;
    }

    r = r - nRet / nDerivative;
    nTemp = 1;
    for (int32_t i = 0; i < nPeriods; ++i) {
      nTemp *= (1 + r);
    }
    nRet = r * nTemp / (nTemp - 1) - nPayment / nPrincipal;
  }
  info.GetReturnValue().Set(r * 12);
}

// static
void CFXJSE_FormCalcContext::CTerm(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 3) {
    pContext->ThrowParamCountMismatchException("CTerm");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
  if (ValueIsNull(info.GetIsolate(), argOne) ||
      ValueIsNull(info.GetIsolate(), argTwo) ||
      ValueIsNull(info.GetIsolate(), argThree)) {
    info.GetReturnValue().SetNull();
    return;
  }

  float nRate = ValueToFloat(info.GetIsolate(), argOne);
  float nFutureValue = ValueToFloat(info.GetIsolate(), argTwo);
  float nInitAmount = ValueToFloat(info.GetIsolate(), argThree);
  if ((nRate <= 0) || (nFutureValue <= 0) || (nInitAmount <= 0)) {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  info.GetReturnValue().Set(log((float)(nFutureValue / nInitAmount)) /
                            log((float)(1 + nRate)));
}

// static
void CFXJSE_FormCalcContext::FV(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 3) {
    pContext->ThrowParamCountMismatchException("FV");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
  if (ValueIsNull(info.GetIsolate(), argOne) ||
      ValueIsNull(info.GetIsolate(), argTwo) ||
      ValueIsNull(info.GetIsolate(), argThree)) {
    info.GetReturnValue().SetNull();
    return;
  }

  double nAmount = ValueToDouble(info.GetIsolate(), argOne);
  double nRate = ValueToDouble(info.GetIsolate(), argTwo);
  int nPeriods = GetValidatedPaymentPeriods(info.GetIsolate(), argThree);
  if (nAmount <= 0 || nRate < 0 || nPeriods == 0) {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  double dResult = 0;
  if (nRate) {
    double nTemp = 1;
    for (int i = 0; i < nPeriods; ++i) {
      nTemp *= 1 + nRate;
    }
    dResult = nAmount * (nTemp - 1) / nRate;
  } else {
    dResult = nAmount * nPeriods;
  }

  info.GetReturnValue().Set(dResult);
}

// static
void CFXJSE_FormCalcContext::IPmt(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 5) {
    pContext->ThrowParamCountMismatchException("IPmt");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
  v8::Local<v8::Value> argFour = GetSimpleValue(info, 3);
  v8::Local<v8::Value> argFive = GetSimpleValue(info, 4);
  if (ValueIsNull(info.GetIsolate(), argOne) ||
      ValueIsNull(info.GetIsolate(), argTwo) ||
      ValueIsNull(info.GetIsolate(), argThree) ||
      ValueIsNull(info.GetIsolate(), argFour) ||
      ValueIsNull(info.GetIsolate(), argFive)) {
    info.GetReturnValue().SetNull();
    return;
  }

  float nPrincipalAmount = ValueToFloat(info.GetIsolate(), argOne);
  float nRate = ValueToFloat(info.GetIsolate(), argTwo);
  float nPayment = ValueToFloat(info.GetIsolate(), argThree);
  float nFirstMonth = ValueToFloat(info.GetIsolate(), argFour);
  float nNumberOfMonths = ValueToFloat(info.GetIsolate(), argFive);
  if ((nPrincipalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) ||
      (nFirstMonth < 0) || (nNumberOfMonths < 0)) {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  float nRateOfMonth = nRate / 12;
  int32_t iNums = static_cast<int32_t>(
      (log10((float)(nPayment / nPrincipalAmount)) -
       log10((float)(nPayment / nPrincipalAmount - nRateOfMonth))) /
      log10((float)(1 + nRateOfMonth)));
  int32_t iEnd =
      std::min(static_cast<int32_t>(nFirstMonth + nNumberOfMonths - 1), iNums);

  if (nPayment < nPrincipalAmount * nRateOfMonth) {
    info.GetReturnValue().Set(0);
    return;
  }

  int32_t i = 0;
  for (i = 0; i < nFirstMonth - 1; ++i)
    nPrincipalAmount -= nPayment - nPrincipalAmount * nRateOfMonth;

  float nSum = 0;
  for (; i < iEnd; ++i) {
    nSum += nPrincipalAmount * nRateOfMonth;
    nPrincipalAmount -= nPayment - nPrincipalAmount * nRateOfMonth;
  }
  info.GetReturnValue().Set(nSum);
}

// static
void CFXJSE_FormCalcContext::NPV(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  int32_t argc = info.Length();
  if (argc < 2) {
    pContext->ThrowParamCountMismatchException("NPV");
    return;
  }

  v8::Local<v8::Value> argValue = GetSimpleValue(info, 0);
  if (ValueIsNull(info.GetIsolate(), argValue)) {
    info.GetReturnValue().SetNull();
    return;
  }

  double nRate = ValueToDouble(info.GetIsolate(), argValue);
  if (nRate <= 0) {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  std::vector<double> data;
  for (int32_t i = 1; i < argc; i++) {
    argValue = GetSimpleValue(info, i);
    if (ValueIsNull(info.GetIsolate(), argValue)) {
      info.GetReturnValue().SetNull();
      return;
    }
    data.push_back(ValueToDouble(info.GetIsolate(), argValue));
  }

  double nSum = 0;
  double nDivisor = 1.0 + nRate;
  while (!data.empty()) {
    nSum += data.back();
    nSum /= nDivisor;
    data.pop_back();
  }
  info.GetReturnValue().Set(nSum);
}

// static
void CFXJSE_FormCalcContext::Pmt(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 3) {
    pContext->ThrowParamCountMismatchException("Pmt");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
  if (ValueIsNull(info.GetIsolate(), argOne) ||
      ValueIsNull(info.GetIsolate(), argTwo) ||
      ValueIsNull(info.GetIsolate(), argThree)) {
    info.GetReturnValue().SetNull();
    return;
  }

  double nPrincipal = ValueToDouble(info.GetIsolate(), argOne);
  double nRate = ValueToDouble(info.GetIsolate(), argTwo);
  int nPeriods = GetValidatedPaymentPeriods(info.GetIsolate(), argThree);
  if (nPrincipal <= 0 || nRate <= 0 || nPeriods == 0) {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  double nSum = pow(1.0 + nRate, nPeriods);
  info.GetReturnValue().Set((nPrincipal * nRate * nSum) / (nSum - 1));
}

// static
void CFXJSE_FormCalcContext::PPmt(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 5) {
    pContext->ThrowParamCountMismatchException("PPmt");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
  v8::Local<v8::Value> argFour = GetSimpleValue(info, 3);
  v8::Local<v8::Value> argFive = GetSimpleValue(info, 4);
  if (ValueIsNull(info.GetIsolate(), argOne) ||
      ValueIsNull(info.GetIsolate(), argTwo) ||
      ValueIsNull(info.GetIsolate(), argThree) ||
      ValueIsNull(info.GetIsolate(), argFour) ||
      ValueIsNull(info.GetIsolate(), argFive)) {
    info.GetReturnValue().SetNull();
    return;
  }

  float nPrincipalAmount = ValueToFloat(info.GetIsolate(), argOne);
  float nRate = ValueToFloat(info.GetIsolate(), argTwo);
  float nPayment = ValueToFloat(info.GetIsolate(), argThree);
  float nFirstMonth = ValueToFloat(info.GetIsolate(), argFour);
  float nNumberOfMonths = ValueToFloat(info.GetIsolate(), argFive);
  if ((nPrincipalAmount <= 0) || (nRate <= 0) || (nPayment <= 0) ||
      (nFirstMonth < 0) || (nNumberOfMonths < 0)) {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  float nRateOfMonth = nRate / 12;
  int32_t iNums = static_cast<int32_t>(
      (log10((float)(nPayment / nPrincipalAmount)) -
       log10((float)(nPayment / nPrincipalAmount - nRateOfMonth))) /
      log10((float)(1 + nRateOfMonth)));
  int32_t iEnd =
      std::min(static_cast<int32_t>(nFirstMonth + nNumberOfMonths - 1), iNums);
  if (nPayment < nPrincipalAmount * nRateOfMonth) {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  int32_t i = 0;
  for (i = 0; i < nFirstMonth - 1; ++i)
    nPrincipalAmount -= nPayment - nPrincipalAmount * nRateOfMonth;

  float nTemp = 0;
  float nSum = 0;
  for (; i < iEnd; ++i) {
    nTemp = nPayment - nPrincipalAmount * nRateOfMonth;
    nSum += nTemp;
    nPrincipalAmount -= nTemp;
  }
  info.GetReturnValue().Set(nSum);
}

// static
void CFXJSE_FormCalcContext::PV(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 3) {
    pContext->ThrowParamCountMismatchException("PV");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
  if (ValueIsNull(info.GetIsolate(), argOne) ||
      ValueIsNull(info.GetIsolate(), argTwo) ||
      ValueIsNull(info.GetIsolate(), argThree)) {
    info.GetReturnValue().SetNull();
    return;
  }

  double nAmount = ValueToDouble(info.GetIsolate(), argOne);
  double nRate = ValueToDouble(info.GetIsolate(), argTwo);
  int nPeriods = GetValidatedPaymentPeriods(info.GetIsolate(), argThree);
  if (nAmount <= 0 || nRate < 0 || nPeriods == 0) {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  double nTemp = 1 / pow(1.0 + nRate, nPeriods);
  info.GetReturnValue().Set(nAmount * ((1.0 - nTemp) / nRate));
}

// static
void CFXJSE_FormCalcContext::Rate(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 3) {
    pContext->ThrowParamCountMismatchException("Rate");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
  if (ValueIsNull(info.GetIsolate(), argOne) ||
      ValueIsNull(info.GetIsolate(), argTwo) ||
      ValueIsNull(info.GetIsolate(), argThree)) {
    info.GetReturnValue().SetNull();
    return;
  }

  float nFuture = ValueToFloat(info.GetIsolate(), argOne);
  float nPresent = ValueToFloat(info.GetIsolate(), argTwo);
  int nPeriods = GetValidatedPaymentPeriods(info.GetIsolate(), argThree);
  if (nFuture <= 0 || nPresent < 0 || nPeriods == 0) {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  info.GetReturnValue().Set(powf(nFuture / nPresent, 1.0f / nPeriods) - 1.0f);
}

// static
void CFXJSE_FormCalcContext::Term(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 3) {
    pContext->ThrowParamCountMismatchException("Term");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
  if (ValueIsNull(info.GetIsolate(), argOne) ||
      ValueIsNull(info.GetIsolate(), argTwo) ||
      ValueIsNull(info.GetIsolate(), argThree)) {
    info.GetReturnValue().SetNull();
    return;
  }

  float nMount = ValueToFloat(info.GetIsolate(), argOne);
  float nRate = ValueToFloat(info.GetIsolate(), argTwo);
  float nFuture = ValueToFloat(info.GetIsolate(), argThree);
  if ((nMount <= 0) || (nRate <= 0) || (nFuture <= 0)) {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  info.GetReturnValue().Set(log((float)(nFuture / nMount * nRate) + 1) /
                            log((float)(1 + nRate)));
}

// static
void CFXJSE_FormCalcContext::Choose(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  int32_t argc = info.Length();
  if (argc < 2) {
    pContext->ThrowParamCountMismatchException("Choose");
    return;
  }

  if (ValueIsNull(info.GetIsolate(), info[0])) {
    info.GetReturnValue().SetNull();
    return;
  }

  int32_t iIndex =
      static_cast<int32_t>(ValueToFloat(info.GetIsolate(), info[0]));
  if (iIndex < 1) {
    info.GetReturnValue().SetEmptyString();
    return;
  }

  bool bFound = false;
  bool bStopCounterFlags = false;
  int32_t iArgIndex = 1;
  int32_t iValueIndex = 0;
  while (!bFound && !bStopCounterFlags && (iArgIndex < argc)) {
    v8::Local<v8::Value> argIndexValue = info[iArgIndex];
    if (fxv8::IsArray(argIndexValue)) {
      v8::Local<v8::Array> arr = argIndexValue.As<v8::Array>();
      uint32_t iLength = fxv8::GetArrayLengthHelper(arr);
      if (iLength > 3)
        bStopCounterFlags = true;

      iValueIndex += (iLength - 2);
      if (iValueIndex >= iIndex) {
        v8::Local<v8::Value> propertyValue =
            fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 1);
        v8::Local<v8::Value> jsValue = fxv8::ReentrantGetArrayElementHelper(
            info.GetIsolate(), arr, (iLength - 1) - (iValueIndex - iIndex));
        v8::Local<v8::Value> newPropertyValue;
        if (fxv8::IsObject(jsValue)) {
          v8::Local<v8::Object> jsObjectValue = jsValue.As<v8::Object>();
          if (fxv8::IsNull(propertyValue)) {
            newPropertyValue =
                GetObjectDefaultValue(info.GetIsolate(), jsObjectValue);
          } else {
            ByteString bsName = fxv8::ReentrantToByteStringHelper(
                info.GetIsolate(), propertyValue);
            newPropertyValue = fxv8::ReentrantGetObjectPropertyHelper(
                info.GetIsolate(), jsObjectValue, bsName.AsStringView());
          }
        }
        ByteString bsChosen =
            ValueToUTF8String(info.GetIsolate(), newPropertyValue);
        info.GetReturnValue().Set(
            fxv8::NewStringHelper(info.GetIsolate(), bsChosen.AsStringView()));
        bFound = true;
      }
    } else {
      iValueIndex++;
      if (iValueIndex == iIndex) {
        ByteString bsChosen =
            ValueToUTF8String(info.GetIsolate(), argIndexValue);
        info.GetReturnValue().Set(
            fxv8::NewStringHelper(info.GetIsolate(), bsChosen.AsStringView()));
        bFound = true;
      }
    }
    iArgIndex++;
  }
  if (!bFound)
    info.GetReturnValue().SetEmptyString();
}

// static
void CFXJSE_FormCalcContext::Exists(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Exists");
    return;
  }
  info.GetReturnValue().Set(fxv8::IsObject(info[0]));
}

// static
void CFXJSE_FormCalcContext::HasValue(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("HasValue");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  if (!fxv8::IsString(argOne)) {
    info.GetReturnValue().Set(
        static_cast<int>(fxv8::IsNumber(argOne) || fxv8::IsBoolean(argOne)));
    return;
  }

  ByteString bsValue =
      fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argOne);
  bsValue.TrimLeft();
  info.GetReturnValue().Set(static_cast<int>(!bsValue.IsEmpty()));
}

// static
void CFXJSE_FormCalcContext::Oneof(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() < 2) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Oneof");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  for (const auto& value : UnfoldArgs(info)) {
    if (SimpleValueCompare(info.GetIsolate(), argOne, value)) {
      info.GetReturnValue().Set(1);
      return;
    }
  }
  info.GetReturnValue().Set(0);
}

// static
void CFXJSE_FormCalcContext::Within(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 3) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Within");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  if (fxv8::IsNull(argOne)) {
    info.GetReturnValue().SetUndefined();
    return;
  }

  v8::Local<v8::Value> argLow = GetSimpleValue(info, 1);
  v8::Local<v8::Value> argHigh = GetSimpleValue(info, 2);
  if (fxv8::IsNumber(argOne)) {
    float oneNumber = ValueToFloat(info.GetIsolate(), argOne);
    float lowNumber = ValueToFloat(info.GetIsolate(), argLow);
    float heightNumber = ValueToFloat(info.GetIsolate(), argHigh);
    info.GetReturnValue().Set(static_cast<int>((oneNumber >= lowNumber) &&
                                               (oneNumber <= heightNumber)));
    return;
  }

  ByteString bsOne = ValueToUTF8String(info.GetIsolate(), argOne);
  ByteString bsLow = ValueToUTF8String(info.GetIsolate(), argLow);
  ByteString bsHeight = ValueToUTF8String(info.GetIsolate(), argHigh);
  info.GetReturnValue().Set(
      static_cast<int>((bsOne.Compare(bsLow.AsStringView()) >= 0) &&
                       (bsOne.Compare(bsHeight.AsStringView()) <= 0)));
}

// static
void CFXJSE_FormCalcContext::If(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 3) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("If");
    return;
  }

  const bool condition = fxv8::ReentrantToBooleanHelper(
      info.GetIsolate(), GetSimpleValue(info, 0));

  info.GetReturnValue().Set(GetSimpleValue(info, condition ? 1 : 2));
}

// static
void CFXJSE_FormCalcContext::Eval(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 1) {
    pContext->ThrowParamCountMismatchException("Eval");
    return;
  }

  v8::Isolate* pIsolate = pContext->GetIsolate();
  v8::Local<v8::Value> scriptValue = GetSimpleValue(info, 0);
  ByteString bsUtf8Script = ValueToUTF8String(info.GetIsolate(), scriptValue);
  if (bsUtf8Script.IsEmpty()) {
    info.GetReturnValue().SetNull();
    return;
  }

  WideString wsCalcScript = WideString::FromUTF8(bsUtf8Script.AsStringView());
  std::optional<WideTextBuffer> wsJavaScriptBuf =
      CFXJSE_FormCalcContext::Translate(pContext->GetDocument()->GetHeap(),
                                        wsCalcScript.AsStringView());
  if (!wsJavaScriptBuf.has_value()) {
    pContext->ThrowCompilerErrorException();
    return;
  }
  std::unique_ptr<CFXJSE_Context> pNewContext =
      CFXJSE_Context::Create(pIsolate, nullptr, nullptr, nullptr);

  ByteString bsScript = FX_UTF8Encode(wsJavaScriptBuf.value().AsStringView());
  CFXJSE_Context::ExecutionResult result = pNewContext->ExecuteScript(
      bsScript.AsStringView(), v8::Local<v8::Object>());

  info.GetReturnValue().Set(result.value->DirectGetValue());
}

// static
void CFXJSE_FormCalcContext::Ref(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 1) {
    pContext->ThrowParamCountMismatchException("Ref");
    return;
  }

  v8::Local<v8::Value> argOne = info[0];
  if (fxv8::IsBoolean(argOne) || fxv8::IsString(argOne) ||
      fxv8::IsNumber(argOne)) {
    info.GetReturnValue().Set(argOne);
    return;
  }

  v8::LocalVector<v8::Value> values(info.GetIsolate(), 3);
  int intVal = 3;
  if (fxv8::IsNull(argOne)) {
    // TODO(dsinclair): Why is this 4 when the others are all 3?
    intVal = 4;
    values[2] = fxv8::NewNullHelper(info.GetIsolate());
  } else if (fxv8::IsArray(argOne)) {
    v8::Local<v8::Array> arr = argOne.As<v8::Array>();
    v8::Local<v8::Value> propertyValue =
        fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 1);
    v8::Local<v8::Value> jsObjectValue =
        fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 2);
    if (!fxv8::IsNull(propertyValue) || fxv8::IsNull(jsObjectValue)) {
      pContext->ThrowArgumentMismatchException();
      return;
    }
    values[2] = jsObjectValue;
  } else if (fxv8::IsObject(argOne)) {
    values[2] = argOne;
  } else {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  values[0] = fxv8::NewNumberHelper(info.GetIsolate(), intVal);
  values[1] = fxv8::NewNullHelper(info.GetIsolate());
  info.GetReturnValue().Set(fxv8::NewArrayHelper(info.GetIsolate(), values));
}

// static
void CFXJSE_FormCalcContext::UnitType(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("UnitType");
    return;
  }

  v8::Local<v8::Value> unitspanValue = GetSimpleValue(info, 0);
  if (fxv8::IsNull(unitspanValue)) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsUnitspan = ValueToUTF8String(info.GetIsolate(), unitspanValue);
  if (bsUnitspan.IsEmpty()) {
    info.GetReturnValue().SetEmptyString();
    return;
  }

  enum XFA_FormCalc_VALUETYPE_ParserStatus {
    VALUETYPE_START,
    VALUETYPE_HAVEINVALIDCHAR,
    VALUETYPE_HAVEDIGIT,
    VALUETYPE_HAVEDIGITWHITE,
    VALUETYPE_ISCM,
    VALUETYPE_ISMM,
    VALUETYPE_ISPT,
    VALUETYPE_ISMP,
    VALUETYPE_ISIN,
  };
  bsUnitspan.MakeLower();
  WideString wsType = WideString::FromUTF8(bsUnitspan.AsStringView());
  const wchar_t* pData = wsType.c_str();
  int32_t u = 0;
  int32_t uLen = wsType.GetLength();
  while (IsWhitespace(pData[u]))
    u++;

  XFA_FormCalc_VALUETYPE_ParserStatus eParserStatus = VALUETYPE_START;
  wchar_t typeChar;
  // TODO(dsinclair): Cleanup this parser, figure out what the various checks
  //    are for.
  while (u < uLen) {
    typeChar = pData[u];
    if (IsWhitespace(typeChar)) {
      if (eParserStatus != VALUETYPE_HAVEDIGIT &&
          eParserStatus != VALUETYPE_HAVEDIGITWHITE) {
        eParserStatus = VALUETYPE_ISIN;
        break;
      }
      eParserStatus = VALUETYPE_HAVEDIGITWHITE;
    } else if (IsPartOfNumberW(typeChar)) {
      if (eParserStatus == VALUETYPE_HAVEDIGITWHITE) {
        eParserStatus = VALUETYPE_ISIN;
        break;
      }
      eParserStatus = VALUETYPE_HAVEDIGIT;
    } else if ((typeChar == 'c' || typeChar == 'p') && (u + 1 < uLen)) {
      wchar_t nextChar = pData[u + 1];
      if ((eParserStatus == VALUETYPE_START ||
           eParserStatus == VALUETYPE_HAVEDIGIT ||
           eParserStatus == VALUETYPE_HAVEDIGITWHITE) &&
          !IsPartOfNumberW(nextChar)) {
        eParserStatus = (typeChar == 'c') ? VALUETYPE_ISCM : VALUETYPE_ISPT;
        break;
      }
      eParserStatus = VALUETYPE_HAVEINVALIDCHAR;
    } else if (typeChar == 'm' && (u + 1 < uLen)) {
      wchar_t nextChar = pData[u + 1];
      if ((eParserStatus == VALUETYPE_START ||
           eParserStatus == VALUETYPE_HAVEDIGIT ||
           eParserStatus == VALUETYPE_HAVEDIGITWHITE) &&
          !IsPartOfNumberW(nextChar)) {
        eParserStatus = VALUETYPE_ISMM;
        if (nextChar == 'p' || ((u + 5 < uLen) && pData[u + 1] == 'i' &&
                                pData[u + 2] == 'l' && pData[u + 3] == 'l' &&
                                pData[u + 4] == 'i' && pData[u + 5] == 'p')) {
          eParserStatus = VALUETYPE_ISMP;
        }
        break;
      }
    } else {
      eParserStatus = VALUETYPE_HAVEINVALIDCHAR;
    }
    u++;
  }
  switch (eParserStatus) {
    case VALUETYPE_ISCM:
      info.GetReturnValue().Set(fxv8::NewStringHelper(info.GetIsolate(), "cm"));
      break;
    case VALUETYPE_ISMM:
      info.GetReturnValue().Set(fxv8::NewStringHelper(info.GetIsolate(), "mm"));
      break;
    case VALUETYPE_ISPT:
      info.GetReturnValue().Set(fxv8::NewStringHelper(info.GetIsolate(), "pt"));
      break;
    case VALUETYPE_ISMP:
      info.GetReturnValue().Set(fxv8::NewStringHelper(info.GetIsolate(), "mp"));
      break;
    default:
      info.GetReturnValue().Set(fxv8::NewStringHelper(info.GetIsolate(), "in"));
      break;
  }
}

// static
void CFXJSE_FormCalcContext::UnitValue(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 1 || argc > 2) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("UnitValue");
    return;
  }

  v8::Local<v8::Value> unitspanValue = GetSimpleValue(info, 0);
  if (fxv8::IsNull(unitspanValue)) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsUnitspan = ValueToUTF8String(info.GetIsolate(), unitspanValue);
  const char* pData = bsUnitspan.c_str();
  if (!pData) {
    info.GetReturnValue().Set(0);
    return;
  }

  size_t u = 0;
  while (IsWhitespace(pData[u]))
    ++u;

  while (u < bsUnitspan.GetLength()) {
    if (!IsPartOfNumber(pData[u]))
      break;
    ++u;
  }

  char* pTemp = nullptr;
  double dFirstNumber = strtod(pData, &pTemp);
  while (IsWhitespace(pData[u]))
    ++u;

  size_t uLen = bsUnitspan.GetLength();
  ByteString bsFirstUnit;
  while (u < uLen) {
    if (pData[u] == ' ')
      break;

    bsFirstUnit += pData[u];
    ++u;
  }
  bsFirstUnit.MakeLower();

  ByteString bsUnit;
  if (argc > 1) {
    v8::Local<v8::Value> unitValue = GetSimpleValue(info, 1);
    ByteString bsUnitTemp = ValueToUTF8String(info.GetIsolate(), unitValue);
    const char* pChar = bsUnitTemp.c_str();
    size_t uVal = 0;
    while (IsWhitespace(pChar[uVal]))
      ++uVal;

    while (uVal < bsUnitTemp.GetLength()) {
      if (!isdigit(pChar[uVal]) && pChar[uVal] != '.')
        break;
      ++uVal;
    }
    while (IsWhitespace(pChar[uVal]))
      ++uVal;

    size_t uValLen = bsUnitTemp.GetLength();
    while (uVal < uValLen) {
      if (pChar[uVal] == ' ')
        break;

      bsUnit += pChar[uVal];
      ++uVal;
    }
    bsUnit.MakeLower();
  } else {
    bsUnit = bsFirstUnit;
  }

  double dResult = 0;
  if (bsFirstUnit == "in" || bsFirstUnit == "inches") {
    if (bsUnit == "mm" || bsUnit == "millimeters")
      dResult = dFirstNumber * 25.4;
    else if (bsUnit == "cm" || bsUnit == "centimeters")
      dResult = dFirstNumber * 2.54;
    else if (bsUnit == "pt" || bsUnit == "points")
      dResult = dFirstNumber / 72;
    else if (bsUnit == "mp" || bsUnit == "millipoints")
      dResult = dFirstNumber / 72000;
    else
      dResult = dFirstNumber;
  } else if (bsFirstUnit == "mm" || bsFirstUnit == "millimeters") {
    if (bsUnit == "mm" || bsUnit == "millimeters")
      dResult = dFirstNumber;
    else if (bsUnit == "cm" || bsUnit == "centimeters")
      dResult = dFirstNumber / 10;
    else if (bsUnit == "pt" || bsUnit == "points")
      dResult = dFirstNumber / 25.4 / 72;
    else if (bsUnit == "mp" || bsUnit == "millipoints")
      dResult = dFirstNumber / 25.4 / 72000;
    else
      dResult = dFirstNumber / 25.4;
  } else if (bsFirstUnit == "cm" || bsFirstUnit == "centimeters") {
    if (bsUnit == "mm" || bsUnit == "millimeters")
      dResult = dFirstNumber * 10;
    else if (bsUnit == "cm" || bsUnit == "centimeters")
      dResult = dFirstNumber;
    else if (bsUnit == "pt" || bsUnit == "points")
      dResult = dFirstNumber / 2.54 / 72;
    else if (bsUnit == "mp" || bsUnit == "millipoints")
      dResult = dFirstNumber / 2.54 / 72000;
    else
      dResult = dFirstNumber / 2.54;
  } else if (bsFirstUnit == "pt" || bsFirstUnit == "points") {
    if (bsUnit == "mm" || bsUnit == "millimeters")
      dResult = dFirstNumber / 72 * 25.4;
    else if (bsUnit == "cm" || bsUnit == "centimeters")
      dResult = dFirstNumber / 72 * 2.54;
    else if (bsUnit == "pt" || bsUnit == "points")
      dResult = dFirstNumber;
    else if (bsUnit == "mp" || bsUnit == "millipoints")
      dResult = dFirstNumber * 1000;
    else
      dResult = dFirstNumber / 72;
  } else if (bsFirstUnit == "mp" || bsFirstUnit == "millipoints") {
    if (bsUnit == "mm" || bsUnit == "millimeters")
      dResult = dFirstNumber / 72000 * 25.4;
    else if (bsUnit == "cm" || bsUnit == "centimeters")
      dResult = dFirstNumber / 72000 * 2.54;
    else if (bsUnit == "pt" || bsUnit == "points")
      dResult = dFirstNumber / 1000;
    else if (bsUnit == "mp" || bsUnit == "millipoints")
      dResult = dFirstNumber;
    else
      dResult = dFirstNumber / 72000;
  }
  info.GetReturnValue().Set(dResult);
}

// static
void CFXJSE_FormCalcContext::At(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 2) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("At");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  if (ValueIsNull(info.GetIsolate(), argOne) ||
      ValueIsNull(info.GetIsolate(), argTwo)) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString stringTwo = ValueToUTF8String(info.GetIsolate(), argTwo);
  if (stringTwo.IsEmpty()) {
    info.GetReturnValue().Set(1);
    return;
  }

  ByteString stringOne = ValueToUTF8String(info.GetIsolate(), argOne);
  auto pos = stringOne.Find(stringTwo.AsStringView());
  info.GetReturnValue().Set(
      static_cast<int>(pos.has_value() ? pos.value() + 1 : 0));
}

// static
void CFXJSE_FormCalcContext::Concat(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 1) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Concat");
    return;
  }

  ByteString bsResult;
  bool bAllNull = true;
  for (int32_t i = 0; i < argc; i++) {
    v8::Local<v8::Value> value = GetSimpleValue(info, i);
    if (ValueIsNull(info.GetIsolate(), value))
      continue;

    bAllNull = false;
    bsResult += ValueToUTF8String(info.GetIsolate(), value);
  }

  if (bAllNull) {
    info.GetReturnValue().SetNull();
    return;
  }
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), bsResult.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Decode(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 1 || argc > 2) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Decode");
    return;
  }

  if (argc == 1) {
    v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
    if (ValueIsNull(info.GetIsolate(), argOne)) {
      info.GetReturnValue().SetNull();
      return;
    }

    WideString decoded = DecodeURL(WideString::FromUTF8(
        ValueToUTF8String(info.GetIsolate(), argOne).AsStringView()));
    auto result = FX_UTF8Encode(decoded.AsStringView());
    info.GetReturnValue().Set(
        fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  if (ValueIsNull(info.GetIsolate(), argOne) ||
      ValueIsNull(info.GetIsolate(), argTwo)) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsToDecode = ValueToUTF8String(info.GetIsolate(), argOne);
  ByteString bsIdentify = ValueToUTF8String(info.GetIsolate(), argTwo);
  WideString decoded;

  WideString wsToDecode = WideString::FromUTF8(bsToDecode.AsStringView());

  if (bsIdentify.EqualNoCase("html"))
    decoded = DecodeHTML(wsToDecode);
  else if (bsIdentify.EqualNoCase("xml"))
    decoded = DecodeXML(wsToDecode);
  else
    decoded = DecodeURL(wsToDecode);

  auto result = FX_UTF8Encode(decoded.AsStringView());
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Encode(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 1 || argc > 2) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Encode");
    return;
  }

  if (argc == 1) {
    v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
    if (ValueIsNull(info.GetIsolate(), argOne)) {
      info.GetReturnValue().SetNull();
      return;
    }
    WideString encoded =
        EncodeURL(ValueToUTF8String(info.GetIsolate(), argOne));
    auto result = FX_UTF8Encode(encoded.AsStringView());
    info.GetReturnValue().Set(
        fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  if (ValueIsNull(info.GetIsolate(), argOne) ||
      ValueIsNull(info.GetIsolate(), argTwo)) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsToEncode = ValueToUTF8String(info.GetIsolate(), argOne);
  ByteString bsIdentify = ValueToUTF8String(info.GetIsolate(), argTwo);
  WideString encoded;
  if (bsIdentify.EqualNoCase("html"))
    encoded = EncodeHTML(bsToEncode);
  else if (bsIdentify.EqualNoCase("xml"))
    encoded = EncodeXML(bsToEncode);
  else
    encoded = EncodeURL(bsToEncode);

  auto result = FX_UTF8Encode(encoded.AsStringView());
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Format(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() < 2) {
    pContext->ThrowParamCountMismatchException("Format");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  ByteString bsPattern = ValueToUTF8String(info.GetIsolate(), argOne);

  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  ByteString bsValue = ValueToUTF8String(info.GetIsolate(), argTwo);

  CXFA_Document* pDoc = pContext->GetDocument();
  CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
  CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
  GCedLocaleIface* pLocale = pThisNode->GetLocale();
  WideString wsPattern = WideString::FromUTF8(bsPattern.AsStringView());
  WideString wsValue = WideString::FromUTF8(bsValue.AsStringView());
  bool bPatternIsString;
  CXFA_LocaleValue::ValueType dwPatternType;
  std::tie(bPatternIsString, dwPatternType) =
      PatternStringType(bsPattern.AsStringView());
  if (!bPatternIsString) {
    switch (dwPatternType) {
      case CXFA_LocaleValue::ValueType::kDateTime: {
        auto iTChar = wsPattern.Find(L'T');
        if (!iTChar.has_value()) {
          info.GetReturnValue().SetEmptyString();
          return;
        }
        WideString wsDatePattern(L"date{");
        wsDatePattern += wsPattern.First(iTChar.value()) + L"} ";

        WideString wsTimePattern(L"time{");
        wsTimePattern +=
            wsPattern.Last(wsPattern.GetLength() - (iTChar.value() + 1)) + L"}";
        wsPattern = wsDatePattern + wsTimePattern;
      } break;
      case CXFA_LocaleValue::ValueType::kDate: {
        wsPattern = L"date{" + wsPattern + L"}";
      } break;
      case CXFA_LocaleValue::ValueType::kTime: {
        wsPattern = L"time{" + wsPattern + L"}";
      } break;
      case CXFA_LocaleValue::ValueType::kText: {
        wsPattern = L"text{" + wsPattern + L"}";
      } break;
      case CXFA_LocaleValue::ValueType::kFloat: {
        wsPattern = L"num{" + wsPattern + L"}";
      } break;
      default: {
        WideString wsTestPattern = L"num{" + wsPattern + L"}";
        CXFA_LocaleValue tempLocaleValue(CXFA_LocaleValue::ValueType::kFloat,
                                         wsValue, wsTestPattern, pLocale, pMgr);
        if (tempLocaleValue.IsValid()) {
          wsPattern = std::move(wsTestPattern);
          dwPatternType = CXFA_LocaleValue::ValueType::kFloat;
        } else {
          wsPattern = L"text{" + wsPattern + L"}";
          dwPatternType = CXFA_LocaleValue::ValueType::kText;
        }
      } break;
    }
  }
  CXFA_LocaleValue localeValue(dwPatternType, wsValue, wsPattern, pLocale,
                               pMgr);
  WideString wsRet;
  if (!localeValue.FormatPatterns(wsRet, wsPattern, pLocale,
                                  XFA_ValuePicture::kDisplay)) {
    info.GetReturnValue().SetEmptyString();
    return;
  }
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), wsRet.ToUTF8().AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Left(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 2) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Left");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  if ((ValueIsNull(info.GetIsolate(), argOne)) ||
      (ValueIsNull(info.GetIsolate(), argTwo))) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsSource = ValueToUTF8String(info.GetIsolate(), argOne);
  int32_t count = std::max(0, ValueToInteger(info.GetIsolate(), argTwo));
  info.GetReturnValue().Set(fxv8::NewStringHelper(
      info.GetIsolate(), bsSource.First(count).AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Len(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Len");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  if (ValueIsNull(info.GetIsolate(), argOne)) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsSource = ValueToUTF8String(info.GetIsolate(), argOne);
  info.GetReturnValue().Set(static_cast<int>(bsSource.GetLength()));
}

// static
void CFXJSE_FormCalcContext::Lower(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 1 || argc > 2) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Lower");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  if (ValueIsNull(info.GetIsolate(), argOne)) {
    info.GetReturnValue().SetNull();
    return;
  }

  WideTextBuffer szLowBuf;
  ByteString bsArg = ValueToUTF8String(info.GetIsolate(), argOne);
  WideString wsArg = WideString::FromUTF8(bsArg.AsStringView());
  for (wchar_t ch : wsArg) {
    if ((ch >= 0x41 && ch <= 0x5A) || (ch >= 0xC0 && ch <= 0xDE))
      ch += 32;
    else if (ch == 0x100 || ch == 0x102 || ch == 0x104)
      ch += 1;
    szLowBuf.AppendChar(ch);
  }
  auto result = FX_UTF8Encode(szLowBuf.AsStringView());
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Ltrim(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Ltrim");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  if (ValueIsNull(info.GetIsolate(), argOne)) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsSource = ValueToUTF8String(info.GetIsolate(), argOne);
  bsSource.TrimLeft();
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), bsSource.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Parse(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 2) {
    pContext->ThrowParamCountMismatchException("Parse");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  if (ValueIsNull(info.GetIsolate(), argTwo)) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsPattern = ValueToUTF8String(info.GetIsolate(), argOne);
  ByteString bsValue = ValueToUTF8String(info.GetIsolate(), argTwo);
  CXFA_Document* pDoc = pContext->GetDocument();
  CXFA_LocaleMgr* pMgr = pDoc->GetLocaleMgr();
  CXFA_Node* pThisNode = ToNode(pDoc->GetScriptContext()->GetThisObject());
  GCedLocaleIface* pLocale = pThisNode->GetLocale();
  WideString wsPattern = WideString::FromUTF8(bsPattern.AsStringView());
  WideString wsValue = WideString::FromUTF8(bsValue.AsStringView());
  bool bPatternIsString;
  CXFA_LocaleValue::ValueType dwPatternType;
  std::tie(bPatternIsString, dwPatternType) =
      PatternStringType(bsPattern.AsStringView());
  if (bPatternIsString) {
    CXFA_LocaleValue localeValue(dwPatternType, wsValue, wsPattern, pLocale,
                                 pMgr);
    if (!localeValue.IsValid()) {
      info.GetReturnValue().SetEmptyString();
      return;
    }
    auto result = localeValue.GetValue().ToUTF8();
    info.GetReturnValue().Set(
        fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
    return;
  }

  switch (dwPatternType) {
    case CXFA_LocaleValue::ValueType::kDateTime: {
      auto iTChar = wsPattern.Find(L'T');
      if (!iTChar.has_value()) {
        info.GetReturnValue().SetEmptyString();
        return;
      }
      WideString wsDatePattern(L"date{" + wsPattern.First(iTChar.value()) +
                               L"} ");
      WideString wsTimePattern(
          L"time{" +
          wsPattern.Last(wsPattern.GetLength() - (iTChar.value() + 1)) + L"}");
      wsPattern = wsDatePattern + wsTimePattern;
      CXFA_LocaleValue localeValue(dwPatternType, wsValue, wsPattern, pLocale,
                                   pMgr);
      if (!localeValue.IsValid()) {
        info.GetReturnValue().SetEmptyString();
        return;
      }
      auto result = localeValue.GetValue().ToUTF8();
      info.GetReturnValue().Set(
          fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
      return;
    }
    case CXFA_LocaleValue::ValueType::kDate: {
      wsPattern = L"date{" + wsPattern + L"}";
      CXFA_LocaleValue localeValue(dwPatternType, wsValue, wsPattern, pLocale,
                                   pMgr);
      if (!localeValue.IsValid()) {
        info.GetReturnValue().SetEmptyString();
        return;
      }
      auto result = localeValue.GetValue().ToUTF8();
      info.GetReturnValue().Set(
          fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
      return;
    }
    case CXFA_LocaleValue::ValueType::kTime: {
      wsPattern = L"time{" + wsPattern + L"}";
      CXFA_LocaleValue localeValue(dwPatternType, wsValue, wsPattern, pLocale,
                                   pMgr);
      if (!localeValue.IsValid()) {
        info.GetReturnValue().SetEmptyString();
        return;
      }
      auto result = localeValue.GetValue().ToUTF8();
      info.GetReturnValue().Set(
          fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
      return;
    }
    case CXFA_LocaleValue::ValueType::kText: {
      wsPattern = L"text{" + wsPattern + L"}";
      CXFA_LocaleValue localeValue(CXFA_LocaleValue::ValueType::kText, wsValue,
                                   wsPattern, pLocale, pMgr);
      if (!localeValue.IsValid()) {
        info.GetReturnValue().SetEmptyString();
        return;
      }
      auto result = localeValue.GetValue().ToUTF8();
      info.GetReturnValue().Set(
          fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
      return;
    }
    case CXFA_LocaleValue::ValueType::kFloat: {
      wsPattern = L"num{" + wsPattern + L"}";
      CXFA_LocaleValue localeValue(CXFA_LocaleValue::ValueType::kFloat, wsValue,
                                   wsPattern, pLocale, pMgr);
      if (!localeValue.IsValid()) {
        info.GetReturnValue().SetEmptyString();
        return;
      }
      info.GetReturnValue().Set(localeValue.GetDoubleNum());
      return;
    }
    default: {
      {
        WideString wsTestPattern = L"num{" + wsPattern + L"}";
        CXFA_LocaleValue localeValue(CXFA_LocaleValue::ValueType::kFloat,
                                     wsValue, wsTestPattern, pLocale, pMgr);
        if (localeValue.IsValid()) {
          info.GetReturnValue().Set(localeValue.GetDoubleNum());
          return;
        }
      }

      {
        WideString wsTestPattern = L"text{" + wsPattern + L"}";
        CXFA_LocaleValue localeValue(CXFA_LocaleValue::ValueType::kText,
                                     wsValue, wsTestPattern, pLocale, pMgr);
        if (localeValue.IsValid()) {
          auto result = localeValue.GetValue().ToUTF8();
          info.GetReturnValue().Set(
              fxv8::NewStringHelper(info.GetIsolate(), result.AsStringView()));
          return;
        }
      }
      info.GetReturnValue().SetEmptyString();
      return;
    }
  }
}

// static
void CFXJSE_FormCalcContext::Replace(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 2 || argc > 3) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Replace");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  ByteString bsOne;
  ByteString bsTwo;
  if (!ValueIsNull(info.GetIsolate(), argOne) &&
      !ValueIsNull(info.GetIsolate(), argTwo)) {
    bsOne = ValueToUTF8String(info.GetIsolate(), argOne);
    bsTwo = ValueToUTF8String(info.GetIsolate(), argTwo);
  }

  ByteString bsThree;
  if (argc > 2) {
    v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
    bsThree = ValueToUTF8String(info.GetIsolate(), argThree);
  }

  bsOne.Replace(bsTwo.AsStringView(), bsThree.AsStringView());
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), bsOne.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Right(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 2) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Right");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  if ((ValueIsNull(info.GetIsolate(), argOne)) ||
      (ValueIsNull(info.GetIsolate(), argTwo))) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsSource = ValueToUTF8String(info.GetIsolate(), argOne);
  int32_t count = std::max(0, ValueToInteger(info.GetIsolate(), argTwo));
  info.GetReturnValue().Set(fxv8::NewStringHelper(
      info.GetIsolate(), bsSource.Last(count).AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Rtrim(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Rtrim");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  if (ValueIsNull(info.GetIsolate(), argOne)) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsSource = ValueToUTF8String(info.GetIsolate(), argOne);
  bsSource.TrimRight();
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), bsSource.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Space(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Space");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  if (fxv8::IsNull(argOne)) {
    info.GetReturnValue().SetNull();
    return;
  }

  int count = std::max(0, ValueToInteger(info.GetIsolate(), argOne));
  if (count > kMaxCharCount) {
    ToFormCalcContext(pThis)->ThrowException("String too long.");
    return;
  }
  DataVector<char> space_string(count, ' ');
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), ByteStringView(space_string)));
}

// static
void CFXJSE_FormCalcContext::Str(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 1 || argc > 3) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Str");
    return;
  }

  v8::Local<v8::Value> numberValue = GetSimpleValue(info, 0);
  if (fxv8::IsNull(numberValue)) {
    info.GetReturnValue().SetNull();
    return;
  }
  float fNumber = ValueToFloat(info.GetIsolate(), numberValue);

  constexpr int32_t kDefaultWidth = 10;
  int32_t iWidth = kDefaultWidth;
  if (argc > 1) {
    v8::Local<v8::Value> widthValue = GetSimpleValue(info, 1);
    iWidth = static_cast<int32_t>(ValueToFloat(info.GetIsolate(), widthValue));
    if (iWidth > kMaxCharCount) {
      ToFormCalcContext(pThis)->ThrowException("String too long.");
      return;
    }
  }

  constexpr int32_t kDefaultPrecision = 0;
  int32_t iPrecision = kDefaultPrecision;
  if (argc > 2) {
    constexpr int32_t kMaxPrecision = 15;
    v8::Local<v8::Value> precision_value = GetSimpleValue(info, 2);
    iPrecision = std::max(0, static_cast<int32_t>(ValueToFloat(
                                 info.GetIsolate(), precision_value)));
    iPrecision = std::min(iPrecision, kMaxPrecision);
  }

  ByteString bsFormat = "%";
  if (iPrecision) {
    bsFormat += ".";
    bsFormat += ByteString::FormatInteger(iPrecision);
  }
  bsFormat += "f";
  ByteString bsNumber = ByteString::Format(bsFormat.c_str(), fNumber);

  const char* pData = bsNumber.c_str();
  int32_t iLength = bsNumber.GetLength();
  int32_t u = 0;
  while (u < iLength) {
    if (pData[u] == '.')
      break;

    ++u;
  }

  if (u > iWidth || (iPrecision + u) >= iWidth) {
    DataVector<char> stars(std::max(iWidth, 0), '*');
    info.GetReturnValue().Set(
        fxv8::NewStringHelper(info.GetIsolate(), ByteStringView(stars)));
    return;
  }

  ByteString resultBuf;
  if (u == iLength) {
    if (iLength > iWidth) {
      int32_t i = 0;
      while (i < iWidth) {
        resultBuf += '*';
        ++i;
      }
    } else {
      int32_t i = 0;
      while (i < iWidth - iLength) {
        resultBuf += ' ';
        ++i;
      }
      resultBuf += pData;
    }
    info.GetReturnValue().Set(
        fxv8::NewStringHelper(info.GetIsolate(), resultBuf.AsStringView()));
    return;
  }

  int32_t iLeavingSpace = iWidth - u - iPrecision;
  if (iPrecision != 0)
    iLeavingSpace--;

  int32_t i = 0;
  while (i < iLeavingSpace) {
    resultBuf += ' ';
    ++i;
  }
  i = 0;
  while (i < u) {
    resultBuf += pData[i];
    ++i;
  }
  if (iPrecision != 0)
    resultBuf += '.';

  u++;
  i = 0;
  while (u < iLength) {
    if (i >= iPrecision)
      break;

    resultBuf += pData[u];
    ++i;
    ++u;
  }
  while (i < iPrecision) {
    resultBuf += '0';
    ++i;
  }
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), resultBuf.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Stuff(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 3 || argc > 4) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Stuff");
    return;
  }

  v8::Local<v8::Value> sourceValue = GetSimpleValue(info, 0);
  v8::Local<v8::Value> startValue = GetSimpleValue(info, 1);
  v8::Local<v8::Value> deleteValue = GetSimpleValue(info, 2);
  if (fxv8::IsNull(sourceValue) || fxv8::IsNull(startValue) ||
      fxv8::IsNull(deleteValue)) {
    info.GetReturnValue().SetNull();
    return;
  }

  int32_t iStart = 1;  // one-based character indexing.
  int32_t iDelete = 0;
  ByteString bsSource = ValueToUTF8String(info.GetIsolate(), sourceValue);
  int32_t iLength = pdfium::base::checked_cast<int32_t>(bsSource.GetLength());
  if (iLength) {
    iStart = std::clamp(
        static_cast<int32_t>(ValueToFloat(info.GetIsolate(), startValue)), 1,
        iLength);
    iDelete = std::clamp(
        static_cast<int32_t>(ValueToFloat(info.GetIsolate(), deleteValue)), 0,
        iLength - iStart + 1);
  }

  ByteString bsInsert;
  if (argc > 3) {
    v8::Local<v8::Value> insertValue = GetSimpleValue(info, 3);
    bsInsert = ValueToUTF8String(info.GetIsolate(), insertValue);
  }

  --iStart;  // now zero-based.
  ByteString bsResult = {bsSource.AsStringView().First(iStart),
                         bsInsert.AsStringView(),
                         bsSource.AsStringView().Substr(iStart + iDelete)};
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), bsResult.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Substr(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 3) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Substr");
    return;
  }

  v8::Local<v8::Value> string_value = GetSimpleValue(info, 0);
  v8::Local<v8::Value> start_value = GetSimpleValue(info, 1);
  v8::Local<v8::Value> end_value = GetSimpleValue(info, 2);
  if (ValueIsNull(info.GetIsolate(), string_value) ||
      ValueIsNull(info.GetIsolate(), start_value) ||
      ValueIsNull(info.GetIsolate(), end_value)) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsSource = ValueToUTF8String(info.GetIsolate(), string_value);
  size_t iLength = bsSource.GetLength();
  if (iLength == 0) {
    info.GetReturnValue().SetEmptyString();
    return;
  }

  // |start_value| is 1-based. Assume first character if |start_value| is less
  // than 1, per spec. Subtract 1 since |iStart| is 0-based.
  size_t iStart =
      std::max(ValueToInteger(info.GetIsolate(), start_value), 1) - 1;
  if (iStart >= iLength) {
    info.GetReturnValue().SetEmptyString();
    return;
  }

  // Negative values are treated as 0. Can't clamp() due to sign mismatches.
  size_t iCount = std::max(ValueToInteger(info.GetIsolate(), end_value), 0);
  iCount = std::min(iCount, iLength - iStart);
  info.GetReturnValue().Set(fxv8::NewStringHelper(
      info.GetIsolate(), bsSource.Substr(iStart, iCount).AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Uuid(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 0 || argc > 1) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Uuid");
    return;
  }

  int32_t iNum = 0;
  if (argc > 0) {
    v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
    iNum = static_cast<int32_t>(ValueToFloat(info.GetIsolate(), argOne));
  }
  info.GetReturnValue().Set(fxv8::NewStringHelper(
      info.GetIsolate(), GUIDString(!!iNum).AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Upper(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 1 || argc > 2) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("Upper");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  if (ValueIsNull(info.GetIsolate(), argOne)) {
    info.GetReturnValue().SetNull();
    return;
  }

  ByteString bsArg = ValueToUTF8String(info.GetIsolate(), argOne);
  WideString wsArg = WideString::FromUTF8(bsArg.AsStringView());
  WideString upperStringBuf;
  upperStringBuf.Reserve(wsArg.GetLength());
  for (wchar_t ch : wsArg) {
    if ((ch >= 0x61 && ch <= 0x7A) || (ch >= 0xE0 && ch <= 0xFE))
      ch -= 32;
    else if (ch == 0x101 || ch == 0x103 || ch == 0x105)
      ch -= 1;

    upperStringBuf += ch;
  }
  info.GetReturnValue().Set(fxv8::NewStringHelper(
      info.GetIsolate(),
      FX_UTF8Encode(upperStringBuf.AsStringView()).AsStringView()));
}

// static
void CFXJSE_FormCalcContext::WordNum(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  int32_t argc = info.Length();
  if (argc < 1 || argc > 3) {
    ToFormCalcContext(pThis)->ThrowParamCountMismatchException("WordNum");
    return;
  }

  v8::Local<v8::Value> numberValue = GetSimpleValue(info, 0);
  if (fxv8::IsNull(numberValue)) {
    info.GetReturnValue().SetNull();
    return;
  }
  float fNumber = ValueToFloat(info.GetIsolate(), numberValue);

  int32_t iIdentifier = 0;
  if (argc > 1) {
    v8::Local<v8::Value> identifierValue = GetSimpleValue(info, 1);
    if (fxv8::IsNull(identifierValue)) {
      info.GetReturnValue().SetNull();
      return;
    }
    iIdentifier =
        static_cast<int32_t>(ValueToFloat(info.GetIsolate(), identifierValue));
  }

  ByteString bsLocale;
  if (argc > 2) {
    v8::Local<v8::Value> localeValue = GetSimpleValue(info, 2);
    if (fxv8::IsNull(localeValue)) {
      info.GetReturnValue().SetNull();
      return;
    }
    bsLocale = ValueToUTF8String(info.GetIsolate(), localeValue);
  }

  if (isnan(fNumber) || fNumber < 0.0f || fNumber > 922337203685477550.0f) {
    info.GetReturnValue().Set(fxv8::NewStringHelper(info.GetIsolate(), "*"));
    return;
  }
  ByteString bsFormatted = ByteString::Format("%.2f", fNumber);
  ByteString bsWorded = WordUS(bsFormatted.AsStringView(), iIdentifier);
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), bsWorded.AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Get(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 1) {
    pContext->ThrowParamCountMismatchException("Get");
    return;
  }

  CXFA_Document* pDoc = pContext->GetDocument();
  if (!pDoc)
    return;

  CXFA_FFApp::CallbackIface* pAppProvider = pDoc->GetNotify()->GetAppProvider();
  if (!pAppProvider)
    return;

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  ByteString bsUrl = ValueToUTF8String(info.GetIsolate(), argOne);
  RetainPtr<IFX_SeekableReadStream> pFile =
      pAppProvider->DownloadURL(WideString::FromUTF8(bsUrl.AsStringView()));
  if (!pFile)
    return;

  FX_FILESIZE size = pFile->GetSize();
  DataVector<uint8_t> dataBuf(size);

  // TODO(tsepez): check return value?
  (void)pFile->ReadBlock(dataBuf);
  info.GetReturnValue().Set(
      fxv8::NewStringHelper(info.GetIsolate(), ByteStringView(dataBuf)));
}

// static
void CFXJSE_FormCalcContext::Post(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  int32_t argc = info.Length();
  if (argc < 2 || argc > 5) {
    pContext->ThrowParamCountMismatchException("Post");
    return;
  }

  CXFA_Document* pDoc = pContext->GetDocument();
  if (!pDoc)
    return;

  CXFA_FFApp::CallbackIface* pAppProvider = pDoc->GetNotify()->GetAppProvider();
  if (!pAppProvider)
    return;

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  ByteString bsURL = ValueToUTF8String(info.GetIsolate(), argOne);

  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  ByteString bsData = ValueToUTF8String(info.GetIsolate(), argTwo);

  ByteString bsContentType;
  if (argc > 2) {
    v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
    bsContentType = ValueToUTF8String(info.GetIsolate(), argThree);
  }

  ByteString bsEncode;
  if (argc > 3) {
    v8::Local<v8::Value> argFour = GetSimpleValue(info, 3);
    bsEncode = ValueToUTF8String(info.GetIsolate(), argFour);
  }

  ByteString bsHeader;
  if (argc > 4) {
    v8::Local<v8::Value> argFive = GetSimpleValue(info, 4);
    bsHeader = ValueToUTF8String(info.GetIsolate(), argFive);
  }

  WideString decodedResponse;
  if (!pAppProvider->PostRequestURL(
          WideString::FromUTF8(bsURL.AsStringView()),
          WideString::FromUTF8(bsData.AsStringView()),
          WideString::FromUTF8(bsContentType.AsStringView()),
          WideString::FromUTF8(bsEncode.AsStringView()),
          WideString::FromUTF8(bsHeader.AsStringView()), decodedResponse)) {
    pContext->ThrowServerDeniedException();
    return;
  }
  info.GetReturnValue().Set(fxv8::NewStringHelper(
      info.GetIsolate(), decodedResponse.ToUTF8().AsStringView()));
}

// static
void CFXJSE_FormCalcContext::Put(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  int32_t argc = info.Length();
  if (argc < 2 || argc > 3) {
    pContext->ThrowParamCountMismatchException("Put");
    return;
  }

  CXFA_Document* pDoc = pContext->GetDocument();
  if (!pDoc)
    return;

  CXFA_FFApp::CallbackIface* pAppProvider = pDoc->GetNotify()->GetAppProvider();
  if (!pAppProvider)
    return;

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  ByteString bsURL = ValueToUTF8String(info.GetIsolate(), argOne);

  v8::Local<v8::Value> argTwo = GetSimpleValue(info, 1);
  ByteString bsData = ValueToUTF8String(info.GetIsolate(), argTwo);

  ByteString bsEncode;
  if (argc > 2) {
    v8::Local<v8::Value> argThree = GetSimpleValue(info, 2);
    bsEncode = ValueToUTF8String(info.GetIsolate(), argThree);
  }
  if (!pAppProvider->PutRequestURL(
          WideString::FromUTF8(bsURL.AsStringView()),
          WideString::FromUTF8(bsData.AsStringView()),
          WideString::FromUTF8(bsEncode.AsStringView()))) {
    pContext->ThrowServerDeniedException();
    return;
  }
  info.GetReturnValue().SetEmptyString();
}

// static
void CFXJSE_FormCalcContext::assign_value_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  v8::Isolate* pIsolate = info.GetIsolate();
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 2) {
    pContext->ThrowCompilerErrorException();
    return;
  }
  ByteStringView bsFuncName("asgn_val_op");
  v8::Local<v8::Value> lValue = info[0];
  v8::Local<v8::Value> rValue = GetSimpleValue(info, 1);
  if (fxv8::IsArray(lValue)) {
    v8::Local<v8::Array> arr = lValue.As<v8::Array>();
    uint32_t iLeftLength = fxv8::GetArrayLengthHelper(arr);
    v8::Local<v8::Value> propertyValue =
        fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, 1);
    for (uint32_t i = 2; i < iLeftLength; i++) {
      v8::Local<v8::Value> jsValue =
          fxv8::ReentrantGetArrayElementHelper(pIsolate, arr, i);
      if (!fxv8::IsObject(jsValue)) {
        pContext->ThrowNoDefaultPropertyException(bsFuncName);
        return;
      }
      v8::Local<v8::Object> jsObjectValue = jsValue.As<v8::Object>();
      if (fxv8::IsNull(propertyValue)) {
        if (!SetObjectDefaultValue(pIsolate, jsObjectValue, rValue)) {
          pContext->ThrowNoDefaultPropertyException(bsFuncName);
          return;
        }
      } else {
        fxv8::ReentrantPutObjectPropertyHelper(
            pIsolate, jsObjectValue,
            fxv8::ReentrantToByteStringHelper(pIsolate, propertyValue)
                .AsStringView(),
            rValue);
      }
    }
  } else if (fxv8::IsObject(lValue)) {
    if (!SetObjectDefaultValue(pIsolate, lValue.As<v8::Object>(), rValue)) {
      pContext->ThrowNoDefaultPropertyException(bsFuncName);
      return;
    }
  }
  info.GetReturnValue().Set(rValue);
}

// static
void CFXJSE_FormCalcContext::logical_or_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 2) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
  if (fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)) {
    info.GetReturnValue().SetNull();
    return;
  }

  float first = ValueToFloat(info.GetIsolate(), argFirst);
  float second = ValueToFloat(info.GetIsolate(), argSecond);
  info.GetReturnValue().Set(static_cast<int>(first || second));
}

// static
void CFXJSE_FormCalcContext::logical_and_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 2) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
  if (fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)) {
    info.GetReturnValue().SetNull();
    return;
  }

  float first = ValueToFloat(info.GetIsolate(), argFirst);
  float second = ValueToFloat(info.GetIsolate(), argSecond);
  info.GetReturnValue().Set(static_cast<int>(first && second));
}

// static
void CFXJSE_FormCalcContext::equality_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 2) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  if (fm_ref_equal(pThis, info)) {
    info.GetReturnValue().Set(1);
    return;
  }

  v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
  if (fxv8::IsNull(argFirst) || fxv8::IsNull(argSecond)) {
    info.GetReturnValue().Set(
        static_cast<int>(fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)));
    return;
  }

  if (fxv8::IsString(argFirst) && fxv8::IsString(argSecond)) {
    info.GetReturnValue().Set(static_cast<int>(
        fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argFirst) ==
        fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argSecond)));
    return;
  }

  double first = ValueToDouble(info.GetIsolate(), argFirst);
  double second = ValueToDouble(info.GetIsolate(), argSecond);
  info.GetReturnValue().Set(static_cast<int>(first == second));
}

// static
void CFXJSE_FormCalcContext::notequality_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 2) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  if (fm_ref_equal(pThis, info)) {
    info.GetReturnValue().Set(0);
    return;
  }

  v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
  if (fxv8::IsNull(argFirst) || fxv8::IsNull(argSecond)) {
    info.GetReturnValue().Set(
        static_cast<int>(!fxv8::IsNull(argFirst) || !fxv8::IsNull(argSecond)));
    return;
  }

  if (fxv8::IsString(argFirst) && fxv8::IsString(argSecond)) {
    info.GetReturnValue().Set(static_cast<int>(
        fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argFirst) !=
        fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argSecond)));
    return;
  }

  double first = ValueToDouble(info.GetIsolate(), argFirst);
  double second = ValueToDouble(info.GetIsolate(), argSecond);
  info.GetReturnValue().Set(static_cast<int>(first != second));
}

// static
bool CFXJSE_FormCalcContext::fm_ref_equal(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  v8::Local<v8::Value> argFirst = info[0];
  v8::Local<v8::Value> argSecond = info[1];
  if (!fxv8::IsArray(argFirst) || !fxv8::IsArray(argSecond))
    return false;

  v8::Local<v8::Array> firstArr = argFirst.As<v8::Array>();
  v8::Local<v8::Array> secondArr = argSecond.As<v8::Array>();
  v8::Local<v8::Value> firstFlag =
      fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), firstArr, 0);
  v8::Local<v8::Value> secondFlag =
      fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), secondArr, 0);
  if (fxv8::ReentrantToInt32Helper(info.GetIsolate(), firstFlag) != 3 ||
      fxv8::ReentrantToInt32Helper(info.GetIsolate(), secondFlag) != 3) {
    return false;
  }

  v8::Local<v8::Value> firstValue =
      fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), firstArr, 2);
  v8::Local<v8::Value> secondValue =
      fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), secondArr, 2);

  if (fxv8::IsNull(firstValue) || fxv8::IsNull(secondValue))
    return false;

  return FXJSE_RetrieveObjectBinding(firstValue) ==
         FXJSE_RetrieveObjectBinding(secondValue);
}

// static
void CFXJSE_FormCalcContext::less_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 2) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
  if (fxv8::IsNull(argFirst) || fxv8::IsNull(argSecond)) {
    info.GetReturnValue().Set(0);
    return;
  }

  if (fxv8::IsString(argFirst) && fxv8::IsString(argSecond)) {
    ByteString bs1 =
        fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argFirst);
    ByteString bs2 =
        fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argSecond);
    info.GetReturnValue().Set(bs1.Compare(bs2.AsStringView()) < 0);
    return;
  }

  double first = ValueToDouble(info.GetIsolate(), argFirst);
  double second = ValueToDouble(info.GetIsolate(), argSecond);
  info.GetReturnValue().Set(static_cast<int>(first < second));
}

// static
void CFXJSE_FormCalcContext::lessequal_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 2) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
  if (fxv8::IsNull(argFirst) || fxv8::IsNull(argSecond)) {
    info.GetReturnValue().Set(
        static_cast<int>(fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)));
    return;
  }

  if (fxv8::IsString(argFirst) && fxv8::IsString(argSecond)) {
    auto bs1 = fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argFirst);
    auto bs2 = fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argSecond);
    info.GetReturnValue().Set(bs1.Compare(bs2.AsStringView()) <= 0);
    return;
  }

  double first = ValueToDouble(info.GetIsolate(), argFirst);
  double second = ValueToDouble(info.GetIsolate(), argSecond);
  info.GetReturnValue().Set(static_cast<int>(first <= second));
}

// static
void CFXJSE_FormCalcContext::greater_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 2) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
  if (fxv8::IsNull(argFirst) || fxv8::IsNull(argSecond)) {
    info.GetReturnValue().Set(0);
    return;
  }

  if (fxv8::IsString(argFirst) && fxv8::IsString(argSecond)) {
    auto bs1 = fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argFirst);
    auto bs2 = fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argSecond);
    info.GetReturnValue().Set(bs1.Compare(bs2.AsStringView()) > 0);
    return;
  }

  double first = ValueToDouble(info.GetIsolate(), argFirst);
  double second = ValueToDouble(info.GetIsolate(), argSecond);
  info.GetReturnValue().Set(static_cast<int>(first > second));
}

// static
void CFXJSE_FormCalcContext::greaterequal_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 2) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
  if (fxv8::IsNull(argFirst) || fxv8::IsNull(argSecond)) {
    info.GetReturnValue().Set(
        static_cast<int>(fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)));
    return;
  }

  if (fxv8::IsString(argFirst) && fxv8::IsString(argSecond)) {
    auto bs1 = fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argFirst);
    auto bs2 = fxv8::ReentrantToByteStringHelper(info.GetIsolate(), argSecond);
    info.GetReturnValue().Set(bs1.Compare(bs2.AsStringView()) >= 0);
    return;
  }

  double first = ValueToDouble(info.GetIsolate(), argFirst);
  double second = ValueToDouble(info.GetIsolate(), argSecond);
  info.GetReturnValue().Set(static_cast<int>(first >= second));
}

// static
void CFXJSE_FormCalcContext::plus_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 2) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  if (ValueIsNull(info.GetIsolate(), info[0]) &&
      ValueIsNull(info.GetIsolate(), info[1])) {
    info.GetReturnValue().SetNull();
    return;
  }

  const double first = ValueToDouble(info.GetIsolate(), info[0]);
  const double second = ValueToDouble(info.GetIsolate(), info[1]);
  info.GetReturnValue().Set(first + second);
}

// static
void CFXJSE_FormCalcContext::minus_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 2) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
  if (fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)) {
    info.GetReturnValue().SetNull();
    return;
  }

  double first = ValueToDouble(info.GetIsolate(), argFirst);
  double second = ValueToDouble(info.GetIsolate(), argSecond);
  info.GetReturnValue().Set(first - second);
}

// static
void CFXJSE_FormCalcContext::multiple_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 2) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
  if (fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)) {
    info.GetReturnValue().SetNull();
    return;
  }

  double first = ValueToDouble(info.GetIsolate(), argFirst);
  double second = ValueToDouble(info.GetIsolate(), argSecond);
  info.GetReturnValue().Set(first * second);
}

// static
void CFXJSE_FormCalcContext::divide_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 2) {
    pContext->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argFirst = GetSimpleValue(info, 0);
  v8::Local<v8::Value> argSecond = GetSimpleValue(info, 1);
  if (fxv8::IsNull(argFirst) && fxv8::IsNull(argSecond)) {
    info.GetReturnValue().SetNull();
    return;
  }

  double second = ValueToDouble(info.GetIsolate(), argSecond);
  if (second == 0.0) {
    pContext->ThrowDivideByZeroException();
    return;
  }

  double first = ValueToDouble(info.GetIsolate(), argFirst);
  info.GetReturnValue().Set(first / second);
}

// static
void CFXJSE_FormCalcContext::positive_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  if (fxv8::IsNull(argOne)) {
    info.GetReturnValue().SetNull();
    return;
  }
  info.GetReturnValue().Set(0.0 + ValueToDouble(info.GetIsolate(), argOne));
}

// static
void CFXJSE_FormCalcContext::negative_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  if (fxv8::IsNull(argOne)) {
    info.GetReturnValue().SetNull();
    return;
  }
  info.GetReturnValue().Set(0.0 - ValueToDouble(info.GetIsolate(), argOne));
}

// static
void CFXJSE_FormCalcContext::logical_not_operator(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  if (fxv8::IsNull(argOne)) {
    info.GetReturnValue().SetNull();
    return;
  }

  double first = ValueToDouble(info.GetIsolate(), argOne);
  info.GetReturnValue().Set((first == 0.0) ? 1 : 0);
}

// static
void CFXJSE_FormCalcContext::dot_accessor(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  DotAccessorCommon(pThis, info, /*bDotAccessor=*/true);
}

// static
void CFXJSE_FormCalcContext::dotdot_accessor(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  DotAccessorCommon(pThis, info, /*bDotAccessor=*/false);
}

// static
void CFXJSE_FormCalcContext::eval_translation(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 1) {
    pContext->ThrowParamCountMismatchException("Eval");
    return;
  }

  v8::Local<v8::Value> argOne = GetSimpleValue(info, 0);
  ByteString bsArg = ValueToUTF8String(info.GetIsolate(), argOne);
  if (bsArg.IsEmpty()) {
    pContext->ThrowArgumentMismatchException();
    return;
  }

  WideString wsCalcScript = WideString::FromUTF8(bsArg.AsStringView());
  std::optional<WideTextBuffer> wsJavaScriptBuf =
      CFXJSE_FormCalcContext::Translate(pContext->GetDocument()->GetHeap(),
                                        wsCalcScript.AsStringView());
  if (!wsJavaScriptBuf.has_value()) {
    pContext->ThrowCompilerErrorException();
    return;
  }
  info.GetReturnValue().Set(fxv8::NewStringHelper(
      info.GetIsolate(),
      FX_UTF8Encode(wsJavaScriptBuf.value().AsStringView()).AsStringView()));
}

// static
void CFXJSE_FormCalcContext::is_fm_object(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  const bool result = info.Length() == 1 && fxv8::IsObject(info[0]);
  info.GetReturnValue().Set(result);
}

// static
void CFXJSE_FormCalcContext::is_fm_array(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  const bool result = info.Length() == 1 && fxv8::IsArray(info[0]);
  info.GetReturnValue().Set(result);
}

// static
void CFXJSE_FormCalcContext::get_fm_value(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 1) {
    pContext->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argOne = info[0];
  if (fxv8::IsArray(argOne)) {
    v8::Local<v8::Array> arr = argOne.As<v8::Array>();
    v8::Local<v8::Value> propertyValue =
        fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 1);
    v8::Local<v8::Value> jsValue =
        fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 2);
    if (!fxv8::IsObject(jsValue)) {
      info.GetReturnValue().Set(fxv8::NewUndefinedHelper(info.GetIsolate()));
      return;
    }
    v8::Local<v8::Object> jsObjectValue = jsValue.As<v8::Object>();
    if (fxv8::IsNull(propertyValue)) {
      info.GetReturnValue().Set(
          GetObjectDefaultValue(info.GetIsolate(), jsObjectValue));
      return;
    }
    ByteString bsName =
        fxv8::ReentrantToByteStringHelper(info.GetIsolate(), propertyValue);
    info.GetReturnValue().Set(fxv8::ReentrantGetObjectPropertyHelper(
        info.GetIsolate(), jsObjectValue, bsName.AsStringView()));
    return;
  }

  if (fxv8::IsObject(argOne)) {
    v8::Local<v8::Object> obj = argOne.As<v8::Object>();
    info.GetReturnValue().Set(GetObjectDefaultValue(info.GetIsolate(), obj));
    return;
  }

  info.GetReturnValue().Set(argOne);
}

// static
void CFXJSE_FormCalcContext::get_fm_jsobj(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  if (info.Length() != 1) {
    ToFormCalcContext(pThis)->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argOne = info[0];
  if (!fxv8::IsArray(argOne)) {
    info.GetReturnValue().Set(argOne);
    return;
  }

  v8::Local<v8::Array> arr = argOne.As<v8::Array>();
  info.GetReturnValue().Set(
      fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 2));
}

// static
void CFXJSE_FormCalcContext::fm_var_filter(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  if (info.Length() != 1) {
    pContext->ThrowCompilerErrorException();
    return;
  }

  v8::Local<v8::Value> argOne = info[0];
  if (!fxv8::IsArray(argOne)) {
    info.GetReturnValue().Set(GetSimpleValue(info, 0));
    return;
  }

  v8::Local<v8::Array> arr = argOne.As<v8::Array>();
  v8::Local<v8::Value> flagsValue =
      fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 0);
  int32_t iFlags = fxv8::ReentrantToInt32Helper(info.GetIsolate(), flagsValue);
  if (iFlags != 3 && iFlags != 4) {
    info.GetReturnValue().Set(GetSimpleValue(info, 0));
    return;
  }

  if (iFlags == 4) {
    v8::LocalVector<v8::Value> values(info.GetIsolate(), 3);
    values[0] = fxv8::NewNumberHelper(info.GetIsolate(), 3);
    values[1] = fxv8::NewNullHelper(info.GetIsolate());
    values[2] = fxv8::NewNullHelper(info.GetIsolate());
    info.GetReturnValue().Set(fxv8::NewArrayHelper(info.GetIsolate(), values));
    return;
  }

  v8::Local<v8::Value> objectValue =
      fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, 2);
  if (fxv8::IsNull(objectValue)) {
    pContext->ThrowCompilerErrorException();
    return;
  }
  info.GetReturnValue().Set(argOne);
}

// static
void CFXJSE_FormCalcContext::concat_fm_object(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  v8::Isolate* pIsolate = ToFormCalcContext(pThis)->GetIsolate();
  v8::LocalVector<v8::Value> returnValues(pIsolate);
  for (int i = 0; i < info.Length(); ++i) {
    if (fxv8::IsArray(info[i])) {
      v8::Local<v8::Array> arr = info[i].As<v8::Array>();
      uint32_t length = fxv8::GetArrayLengthHelper(arr);
      for (uint32_t j = 2; j < length; j++) {
        returnValues.push_back(
            fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, j));
      }
    }
    returnValues.push_back(info[i]);
  }
  info.GetReturnValue().Set(fxv8::NewArrayHelper(pIsolate, returnValues));
}

// static
ByteString CFXJSE_FormCalcContext::GenerateSomExpression(ByteStringView bsName,
                                                         int32_t iIndexFlags,
                                                         int32_t iIndexValue,
                                                         bool bIsStar) {
  if (bIsStar)
    return ByteString(bsName, "[*]");

  // `iIndexFlags` values are the same as enum class
  // `CXFA_FMIndexExpression::AccessorIndex` values.
  if (iIndexFlags == 0)
    return ByteString(bsName);

  if (iIndexFlags == 1 || iIndexValue == 0) {
    return ByteString(bsName, "[") + ByteString::FormatInteger(iIndexValue) +
           "]";
  }

  const bool bNegative = iIndexValue < 0;
  ByteString bsSomExp(bsName);
  if (iIndexFlags == 2) {
    bsSomExp += bNegative ? "[-" : "[+";
  } else {
    DCHECK_EQ(iIndexFlags, 3);
    bsSomExp += bNegative ? "[" : "[-";
  }

  FX_SAFE_INT32 safe_index = iIndexValue;
  if (bNegative)
    safe_index = -safe_index;
  bsSomExp += ByteString::FormatInteger(safe_index.ValueOrDefault(0));
  bsSomExp += "]";
  return bsSomExp;
}

std::optional<WideTextBuffer> CFXJSE_FormCalcContext::Translate(
    cppgc::Heap* pHeap,
    WideStringView wsFormcalc) {
  if (wsFormcalc.IsEmpty())
    return WideTextBuffer();

  CXFA_FMLexer lexer(wsFormcalc);
  CXFA_FMParser parser(pHeap, &lexer);
  CXFA_FMAST* ast = parser.Parse();
  if (!ast || parser.HasError())
    return std::nullopt;

  CXFA_FMToJavaScriptDepth::Reset();
  std::optional<WideTextBuffer> wsJavaScript = ast->ToJavaScript();
  if (!wsJavaScript.has_value())
    return std::nullopt;

  if (CXFA_IsTooBig(wsJavaScript.value()))
    return std::nullopt;

  return wsJavaScript;
}

CFXJSE_FormCalcContext::CFXJSE_FormCalcContext(v8::Isolate* pIsolate,
                                               CFXJSE_Context* pScriptContext,
                                               CXFA_Document* pDoc)
    : m_pIsolate(pIsolate), m_pDocument(pDoc) {
  m_Value.Reset(m_pIsolate,
                NewBoundV8Object(
                    m_pIsolate, CFXJSE_Class::Create(
                                    pScriptContext, &kFormCalcDescriptor, false)
                                    ->GetTemplate(m_pIsolate)));
}

CFXJSE_FormCalcContext::~CFXJSE_FormCalcContext() = default;

CFXJSE_FormCalcContext* CFXJSE_FormCalcContext::AsFormCalcContext() {
  return this;
}

v8::Local<v8::Value> CFXJSE_FormCalcContext::GlobalPropertyGetter() {
  return v8::Local<v8::Value>::New(m_pIsolate, m_Value);
}

// static
void CFXJSE_FormCalcContext::DotAccessorCommon(
    CFXJSE_HostObject* pThis,
    const v8::FunctionCallbackInfo<v8::Value>& info,
    bool bDotAccessor) {
  CFXJSE_FormCalcContext* pContext = ToFormCalcContext(pThis);
  v8::Isolate* pIsolate = pContext->GetIsolate();
  int32_t argc = info.Length();
  if (argc < 4 || argc > 5) {
    pContext->ThrowCompilerErrorException();
    return;
  }

  bool bIsStar = true;
  int32_t iIndexValue = 0;
  if (argc > 4) {
    bIsStar = false;
    iIndexValue = ValueToInteger(info.GetIsolate(), info[4]);
  }

  const ByteString bsName =
      fxv8::ReentrantToByteStringHelper(info.GetIsolate(), info[2]);
  const bool bHasNoResolveName = bDotAccessor && bsName.IsEmpty();
  ByteString bsSomExp = GenerateSomExpression(
      bsName.AsStringView(),
      fxv8::ReentrantToInt32Helper(info.GetIsolate(), info[3]), iIndexValue,
      bIsStar);

  v8::Local<v8::Value> argAccessor = info[0];
  if (fxv8::IsArray(argAccessor)) {
    v8::Local<v8::Array> arr = argAccessor.As<v8::Array>();
    uint32_t iLength = fxv8::GetArrayLengthHelper(arr);
    if (iLength < 3) {
      pContext->ThrowArgumentMismatchException();
      return;
    }

    // TODO(crbug.com/pdfium/2090) - doublecheck use of std::vector
    std::vector<v8::LocalVector<v8::Value>> resolveValues(
        iLength - 2, v8::LocalVector<v8::Value>(info.GetIsolate()));

    bool bAttribute = false;
    bool bAllEmpty = true;
    for (uint32_t i = 2; i < iLength; i++) {
      v8::Local<v8::Value> hJSObjValue =
          fxv8::ReentrantGetArrayElementHelper(info.GetIsolate(), arr, i);
      std::optional<CFXJSE_Engine::ResolveResult> maybeResult =
          ResolveObjects(pThis, hJSObjValue, bsSomExp.AsStringView(),
                         bDotAccessor, bHasNoResolveName);
      if (maybeResult.has_value()) {
        resolveValues[i - 2] = ParseResolveResult(pThis, maybeResult.value(),
                                                  hJSObjValue, &bAttribute);
        bAllEmpty = bAllEmpty && resolveValues[i - 2].empty();
      }
    }
    if (bAllEmpty) {
      pContext->ThrowPropertyNotInObjectException(bsName.AsStringView(),
                                                  bsSomExp.AsStringView());
      return;
    }

    v8::LocalVector<v8::Value> values(pIsolate);
    values.push_back(fxv8::NewNumberHelper(pIsolate, 1));
    values.push_back(
        bAttribute ? fxv8::NewStringHelper(pIsolate, bsName.AsStringView())
                         .As<v8::Value>()
                   : fxv8::NewNullHelper(pIsolate).As<v8::Value>());
    for (uint32_t i = 0; i < iLength - 2; i++) {
      for (size_t j = 0; j < resolveValues[i].size(); j++)
        values.push_back(resolveValues[i][j]);
    }
    info.GetReturnValue().Set(fxv8::NewArrayHelper(pIsolate, values));
    return;
  }

  std::optional<CFXJSE_Engine::ResolveResult> maybeResult;
  ByteString bsAccessorName =
      fxv8::ReentrantToByteStringHelper(info.GetIsolate(), info[1]);
  if (fxv8::IsObject(argAccessor) ||
      (fxv8::IsNull(argAccessor) && bsAccessorName.IsEmpty())) {
    maybeResult = ResolveObjects(pThis, argAccessor, bsSomExp.AsStringView(),
                                 bDotAccessor, bHasNoResolveName);
  } else if (!fxv8::IsObject(argAccessor) && !bsAccessorName.IsEmpty()) {
    v8::Local<v8::Value> obj =
        GetObjectForName(pThis, bsAccessorName.AsStringView());
    if (!obj.IsEmpty()) {
      argAccessor = obj;
      maybeResult = ResolveObjects(pThis, argAccessor, bsSomExp.AsStringView(),
                                   bDotAccessor, bHasNoResolveName);
    }
  }
  if (!maybeResult.has_value()) {
    pContext->ThrowPropertyNotInObjectException(bsName.AsStringView(),
                                                bsSomExp.AsStringView());
    return;
  }

  bool bAttribute = false;
  v8::LocalVector<v8::Value> resolveValues =
      ParseResolveResult(pThis, maybeResult.value(), argAccessor, &bAttribute);

  v8::LocalVector<v8::Value> values(pIsolate, resolveValues.size() + 2);
  values[0] = fxv8::NewNumberHelper(pIsolate, 1);
  values[1] = bAttribute
                  ? fxv8::NewStringHelper(pIsolate, bsName.AsStringView())
                        .As<v8::Value>()
                  : fxv8::NewNullHelper(pIsolate).As<v8::Value>();

  for (size_t i = 0; i < resolveValues.size(); i++)
    values[i + 2] = resolveValues[i];

  info.GetReturnValue().Set(fxv8::NewArrayHelper(pIsolate, values));
}

// static
bool CFXJSE_FormCalcContext::IsIsoDateFormat(ByteStringView bsData,
                                             int32_t* pYear,
                                             int32_t* pMonth,
                                             int32_t* pDay) {
  pdfium::span<const char> pData = bsData.span();

  int32_t& iYear = *pYear;
  int32_t& iMonth = *pMonth;
  int32_t& iDay = *pDay;

  iYear = 0;
  iMonth = 1;
  iDay = 1;

  if (pData.size() < 4) {
    return false;
  }

  char szYear[5];
  szYear[4] = '\0';
  for (int32_t i = 0; i < 4; ++i) {
    if (!isdigit(pData[i])) {
      return false;
    }

    szYear[i] = pData[i];
  }
  iYear = FXSYS_atoi(szYear);
  if (pData.size() == 4) {
    return true;
  }

  int32_t iStyle = pData[4] == '-' ? 1 : 0;
  size_t iPosOff = iStyle == 0 ? 4 : 5;
  if (!isdigit(pData[iPosOff]) || !isdigit(pData[iPosOff + 1])) {
    return false;
  }

  char szBuffer[3] = {};
  szBuffer[0] = pData[iPosOff];
  szBuffer[1] = pData[iPosOff + 1];
  iMonth = FXSYS_atoi(szBuffer);
  if (iMonth > 12 || iMonth < 1) {
    return false;
  }

  if (iStyle == 0) {
    iPosOff += 2;
    if (pData.size() == 6) {
      return true;
    }
  } else {
    iPosOff += 3;
    if (pData.size() == 7) {
      return true;
    }
  }
  if (!isdigit(pData[iPosOff]) || !isdigit(pData[iPosOff + 1])) {
    return false;
  }

  szBuffer[0] = pData[iPosOff];
  szBuffer[1] = pData[iPosOff + 1];
  iDay = FXSYS_atoi(szBuffer);
  if (iPosOff + 2 < pData.size()) {
    return false;
  }

  if (iMonth == 2) {
    bool bIsLeap = (!(iYear % 4) && (iYear % 100)) || !(iYear % 400);
    return iDay <= (bIsLeap ? 29 : 28);
  }

  if (iMonth < 8) {
    return iDay <= (iMonth % 2 == 0 ? 30 : 31);
  }
  return iDay <= (iMonth % 2 == 0 ? 31 : 30);
}

// static
bool CFXJSE_FormCalcContext::IsIsoTimeFormat(ByteStringView bsData) {
  enum State { kHour, kMinute, kSecond, kZoneHour, kZoneMinute, kFinished };

  pdfium::span<const char> pData = bsData.span();
  if (pData.empty()) {
    return false;
  }

  size_t iZone = 0;
  size_t i = 0;
  while (i < pData.size()) {
    if (!isdigit(pData[i]) && pData[i] != ':') {
      iZone = i;
      break;
    }
    ++i;
  }
  if (i == pData.size()) {
    iZone = pData.size();
  }

  char szBuffer[3] = {};  // Last char always stays NUL for termination.
  State state = kHour;
  size_t iIndex = 0;
  while (iIndex + 1 < iZone) {
    szBuffer[0] = pData[iIndex];
    szBuffer[1] = pData[iIndex + 1];
    if (!isdigit(szBuffer[0]) || !isdigit(szBuffer[1])) {
      return false;
    }
    int32_t value = FXSYS_atoi(szBuffer);
    if (state == kHour) {
      if (value >= 24) {
        return false;
      }
      state = kMinute;
    } else if (state == kMinute) {
      if (value >= 60) {
        return false;
      }
      state = kSecond;
    } else if (state == kSecond) {
      // Allow leap second.
      if (value > 60) {
        return false;
      }
      state = kFinished;
    } else {
      return false;
    }
    iIndex += 2;
    if (iIndex < iZone && pData[iIndex] == ':') {
      ++iIndex;
    }
  }

  if (iIndex < pData.size() && pData[iIndex] == '.') {
    constexpr int kSubSecondLength = 3;
    if (iIndex + kSubSecondLength >= pData.size()) {
      return false;
    }

    ++iIndex;
    char szMilliSeconds[kSubSecondLength + 1] = {};
    for (int j = 0; j < kSubSecondLength; ++j) {
      char c = pData[iIndex + j];
      if (!isdigit(c)) {
        return false;
      }
      szMilliSeconds[j] = c;
    }
    if (FXSYS_atoi(szMilliSeconds) >= 1000) {
      return false;
    }
    iIndex += kSubSecondLength;
  }

  if (iIndex < pData.size() && FXSYS_towlower(pData[iIndex]) == 'z') {
    return true;
  }

  if (iIndex < pData.size()) {
    if (pData[iIndex] == '+') {
      ++iIndex;
    } else if (pData[iIndex] == '-') {
      ++iIndex;
    }
  }
  state = kZoneHour;
  while (iIndex + 1 < pData.size()) {
    szBuffer[0] = pData[iIndex];
    szBuffer[1] = pData[iIndex + 1];
    if (!isdigit(szBuffer[0]) || !isdigit(szBuffer[1])) {
      return false;
    }
    int32_t value = FXSYS_atoi(szBuffer);
    if (state == kZoneHour) {
      if (value >= 24) {
        return false;
      }
      state = kZoneMinute;
    } else if (state == kZoneMinute) {
      if (value >= 60) {
        return false;
      }
      state = kFinished;
    } else {
      return false;
    }
    iIndex += 2;
    if (iIndex < pData.size() && pData[iIndex] == ':') {
      ++iIndex;
    }
  }

  // Success if all input was processed.
  return iIndex == pData.size();
}

bool CFXJSE_FormCalcContext::IsIsoDateTimeFormat(ByteStringView bsData,
                                                 int32_t* pYear,
                                                 int32_t* pMonth,
                                                 int32_t* pDay) {
  *pYear = 0;
  *pMonth = 0;
  *pDay = 0;

  size_t iIndex = 0;
  while (iIndex < bsData.GetLength()) {
    if (bsData[iIndex] == 'T' || bsData[iIndex] == 't') {
      break;
    }
    ++iIndex;
  }
  if (iIndex == bsData.GetLength() || (iIndex != 8 && iIndex != 10)) {
    return false;
  }

  ByteStringView date_part = bsData.First(iIndex);
  ByteStringView time_part = bsData.Substr(iIndex + 1);
  return IsIsoDateFormat(date_part, pYear, pMonth, pDay) &&
         IsIsoTimeFormat(time_part);
}

// static
int32_t CFXJSE_FormCalcContext::DateString2Num(ByteStringView bsDate) {
  int32_t iYear = 0;
  int32_t iMonth = 0;
  int32_t iDay = 0;
  if (bsDate.GetLength() <= 10) {
    if (!IsIsoDateFormat(bsDate, &iYear, &iMonth, &iDay)) {
      return 0;
    }
  } else {
    if (!IsIsoDateTimeFormat(bsDate, &iYear, &iMonth, &iDay)) {
      return 0;
    }
  }

  float dDays = 0;
  int32_t i = 1;
  if (iYear < 1900) {
    return 0;
  }

  while (iYear - i >= 1900) {
    dDays +=
        ((!((iYear - i) % 4) && ((iYear - i) % 100)) || !((iYear - i) % 400))
            ? 366
            : 365;
    ++i;
  }
  i = 1;
  while (i < iMonth) {
    if (i == 2) {
      dDays += ((!(iYear % 4) && (iYear % 100)) || !(iYear % 400)) ? 29 : 28;
    } else if (i <= 7) {
      dDays += (i % 2 == 0) ? 30 : 31;
    } else {
      dDays += (i % 2 == 0) ? 31 : 30;
    }

    ++i;
  }
  i = 0;
  while (iDay - i > 0) {
    ++dDays;
    ++i;
  }
  return static_cast<int32_t>(dDays);
}

bool CFXJSE_FormCalcContext::ApplyToExpansion(
    std::function<void(v8::Isolate*, v8::Local<v8::Value>)> fn,
    const v8::FunctionCallbackInfo<v8::Value>& info,
    bool bStrict) {
  v8::Isolate* pIsolate = info.GetIsolate();
  for (int32_t i = 0; i < info.Length(); i++) {
    v8::Local<v8::Value> argValue = info[i];
    if (fxv8::IsArray(argValue)) {
      if (!ApplyToArray(pIsolate, fn, argValue.As<v8::Array>()) && bStrict) {
        ThrowArgumentMismatchException();
        return false;
      }
    } else if (fxv8::IsObject(argValue)) {
      ApplyToObject(pIsolate, fn, argValue.As<v8::Object>());
    } else if (!fxv8::IsNull(argValue)) {
      fn(pIsolate, argValue);
    }
  }
  return true;
}

bool CFXJSE_FormCalcContext::ApplyToArray(
    v8::Isolate* pIsolate,
    std::function<void(v8::Isolate*, v8::Local<v8::Value>)> fn,
    v8::Local<v8::Array> pArray) {
  uint32_t iLength = fxv8::GetArrayLengthHelper(pArray);
  if (iLength < 3)
    return false;

  v8::Local<v8::Value> propertyValue =
      fxv8::ReentrantGetArrayElementHelper(pIsolate, pArray, 1);

  ByteString bsName;
  const bool nullprop = fxv8::IsNull(propertyValue);
  if (!nullprop)
    bsName = fxv8::ReentrantToByteStringHelper(pIsolate, propertyValue);

  for (uint32_t j = 2; j < iLength; j++) {
    v8::Local<v8::Value> jsValue =
        fxv8::ReentrantGetArrayElementHelper(pIsolate, pArray, j);
    if (!fxv8::IsObject(jsValue))
      continue;

    v8::Local<v8::Object> jsObjectValue = jsValue.As<v8::Object>();
    v8::Local<v8::Value> newPropertyValue =
        nullprop ? GetObjectDefaultValue(pIsolate, jsObjectValue)
                 : fxv8::ReentrantGetObjectPropertyHelper(
                       pIsolate, jsObjectValue, bsName.AsStringView());
    if (!fxv8::IsNull(newPropertyValue))
      fn(pIsolate, newPropertyValue);
  }
  return true;
}

void CFXJSE_FormCalcContext::ApplyToObject(
    v8::Isolate* pIsolate,
    std::function<void(v8::Isolate*, v8::Local<v8::Value>)> fn,
    v8::Local<v8::Object> pObject) {
  v8::Local<v8::Value> newPropertyValue =
      GetObjectDefaultValue(pIsolate, pObject);
  if (!fxv8::IsNull(newPropertyValue))
    fn(pIsolate, newPropertyValue);
}

void CFXJSE_FormCalcContext::ThrowNoDefaultPropertyException(
    ByteStringView name) const {
  ByteString msg(name);
  msg += " doesn't have a default property.";
  ThrowException(msg.AsStringView());
}

void CFXJSE_FormCalcContext::ThrowCompilerErrorException() const {
  ThrowException("Compiler error.");
}

void CFXJSE_FormCalcContext::ThrowDivideByZeroException() const {
  ThrowException("Divide by zero.");
}

void CFXJSE_FormCalcContext::ThrowServerDeniedException() const {
  ThrowException("Server does not permit operation.");
}

void CFXJSE_FormCalcContext::ThrowPropertyNotInObjectException(
    ByteStringView name,
    ByteStringView exp) const {
  ByteString msg("An attempt was made to reference property '");
  msg += name;
  msg += "' of a non-object in SOM expression ";
  msg += exp;
  msg += ".";
  ThrowException(msg.AsStringView());
}

void CFXJSE_FormCalcContext::ThrowParamCountMismatchException(
    ByteStringView method) const {
  ByteString msg("Incorrect number of parameters calling method '");
  msg += method;
  msg += "'.";
  ThrowException(msg.AsStringView());
}

void CFXJSE_FormCalcContext::ThrowArgumentMismatchException() const {
  ThrowException("Argument mismatch in property or function argument.");
}

void CFXJSE_FormCalcContext::ThrowException(ByteStringView str) const {
  DCHECK(!str.IsEmpty());
  FXJSE_ThrowMessage(GetIsolate(), str);
}
