Syntax sugar for constructing an object.
#pragma once
#include <stdint.h>
#include "js_thread_i.h"
#include <flipper_application/plugins/plugin_manager.h>
#include <flipper_application/plugins/composite_resolver.h>
#define PLUGIN_APP_ID "js"
#define PLUGIN_API_VERSION 1
#define JS_SDK_VENDOR "flipperdevices"
#define JS_SDK_MAJOR 0
#define JS_SDK_MINOR 1
#define JS_GET_INST(mjs, obj) mjs_get_ptr(mjs, mjs_get(mjs, obj, INST_PROP_NAME, ~0))
#define JS_GET_CONTEXT(mjs) JS_GET_INST(mjs, mjs_get_this(mjs))
#define JS_ASSIGN_MULTI(mjs, object) \
for(struct { \
struct mjs* mjs; \
mjs_val_t val; \
int i; \
} _ass_multi = {mjs, object, 0}; \
_ass_multi.i == 0; \
_ass_multi.i++)
#define JS_FIELD(name, value) mjs_set(_ass_multi.mjs, _ass_multi.val, name, ~0, value)
typedef enum {
JsForeignMagicStart = 0x15BAD000,
JsForeignMagic_JsEventLoopContract,
} JsForeignMagic;
#define JS_EXACTLY ==
#define JS_AT_LEAST >=
#define JS_ENUM_MAP(var_name, ...) \
static const JsEnumMapping var_name##_mapping[] = { \
{NULL, sizeof(var_name)}, \
__VA_ARGS__, \
{NULL, 0}, \
};
typedef struct {
const char* name;
size_t value;
typedef struct {
void* out;
int (*validator)(mjs_val_t);
void (*converter)(
struct mjs*, mjs_val_t*,
void* out,
const void* extra);
const char* expected_type;
bool (*extended_validator)(
struct mjs*, mjs_val_t,
const void* extra);
const void* extra_data;
static inline void _js_to_int32(
struct mjs*
mjs, mjs_val_t* in,
void* out,
const void* extra) {
UNUSED(extra);
*(int32_t*)out = mjs_get_int32(
mjs, *in);
}
#define JS_ARG_INT32(out) ((_js_arg_decl){out, mjs_is_number, _js_to_int32, "number", NULL, NULL})
static inline void _js_to_ptr(
struct mjs*
mjs, mjs_val_t* in,
void* out,
const void* extra) {
UNUSED(extra);
*(
void**)out = mjs_get_ptr(
mjs, *in);
}
#define JS_ARG_PTR(out) \
((_js_arg_decl){out, mjs_is_foreign, _js_to_ptr, "opaque pointer", NULL, NULL})
static inline void _js_to_string(
struct mjs*
mjs, mjs_val_t* in,
void* out,
const void* extra) {
UNUSED(extra);
*(
const char**)out = mjs_get_string(
mjs, in, NULL);
}
#define JS_ARG_STR(out) ((_js_arg_decl){out, mjs_is_string, _js_to_string, "string", NULL, NULL})
static inline void _js_to_bool(
struct mjs*
mjs, mjs_val_t* in,
void* out,
const void* extra) {
UNUSED(extra);
*(
bool*)out = !!mjs_get_bool(
mjs, *in);
}
#define JS_ARG_BOOL(out) ((_js_arg_decl){out, mjs_is_boolean, _js_to_bool, "boolean", NULL, NULL})
static inline void _js_passthrough(
struct mjs*
mjs, mjs_val_t* in,
void* out,
const void* extra) {
UNUSED(extra);
*(mjs_val_t*)out = *in;
}
#define JS_ARG_ANY(out) ((_js_arg_decl){out, NULL, _js_passthrough, "any", NULL, NULL})
#define JS_ARG_OBJ(out) ((_js_arg_decl){out, mjs_is_object, _js_passthrough, "any", NULL, NULL})
#define JS_ARG_FN(out) \
((_js_arg_decl){out, mjs_is_function, _js_passthrough, "function", NULL, NULL})
#define JS_ARG_ARR(out) ((_js_arg_decl){out, mjs_is_array, _js_passthrough, "array", NULL, NULL})
static inline bool _js_validate_struct(
struct mjs*
mjs, mjs_val_t val,
const void* extra) {
JsForeignMagic expected_magic = (JsForeignMagic)(size_t)extra;
JsForeignMagic struct_magic = *(JsForeignMagic*)mjs_get_ptr(
mjs, val);
return struct_magic == expected_magic;
}
#define JS_ARG_STRUCT(type, out) \
((_js_arg_decl){ \
out, \
mjs_is_foreign, \
_js_to_ptr, \
#type, \
_js_validate_struct, \
(void*)JsForeignMagic##_##type})
static inline bool _js_validate_obj_w_struct(
struct mjs*
mjs, mjs_val_t val,
const void* extra) {
JsForeignMagic expected_magic = (JsForeignMagic)(size_t)extra;
JsForeignMagic struct_magic = *(JsForeignMagic*)JS_GET_INST(
mjs, val);
return struct_magic == expected_magic;
}
#define JS_ARG_OBJ_WITH_STRUCT(type, out) \
((_js_arg_decl){ \
out, \
mjs_is_object, \
_js_passthrough, \
#type, \
_js_validate_obj_w_struct, \
(void*)JsForeignMagic##_##type})
static inline bool _js_validate_enum(
struct mjs*
mjs, mjs_val_t val,
const void* extra) {
if(strcmp(mapping->name, mjs_get_string(
mjs, &val, NULL)) == 0)
return true;
return false;
}
static inline void
_js_convert_enum(
struct mjs*
mjs, mjs_val_t* val,
void* out,
const void* extra) {
size_t size = mapping->
value;
for(mapping++; mapping->name; mapping++) {
if(strcmp(mapping->name, mjs_get_string(
mjs, val, NULL)) == 0) {
if(size == 1)
*(uint8_t*)out = mapping->value;
else if(size == 2)
*(uint16_t*)out = mapping->value;
else if(size == 4)
*(uint32_t*)out = mapping->value;
else if(size == 8)
*(uint64_t*)out = mapping->value;
return;
}
}
}
#define JS_ARG_ENUM(var_name, name) \
((_js_arg_decl){ \
&var_name, \
mjs_is_string, \
_js_convert_enum, \
name " enum", \
_js_validate_enum, \
var_name##_mapping})
#define JS_FETCH_ARGS_OR_RETURN(mjs, arg_operator, ...) \
_js_arg_decl _js_args[] = {__VA_ARGS__}; \
int _js_arg_cnt = COUNT_OF(_js_args); \
mjs_val_t _js_arg_vals[_js_arg_cnt]; \
if(!(mjs_nargs(mjs) arg_operator _js_arg_cnt)) \
JS_ERROR_AND_RETURN( \
mjs, \
MJS_BAD_ARGS_ERROR, \
"expected %s%d arguments, got %d", \
#arg_operator, \
_js_arg_cnt, \
mjs_nargs(mjs)); \
for(int _i = 0; _i < _js_arg_cnt; _i++) { \
_js_arg_vals[_i] = mjs_arg(mjs, _i); \
if(_js_args[_i].validator) \
if(!_js_args[_i].validator(_js_arg_vals[_i])) \
JS_ERROR_AND_RETURN( \
mjs, \
MJS_BAD_ARGS_ERROR, \
"argument %d: expected %s", \
_i, \
_js_args[_i].expected_type); \
if(_js_args[_i].extended_validator) \
if(!_js_args[_i].extended_validator(mjs, _js_arg_vals[_i], _js_args[_i].extra_data)) \
JS_ERROR_AND_RETURN( \
mjs, \
MJS_BAD_ARGS_ERROR, \
"argument %d: expected %s", \
_i, \
_js_args[_i].expected_type); \
_js_args[_i].converter( \
mjs, &_js_arg_vals[_i], _js_args[_i].out, _js_args[_i].extra_data); \
}
#define JS_ERROR_AND_RETURN(mjs, error_code, ...) \
do { \
mjs_prepend_errorf(mjs, error_code, __VA_ARGS__); \
mjs_return(mjs, MJS_UNDEFINED); \
return; \
} while(0)
typedef void* (*JsModuleConstructor)(
struct mjs*
mjs, mjs_val_t* object,
JsModules* modules);
typedef void (*JsModuleDestructor)(void* inst);
typedef struct {
char* name;
JsModuleConstructor create;
JsModuleDestructor destroy;
mjs_val_t js_module_require(
JsModules* modules,
const char* name,
size_t name_len);
void* js_module_get(
JsModules* modules,
const char* name);
void js_sdk_compatibility_status(
struct mjs*
mjs);
void js_is_sdk_compatible(
struct mjs*
mjs);
void js_check_sdk_compatibility(
struct mjs*
mjs);
void js_does_sdk_support(
struct mjs*
mjs);
void js_check_sdk_features(
struct mjs*
mjs);
Definition js_modules.h:96
Definition composite_resolver.c:10
Interface for ELF loader to resolve symbols.
Definition elf_api_interface.h:9
Definition js_modules.h:91
Definition js_modules.h:262
Definition js_modules.c:40