Skip to content

Commit

Permalink
Add optimization for noexcept methods and test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
ujjwalchadha committed Oct 5, 2020
1 parent 48fd923 commit 4f86482
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 22 deletions.
6 changes: 3 additions & 3 deletions TestComponentCSharp/Class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -718,7 +718,7 @@ namespace winrt::TestComponentCSharp::implementation
return winrt::single_threaded_vector_view(std::vector<IProperties1>{ *this, *this, *this });
}

IVectorView<TestComponentCSharp::Class> Class::GetClassVector()
IVectorView<TestComponentCSharp::Class> Class::GetClassVector() noexcept
{
return winrt::single_threaded_vector_view(std::vector<TestComponentCSharp::Class>{ *this, *this, *this });
}
Expand Down Expand Up @@ -1031,11 +1031,11 @@ namespace winrt::TestComponentCSharp::implementation
return _string;
}

int32_t Class::ReadWriteProperty()
int32_t Class::ReadWriteProperty()
{
return _int;
}
void Class::ReadWriteProperty(int32_t value)
void Class::ReadWriteProperty(int32_t value) noexcept
{
_int = value;
}
Expand Down
4 changes: 2 additions & 2 deletions TestComponentCSharp/Class.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ namespace winrt::TestComponentCSharp::implementation
Windows::Foundation::Collections::IVectorView<TestComponentCSharp::ComposedNonBlittableStruct> GetNonBlittableStructVector();
Windows::Foundation::Collections::IVectorView<Windows::Foundation::IInspectable> GetObjectVector();
Windows::Foundation::Collections::IVectorView<TestComponentCSharp::IProperties1> GetInterfaceVector();
Windows::Foundation::Collections::IVectorView<TestComponentCSharp::Class> GetClassVector();
Windows::Foundation::Collections::IVectorView<TestComponentCSharp::Class> GetClassVector() noexcept;

Windows::Foundation::Collections::IIterable<int32_t> GetIntIterable();
void SetIntIterable(Windows::Foundation::Collections::IIterable<int32_t> const& value);
Expand Down Expand Up @@ -316,7 +316,7 @@ namespace winrt::TestComponentCSharp::implementation
//int32_t DrawTo();
int32_t ReadWriteProperty();
//int32_t DistinctProperty();
void ReadWriteProperty(int32_t value);
void ReadWriteProperty(int32_t value) noexcept;
//hstring DistinctProperty();
//void DistinctProperty(hstring const& value);

Expand Down
4 changes: 2 additions & 2 deletions TestComponentCSharp/TestComponentCSharp.idl
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ namespace TestComponentCSharp

interface IProperties2 requires IProperties1
{
Int32 ReadWriteProperty{ set; };
[noexcept] Int32 ReadWriteProperty{ set; };
//String DisjointProperty{ set; };
//String DistinctProperty{ get; set; };
}
Expand Down Expand Up @@ -224,7 +224,7 @@ namespace TestComponentCSharp
Windows.Foundation.Collections.IVectorView<ComposedNonBlittableStruct> GetNonBlittableStructVector();
Windows.Foundation.Collections.IVectorView<Object> GetObjectVector();
Windows.Foundation.Collections.IVectorView<IProperties1> GetInterfaceVector();
Windows.Foundation.Collections.IVectorView<Class> GetClassVector();
[noexcept] Windows.Foundation.Collections.IVectorView<Class> GetClassVector();

Windows.Foundation.Collections.IIterable<Int32> GetIntIterable();
void SetIntIterable(Windows.Foundation.Collections.IIterable<Int32> value);
Expand Down
35 changes: 20 additions & 15 deletions cswinrt/code_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@ namespace cswinrt
{
using namespace winmd::reader;

static inline bool starts_with(std::string_view const& value, std::string_view const& match) noexcept
{
return 0 == value.compare(0, match.size(), match);
}

static const struct
{
char const* csharp;
Expand Down Expand Up @@ -2457,15 +2452,15 @@ event % %;)",
return marshalers;
}

void write_abi_method_call_marshalers(writer& w, std::string_view invoke_target, bool is_generic, std::vector<abi_marshaler> const& marshalers)
void write_abi_method_call_marshalers(writer& w, std::string_view invoke_target, bool is_generic, std::vector<abi_marshaler> const& marshalers, bool has_noexcept_attr = false)
{
auto write_abi_invoke = [&](writer& w)
{
if (is_generic)
{
w.write("%.DynamicInvokeAbi(__params);\n", invoke_target);
}
else
else if (!has_noexcept_attr)
{
w.write("global::WinRT.ExceptionHelpers.ThrowExceptionForHR(%(ThisPtr%));\n",
invoke_target,
Expand All @@ -2475,6 +2470,15 @@ event % %;)",
m.write_marshal_to_abi(w);
}, marshalers));
}
else {
w.write("%(ThisPtr%);\n",
invoke_target,
bind_each([](writer& w, abi_marshaler const& m)
{
w.write(", ");
m.write_marshal_to_abi(w);
}, marshalers));
}
for (auto&& m : marshalers)
{
m.write_marshal_from_abi(w);
Expand Down Expand Up @@ -2529,9 +2533,9 @@ finally
);
}

