static EncodedJSValue JSC_HOST_CALL IntlCollatorFuncCompare(ExecState* state) { VM& vm = state->vm(); auto scope = DECLARE_THROW_SCOPE(vm); // 10.3.4 Collator Compare Functions (ECMA-402 2.0) // 1. Let collator be the this value. // 2. Assert: Type(collator) is Object and collator has an [[initializedCollator]] internal slot whose value is true. IntlCollator* collator = jsCast<IntlCollator*>(state->thisValue()); // 3. If x is not provided, let x be undefined. // 4. If y is not provided, let y be undefined. // 5. Let X be ToString(x). JSString* x = state->argument(0).toString(state); // 6. ReturnIfAbrupt(X). RETURN_IF_EXCEPTION(scope, encodedJSValue()); // 7. Let Y be ToString(y). JSString* y = state->argument(1).toString(state); // 8. ReturnIfAbrupt(Y). RETURN_IF_EXCEPTION(scope, encodedJSValue()); // 9. Return CompareStrings(collator, X, Y). auto xViewWithString = x->viewWithUnderlyingString(*state); RETURN_IF_EXCEPTION(scope, encodedJSValue()); auto yViewWithString = y->viewWithUnderlyingString(*state); RETURN_IF_EXCEPTION(scope, encodedJSValue()); scope.release(); return JSValue::encode(collator->compareStrings(*state, xViewWithString.view, yViewWithString.view)); }
EncodedJSValue JSC_HOST_CALL IntlCollatorPrototypeGetterCompare(ExecState* exec) { // 10.3.3 Intl.Collator.prototype.compare (ECMA-402 2.0) // 1. Let collator be this Collator object. IntlCollator* collator = jsDynamicCast<IntlCollator*>(exec->thisValue()); if (!collator) return JSValue::encode(throwTypeError(exec, ASCIILiteral("Intl.Collator.prototype.compare called on value that's not an object initialized as a Collator"))); JSBoundFunction* boundCompare = collator->boundCompare(); // 2. If collator.[[boundCompare]] is undefined, if (!boundCompare) { VM& vm = exec->vm(); JSGlobalObject* globalObject = collator->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 2. JSFunction* targetObject = JSFunction::create(vm, globalObject, 2, ASCIILiteral("compare"), IntlCollatorFuncCompare, NoIntrinsic); JSArray* boundArgs = JSArray::tryCreateUninitialized(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), 0); if (!boundArgs) return JSValue::encode(throwOutOfMemoryError(exec)); // c. Let bc be BoundFunctionCreate(F, «this value»). boundCompare = JSBoundFunction::create(vm, globalObject, targetObject, collator, boundArgs, 2, ASCIILiteral("compare")); // d. Set collator.[[boundCompare]] to bc. collator->setBoundCompare(vm, boundCompare); } // 3. Return collator.[[boundCompare]]. return JSValue::encode(boundCompare); }
EncodedJSValue JSC_HOST_CALL IntlCollatorPrototypeGetterCompare(ExecState* state) { VM& vm = state->vm(); auto scope = DECLARE_THROW_SCOPE(vm); // 10.3.3 Intl.Collator.prototype.compare (ECMA-402 2.0) // 1. Let collator be this Collator object. IntlCollator* collator = jsDynamicCast<IntlCollator*>(state->thisValue()); if (!collator) return JSValue::encode(throwTypeError(state, scope, ASCIILiteral("Intl.Collator.prototype.compare called on value that's not an object initialized as a Collator"))); JSBoundFunction* boundCompare = collator->boundCompare(); // 2. If collator.[[boundCompare]] is undefined, if (!boundCompare) { JSGlobalObject* globalObject = collator->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 2. JSFunction* targetObject = JSFunction::create(vm, globalObject, 2, ASCIILiteral("compare"), IntlCollatorFuncCompare, NoIntrinsic); // c. Let bc be BoundFunctionCreate(F, «this value»). boundCompare = JSBoundFunction::create(vm, state, globalObject, targetObject, collator, nullptr, 2, ASCIILiteral("compare")); RETURN_IF_EXCEPTION(scope, encodedJSValue()); // d. Set collator.[[boundCompare]] to bc. collator->setBoundCompare(vm, boundCompare); } // 3. Return collator.[[boundCompare]]. return JSValue::encode(boundCompare); }
EncodedJSValue JSC_HOST_CALL IntlCollatorPrototypeFuncResolvedOptions(ExecState* state) { VM& vm = state->vm(); auto scope = DECLARE_THROW_SCOPE(vm); // 10.3.5 Intl.Collator.prototype.resolvedOptions() (ECMA-402 2.0) IntlCollator* collator = jsDynamicCast<IntlCollator*>(state->thisValue()); if (!collator) return JSValue::encode(throwTypeError(state, scope, ASCIILiteral("Intl.Collator.prototype.resolvedOptions called on value that's not an object initialized as a Collator"))); return JSValue::encode(collator->resolvedOptions(*state)); }
EncodedJSValue JSC_HOST_CALL IntlCollatorPrototypeFuncResolvedOptions(ExecState* exec) { // 10.3.5 Intl.Collator.prototype.resolvedOptions() (ECMA-402 2.0) IntlCollator* collator = jsDynamicCast<IntlCollator*>(exec->thisValue()); if (!collator) return JSValue::encode(throwTypeError(exec, ASCIILiteral("Intl.Collator.prototype.resolvedOptions called on value that's not an object initialized as a Collator"))); // The function returns a new object whose properties and attributes are set as if // constructed by an object literal assigning to each of the following properties the // value of the corresponding internal slot of this Collator object (see 10.4): locale, // usage, sensitivity, ignorePunctuation, collation, as well as those properties shown // in Table 1 whose keys are included in the %Collator%[[relevantExtensionKeys]] // internal slot of the standard built-in object that is the initial value of // Intl.Collator. VM& vm = exec->vm(); JSObject* options = constructEmptyObject(exec); options->putDirect(vm, vm.propertyNames->locale, jsString(exec, collator->locale())); options->putDirect(vm, vm.propertyNames->usage, jsString(exec, collator->usage())); options->putDirect(vm, vm.propertyNames->sensitivity, jsString(exec, collator->sensitivity())); options->putDirect(vm, vm.propertyNames->ignorePunctuation, jsBoolean(collator->ignorePunctuation())); options->putDirect(vm, vm.propertyNames->collation, jsString(exec, collator->collation())); options->putDirect(vm, vm.propertyNames->numeric, jsBoolean(collator->numeric())); return JSValue::encode(options); }
static EncodedJSValue JSC_HOST_CALL constructIntlCollator(ExecState* state) { VM& vm = state->vm(); auto scope = DECLARE_THROW_SCOPE(vm); // 10.1.2 Intl.Collator ([locales [, options]]) (ECMA-402 2.0) // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget. // 2. Let collator be OrdinaryCreateFromConstructor(newTarget, %CollatorPrototype%). // 3. ReturnIfAbrupt(collator). Structure* structure = InternalFunction::createSubclassStructure(state, state->newTarget(), jsCast<IntlCollatorConstructor*>(state->jsCallee())->collatorStructure(vm)); RETURN_IF_EXCEPTION(scope, encodedJSValue()); IntlCollator* collator = IntlCollator::create(vm, structure); ASSERT(collator); // 4. Return InitializeCollator(collator, locales, options). scope.release(); collator->initializeCollator(*state, state->argument(0), state->argument(1)); return JSValue::encode(collator); }
static EncodedJSValue JSC_HOST_CALL callIntlCollator(ExecState* state) { // 10.1.2 Intl.Collator ([locales [, options]]) (ECMA-402 2.0) // 1. If NewTarget is undefined, let newTarget be the active function object, else let newTarget be NewTarget. // NewTarget is always undefined when called as a function. VM& vm = state->vm(); IntlCollatorConstructor* callee = jsCast<IntlCollatorConstructor*>(state->jsCallee()); // FIXME: Collator does not get the workaround for ECMA-402 1.0 compatibility. // https://bugs.webkit.org/show_bug.cgi?id=153679 // 2. Let collator be OrdinaryCreateFromConstructor(newTarget, %CollatorPrototype%). // 3. ReturnIfAbrupt(collator). IntlCollator* collator = IntlCollator::create(vm, callee->collatorStructure(vm)); ASSERT(collator); // 4. Return InitializeCollator(collator, locales, options). collator->initializeCollator(*state, state->argument(0), state->argument(1)); return JSValue::encode(collator); }
IntlCollator* IntlCollator::create(VM& vm, Structure* structure) { IntlCollator* format = new (NotNull, allocateCell<IntlCollator>(vm.heap)) IntlCollator(vm, structure); format->finishCreation(vm); return format; }
IntlCollator* IntlCollator::create(VM& vm, IntlCollatorConstructor* constructor) { IntlCollator* format = new (NotNull, allocateCell<IntlCollator>(vm.heap)) IntlCollator(vm, constructor->collatorStructure()); format->finishCreation(vm); return format; }