summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2016-11-27 14:17:11 (GMT)
committer Vincent Sanders <vince@kyllikki.org>2016-11-27 14:17:11 (GMT)
commit3b3b926d7fb92361b1e8eed2efb351c32cb7bfaa (patch)
treed8a7a0170c7627b12a5b55fa263134c784a3d071
parentab1f1cb380783ce4e9c87632daad2cf08ca22da5 (diff)
downloadnsgenbind-3b3b926d7fb92361b1e8eed2efb351c32cb7bfaa.tar.gz
nsgenbind-3b3b926d7fb92361b1e8eed2efb351c32cb7bfaa.tar.bz2
restructure AST node creation to avoid casts
This changes Abstract Syntax Tree node creation for both webidl and genbind syntax tress. If a node is to be created with a numeric value instead of a pointer a separate API is now used instead of casting through void. This fixes parsing and AST building on big endian 64bit platforms where casting through void, which is completely undefined behaviour, generates different and non-functioning code. The solution in this patch is properly portable and correct without relying on casting at all. Thanks to James Clarke <jrtc27@jrtc27.com> for the original debugging and patch demonstrating how to work round the bug.
-rw-r--r--src/nsgenbind-ast.c13
-rw-r--r--src/nsgenbind-ast.h11
-rw-r--r--src/nsgenbind-parser.y22
-rw-r--r--src/webidl-ast.c17
-rw-r--r--src/webidl-ast.h9
-rw-r--r--src/webidl-parser.y150
6 files changed, 153 insertions, 69 deletions
diff --git a/src/nsgenbind-ast.c b/src/nsgenbind-ast.c
index 49732a0..f78fe26 100644
--- a/src/nsgenbind-ast.c
+++ b/src/nsgenbind-ast.c
@@ -132,6 +132,19 @@ genbind_new_node(enum genbind_node_type type, struct genbind_node *l, void *r)
return nn;
}
+struct genbind_node *
+genbind_new_number_node(enum genbind_node_type type,
+ struct genbind_node *l,
+ int number)
+{
+ struct genbind_node *nn;
+ nn = calloc(1, sizeof(struct genbind_node));
+ nn->type = type;
+ nn->l = l;
+ nn->r.number = number;
+ return nn;
+}
+
/* exported interface defined in nsgenbind-ast.h */
int
diff --git a/src/nsgenbind-ast.h b/src/nsgenbind-ast.h
index 49db23b..6fb7221 100644
--- a/src/nsgenbind-ast.h
+++ b/src/nsgenbind-ast.h
@@ -71,7 +71,18 @@ int genbind_parsefile(char *infilename, struct genbind_node **ast);
char *genbind_strapp(char *a, char *b);
+/**
+ * create a new node with value from pointer
+ */
struct genbind_node *genbind_new_node(enum genbind_node_type type, struct genbind_node *l, void *r);
+
+/**
+ * create a new number node
+ *
+ * Create a node with of number type
+ */
+struct genbind_node *genbind_new_number_node(enum genbind_node_type type, struct genbind_node *l, int number);
+
struct genbind_node *genbind_node_link(struct genbind_node *tgt, struct genbind_node *src);
struct genbind_node *genbind_node_prepend(struct genbind_node *list, struct genbind_node *inst);
diff --git a/src/nsgenbind-parser.y b/src/nsgenbind-parser.y
index c6b9a74..fd41c37 100644
--- a/src/nsgenbind-parser.y
+++ b/src/nsgenbind-parser.y
@@ -138,17 +138,17 @@ add_method(struct genbind_node **genbind_ast,
}
location_node = genbind_new_node(GENBIND_NODE_TYPE_FILE,
- genbind_new_node(GENBIND_NODE_TYPE_LINE,
- cdata_node,
- (void *)lineno),
+ genbind_new_number_node(GENBIND_NODE_TYPE_LINE,
+ cdata_node,
+ lineno),
strdup(filename));
/* generate method node */
method_node = genbind_new_node(GENBIND_NODE_TYPE_METHOD,
NULL,
- genbind_new_node(GENBIND_NODE_TYPE_METHOD_TYPE,
+ genbind_new_number_node(GENBIND_NODE_TYPE_METHOD_TYPE,
location_node,
- (void *)methodtype));
+ methodtype));
class_node = genbind_node_find_type_ident(*genbind_ast,
NULL,
@@ -304,11 +304,11 @@ BindingArg:
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_METHOD,
NULL,
- genbind_new_node(GENBIND_NODE_TYPE_METHOD_TYPE,
+ genbind_new_number_node(GENBIND_NODE_TYPE_METHOD_TYPE,
genbind_new_node(GENBIND_NODE_TYPE_CDATA,
NULL,
$2),
- (void *)$1));
+ $1));
}
;
@@ -568,11 +568,11 @@ ClassArg:
TOK_PROPERTY Modifiers TOK_IDENTIFIER ';'
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_PROPERTY, NULL,
- genbind_new_node(GENBIND_NODE_TYPE_MODIFIER,
+ genbind_new_number_node(GENBIND_NODE_TYPE_MODIFIER,
genbind_new_node(GENBIND_NODE_TYPE_IDENT,
NULL,
$3),
- (void *)$2));
+ $2));
}
|
TOK_FLAGS ClassFlags ';'
@@ -584,11 +584,11 @@ ClassArg:
{
$$ = genbind_new_node(GENBIND_NODE_TYPE_METHOD,
NULL,
- genbind_new_node(GENBIND_NODE_TYPE_METHOD_TYPE,
+ genbind_new_number_node(GENBIND_NODE_TYPE_METHOD_TYPE,
genbind_new_node(GENBIND_NODE_TYPE_CDATA,
NULL,
$2),
- (void *)$1));
+ $1));
}
;
diff --git a/src/webidl-ast.c b/src/webidl-ast.c
index 0d908ce..a1133e3 100644
--- a/src/webidl-ast.c
+++ b/src/webidl-ast.c
@@ -120,6 +120,7 @@ webidl_node_add(struct webidl_node *node, struct webidl_node *list)
struct webidl_node *
+/* exported interface documented in webidl-ast.h */
webidl_node_new(enum webidl_node_type type,
struct webidl_node *l,
void *r)
@@ -128,7 +129,21 @@ webidl_node_new(enum webidl_node_type type,
nn = calloc(1, sizeof(struct webidl_node));
nn->type = type;
nn->l = l;
- nn->r.text = r;
+ nn->r.value = r;
+ return nn;
+}
+
+/* exported interface documented in webidl-ast.h */
+struct webidl_node *
+webidl_new_number_node(enum webidl_node_type type,
+ struct webidl_node *l,
+ int number)
+{
+ struct webidl_node *nn;
+ nn = calloc(1, sizeof(struct webidl_node));
+ nn->type = type;
+ nn->l = l;
+ nn->r.number = number;
return nn;
}
diff --git a/src/webidl-ast.h b/src/webidl-ast.h
index bd9b313..fad070b 100644
--- a/src/webidl-ast.h
+++ b/src/webidl-ast.h
@@ -92,8 +92,17 @@ typedef int (webidl_callback_t)(struct webidl_node *node, void *ctx);
int webidl_cmp_node_type(struct webidl_node *node, void *ctx);
+/**
+ * create a new node with a pointer value
+ */
struct webidl_node *webidl_node_new(enum webidl_node_type, struct webidl_node *l, void *r);
+/**
+ * create a new node with an integer value
+ */
+struct webidl_node *webidl_new_number_node(enum webidl_node_type type, struct webidl_node *l, int number);
+
+
void webidl_node_set(struct webidl_node *node, enum webidl_node_type type, void *r);
struct webidl_node *webidl_node_prepend(struct webidl_node *list, struct webidl_node *node);
diff --git a/src/webidl-parser.y b/src/webidl-parser.y
index ec3309c..0e46b17 100644
--- a/src/webidl-parser.y
+++ b/src/webidl-parser.y
@@ -735,9 +735,9 @@ ConstValue:
|
TOK_INT_LITERAL
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_LITERAL_INT,
- NULL,
- (void *)$1);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_LITERAL_INT,
+ NULL,
+ $1);
}
|
TOK_NULL_LITERAL
@@ -750,16 +750,16 @@ ConstValue:
BooleanLiteral:
TOK_TRUE
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_LITERAL_BOOL,
- NULL,
- (void *)true);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_LITERAL_BOOL,
+ NULL,
+ (int)true);
}
|
TOK_FALSE
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_LITERAL_BOOL,
- NULL,
- (void *)false);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_LITERAL_BOOL,
+ NULL,
+ (int)false);
}
;
@@ -846,16 +846,18 @@ Attribute:
/* deal with inherit modifier */
if ($1) {
- attribute = webidl_node_new(WEBIDL_NODE_TYPE_MODIFIER,
+ attribute = webidl_new_number_node(
+ WEBIDL_NODE_TYPE_MODIFIER,
attribute,
- (void *)WEBIDL_TYPE_MODIFIER_INHERIT);
+ WEBIDL_TYPE_MODIFIER_INHERIT);
}
/* deal with readonly modifier */
if ($2) {
- attribute = webidl_node_new(WEBIDL_NODE_TYPE_MODIFIER,
+ attribute = webidl_new_number_node(
+ WEBIDL_NODE_TYPE_MODIFIER,
attribute,
- (void *)WEBIDL_TYPE_MODIFIER_READONLY);
+ WEBIDL_TYPE_MODIFIER_READONLY);
}
$$ = webidl_node_new(WEBIDL_NODE_TYPE_ATTRIBUTE,
@@ -880,14 +882,16 @@ StaticMemberRest:
{
struct webidl_node *attribute;
- attribute = webidl_node_new(WEBIDL_NODE_TYPE_MODIFIER,
- $2, (void *)WEBIDL_TYPE_MODIFIER_STATIC);
+ attribute = webidl_new_number_node(WEBIDL_NODE_TYPE_MODIFIER,
+ $2,
+ WEBIDL_TYPE_MODIFIER_STATIC);
/* deal with readonly modifier */
if ($1) {
- attribute = webidl_node_new(WEBIDL_NODE_TYPE_MODIFIER,
+ attribute = webidl_new_number_node(
+ WEBIDL_NODE_TYPE_MODIFIER,
attribute,
- (void *)WEBIDL_TYPE_MODIFIER_READONLY);
+ WEBIDL_TYPE_MODIFIER_READONLY);
}
$$ = webidl_node_new(WEBIDL_NODE_TYPE_ATTRIBUTE,
@@ -900,8 +904,9 @@ StaticMemberRest:
struct webidl_node *operation;
/* add static modifier */
- operation = webidl_node_new(WEBIDL_NODE_TYPE_MODIFIER,
- $2, (void *)WEBIDL_TYPE_MODIFIER_STATIC);
+ operation = webidl_new_number_node(WEBIDL_NODE_TYPE_MODIFIER,
+ $2,
+ WEBIDL_TYPE_MODIFIER_STATIC);
/* put return type on the operation */
operation = webidl_node_prepend($1, operation);
@@ -1015,16 +1020,16 @@ Specials:
Special:
TOK_GETTER
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_SPECIAL,
- NULL,
- (void *)WEBIDL_TYPE_SPECIAL_GETTER);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_SPECIAL,
+ NULL,
+ WEBIDL_TYPE_SPECIAL_GETTER);
}
|
TOK_SETTER
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_SPECIAL,
- NULL,
- (void *)WEBIDL_TYPE_SPECIAL_SETTER);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_SPECIAL,
+ NULL,
+ WEBIDL_TYPE_SPECIAL_SETTER);
}
|
TOK_CREATOR
@@ -1032,23 +1037,23 @@ Special:
/* second edition removed this special but the
* specifications still use it!
*/
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_SPECIAL,
- NULL,
- (void *)WEBIDL_TYPE_SPECIAL_CREATOR);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_SPECIAL,
+ NULL,
+ WEBIDL_TYPE_SPECIAL_CREATOR);
}
|
TOK_DELETER
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_SPECIAL,
- NULL,
- (void *)WEBIDL_TYPE_SPECIAL_DELETER);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_SPECIAL,
+ NULL,
+ WEBIDL_TYPE_SPECIAL_DELETER);
}
|
TOK_LEGACYCALLER
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_SPECIAL,
- NULL,
- (void *)WEBIDL_TYPE_SPECIAL_LEGACYCALLER);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_SPECIAL,
+ NULL,
+ WEBIDL_TYPE_SPECIAL_LEGACYCALLER);
}
;
@@ -1679,8 +1684,9 @@ SingleType:
TOK_ANY TypeSuffixStartingWithArray
{
/* todo deal with TypeSuffixStartingWithArray */
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE,
- NULL, (void *)WEBIDL_TYPE_ANY);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ NULL,
+ WEBIDL_TYPE_ANY);
}
;
@@ -1742,29 +1748,39 @@ NonAnyType:
|
TOK_STRING TypeSuffix
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, $2, (void *)WEBIDL_TYPE_STRING);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ $2,
+ WEBIDL_TYPE_STRING);
}
|
TOK_IDENTIFIER TypeSuffix
{
struct webidl_node *type;
- type = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, $2, (void *)WEBIDL_TYPE_USER);
+ type = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ $2,
+ WEBIDL_TYPE_USER);
$$ = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, type, $1);
}
|
TOK_SEQUENCE '<' Type '>' Null
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, $3, (void *)WEBIDL_TYPE_SEQUENCE);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ $3,
+ WEBIDL_TYPE_SEQUENCE);
}
|
TOK_OBJECT TypeSuffix
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, $2, (void *)WEBIDL_TYPE_OBJECT);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ $2,
+ WEBIDL_TYPE_OBJECT);
}
|
TOK_DATE TypeSuffix
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, $2, (void *)WEBIDL_TYPE_DATE);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ $2,
+ WEBIDL_TYPE_DATE);
}
;
@@ -1778,7 +1794,9 @@ ConstType:
TOK_IDENTIFIER Null
{
struct webidl_node *type;
- type = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_USER);
+ type = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ NULL,
+ WEBIDL_TYPE_USER);
type = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, type, $1);
$$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE, NULL, type);
}
@@ -1793,17 +1811,23 @@ PrimitiveType:
|
TOK_BOOLEAN
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_BOOL);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ NULL,
+ WEBIDL_TYPE_BOOL);
}
|
TOK_BYTE
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_BYTE);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ NULL,
+ WEBIDL_TYPE_BYTE);
}
|
TOK_OCTET
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_OCTET);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ NULL,
+ WEBIDL_TYPE_OCTET);
}
;
@@ -1811,9 +1835,9 @@ PrimitiveType:
UnrestrictedFloatType:
TOK_UNRESTRICTED FloatType
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_MODIFIER,
- $2,
- (void *)WEBIDL_TYPE_MODIFIER_UNRESTRICTED);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_MODIFIER,
+ $2,
+ WEBIDL_TYPE_MODIFIER_UNRESTRICTED);
}
|
FloatType
@@ -1823,12 +1847,16 @@ UnrestrictedFloatType:
FloatType:
TOK_FLOAT
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_FLOAT);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ NULL,
+ WEBIDL_TYPE_FLOAT);
}
|
TOK_DOUBLE
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_DOUBLE);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ NULL,
+ WEBIDL_TYPE_DOUBLE);
}
;
@@ -1836,9 +1864,9 @@ FloatType:
UnsignedIntegerType:
TOK_UNSIGNED IntegerType
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_MODIFIER,
- $2,
- (void *)WEBIDL_TYPE_MODIFIER_UNSIGNED);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_MODIFIER,
+ $2,
+ WEBIDL_TYPE_MODIFIER_UNSIGNED);
}
|
IntegerType
@@ -1848,15 +1876,21 @@ UnsignedIntegerType:
IntegerType:
TOK_SHORT
{
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_SHORT);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ NULL,
+ WEBIDL_TYPE_SHORT);
}
|
TOK_LONG OptionalLong
{
if ($2) {
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_LONGLONG);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ NULL,
+ WEBIDL_TYPE_LONGLONG);
} else {
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_LONG);
+ $$ = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ NULL,
+ WEBIDL_TYPE_LONG);
}
}
;
@@ -1927,7 +1961,9 @@ ReturnType:
TOK_VOID
{
struct webidl_node *type;
- type = webidl_node_new(WEBIDL_NODE_TYPE_TYPE_BASE, NULL, (void *)WEBIDL_TYPE_VOID);
+ type = webidl_new_number_node(WEBIDL_NODE_TYPE_TYPE_BASE,
+ NULL,
+ WEBIDL_TYPE_VOID);
$$ = webidl_node_new(WEBIDL_NODE_TYPE_TYPE, NULL, type);
}