void write_abi_method_call(writer& w, method_signature signature, std::string_view invoke_target, bool is_generic, bool raw_return_type = false)
void write_abi_method_call(writer& w, method_signature signature, std::string_view invoke_target, bool is_generic, bool raw_return_type = false, bool has_noexcept_attr = false)
{
write_abi_method_call_marshalers(w, invoke_target, is_generic, get_abi_marshalers(w, signature, is_generic, "", raw_return_type));
write_abi_method_call_marshalers(w, invoke_target, is_generic, get_abi_marshalers(w, signature, is_generic, "", raw_return_type), has_noexcept_attr);
}

void write_abi_method_with_raw_return_type(writer& w, MethodDef const& method)
Expand Down Expand Up @@ -2574,7 +2578,7 @@ public unsafe %% %(%)
bind(write_raw_return_type, signature),
method.Name(),
bind_list<write_projection_parameter>(", ", signature.params()),
bind<write_abi_method_call>(signature, invoke_target, is_generic, true));
bind<write_abi_method_call>(signature, invoke_target, is_generic, true, is_noexcept(method)));
}


Expand Down Expand Up @@ -2652,7 +2656,7 @@ public unsafe % %(%)
bind(write_raw_return_type, signature),
method.Name(),
bind(write_composable_constructor_params, signature),
bind<write_abi_method_call_marshalers>(invoke_target, is_generic, abi_marshalers));
bind<write_abi_method_call_marshalers>(invoke_target, is_generic, abi_marshalers, is_noexcept(method)));
}

template<auto method_writer>
Expand Down Expand Up @@ -2768,7 +2772,7 @@ global::System.Collections.Concurrent.ConcurrentDictionary<RuntimeTypeHandle, IO
method.Name(),
bind_list<write_projection_parameter>(", ", signature.params()),
bind(init_call_variables),
bind<write_abi_method_call>(signature, invoke_target, is_generic, false));
bind<write_abi_method_call>(signature, invoke_target, is_generic, false, is_noexcept(method)));
}

for (auto&& prop : type.PropertyList())
Expand All @@ -2788,6 +2792,7 @@ global::System.Collections.Concurrent.ConcurrentDictionary<RuntimeTypeHandle, IO
}
}),
prop.Name());

if (getter)
{
auto [invoke_target, is_generic] = get_method_info(getter);
Expand All @@ -2797,7 +2802,7 @@ global::System.Collections.Concurrent.ConcurrentDictionary<RuntimeTypeHandle, IO
{%%}
)",
bind(init_call_variables),
bind<write_abi_method_call_marshalers>(invoke_target, is_generic, marshalers));
bind<write_abi_method_call_marshalers>(invoke_target, is_generic, marshalers, is_noexcept(prop)));
}
if (setter)
{
Expand All @@ -2815,7 +2820,7 @@ global::System.Collections.Concurrent.ConcurrentDictionary<RuntimeTypeHandle, IO
{%%}
)",
bind(init_call_variables),
bind<write_abi_method_call_marshalers>(invoke_target, is_generic, marshalers));
bind<write_abi_method_call_marshalers>(invoke_target, is_generic, marshalers, is_noexcept(prop)));
}
w.write("}\n");
}
Expand Down Expand Up @@ -5193,7 +5198,7 @@ public static Guid PIID = GuidGenerator.CreateIID(typeof(%));)",
bind<write_abi_parameter_types>(signature));
}
}),
bind<write_abi_method_call>(signature, "abiInvoke", is_generic, false),
bind<write_abi_method_call>(signature, "abiInvoke", is_generic, false, is_noexcept(method)),
// FromManaged
type_name,
// DisposeMarshaler
Expand Down
20 changes: 20 additions & 0 deletions cswinrt/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,32 @@ namespace cswinrt
using namespace std::literals;
using namespace winmd::reader;

static inline bool starts_with(std::string_view const& value, std::string_view const& match) noexcept
{
return 0 == value.compare(0, match.size(), match);
}

static bool is_remove_overload(MethodDef const& method)
{
return method.SpecialName() && starts_with(method.Name(), "remove_");
}

template <typename T>
bool has_attribute(T const& row, std::string_view const& type_namespace, std::string_view const& type_name)
{
return static_cast<bool>(get_attribute(row, type_namespace, type_name));
}

static bool is_noexcept(MethodDef const& method)
{
return is_remove_overload(method) || has_attribute(method, "Windows.Foundation.Metadata", "NoExceptionAttribute");
}

static bool is_noexcept(Property const& prop)
{
return has_attribute(prop, "Windows.Foundation.Metadata", "NoExceptionAttribute");
}

bool is_exclusive_to(TypeDef const& type)
{
return get_category(type) == category::interface_type && has_attribute(type, "Windows.Foundation.Metadata"sv, "ExclusiveToAttribute"sv);
Expand Down

0 comments on commit 4f86482

Please sign in to comment.