Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AP_Scripting: load uint32_t via generator #20693

Merged
merged 4 commits into from May 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 21 additions & 0 deletions libraries/AP_Scripting/generator/description/bindings.desc
Expand Up @@ -524,3 +524,24 @@ singleton i2c manual get_device lua_get_i2c_device
global manual millis lua_millis
global manual micros lua_micros
global manual mission_receive lua_mission_receive

userdata uint32_t creation lua_new_uint32_t
userdata uint32_t manual_operator __add uint32_t___add
userdata uint32_t manual_operator __sub uint32_t___sub
userdata uint32_t manual_operator __mul uint32_t___mul
userdata uint32_t manual_operator __div uint32_t___div
userdata uint32_t manual_operator __mod uint32_t___mod
userdata uint32_t manual_operator __idiv uint32_t___idiv
userdata uint32_t manual_operator __band uint32_t___band
userdata uint32_t manual_operator __bor uint32_t___bor
userdata uint32_t manual_operator __bxor uint32_t___bxor
userdata uint32_t manual_operator __shl uint32_t___shl
userdata uint32_t manual_operator __shr uint32_t___shr
userdata uint32_t manual_operator __eq uint32_t___eq
userdata uint32_t manual_operator __lt uint32_t___lt
userdata uint32_t manual_operator __le uint32_t___le
userdata uint32_t manual_operator __bnot uint32_t___bnot
userdata uint32_t manual_operator __tostring uint32_t___tostring
userdata uint32_t manual toint uint32_t_toint
userdata uint32_t manual tofloat uint32_t_tofloat

102 changes: 52 additions & 50 deletions libraries/AP_Scripting/generator/src/main.c
Expand Up @@ -29,6 +29,8 @@ char keyword_reference[] = "reference";
char keyword_deprecate[] = "deprecate";
char keyword_manual[] = "manual";
char keyword_global[] = "global";
char keyword_creation[] = "creation";
char keyword_manual_operator[] = "manual_operator";

// attributes (should include the leading ' )
char keyword_attr_enum[] = "'enum";
Expand Down Expand Up @@ -135,6 +137,7 @@ enum operator_type {
OP_SUB = (1U << 1),
OP_MUL = (1U << 2),
OP_DIV = (1U << 3),
OP_MANUAL = (1U << 4),
OP_LAST
};

Expand Down Expand Up @@ -351,12 +354,18 @@ struct method {
uint32_t flags; // filled out with TYPE_FLAGS
};

enum alias_type {
ALIAS_TYPE_NONE,
ALIAS_TYPE_MANUAL,
ALIAS_TYPE_MANUAL_OPERATOR,
};

struct method_alias {
struct method_alias *next;
char *name;
char *alias;
int line;
int is_manual;
enum alias_type type;
};

struct userdata_field {
Expand Down Expand Up @@ -395,6 +404,7 @@ struct userdata {
uint32_t operations; // bitset of enum operation_types
int flags; // flags from the userdata_flags enum
char *dependency;
char *creation; // name of a manual creation function if set, note that this will not be used internally
};

static struct userdata *parsed_userdata;
Expand Down Expand Up @@ -825,7 +835,7 @@ void handle_method(struct userdata *node) {
}
}

