Skip to content

Commit

Permalink
constant: Add support for other expressions WebRender uses.
Browse files Browse the repository at this point in the history
  • Loading branch information
emilio committed Apr 14, 2022
1 parent 882af0b commit 770f352
Show file tree
Hide file tree
Showing 11 changed files with 292 additions and 16 deletions.
90 changes: 84 additions & 6 deletions src/bindgen/ir/constant.rs
Expand Up @@ -27,6 +27,56 @@ fn member_to_ident(member: &syn::Member) -> String {
}
}

// TODO: Maybe add support to more std associated constants.
fn to_known_assoc_constant(associated_to: &Path, name: &str) -> Option<String> {
use crate::bindgen::ir::{IntKind, PrimitiveType};

if name != "MAX" && name != "MIN" {
return None;
}

let prim = PrimitiveType::maybe(associated_to.name())?;
let prefix = match prim {
PrimitiveType::Integer {
kind,
signed,
zeroable: _,
} => match kind {
IntKind::B8 => {
if signed {
"INT8"
} else {
"UINT8"
}
}
IntKind::B16 => {
if signed {
"INT16"
} else {
"UINT16"
}
}
IntKind::B32 => {
if signed {
"INT32"
} else {
"UINT32"
}
}
IntKind::B64 => {
if signed {
"INT64"
} else {
"UINT64"
}
}
_ => return None,
},
_ => return None,
};
Some(format!("{}_{}", prefix, name))
}

