src: use DictionaryTemplate more in URLPattern · nodejs/node@d17f299
@@ -61,6 +61,7 @@ using v8::FunctionTemplate;
6161using v8::Global;
6262using v8::Isolate;
6363using v8::Local;
64+using v8::LocalVector;
6465using v8::MaybeLocal;
6566using v8::Name;
6667using v8::NewStringType;
@@ -284,27 +285,56 @@ MaybeLocal<Value> URLPattern::URLPatternInit::ToJsObject(
284285 Environment* env, const ada::url_pattern_init& init) {
285286auto isolate = env->isolate();
286287auto context = env->context();
287-auto result = Object::New(isolate);
288288289-const auto trySet = [&](auto name, const std::optional<std::string>& val) {
290-if (!val) return true;
291- Local<Value> temp;
292-return ToV8Value(context, *val).ToLocal(&temp) &&
293- result->Set(context, name, temp).IsJust();
289+auto tmpl = env->urlpatterninit_template();
290+if (tmpl.IsEmpty()) {
291+static constexpr std::string_view namesVec[] = {
292+"protocol",
293+"username",
294+"password",
295+"hostname",
296+"port",
297+"pathname",
298+"search",
299+"hash",
300+"baseURL",
301+ };
302+ tmpl = DictionaryTemplate::New(isolate, namesVec);
303+ env->set_urlpatterninit_template(tmpl);
304+ }
305+306+ MaybeLocal<Value> values[] = {
307+Undefined(isolate), // protocol
308+Undefined(isolate), // username
309+Undefined(isolate), // password
310+Undefined(isolate), // hostname
311+Undefined(isolate), // port
312+Undefined(isolate), // pathname
313+Undefined(isolate), // search
314+Undefined(isolate), // hash
315+Undefined(isolate), // baseURL
316+ };
317+318+int idx = 0;
319+ Local<Value> temp;
320+const auto trySet = [&](const std::optional<std::string>& val) {
321+if (val.has_value()) {
322+if (!ToV8Value(context, *val).ToLocal(&temp)) {
323+return false;
324+ }
325+ values[idx] = temp;
326+ }
327+ idx++;
328+return true;
294329 };
295330296-if (!trySet(env->protocol_string(), init.protocol) ||
297- !trySet(env->username_string(), init.username) ||
298- !trySet(env->password_string(), init.password) ||
299- !trySet(env->hostname_string(), init.hostname) ||
300- !trySet(env->port_string(), init.port) ||
301- !trySet(env->pathname_string(), init.pathname) ||
302- !trySet(env->search_string(), init.search) ||
303- !trySet(env->hash_string(), init.hash) ||
304- !trySet(env->base_url_string(), init.base_url)) {
331+if (!trySet(init.protocol) || !trySet(init.username) ||
332+ !trySet(init.password) || !trySet(init.hostname) || !trySet(init.port) ||
333+ !trySet(init.pathname) || !trySet(init.search) || !trySet(init.hash) ||
334+ !trySet(init.base_url)) {
305335return {};
306336 }
307-return result;
337+return NewDictionaryInstance(env->context(), tmpl, values);
308338}
309339310340std::optional<ada::url_pattern_init> URLPattern::URLPatternInit::FromJsObject(
@@ -364,12 +394,16 @@ MaybeLocal<Object> URLPattern::URLPatternComponentResult::ToJSObject(
364394 Environment* env, const ada::url_pattern_component_result& result) {
365395auto isolate = env->isolate();
366396auto context = env->context();
367-auto parsed_group = Object::New(isolate);
397+ LocalVector<Name> group_names(isolate);
398+ LocalVector<Value> group_values(isolate);
399+ group_names.reserve(result.groups.size());
400+ group_values.reserve(result.groups.size());
368401for (const auto& [group_key, group_value] : result.groups) {
369402 Local<Value> key;
370403if (!ToV8Value(context, group_key).ToLocal(&key)) {
371404return {};
372405 }
406+ group_names.push_back(key.As<Name>());
373407 Local<Value> value;
374408if (group_value) {
375409if (!ToV8Value(env->context(), *group_value).ToLocal(&value)) {
@@ -378,19 +412,30 @@ MaybeLocal<Object> URLPattern::URLPatternComponentResult::ToJSObject(
378412 } else {
379413 value = Undefined(isolate);
380414 }
381-if (parsed_group->Set(context, key, value).IsNothing()) {
382-return {};
383- }
415+ group_values.push_back(value);
384416 }
417+auto parsed_group = Object::New(isolate,
418+Object::New(isolate),
419+ group_names.data(),
420+ group_values.data(),
421+ group_names.size());
422+385423 Local<Value> input;
386424if (!ToV8Value(env->context(), result.input).ToLocal(&input)) {
387425return {};
388426 }
389- Local<Name> names[] = {env->input_string(), env->groups_string()};
390- Local<Value> values[] = {input, parsed_group};
391-DCHECK_EQ(arraysize(names), arraysize(values));
392-return Object::New(
393- isolate, Object::New(isolate), names, values, arraysize(names));
427+428+auto tmpl = env->urlpatterncomponentresult_template();
429+if (tmpl.IsEmpty()) {
430+static constexpr std::string_view namesVec[] = {
431+"input",
432+"groups",
433+ };
434+ tmpl = DictionaryTemplate::New(isolate, namesVec);
435+ env->set_urlpatterncomponentresult_template(tmpl);
436+ }
437+ MaybeLocal<Value> values[] = {input, parsed_group};
438+return NewDictionaryInstance(env->context(), tmpl, values);
394439}
395440396441MaybeLocal<Value> URLPattern::URLPatternResult::ToJSValue(