void handle_manual(struct userdata *node) {
void handle_manual(struct userdata *node, enum alias_type type) {
char *name = next_token();
if (name == NULL) {
error(ERROR_SINGLETON, "Expected a lua name for manual %s method",node->name);
Expand All @@ -838,7 +848,7 @@ void handle_manual(struct userdata *node) {
string_copy(&(alias->name), cpp_function_name);
string_copy(&(alias->alias), name);
alias->line = state.line_num;
alias->is_manual = 1;
alias->type = type;
alias->next = node->method_aliases;
node->method_aliases = alias;
}
Expand Down Expand Up @@ -939,6 +949,23 @@ void handle_userdata(void) {
}
string_copy(&(node->dependency), depends);

} else if (strcmp(type, keyword_manual) == 0) {
handle_manual(node, ALIAS_TYPE_MANUAL);

} else if (strcmp(type, keyword_creation) == 0) {
if (node->creation != NULL) {
error(ERROR_SINGLETON, "Userdata only support a single creation function");
}
char *creation = strtok(NULL, "");
if (creation == NULL) {
error(ERROR_USERDATA, "Expected a creation string for %s",node->name);
}
string_copy(&(node->creation), creation);

} else if (strcmp(type, keyword_manual_operator) == 0) {
handle_manual(node, ALIAS_TYPE_MANUAL_OPERATOR);
node->operations |= OP_MANUAL;

} else {
error(ERROR_USERDATA, "Unknown or unsupported type for userdata: %s", type);
}
Expand Down Expand Up @@ -1014,7 +1041,7 @@ void handle_singleton(void) {
} else if (strcmp(type, keyword_reference) == 0) {
node->flags |= UD_FLAG_REFERENCE;
} else if (strcmp(type, keyword_manual) == 0) {
handle_manual(node);
handle_manual(node, ALIAS_TYPE_MANUAL);
} else {
error(ERROR_SINGLETON, "Singletons only support renames, methods, semaphore, depends, literal or manual keywords (got %s)", type);
}
Expand Down Expand Up @@ -1116,7 +1143,7 @@ void handle_global(void) {
}

if (strcmp(type, keyword_manual) == 0) {
handle_manual(parsed_globals);
handle_manual(parsed_globals, ALIAS_TYPE_MANUAL);
} else {
error(ERROR_GLOBALS, "globals only support manual keyword (got %s)", type);
}
Expand All @@ -1130,7 +1157,7 @@ void handle_global(void) {
void sanity_check_userdata(void) {
struct userdata * node = parsed_userdata;
while(node) {
if ((node->fields == NULL) && (node->methods == NULL)) {
if ((node->fields == NULL) && (node->methods == NULL) && (node->method_aliases == NULL)) {
error(ERROR_USERDATA, "Userdata %s has no fields or methods", node->name);
}
node = node->next;
Expand Down Expand Up @@ -2008,6 +2035,7 @@ const char * get_name_for_operation(enum operator_type op) {
case OP_DIV:
return "__div";
break;
case OP_MANUAL:
case OP_LAST:
return NULL;
}
Expand Down Expand Up @@ -2039,6 +2067,7 @@ void emit_operators(struct userdata *data) {
case OP_DIV:
op_sym = '/';
break;
case OP_MANUAL:
case OP_LAST:
return;
}
Expand Down Expand Up @@ -2076,40 +2105,6 @@ void emit_methods(struct userdata *node) {
}
}

void emit_userdata_metatables(void) {
struct userdata * node = parsed_userdata;
while(node) {
start_dependency(source, node->dependency);
fprintf(source, "const luaL_Reg %s_meta[] = {\n", node->sanatized_name);

struct userdata_field *field = node->fields;
while(field) {
fprintf(source, " {\"%s\", %s_%s},\n", field->rename ? field->rename : field->name, node->sanatized_name, field->name);
field = field->next;
}

struct method *method = node->methods;
while(method) {
fprintf(source, " {\"%s\", %s_%s},\n", method->rename ? method->rename : method->name, node->sanatized_name, method->sanatized_name);
method = method->next;
}

for (uint32_t i = 1; i < OP_LAST; i = i << 1) {
const char * op_name = get_name_for_operation((node->operations) & i);
if (op_name == NULL) {
continue;
}
fprintf(source, " {\"%s\", %s_%s},\n", op_name, node->sanatized_name, op_name);
}

fprintf(source, " {NULL, NULL}\n");
fprintf(source, "};\n");
end_dependency(source, node->dependency);
fprintf(source, "\n");
node = node->next;
}
}

void emit_enum(struct userdata * data) {
fprintf(source, "struct userdata_enum %s_enums[] = {\n", data->sanatized_name);
struct userdata_enum *ud_enum = data->enums;
Expand Down Expand Up @@ -2142,9 +2137,9 @@ void emit_index(struct userdata *head) {

struct method_alias *alias = node->method_aliases;
while(alias) {
if (alias->is_manual) {
if (alias->type == ALIAS_TYPE_MANUAL) {
fprintf(source, " {\"%s\", %s},\n", alias->alias, alias->name);
} else {
} else if (alias->type == ALIAS_TYPE_NONE) {
fprintf(source, " {\"%s\", %s_%s},\n", alias->alias, node->sanatized_name, alias->name);
}
alias = alias->next;
Expand All @@ -2161,6 +2156,13 @@ void emit_index(struct userdata *head) {
}
fprintf(source, " {\"%s\", %s_%s},\n", op_name, node->sanatized_name, op_name);
}
struct method_alias *alias = node->method_aliases;
while(alias) {
if (alias->type == ALIAS_TYPE_MANUAL_OPERATOR) {
fprintf(source, " {\"%s\", %s},\n", alias->alias, alias->name);
}
alias = alias->next;
}
fprintf(source, " {NULL, NULL},\n");
fprintf(source, "};\n\n");
}
Expand Down Expand Up @@ -2276,8 +2278,6 @@ void emit_loaders(void) {
fprintf(source, " }\n");

fprintf(source, "\n");
fprintf(source, " load_boxed_numerics(L);\n");

fprintf(source, "}\n\n");
}

Expand All @@ -2289,7 +2289,12 @@ void emit_sandbox(void) {
fprintf(source, "} new_userdata[] = {\n");
while (data) {
start_dependency(source, data->dependency);
fprintf(source, " {\"%s\", new_%s},\n", data->rename ? data->rename : data->name, data->sanatized_name);
if (data->creation) {
// expose custom creation function to user (not used internally)
fprintf(source, " {\"%s\", %s},\n", data->rename ? data->rename : data->name, data->creation);
} else {
fprintf(source, " {\"%s\", new_%s},\n", data->rename ? data->rename : data->name, data->sanatized_name);
}
end_dependency(source, data->dependency);
data = data->next;
}
Expand All @@ -2303,7 +2308,7 @@ void emit_sandbox(void) {
if (parsed_globals) {
struct method_alias *manual_aliases = parsed_globals->method_aliases;
while (manual_aliases) {
if (manual_aliases->is_manual == 0) {
if (manual_aliases->type != ALIAS_TYPE_MANUAL) {
error(ERROR_GLOBALS, "Globals only support manual methods");
}
fprintf(source, " {\"%s\", %s},\n", manual_aliases->alias, manual_aliases->name);
Expand All @@ -2328,9 +2333,6 @@ void emit_sandbox(void) {
fprintf(source, " }\n");

fprintf(source, "\n");
fprintf(source, " load_boxed_numerics_sandbox(L);\n");

// load the userdata complex functions
fprintf(source, "}\n");
}

Expand Down Expand Up @@ -2539,7 +2541,7 @@ void emit_docs(struct userdata *node, int is_userdata, int emit_creation) {
struct method_alias *alias = node->method_aliases;
while(alias) {
// dont do manual bindings
if (alias->is_manual == 0) {
if (alias->type == ALIAS_TYPE_NONE) {
// find the method this is a alias of
struct method * method = node->methods;
while (method != NULL && strcmp(method->name, alias->name)) {
Expand Down