#[derive(Debug, Clone)]
pub enum Literal {
Expr(String),
Expand Down Expand Up @@ -112,10 +162,12 @@ impl Literal {
match *self {
Literal::Expr(..) => true,
Literal::Path {
ref associated_to, ..
ref associated_to,
ref name,
} => {
if let Some((ref path, _export_name)) = associated_to {
return bindings.struct_exists(path);
return bindings.struct_exists(path)
|| to_known_assoc_constant(path, name).is_some();
}
true
}
Expand Down Expand Up @@ -274,6 +326,30 @@ impl Literal {
field: member_to_ident(member),
}),

syn::Expr::Call(syn::ExprCall {
ref func, ref args, ..
}) => {
let struct_name = match Literal::load(func)? {
Literal::Path {
associated_to: None,
name,
} => name,
_ => return Err(format!("Unsupported call expression. {:?}", *expr)),
};
let mut fields = HashMap::<String, Literal>::default();
for (index, arg) in args.iter().enumerate() {
let ident =
member_to_ident(&syn::Member::Unnamed(syn::Index::from(index))).to_string();
let value = Literal::load(arg)?;
fields.insert(ident, value);
}
Ok(Literal::Struct {
path: Path::new(struct_name.clone()),
export_name: struct_name,
fields,
})
}

syn::Expr::Struct(syn::ExprStruct {
ref path,
ref fields,
Expand All @@ -282,10 +358,9 @@ impl Literal {
let struct_name = path.segments[0].ident.unraw().to_string();
let mut field_map = HashMap::<String, Literal>::default();
for field in fields {
let ident = member_to_ident(&field.member);
let key = ident.to_string();
let ident = member_to_ident(&field.member).to_string();
let value = Literal::load(&field.expr)?;
field_map.insert(key, value);
field_map.insert(ident, value);
}
Ok(Literal::Struct {
path: Path::new(struct_name.clone()),
Expand Down Expand Up @@ -357,7 +432,10 @@ impl Literal {
ref associated_to,
ref name,
} => {
if let Some((_, ref export_name)) = associated_to {
if let Some((ref path, ref export_name)) = associated_to {
if let Some(known) = to_known_assoc_constant(path, name) {
return write!(out, "{}", known);
}
let path_separator = match config.language {
Language::Cython | Language::C => "_",
Language::Cxx => {
Expand Down
23 changes: 22 additions & 1 deletion tests/expectations/associated_in_body.both.c
Expand Up @@ -35,4 +35,25 @@ typedef struct StyleAlignFlags {
#define StyleAlignFlags_MIXED (StyleAlignFlags){ .bits = (uint8_t)(((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }
#define StyleAlignFlags_MIXED_SELF (StyleAlignFlags){ .bits = (uint8_t)(((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }

void root(struct StyleAlignFlags flags);
/**
* An arbitrary identifier for a native (OS compositor) surface
*/
typedef struct StyleNativeSurfaceId {
uint64_t _0;
} StyleNativeSurfaceId;
/**
* A special id for the native surface that is used for debug / profiler overlays.
*/
#define StyleNativeSurfaceId_DEBUG_OVERLAY (StyleNativeSurfaceId){ ._0 = UINT64_MAX }

typedef struct StyleNativeTileId {
struct StyleNativeSurfaceId surface_id;
int32_t x;
int32_t y;
} StyleNativeTileId;
/**
* A special id for the native surface that is used for debug / profiler overlays.
*/
#define StyleNativeTileId_DEBUG_OVERLAY (StyleNativeTileId){ .surface_id = StyleNativeSurfaceId_DEBUG_OVERLAY, .x = 0, .y = 0 }

void root(struct StyleAlignFlags flags, struct StyleNativeTileId tile);
23 changes: 22 additions & 1 deletion tests/expectations/associated_in_body.both.compat.c
Expand Up @@ -35,11 +35,32 @@ typedef struct StyleAlignFlags {
#define StyleAlignFlags_MIXED (StyleAlignFlags){ .bits = (uint8_t)(((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }
#define StyleAlignFlags_MIXED_SELF (StyleAlignFlags){ .bits = (uint8_t)(((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }

/**
* An arbitrary identifier for a native (OS compositor) surface
*/
typedef struct StyleNativeSurfaceId {
uint64_t _0;
} StyleNativeSurfaceId;
/**
* A special id for the native surface that is used for debug / profiler overlays.
*/
#define StyleNativeSurfaceId_DEBUG_OVERLAY (StyleNativeSurfaceId){ ._0 = UINT64_MAX }

typedef struct StyleNativeTileId {
struct StyleNativeSurfaceId surface_id;
int32_t x;
int32_t y;
} StyleNativeTileId;
/**
* A special id for the native surface that is used for debug / profiler overlays.
*/
#define StyleNativeTileId_DEBUG_OVERLAY (StyleNativeTileId){ .surface_id = StyleNativeSurfaceId_DEBUG_OVERLAY, .x = 0, .y = 0 }

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

void root(struct StyleAlignFlags flags);
void root(struct StyleAlignFlags flags, struct StyleNativeTileId tile);

#ifdef __cplusplus
} // extern "C"
Expand Down
23 changes: 22 additions & 1 deletion tests/expectations/associated_in_body.c
Expand Up @@ -35,4 +35,25 @@ typedef struct {
#define StyleAlignFlags_MIXED (StyleAlignFlags){ .bits = (uint8_t)(((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }
#define StyleAlignFlags_MIXED_SELF (StyleAlignFlags){ .bits = (uint8_t)(((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }

void root(StyleAlignFlags flags);
/**
* An arbitrary identifier for a native (OS compositor) surface
*/
typedef struct {
uint64_t _0;
} StyleNativeSurfaceId;
/**
* A special id for the native surface that is used for debug / profiler overlays.
*/
#define StyleNativeSurfaceId_DEBUG_OVERLAY (StyleNativeSurfaceId){ ._0 = UINT64_MAX }

typedef struct {
StyleNativeSurfaceId surface_id;
int32_t x;
int32_t y;
} StyleNativeTileId;
/**
* A special id for the native surface that is used for debug / profiler overlays.
*/
#define StyleNativeTileId_DEBUG_OVERLAY (StyleNativeTileId){ .surface_id = StyleNativeSurfaceId_DEBUG_OVERLAY, .x = 0, .y = 0 }

void root(StyleAlignFlags flags, StyleNativeTileId tile);
23 changes: 22 additions & 1 deletion tests/expectations/associated_in_body.compat.c
Expand Up @@ -35,11 +35,32 @@ typedef struct {
#define StyleAlignFlags_MIXED (StyleAlignFlags){ .bits = (uint8_t)(((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }
#define StyleAlignFlags_MIXED_SELF (StyleAlignFlags){ .bits = (uint8_t)(((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }

/**
* An arbitrary identifier for a native (OS compositor) surface
*/
typedef struct {
uint64_t _0;
} StyleNativeSurfaceId;
/**
* A special id for the native surface that is used for debug / profiler overlays.
*/
#define StyleNativeSurfaceId_DEBUG_OVERLAY (StyleNativeSurfaceId){ ._0 = UINT64_MAX }

typedef struct {
StyleNativeSurfaceId surface_id;
int32_t x;
int32_t y;
} StyleNativeTileId;
/**
* A special id for the native surface that is used for debug / profiler overlays.
*/
#define StyleNativeTileId_DEBUG_OVERLAY (StyleNativeTileId){ .surface_id = StyleNativeSurfaceId_DEBUG_OVERLAY, .x = 0, .y = 0 }

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

void root(StyleAlignFlags flags);
void root(StyleAlignFlags flags, StyleNativeTileId tile);

#ifdef __cplusplus
} // extern "C"
Expand Down
19 changes: 18 additions & 1 deletion tests/expectations/associated_in_body.cpp
Expand Up @@ -60,8 +60,25 @@ inline const StyleAlignFlags StyleAlignFlags::FLEX_START = StyleAlignFlags{ /* .
inline const StyleAlignFlags StyleAlignFlags::MIXED = StyleAlignFlags{ /* .bits = */ (uint8_t)(((1 << 4) | (StyleAlignFlags::FLEX_START).bits) | (StyleAlignFlags::END).bits) };
inline const StyleAlignFlags StyleAlignFlags::MIXED_SELF = StyleAlignFlags{ /* .bits = */ (uint8_t)(((1 << 5) | (StyleAlignFlags::FLEX_START).bits) | (StyleAlignFlags::END).bits) };

/// An arbitrary identifier for a native (OS compositor) surface
struct StyleNativeSurfaceId {
uint64_t _0;
static const StyleNativeSurfaceId DEBUG_OVERLAY;
};
/// A special id for the native surface that is used for debug / profiler overlays.
inline const StyleNativeSurfaceId StyleNativeSurfaceId::DEBUG_OVERLAY = StyleNativeSurfaceId{ /* ._0 = */ UINT64_MAX };

struct StyleNativeTileId {
StyleNativeSurfaceId surface_id;
int32_t x;
int32_t y;
static const StyleNativeTileId DEBUG_OVERLAY;
};
/// A special id for the native surface that is used for debug / profiler overlays.
inline const StyleNativeTileId StyleNativeTileId::DEBUG_OVERLAY = StyleNativeTileId{ /* .surface_id = */ StyleNativeSurfaceId::DEBUG_OVERLAY, /* .x = */ 0, /* .y = */ 0 };

extern "C" {

void root(StyleAlignFlags flags);
void root(StyleAlignFlags flags, StyleNativeTileId tile);

} // extern "C"
15 changes: 14 additions & 1 deletion tests/expectations/associated_in_body.pyx
Expand Up @@ -25,4 +25,17 @@ cdef extern from *:
const StyleAlignFlags StyleAlignFlags_MIXED # = <StyleAlignFlags>{ <uint8_t>(((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }
const StyleAlignFlags StyleAlignFlags_MIXED_SELF # = <StyleAlignFlags>{ <uint8_t>(((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }

void root(StyleAlignFlags flags);
# An arbitrary identifier for a native (OS compositor) surface
ctypedef struct StyleNativeSurfaceId:
uint64_t _0;
# A special id for the native surface that is used for debug / profiler overlays.
const StyleNativeSurfaceId StyleNativeSurfaceId_DEBUG_OVERLAY # = <StyleNativeSurfaceId>{ UINT64_MAX }

ctypedef struct StyleNativeTileId:
StyleNativeSurfaceId surface_id;
int32_t x;
int32_t y;
# A special id for the native surface that is used for debug / profiler overlays.
const StyleNativeTileId StyleNativeTileId_DEBUG_OVERLAY # = <StyleNativeTileId>{ StyleNativeSurfaceId_DEBUG_OVERLAY, 0, 0 }

void root(StyleAlignFlags flags, StyleNativeTileId tile);
23 changes: 22 additions & 1 deletion tests/expectations/associated_in_body.tag.c
Expand Up @@ -35,4 +35,25 @@ struct StyleAlignFlags {
#define StyleAlignFlags_MIXED (StyleAlignFlags){ .bits = (uint8_t)(((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }
#define StyleAlignFlags_MIXED_SELF (StyleAlignFlags){ .bits = (uint8_t)(((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }

void root(struct StyleAlignFlags flags);
/**
* An arbitrary identifier for a native (OS compositor) surface
*/
struct StyleNativeSurfaceId {
uint64_t _0;
};
/**
* A special id for the native surface that is used for debug / profiler overlays.
*/
#define StyleNativeSurfaceId_DEBUG_OVERLAY (StyleNativeSurfaceId){ ._0 = UINT64_MAX }

struct StyleNativeTileId {
struct StyleNativeSurfaceId surface_id;
int32_t x;
int32_t y;
};
/**
* A special id for the native surface that is used for debug / profiler overlays.
*/
#define StyleNativeTileId_DEBUG_OVERLAY (StyleNativeTileId){ .surface_id = StyleNativeSurfaceId_DEBUG_OVERLAY, .x = 0, .y = 0 }

void root(struct StyleAlignFlags flags, struct StyleNativeTileId tile);
23 changes: 22 additions & 1 deletion tests/expectations/associated_in_body.tag.compat.c
Expand Up @@ -35,11 +35,32 @@ struct StyleAlignFlags {
#define StyleAlignFlags_MIXED (StyleAlignFlags){ .bits = (uint8_t)(((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }
#define StyleAlignFlags_MIXED_SELF (StyleAlignFlags){ .bits = (uint8_t)(((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }

/**
* An arbitrary identifier for a native (OS compositor) surface
*/
struct StyleNativeSurfaceId {
uint64_t _0;
};
/**
* A special id for the native surface that is used for debug / profiler overlays.
*/
#define StyleNativeSurfaceId_DEBUG_OVERLAY (StyleNativeSurfaceId){ ._0 = UINT64_MAX }

struct StyleNativeTileId {
struct StyleNativeSurfaceId surface_id;
int32_t x;
int32_t y;
};
/**
* A special id for the native surface that is used for debug / profiler overlays.
*/
#define StyleNativeTileId_DEBUG_OVERLAY (StyleNativeTileId){ .surface_id = StyleNativeSurfaceId_DEBUG_OVERLAY, .x = 0, .y = 0 }

#ifdef __cplusplus
extern "C" {
#endif // __cplusplus

void root(struct StyleAlignFlags flags);
void root(struct StyleAlignFlags flags, struct StyleNativeTileId tile);

#ifdef __cplusplus
} // extern "C"
Expand Down
15 changes: 14 additions & 1 deletion tests/expectations/associated_in_body.tag.pyx
Expand Up @@ -25,4 +25,17 @@ cdef extern from *:
const StyleAlignFlags StyleAlignFlags_MIXED # = <StyleAlignFlags>{ <uint8_t>(((1 << 4) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }
const StyleAlignFlags StyleAlignFlags_MIXED_SELF # = <StyleAlignFlags>{ <uint8_t>(((1 << 5) | (StyleAlignFlags_FLEX_START).bits) | (StyleAlignFlags_END).bits) }

void root(StyleAlignFlags flags);
# An arbitrary identifier for a native (OS compositor) surface
cdef struct StyleNativeSurfaceId:
uint64_t _0;
# A special id for the native surface that is used for debug / profiler overlays.
const StyleNativeSurfaceId StyleNativeSurfaceId_DEBUG_OVERLAY # = <StyleNativeSurfaceId>{ UINT64_MAX }

cdef struct StyleNativeTileId:
StyleNativeSurfaceId surface_id;
int32_t x;
int32_t y;
# A special id for the native surface that is used for debug / profiler overlays.
const StyleNativeTileId StyleNativeTileId_DEBUG_OVERLAY # = <StyleNativeTileId>{ StyleNativeSurfaceId_DEBUG_OVERLAY, 0, 0 }

void root(StyleAlignFlags flags, StyleNativeTileId tile);

0 comments on commit 770f352

Please sign in to comment.