LibJS: Replace PropertyKey(char[]) with PropertyKey(FlyString)

...and deal with the fallout.
This commit is contained in:
Andreas Kling 2025-03-16 21:25:29 -05:00 committed by Andreas Kling
commit 53da8893ac
Notes: github-actions[bot] 2025-03-24 22:28:43 +00:00
55 changed files with 254 additions and 251 deletions

View file

@ -233,7 +233,7 @@ ThrowCompletionOr<void> initialize_bound_name(VM& vm, DeprecatedFlyString const&
bool is_compatible_property_descriptor(bool extensible, PropertyDescriptor const& descriptor, Optional<PropertyDescriptor> const& current)
{
// 1. Return ValidateAndApplyPropertyDescriptor(undefined, "", Extensible, Desc, Current).
return validate_and_apply_property_descriptor(nullptr, "", extensible, descriptor, current);
return validate_and_apply_property_descriptor(nullptr, FlyString {}, extensible, descriptor, current);
}
// 10.1.6.3 ValidateAndApplyPropertyDescriptor ( O, P, extensible, Desc, current ), https://tc39.es/ecma262/#sec-validateandapplypropertydescriptor
@ -1544,7 +1544,7 @@ ThrowCompletionOr<GC::Ptr<FunctionObject>> get_dispose_method(VM& vm, Value valu
// thrown synchronously.
// 3. Return CreateBuiltinFunction(closure, 0, "", « »).
return NativeFunction::create(realm, move(closure), 0, "");
return NativeFunction::create(realm, move(closure), 0);
}
}
}

View file

@ -68,7 +68,7 @@ JS_DEFINE_NATIVE_FUNCTION(AsyncDisposableStackPrototype::adopt)
};
// 6. Let F be CreateBuiltinFunction(closure, 0, "", « »).
auto function = NativeFunction::create(realm, move(closure), 0, "");
auto function = NativeFunction::create(realm, move(closure), 0);
// 7. Perform ? AddDisposableResource(asyncDisposableStack.[[DisposeCapability]], undefined, async-dispose, F).
TRY(add_disposable_resource(vm, async_disposable_stack->dispose_capability(), js_undefined(), Environment::InitializeBindingHint::AsyncDispose, function));

View file

@ -58,7 +58,7 @@ static Object* async_from_sync_iterator_continuation(VM& vm, Object& result, Pro
// 9. Let onFulfilled be CreateBuiltinFunction(unwrap, 1, "", « »).
// 10. NOTE: onFulfilled is used when processing the "value" property of an IteratorResult object in order to wait for its value if it is a promise and re-package the result in a new "unwrapped" IteratorResult object.
auto on_fulfilled = NativeFunction::create(realm, move(unwrap), 1, "");
auto on_fulfilled = NativeFunction::create(realm, move(unwrap), 1);
// 11. Perform PerformPromiseThen(valueWrapper, onFulfilled, undefined, promiseCapability).
as<Promise>(value_wrapper)->perform_then(move(on_fulfilled), js_undefined(), &promise_capability);

View file

@ -75,7 +75,7 @@ ThrowCompletionOr<void> AsyncFunctionDriverWrapper::await(JS::Value value)
};
// 4. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
auto on_fulfilled = NativeFunction::create(realm, move(fulfilled_closure), 1, "");
auto on_fulfilled = NativeFunction::create(realm, move(fulfilled_closure), 1);
// 5. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures asyncContext and performs the
// following steps when called:
@ -103,7 +103,7 @@ ThrowCompletionOr<void> AsyncFunctionDriverWrapper::await(JS::Value value)
};
// 6. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
auto on_rejected = NativeFunction::create(realm, move(rejected_closure), 1, "");
auto on_rejected = NativeFunction::create(realm, move(rejected_closure), 1);
// 7. Perform PerformPromiseThen(promise, onFulfilled, onRejected).
m_current_promise = as<Promise>(promise_object);

View file

