Skip to content

Commit b6ef80f

Browse files
awesomeklingtrflynn89
authored andcommitted
LibJS: Avoid options object allocation in fromBase64() and toBase64()
When no options (or undefined) are passed into these APIs, the spec has us synthesize a temporary "options object" to read the options from. We don't actually need these objects, so let's sidestep the allocation if we can (and just use the default values in that case).
1 parent b2761b5 commit b6ef80f

File tree

1 file changed

+33
-23
lines changed

1 file changed

+33
-23
lines changed

Libraries/LibJS/Runtime/Uint8Array.cpp

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -89,18 +89,23 @@ JS_DEFINE_NATIVE_FUNCTION(Uint8ArrayConstructorHelpers::from_base64)
8989
if (!string_value.is_string())
9090
return vm.throw_completion<TypeError>(ErrorType::NotAString, string_value);
9191

92-
// 2. Let opts be ? GetOptionsObject(options).
93-
auto options = TRY(get_options_object(vm, options_value));
94-
95-
// 3. Let alphabet be ? Get(opts, "alphabet").
96-
// 4. If alphabet is undefined, set alphabet to "base64".
97-
// 5. If alphabet is neither "base64" nor "base64url", throw a TypeError exception.
98-
auto alphabet = TRY(parse_alphabet(vm, *options));
99-
100-
// 6. Let lastChunkHandling be ? Get(opts, "lastChunkHandling").
101-
// 7. If lastChunkHandling is undefined, set lastChunkHandling to "loose".
102-
// 8. If lastChunkHandling is not one of "loose", "strict", or "stop-before-partial", throw a TypeError exception.
103-
auto last_chunk_handling = TRY(parse_last_chunk_handling(vm, *options));
92+
// OPTIMIZATION: Avoid allocating an empty options object if none was provided.
93+
Alphabet alphabet = Alphabet::Base64;
94+
AK::LastChunkHandling last_chunk_handling = AK::LastChunkHandling::Loose;
95+
if (!options_value.is_undefined()) {
96+
// 2. Let opts be ? GetOptionsObject(options).
97+
auto options = TRY(get_options_object(vm, options_value));
98+
99+
// 3. Let alphabet be ? Get(opts, "alphabet").
100+
// 4. If alphabet is undefined, set alphabet to "base64".
101+
// 5. If alphabet is neither "base64" nor "base64url", throw a TypeError exception.
102+
alphabet = TRY(parse_alphabet(vm, *options));
103+
104+
// 6. Let lastChunkHandling be ? Get(opts, "lastChunkHandling").
105+
// 7. If lastChunkHandling is undefined, set lastChunkHandling to "loose".
106+
// 8. If lastChunkHandling is not one of "loose", "strict", or "stop-before-partial", throw a TypeError exception.
107+
last_chunk_handling = TRY(parse_last_chunk_handling(vm, *options));
108+
}
104109

105110
// 9. Let result be FromBase64(string, alphabet, lastChunkHandling).
106111
auto result = JS::from_base64(vm, string_value.as_string().utf8_string_view(), alphabet, last_chunk_handling);
@@ -310,17 +315,22 @@ JS_DEFINE_NATIVE_FUNCTION(Uint8ArrayPrototypeHelpers::to_base64)
310315
// 2. Perform ? ValidateUint8Array(O).
311316
auto typed_array = TRY(validate_uint8_array(vm));
312317

313-
// 3. Let opts be ? GetOptionsObject(options).
314-
auto options = TRY(get_options_object(vm, options_value));
315-
316-
// 4. Let alphabet be ? Get(opts, "alphabet").
317-
// 5. If alphabet is undefined, set alphabet to "base64".
318-
// 6. If alphabet is neither "base64" nor "base64url", throw a TypeError exception.
319-
auto alphabet = TRY(parse_alphabet(vm, *options));
320-
321-
// 7. Let omitPadding be ToBoolean(? Get(opts, "omitPadding")).
322-
auto omit_padding_value = TRY(options->get(vm.names.omitPadding)).to_boolean();
323-
auto omit_padding = omit_padding_value ? AK::OmitPadding::Yes : AK::OmitPadding::No;
318+
// OPTIMIZATION: Avoid allocating an empty options object if none was provided.
319+
Alphabet alphabet = Alphabet::Base64;
320+
AK::OmitPadding omit_padding = AK::OmitPadding::No;
321+
if (!options_value.is_undefined()) {
322+
// 3. Let opts be ? GetOptionsObject(options).
323+
auto options = TRY(get_options_object(vm, options_value));
324+
325+
// 4. Let alphabet be ? Get(opts, "alphabet").
326+
// 5. If alphabet is undefined, set alphabet to "base64".
327+
// 6. If alphabet is neither "base64" nor "base64url", throw a TypeError exception.
328+
alphabet = TRY(parse_alphabet(vm, *options));
329+
330+
// 7. Let omitPadding be ToBoolean(? Get(opts, "omitPadding")).
331+
auto omit_padding_value = TRY(options->get(vm.names.omitPadding)).to_boolean();
332+
omit_padding = omit_padding_value ? AK::OmitPadding::Yes : AK::OmitPadding::No;
333+
}
324334

325335
// 8. Let toEncode be ? GetUint8ArrayBytes(O).
326336
auto to_encode = TRY(get_uint8_array_bytes(vm, typed_array));

0 commit comments

Comments
 (0)