Skip to content

Commit

Permalink
Omit static constructors when not needed
Browse files Browse the repository at this point in the history
  • Loading branch information
Sergio0694 committed Jan 21, 2025
1 parent b37f1cc commit e4867a5
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 6 deletions.
20 changes: 14 additions & 6 deletions src/cswinrt/code_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -10133,8 +10133,20 @@ bind_list<write_parameter_name_with_modifier>(", ", signature.params())
{
auto factory_type_name = write_type_name_temp(w, type, "%ServerActivationFactory", typedef_name_type::CCW);
auto is_activatable = !is_static(type) && has_default_constructor(type);
auto should_run_class_constructor = has_static_constructor(type);
auto type_name = write_type_name_temp(w, type, "%", typedef_name_type::Projected);

// If the type doesn't have a static constructor, we can omit calling 'RuntimeHelpers.RunClassConstructor'.
// This is technically only required if the type declares any dependency properties (we think, though we're
// not 100% sure), but at least skipping this for types without a static constructor is good enough.
// In practice, it will skip the call for most types.
auto static_constructor = should_run_class_constructor
? ? w.write_temp(R"(static %()
{
RuntimeHelpers.RunClassConstructor(typeof(%).TypeHandle);
})", factory_type_name, type_name)
: "";

// If the type is activatable, we implement IActivationFactory by creating an
// instance and marshalling it to IntPtr. Otherwise, we just throw an exception.
auto activate_instance_body = is_activatable
Expand All @@ -10148,10 +10160,7 @@ bind_list<write_parameter_name_with_modifier>(", ", signature.params())
internal sealed class % : global::WinRT.Interop.IActivationFactory%
{
static %()
{
RuntimeHelpers.RunClassConstructor(typeof(%).TypeHandle);
}
%
public static IntPtr Make()
{
Expand All @@ -10171,8 +10180,7 @@ public IntPtr ActivateInstance()
bind<write_winrt_exposed_type_attribute>(type, true),
factory_type_name,
bind<write_factory_class_inheritance>(type),
factory_type_name,
type_name,
static_constructor,
factory_type_name,
factory_type_name,
factory_type_name,
Expand Down
18 changes: 18 additions & 0 deletions src/cswinrt/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,24 @@ namespace cswinrt
return false;
}

bool has_static_constructor(TypeDef const& type)
{
XLANG_ASSERT(get_category(type) == category::class_type);

for (auto&& method : type.MethodList())
{
if (is_constructor(method) && is_static(method))
{
// Static constructors can't have parameters
XLANG_ASSERT(size(method.ParamList()) == 0);

return true;
}
}

return false;
}

bool is_special(MethodDef const& method)
{
return method.SpecialName() || method.Flags().RTSpecialName();
Expand Down

0 comments on commit e4867a5

Please sign in to comment.