@ -104,7 +104,7 @@ ThrowCompletionOr<void> AsyncGenerator::await(Value value)
};
// 4. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
auto on_fulfilled = NativeFunction::create(realm, move(fulfilled_closure), 1, "");
auto on_fulfilled = NativeFunction::create(realm, move(fulfilled_closure), 1);
// 5. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures asyncContext and performs the
// following steps when called:
@ -131,7 +131,7 @@ ThrowCompletionOr<void> AsyncGenerator::await(Value value)
};
// 6. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
auto on_rejected = NativeFunction::create(realm, move(rejected_closure), 1, "");
auto on_rejected = NativeFunction::create(realm, move(rejected_closure), 1);
// 7. Perform PerformPromiseThen(promise, onFulfilled, onRejected).
m_current_promise = as<Promise>(promise_object);
@ -155,15 +155,15 @@ void AsyncGenerator::execute(VM& vm, Completion completion)
// Loosely based on step 4 of https://tc39.es/ecma262/#sec-asyncgeneratorstart
VERIFY(completion.value().has_value());
auto generated_value = [](Value value) -> Value {
auto generated_value = [&vm](Value value) -> Value {
if (value.is_object())
return value.as_object().get_without_side_effects("result");
return value.as_object().get_without_side_effects(vm.names.result);
return value.is_empty() ? js_undefined() : value;
};
auto generated_continuation = [&](Value value) -> Optional<size_t> {
if (value.is_object()) {
auto number_value = value.as_object().get_without_side_effects("continuation");
auto number_value = value.as_object().get_without_side_effects(vm.names.continuation);
if (number_value.is_null())
return {};
return static_cast<size_t>(number_value.as_double());
@ -171,9 +171,9 @@ void AsyncGenerator::execute(VM& vm, Completion completion)
return {};
};
auto generated_is_await = [](Value value) -> bool {
auto generated_is_await = [&vm](Value value) -> bool {
if (value.is_object())
return value.as_object().get_without_side_effects("isAwait").as_bool();
return value.as_object().get_without_side_effects(vm.names.isAwait).as_bool();
return false;
};
@ -393,7 +393,7 @@ void AsyncGenerator::await_return()
};
// 11. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
auto on_fulfilled = NativeFunction::create(realm, move(fulfilled_closure), 1, "");
auto on_fulfilled = NativeFunction::create(realm, move(fulfilled_closure), 1);
// 12. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures generator and performs
// the following steps when called:
@ -415,7 +415,7 @@ void AsyncGenerator::await_return()
};
// 13. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
auto on_rejected = NativeFunction::create(realm, move(rejected_closure), 1, "");
auto on_rejected = NativeFunction::create(realm, move(rejected_closure), 1);
// 14. Perform PerformPromiseThen(promise, onFulfilled, onRejected).
// NOTE: await_return should only be called when the generator is in SuspendedStart or Completed state,

View file

@ -92,6 +92,7 @@ namespace JS {
P(construct) \
P(constructor) \
P(containing) \
P(continuation) \
P(copyWithin) \
P(cos) \
P(cosh) \
@ -277,6 +278,7 @@ namespace JS {
P(Intl) \
P(is) \
P(isArray) \
P(isAwait) \
P(isDisjointFrom) \
P(isError) \
P(isExtensible) \
@ -408,6 +410,7 @@ namespace JS {
P(reason) \
P(reduce) \
P(reduceRight) \
P(result) \
P(Reflect) \
P(RegExp) \
P(region) \

View file

@ -66,7 +66,7 @@ ThrowCompletionOr<Value> await(VM& vm, Value value)
};
// 4. Let onFulfilled be CreateBuiltinFunction(fulfilledClosure, 1, "", « »).
auto on_fulfilled = NativeFunction::create(realm, move(fulfilled_closure), 1, "");
auto on_fulfilled = NativeFunction::create(realm, move(fulfilled_closure), 1);
// 5. Let rejectedClosure be a new Abstract Closure with parameters (reason) that captures asyncContext and performs the following steps when called:
auto rejected_closure = [&success, &result](VM& vm) -> ThrowCompletionOr<Value> {
@ -90,7 +90,7 @@ ThrowCompletionOr<Value> await(VM& vm, Value value)
};
// 6. Let onRejected be CreateBuiltinFunction(rejectedClosure, 1, "", « »).
auto on_rejected = NativeFunction::create(realm, move(rejected_closure), 1, "");
auto on_rejected = NativeFunction::create(realm, move(rejected_closure), 1);
// 7. Perform PerformPromiseThen(promise, onFulfilled, onRejected).
auto promise = as<Promise>(promise_object);

View file

@ -67,7 +67,7 @@ JS_DEFINE_NATIVE_FUNCTION(DisposableStackPrototype::adopt)
};
// 6. Let F be CreateBuiltinFunction(closure, 0, "", « »).
auto function = NativeFunction::create(realm, move(closure), 0, "");
auto function = NativeFunction::create(realm, move(closure), 0);
// 7. Perform ? AddDisposableResource(disposableStack.[[DisposeCapability]], undefined, sync-dispose, F).
TRY(add_disposable_resource(vm, disposable_stack->dispose_capability(), js_undefined(), Environment::InitializeBindingHint::SyncDispose, function));

View file

@ -82,15 +82,15 @@ ThrowCompletionOr<Value> GeneratorObject::execute(VM& vm, Completion const& comp
VERIFY(completion.value().has_value());
auto generated_value = [](Value value) -> Value {
auto generated_value = [&vm](Value value) -> Value {
if (value.is_object())
return value.as_object().get_without_side_effects("result");
return value.as_object().get_without_side_effects(vm.names.result);
return value.is_empty() ? js_undefined() : value;
};
auto generated_continuation = [&](Value value) -> Optional<size_t> {
if (value.is_object()) {
auto number_value = value.as_object().get_without_side_effects("continuation");
auto number_value = value.as_object().get_without_side_effects(vm.names.continuation);
if (number_value.is_null())
return {};
return static_cast<u64>(number_value.as_double());

View file

@ -246,7 +246,7 @@ void Intrinsics::initialize_intrinsics(Realm& realm)
realm, [](VM& vm) {
return vm.throw_completion<TypeError>(ErrorType::RestrictedFunctionPropertiesAccess);
},
0, "", &realm);
0, FlyString {}, &realm);
m_throw_type_error_function->define_direct_property(vm.names.length, Value(0), 0);
m_throw_type_error_function->define_direct_property(vm.names.name, PrimitiveString::create(vm, String {}), 0);
MUST(m_throw_type_error_function->internal_prevent_extensions());

View file

@ -21,7 +21,7 @@ class NativeFunction : public FunctionObject {
GC_DECLARE_ALLOCATOR(NativeFunction);
public:
static GC::Ref<NativeFunction> create(Realm&, ESCAPING Function<ThrowCompletionOr<Value>(VM&)> behaviour, i32 length, PropertyKey const& name, Optional<Realm*> = {}, Optional<Object*> prototype = {}, Optional<StringView> const& prefix = {});
static GC::Ref<NativeFunction> create(Realm&, ESCAPING Function<ThrowCompletionOr<Value>(VM&)> behaviour, i32 length, PropertyKey const& name = FlyString {}, Optional<Realm*> = {}, Optional<Object*> prototype = {}, Optional<StringView> const& prefix = {});
static GC::Ref<NativeFunction> create(Realm&, DeprecatedFlyString const& name, ESCAPING Function<ThrowCompletionOr<Value>(VM&)>);
virtual ~NativeFunction() override = default;

View file

@ -90,7 +90,7 @@ ThrowCompletionOr<GC::Ref<PromiseCapability>> new_promise_capability(VM& vm, Val
};
// 5. Let executor be CreateBuiltinFunction(executorClosure, 2, "", « »).
auto executor = NativeFunction::create(realm, move(executor_closure), 2, "");
auto executor = NativeFunction::create(realm, move(executor_closure), 2);
// 6. Let promise be ? Construct(C, « executor »).
auto promise = TRY(construct(vm, constructor.as_function(), executor));

View file

@ -121,14 +121,14 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
};
// iv. Let valueThunk be CreateBuiltinFunction(returnValue, 0, "", « »).
auto value_thunk = NativeFunction::create(realm, move(return_value), 0, "");
auto value_thunk = NativeFunction::create(realm, move(return_value), 0);
// v. Return ? Invoke(promise, "then", « valueThunk »).
return TRY(Value(promise).invoke(vm, vm.names.then, value_thunk));
};
// b. Let thenFinally be CreateBuiltinFunction(thenFinallyClosure, 1, "", « »).
then_finally = NativeFunction::create(realm, move(then_finally_closure), 1, "");
then_finally = NativeFunction::create(realm, move(then_finally_closure), 1);
// c. Let catchFinallyClosure be a new Abstract Closure with parameters (reason) that captures onFinally and C and performs the following steps when called:
auto catch_finally_closure = [constructor, on_finally](auto& vm) -> ThrowCompletionOr<Value> {
@ -148,14 +148,14 @@ JS_DEFINE_NATIVE_FUNCTION(PromisePrototype::finally)
};
// iv. Let thrower be CreateBuiltinFunction(throwReason, 0, "", « »).
auto thrower = NativeFunction::create(realm, move(throw_reason), 0, "");
auto thrower = NativeFunction::create(realm, move(throw_reason), 0);
// v. Return ? Invoke(promise, "then", « thrower »).
return TRY(Value(promise).invoke(vm, vm.names.then, thrower));
};
// d. Let catchFinally be CreateBuiltinFunction(catchFinallyClosure, 1, "", « »).
catch_finally = NativeFunction::create(realm, move(catch_finally_closure), 1, "");
catch_finally = NativeFunction::create(realm, move(catch_finally_closure), 1);
}
// 7. Return ? Invoke(promise, "then", « thenFinally, catchFinally »).

View file

@ -61,9 +61,8 @@ public:
{
}
template<size_t N>
PropertyKey(char const (&chars)[N])
: PropertyKey(DeprecatedFlyString(chars))
PropertyKey(FlyString const& string)
: PropertyKey(string.to_deprecated_fly_string())
{
}

View file

@ -108,7 +108,7 @@ JS_DEFINE_NATIVE_FUNCTION(ProxyConstructor::revocable)
// 3. Let revoker be CreateBuiltinFunction(revokerClosure, 0, "", « [[RevocableProxy]] »).
// 4. Set revoker.[[RevocableProxy]] to p.
auto revoker = NativeFunction::create(realm, move(revoker_closure), 0, "");
auto revoker = NativeFunction::create(realm, move(revoker_closure), 0);
// 5. Let result be OrdinaryObjectCreate(%Object.prototype%).
auto result = Object::create(realm, realm.intrinsics().object_prototype());

View file

@ -253,7 +253,7 @@ ThrowCompletionOr<Value> shadow_realm_import_value(VM& vm, String specifier_stri
// 10. Let onFulfilled be CreateBuiltinFunction(steps, 1, "", « [[ExportNameString]] », callerRealm).
// 11. Set onFulfilled.[[ExportNameString]] to exportNameString.
auto on_fulfilled = NativeFunction::create(realm, move(steps), 1, "", &caller_realm);
auto on_fulfilled = NativeFunction::create(realm, move(steps), 1, FlyString {}, &caller_realm);
// 12. Let promiseCapability be ! NewPromiseCapability(%Promise%).
auto promise_capability = MUST(new_promise_capability(vm, realm.intrinsics().promise_constructor()));

View file

@ -603,7 +603,7 @@ JS_DEFINE_NATIVE_FUNCTION(StringPrototype::match_all)
// b. If isRegExp is true, then
if (is_regexp) {
// i. Let flags be ? Get(regexp, "flags").
auto flags = TRY(regexp.as_object().get("flags"));
auto flags = TRY(regexp.as_object().get(vm.names.flags));
// ii. Perform ? RequireObjectCoercible(flags).
auto flags_object = TRY(require_object_coercible(vm, flags));