mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-06 22:53:35 +00:00
Make codegen not cast between fnptrs.
When generating the proc tables for dawn_native and dawn_wire (for the client), we were casting between function pointers with the C types and function pointers with the internal types. This is UB and was caught by UBSan. Replace casts between function pointers by casts between types inside the functions themselves. BUG=chromium:906349 Change-Id: Icd8f6eedfa729e767ae3bacb2d6951f5ad5c4c82 Reviewed-on: https://dawn-review.googlesource.com/c/2400 Reviewed-by: Stephen White <senorblanco@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
c56860e27f
commit
c7d78088cd
@ -81,16 +81,30 @@ namespace dawn_native {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//* Entry point with validation
|
//* Entry point with validation
|
||||||
{{as_frontendType(method.return_type)}} Validating{{suffix}}(
|
{{as_cType(method.return_type.name)}} Validating{{suffix}}(
|
||||||
{{-as_frontendType(type)}} self
|
{{-as_cType(type.name)}} cSelf
|
||||||
{%- for arg in method.arguments -%}
|
{%- for arg in method.arguments -%}
|
||||||
, {{as_annotated_frontendType(arg)}}
|
, {{as_annotated_cType(arg)}}
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
) {
|
) {
|
||||||
|
//* Perform conversion between C types and frontend types
|
||||||
|
auto self = reinterpret_cast<{{as_frontendType(type)}}>(cSelf);
|
||||||
|
|
||||||
|
{% for arg in method.arguments %}
|
||||||
|
{% set varName = as_varName(arg.name) %}
|
||||||
|
{% if arg.type.category in ["enum", "bitmask"] %}
|
||||||
|
auto {{varName}}_ = static_cast<{{as_frontendType(arg.type)}}>({{varName}});
|
||||||
|
{% elif arg.annotation != "value" or arg.type.category == "object" %}
|
||||||
|
auto {{varName}}_ = reinterpret_cast<{{decorate("", as_frontendType(arg.type), arg)}}>({{varName}});
|
||||||
|
{% else %}
|
||||||
|
auto {{varName}}_ = {{as_varName(arg.name)}};
|
||||||
|
{% endif %}
|
||||||
|
{%- endfor-%}
|
||||||
|
|
||||||
//* Do the autogenerated checks
|
//* Do the autogenerated checks
|
||||||
bool valid = ValidateBase{{suffix}}(self
|
bool valid = ValidateBase{{suffix}}(self
|
||||||
{%- for arg in method.arguments -%}
|
{%- for arg in method.arguments -%}
|
||||||
, {{as_varName(arg.name)}}
|
, {{as_varName(arg.name)}}_
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -100,7 +114,7 @@ namespace dawn_native {
|
|||||||
if (valid) {
|
if (valid) {
|
||||||
MaybeError error = self->Validate{{method.name.CamelCase()}}(
|
MaybeError error = self->Validate{{method.name.CamelCase()}}(
|
||||||
{%- for arg in method.arguments -%}
|
{%- for arg in method.arguments -%}
|
||||||
{% if not loop.first %}, {% endif %}{{as_varName(arg.name)}}
|
{% if not loop.first %}, {% endif %}{{as_varName(arg.name)}}_
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
);
|
);
|
||||||
//* Builders want to handle error themselves, unpack the error and make
|
//* Builders want to handle error themselves, unpack the error and make
|
||||||
@ -141,17 +155,11 @@ namespace dawn_native {
|
|||||||
self->{{method.name.CamelCase()}}(
|
self->{{method.name.CamelCase()}}(
|
||||||
{%- for arg in method.arguments -%}
|
{%- for arg in method.arguments -%}
|
||||||
{%- if not loop.first %}, {% endif -%}
|
{%- if not loop.first %}, {% endif -%}
|
||||||
{%- if arg.type.category in ["enum", "bitmask"] -%}
|
{{as_varName(arg.name)}}_
|
||||||
static_cast<dawn::{{as_cppType(arg.type.name)}}>({{as_varName(arg.name)}})
|
|
||||||
{%- elif arg.type.category == "structure" and arg.annotation != "value" -%}
|
|
||||||
reinterpret_cast<const {{as_cppType(arg.type.name)}}*>({{as_varName(arg.name)}})
|
|
||||||
{%- else -%}
|
|
||||||
{{as_varName(arg.name)}}
|
|
||||||
{%- endif -%}
|
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
);
|
);
|
||||||
{% if method.return_type.name.canonical_case() != "void" %}
|
{% if method.return_type.name.canonical_case() != "void" %}
|
||||||
return reinterpret_cast<{{as_frontendType(method.return_type)}}>(result);
|
return reinterpret_cast<{{as_cType(method.return_type.name)}}>(result);
|
||||||
{% endif %}
|
{% endif %}
|
||||||
}
|
}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@ -162,7 +170,7 @@ namespace dawn_native {
|
|||||||
dawnProcTable table;
|
dawnProcTable table;
|
||||||
{% for type in by_category["object"] %}
|
{% for type in by_category["object"] %}
|
||||||
{% for method in native_methods(type) %}
|
{% for method in native_methods(type) %}
|
||||||
table.{{as_varName(type.name, method.name)}} = reinterpret_cast<{{as_cProc(type.name, method.name)}}>(Validating{{as_MethodSuffix(type.name, method.name)}});
|
table.{{as_varName(type.name, method.name)}} = Validating{{as_MethodSuffix(type.name, method.name)}};
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
return table;
|
return table;
|
||||||
|
@ -238,12 +238,13 @@ namespace dawn_wire {
|
|||||||
//* Implementation of the client API functions.
|
//* Implementation of the client API functions.
|
||||||
{% for type in by_category["object"] %}
|
{% for type in by_category["object"] %}
|
||||||
{% set Type = type.name.CamelCase() %}
|
{% set Type = type.name.CamelCase() %}
|
||||||
|
{% set cType = as_cType(type.name) %}
|
||||||
|
|
||||||
{% for method in type.methods %}
|
{% for method in type.methods %}
|
||||||
{% set Suffix = as_MethodSuffix(type.name, method.name) %}
|
{% set Suffix = as_MethodSuffix(type.name, method.name) %}
|
||||||
|
|
||||||
{{as_wireType(method.return_type)}} Client{{Suffix}}(
|
{{as_cType(method.return_type.name)}} Client{{Suffix}}(
|
||||||
{{-as_cType(type.name)}} cSelf
|
{{-cType}} cSelf
|
||||||
{%- for arg in method.arguments -%}
|
{%- for arg in method.arguments -%}
|
||||||
, {{as_annotated_cType(arg)}}
|
, {{as_annotated_cType(arg)}}
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
@ -282,16 +283,17 @@ namespace dawn_wire {
|
|||||||
cmd.Serialize(allocatedBuffer, *device);
|
cmd.Serialize(allocatedBuffer, *device);
|
||||||
|
|
||||||
{% if method.return_type.category == "object" %}
|
{% if method.return_type.category == "object" %}
|
||||||
return allocation->object.get();
|
return reinterpret_cast<{{as_cType(method.return_type.name)}}>(allocation->object.get());
|
||||||
{% endif %}
|
{% endif %}
|
||||||
}
|
}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% if type.is_builder %}
|
{% if type.is_builder %}
|
||||||
void Client{{as_MethodSuffix(type.name, Name("set error callback"))}}({{Type}}* self,
|
void Client{{as_MethodSuffix(type.name, Name("set error callback"))}}({{cType}} cSelf,
|
||||||
dawnBuilderErrorCallback callback,
|
dawnBuilderErrorCallback callback,
|
||||||
dawnCallbackUserdata userdata1,
|
dawnCallbackUserdata userdata1,
|
||||||
dawnCallbackUserdata userdata2) {
|
dawnCallbackUserdata userdata2) {
|
||||||
|
{{Type}}* self = reinterpret_cast<{{Type}}*>(cSelf);
|
||||||
self->builderCallback.callback = callback;
|
self->builderCallback.callback = callback;
|
||||||
self->builderCallback.userdata1 = userdata1;
|
self->builderCallback.userdata1 = userdata1;
|
||||||
self->builderCallback.userdata2 = userdata2;
|
self->builderCallback.userdata2 = userdata2;
|
||||||
@ -300,7 +302,8 @@ namespace dawn_wire {
|
|||||||
|
|
||||||
{% if not type.name.canonical_case() == "device" %}
|
{% if not type.name.canonical_case() == "device" %}
|
||||||
//* When an object's refcount reaches 0, notify the server side of it and delete it.
|
//* When an object's refcount reaches 0, notify the server side of it and delete it.
|
||||||
void Client{{as_MethodSuffix(type.name, Name("release"))}}({{Type}}* obj) {
|
void Client{{as_MethodSuffix(type.name, Name("release"))}}({{cType}} cObj) {
|
||||||
|
{{Type}}* obj = reinterpret_cast<{{Type}}*>(cObj);
|
||||||
obj->refcount --;
|
obj->refcount --;
|
||||||
|
|
||||||
if (obj->refcount > 0) {
|
if (obj->refcount > 0) {
|
||||||
@ -318,13 +321,16 @@ namespace dawn_wire {
|
|||||||
obj->device->{{type.name.camelCase()}}.Free(obj);
|
obj->device->{{type.name.camelCase()}}.Free(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client{{as_MethodSuffix(type.name, Name("reference"))}}({{Type}}* obj) {
|
void Client{{as_MethodSuffix(type.name, Name("reference"))}}({{cType}} cObj) {
|
||||||
|
{{Type}}* obj = reinterpret_cast<{{Type}}*>(cObj);
|
||||||
obj->refcount ++;
|
obj->refcount ++;
|
||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
void ClientBufferMapReadAsync(Buffer* buffer, uint32_t start, uint32_t size, dawnBufferMapReadCallback callback, dawnCallbackUserdata userdata) {
|
void ClientBufferMapReadAsync(dawnBuffer cBuffer, uint32_t start, uint32_t size, dawnBufferMapReadCallback callback, dawnCallbackUserdata userdata) {
|
||||||
|
Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
|
||||||
|
|
||||||
uint32_t serial = buffer->requestSerial++;
|
uint32_t serial = buffer->requestSerial++;
|
||||||
ASSERT(buffer->requests.find(serial) == buffer->requests.end());
|
ASSERT(buffer->requests.find(serial) == buffer->requests.end());
|
||||||
|
|
||||||
@ -346,7 +352,9 @@ namespace dawn_wire {
|
|||||||
*allocCmd = cmd;
|
*allocCmd = cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientBufferMapWriteAsync(Buffer* buffer, uint32_t start, uint32_t size, dawnBufferMapWriteCallback callback, dawnCallbackUserdata userdata) {
|
void ClientBufferMapWriteAsync(dawnBuffer cBuffer, uint32_t start, uint32_t size, dawnBufferMapWriteCallback callback, dawnCallbackUserdata userdata) {
|
||||||
|
Buffer* buffer = reinterpret_cast<Buffer*>(cBuffer);
|
||||||
|
|
||||||
uint32_t serial = buffer->requestSerial++;
|
uint32_t serial = buffer->requestSerial++;
|
||||||
ASSERT(buffer->requests.find(serial) == buffer->requests.end());
|
ASSERT(buffer->requests.find(serial) == buffer->requests.end());
|
||||||
|
|
||||||
@ -401,13 +409,14 @@ namespace dawn_wire {
|
|||||||
ClientBufferUnmap(cBuffer);
|
ClientBufferUnmap(cBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientDeviceReference(Device*) {
|
void ClientDeviceReference(dawnDevice) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientDeviceRelease(Device*) {
|
void ClientDeviceRelease(dawnDevice) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientDeviceSetErrorCallback(Device* self, dawnDeviceErrorCallback callback, dawnCallbackUserdata userdata) {
|
void ClientDeviceSetErrorCallback(dawnDevice cSelf, dawnDeviceErrorCallback callback, dawnCallbackUserdata userdata) {
|
||||||
|
Device* self = reinterpret_cast<Device*>(cSelf);
|
||||||
self->errorCallback = callback;
|
self->errorCallback = callback;
|
||||||
self->errorUserdata = userdata;
|
self->errorUserdata = userdata;
|
||||||
}
|
}
|
||||||
@ -425,9 +434,9 @@ namespace dawn_wire {
|
|||||||
{% for method in native_methods(type) %}
|
{% for method in native_methods(type) %}
|
||||||
{% set suffix = as_MethodSuffix(type.name, method.name) %}
|
{% set suffix = as_MethodSuffix(type.name, method.name) %}
|
||||||
{% if suffix in proxied_commands %}
|
{% if suffix in proxied_commands %}
|
||||||
table.{{as_varName(type.name, method.name)}} = reinterpret_cast<{{as_cProc(type.name, method.name)}}>(ProxyClient{{suffix}});
|
table.{{as_varName(type.name, method.name)}} = ProxyClient{{suffix}};
|
||||||
{% else %}
|
{% else %}
|
||||||
table.{{as_varName(type.name, method.name)}} = reinterpret_cast<{{as_cProc(type.name, method.name)}}>(Client{{suffix}});
|
table.{{as_varName(type.name, method.name)}} = Client{{suffix}};
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user