EncodedJSValue JSC_HOST_CALL IntlNumberFormatPrototypeGetterFormat(ExecState* state) { // 11.3.3 Intl.NumberFormat.prototype.format (ECMA-402 2.0) // 1. Let nf be this NumberFormat object. IntlNumberFormat* nf = jsDynamicCast<IntlNumberFormat*>(state->thisValue()); // FIXME: Workaround to provide compatibility with ECMA-402 1.0 call/apply patterns. if (!nf) nf = jsDynamicCast<IntlNumberFormat*>(state->thisValue().get(state, state->vm().propertyNames->intlSubstituteValuePrivateName)); if (!nf) return JSValue::encode(throwTypeError(state, ASCIILiteral("Intl.NumberFormat.prototype.format called on value that's not an object initialized as a NumberFormat"))); JSBoundFunction* boundFormat = nf->boundFormat(); // 2. If nf.[[boundFormat]] is undefined, if (!boundFormat) { VM& vm = state->vm(); JSGlobalObject* globalObject = nf->globalObject(); // a. Let F be a new built-in function object as defined in 11.3.4. // b. The value of F’s length property is 1. JSFunction* targetObject = JSFunction::create(vm, globalObject, 1, ASCIILiteral("format"), IntlNumberFormatFuncFormatNumber, NoIntrinsic); JSArray* boundArgs = JSArray::tryCreateUninitialized(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), 0); if (!boundArgs) return JSValue::encode(throwOutOfMemoryError(state)); // c. Let bf be BoundFunctionCreate(F, «this value»). boundFormat = JSBoundFunction::create(vm, state, globalObject, targetObject, nf, boundArgs, 1, ASCIILiteral("format")); if (vm.exception()) return JSValue::encode(JSValue()); // d. Set nf.[[boundFormat]] to bf. nf->setBoundFormat(vm, boundFormat); } // 3. Return nf.[[boundFormat]]. return JSValue::encode(boundFormat); }
EncodedJSValue JSC_HOST_CALL IntlNumberFormatPrototypeFuncResolvedOptions(ExecState* state) { // 11.3.5 Intl.NumberFormat.prototype.resolvedOptions() (ECMA-402 2.0) IntlNumberFormat* numberFormat = jsDynamicCast<IntlNumberFormat*>(state->thisValue()); if (!numberFormat) return JSValue::encode(throwTypeError(state, ASCIILiteral("Intl.NumberFormat.prototype.resolvedOptions called on value that's not an object initialized as a NumberFormat"))); return JSValue::encode(numberFormat->resolvedOptions(*state)); }
EncodedJSValue JSC_HOST_CALL IntlNumberFormatPrototypeFuncResolvedOptions(ExecState* state) { // 11.3.5 Intl.NumberFormat.prototype.resolvedOptions() (ECMA-402 2.0) IntlNumberFormat* numberFormat = jsDynamicCast<IntlNumberFormat*>(state->thisValue()); // FIXME: Workaround to provide compatibility with ECMA-402 1.0 call/apply patterns. if (!numberFormat) numberFormat = jsDynamicCast<IntlNumberFormat*>(state->thisValue().get(state, state->vm().propertyNames->intlSubstituteValuePrivateName)); if (!numberFormat) return JSValue::encode(throwTypeError(state, ASCIILiteral("Intl.NumberFormat.prototype.resolvedOptions called on value that's not an object initialized as a NumberFormat"))); return JSValue::encode(numberFormat->resolvedOptions(*state)); }
static EncodedJSValue JSC_HOST_CALL IntlNumberFormatFuncFormatNumber(ExecState* state) { // 11.3.4 Format Number Functions (ECMA-402 2.0) // 1. Let nf be the this value. // 2. Assert: Type(nf) is Object and nf has an [[initializedNumberFormat]] internal slot whose value true. IntlNumberFormat* numberFormat = jsCast<IntlNumberFormat*>(state->thisValue()); // 3. If value is not provided, let value be undefined. // 4. Let x be ToNumber(value). double number = state->argument(0).toNumber(state); // 5. ReturnIfAbrupt(x). if (state->hadException()) return JSValue::encode(jsUndefined()); // 6. Return FormatNumber(nf, x). return JSValue::encode(numberFormat->formatNumber(*state, number)); }
static EncodedJSValue JSC_HOST_CALL IntlNumberFormatFuncFormatNumber(ExecState* state) { VM& vm = state->vm(); auto scope = DECLARE_THROW_SCOPE(vm); // 11.3.4 Format Number Functions (ECMA-402 2.0) // 1. Let nf be the this value. // 2. Assert: Type(nf) is Object and nf has an [[initializedNumberFormat]] internal slot whose value true. IntlNumberFormat* numberFormat = jsCast<IntlNumberFormat*>(state->thisValue()); // 3. If value is not provided, let value be undefined. // 4. Let x be ToNumber(value). double number = state->argument(0).toNumber(state); // 5. ReturnIfAbrupt(x). RETURN_IF_EXCEPTION(scope, encodedJSValue()); // 6. Return FormatNumber(nf, x). scope.release(); return JSValue::encode(numberFormat->formatNumber(*state, number)); }
EncodedJSValue JSC_HOST_CALL IntlNumberFormatPrototypeFuncResolvedOptions(ExecState* state) { VM& vm = state->vm(); auto scope = DECLARE_THROW_SCOPE(vm); // 11.3.5 Intl.NumberFormat.prototype.resolvedOptions() (ECMA-402 2.0) IntlNumberFormat* numberFormat = jsDynamicCast<IntlNumberFormat*>(vm, state->thisValue()); // FIXME: Workaround to provide compatibility with ECMA-402 1.0 call/apply patterns. // https://bugs.webkit.org/show_bug.cgi?id=153679 if (!numberFormat) { JSValue value = state->thisValue().get(state, vm.propertyNames->builtinNames().intlSubstituteValuePrivateName()); RETURN_IF_EXCEPTION(scope, encodedJSValue()); numberFormat = jsDynamicCast<IntlNumberFormat*>(vm, value); } if (!numberFormat) return JSValue::encode(throwTypeError(state, scope, ASCIILiteral("Intl.NumberFormat.prototype.resolvedOptions called on value that's not an object initialized as a NumberFormat"))); scope.release(); return JSValue::encode(numberFormat->resolvedOptions(*state)); }
EncodedJSValue JSC_HOST_CALL IntlNumberFormatPrototypeGetterFormat(ExecState* state) { VM& vm = state->vm(); auto scope = DECLARE_THROW_SCOPE(vm); // 11.3.3 Intl.NumberFormat.prototype.format (ECMA-402 2.0) // 1. Let nf be this NumberFormat object. IntlNumberFormat* nf = jsDynamicCast<IntlNumberFormat*>(vm, state->thisValue()); // FIXME: Workaround to provide compatibility with ECMA-402 1.0 call/apply patterns. // https://bugs.webkit.org/show_bug.cgi?id=153679 if (!nf) { JSValue value = state->thisValue().get(state, vm.propertyNames->builtinNames().intlSubstituteValuePrivateName()); RETURN_IF_EXCEPTION(scope, encodedJSValue()); nf = jsDynamicCast<IntlNumberFormat*>(vm, value); } if (!nf) return JSValue::encode(throwTypeError(state, scope, ASCIILiteral("Intl.NumberFormat.prototype.format called on value that's not an object initialized as a NumberFormat"))); JSBoundFunction* boundFormat = nf->boundFormat(); // 2. If nf.[[boundFormat]] is undefined, if (!boundFormat) { JSGlobalObject* globalObject = nf->globalObject(); // a. Let F be a new built-in function object as defined in 11.3.4. // b. The value of F’s length property is 1. JSFunction* targetObject = JSFunction::create(vm, globalObject, 1, ASCIILiteral("format"), IntlNumberFormatFuncFormatNumber, NoIntrinsic); // c. Let bf be BoundFunctionCreate(F, «this value»). boundFormat = JSBoundFunction::create(vm, state, globalObject, targetObject, nf, nullptr, 1, ASCIILiteral("format")); RETURN_IF_EXCEPTION(scope, encodedJSValue()); // d. Set nf.[[boundFormat]] to bf. nf->setBoundFormat(vm, boundFormat); } // 3. Return nf.[[boundFormat]]. return JSValue::encode(boundFormat); }
IntlNumberFormat* IntlNumberFormat::create(VM& vm, Structure* structure) { IntlNumberFormat* format = new (NotNull, allocateCell<IntlNumberFormat>(vm.heap)) IntlNumberFormat(vm, structure); format->finishCreation(vm); return format; }
IntlNumberFormat* IntlNumberFormat::create(VM& vm, IntlNumberFormatConstructor* constructor) { IntlNumberFormat* format = new (NotNull, allocateCell<IntlNumberFormat>(vm.heap)) IntlNumberFormat(vm, constructor->numberFormatStructure()); format->finishCreation(vm); return format; }