From 6594a7359bd4b221b6bec4f91c83f3dd9bc11579 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Tue, 7 Apr 2015 12:42:55 +0300 Subject: [PATCH] Supporting return values in functions of plugins. --- .../builtin-objects/ecma-builtin-jerry.cpp | 86 ++++++++++++++++++- jerry-core/jerry-api.h | 3 +- jerry-core/jerry-extension.h | 13 +-- jerry-core/jerry-extension.inc.h | 36 +++++--- plugins/io/io-extension-description.inc.h | 2 + 5 files changed, 117 insertions(+), 23 deletions(-) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-jerry.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-jerry.cpp index 8b3bd315a..f862ce397 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-jerry.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-jerry.cpp @@ -138,7 +138,7 @@ ecma_builtin_jerry_dispatch_routine (uint16_t builtin_routine_id, /**< built-in JERRY_ASSERT (desc_p != NULL); JERRY_ASSERT (function_index < desc_p->functions_count); - const jerry_extension_function_t *function_p = &desc_p->functions_p [function_index]; + jerry_extension_function_t *function_p = &desc_p->functions_p [function_index]; bool throw_type_error = false; if (function_p->args_number != arguments_number) @@ -260,7 +260,85 @@ ecma_builtin_jerry_dispatch_routine (uint16_t builtin_routine_id, /**< built-in } else { - return ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_UNDEFINED); + jerry_api_value_t& ret_value = function_p->ret_value; + ecma_completion_value_t completion; + + switch (ret_value.type) + { + case JERRY_API_DATA_TYPE_VOID: + { + completion = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_UNDEFINED); + + break; + } + + case JERRY_API_DATA_TYPE_UNDEFINED: + case JERRY_API_DATA_TYPE_NULL: + { + JERRY_UNREACHABLE (); + } + + case JERRY_API_DATA_TYPE_BOOLEAN: + { + if (ret_value.v_bool) + { + completion = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_TRUE); + } + else + { + completion = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_FALSE); + } + + break; + } + + case JERRY_API_DATA_TYPE_UINT32: + case JERRY_API_DATA_TYPE_FLOAT32: + case JERRY_API_DATA_TYPE_FLOAT64: + { + ecma_number_t* num_value_p = ecma_alloc_number (); + if (ret_value.type == JERRY_API_DATA_TYPE_FLOAT32) + { + *num_value_p = ret_value.v_float32; + } + else if (ret_value.type == JERRY_API_DATA_TYPE_FLOAT64) + { +#if CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT32 + JERRY_UNREACHABLE (); +#elif CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 + *num_value_p = ret_value.v_float64; +#endif /* CONFIG_ECMA_NUMBER_TYPE == CONFIG_ECMA_NUMBER_FLOAT64 */ + } + else if (ret_value.type == JERRY_API_DATA_TYPE_UINT32) + { + *num_value_p = ecma_uint32_to_number (ret_value.v_uint32); + } + + completion = ecma_make_normal_completion_value (ecma_make_number_value (num_value_p)); + + break; + } + + case JERRY_API_DATA_TYPE_STRING: + { + completion = ecma_make_normal_completion_value (ecma_make_string_value (ret_value.v_string)); + + ret_value.v_string = NULL; + + break; + } + + case JERRY_API_DATA_TYPE_OBJECT: + { + completion = ecma_make_normal_completion_value (ecma_make_object_value (ret_value.v_object)); + + ret_value.v_object = NULL; + + break; + } + } + + return completion; } } /* ecma_builtin_jerry_dispatch_routine */ @@ -440,6 +518,10 @@ ecma_op_extension_object_get_own_property (ecma_object_t *obj_p, /**< the extens switch (field_p->type) { + case JERRY_API_DATA_TYPE_VOID: + { + JERRY_UNREACHABLE (); + } case JERRY_API_DATA_TYPE_UNDEFINED: { value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); diff --git a/jerry-core/jerry-api.h b/jerry-core/jerry-api.h index a957e3cc5..637b8f751 100644 --- a/jerry-core/jerry-api.h +++ b/jerry-core/jerry-api.h @@ -36,12 +36,13 @@ */ typedef enum { + JERRY_API_DATA_TYPE_VOID, /**< no return value */ JERRY_API_DATA_TYPE_UNDEFINED, /**< undefined */ JERRY_API_DATA_TYPE_NULL, /**< null */ JERRY_API_DATA_TYPE_BOOLEAN, /**< bool */ JERRY_API_DATA_TYPE_FLOAT32, /**< 32-bit float */ JERRY_API_DATA_TYPE_FLOAT64, /**< 64-bit float */ - JERRY_API_DATA_TYPE_UINT32, /**< number converted to 32-bit unsigned integer*/ + JERRY_API_DATA_TYPE_UINT32, /**< number converted to 32-bit unsigned integer */ JERRY_API_DATA_TYPE_STRING, /**< string */ JERRY_API_DATA_TYPE_OBJECT /**< object */ } jerry_api_data_type_t; diff --git a/jerry-core/jerry-extension.h b/jerry-core/jerry-extension.h index 186e40674..ba349b72b 100644 --- a/jerry-core/jerry-extension.h +++ b/jerry-core/jerry-extension.h @@ -54,14 +54,14 @@ typedef struct } jerry_extension_field_t; /** - * Forward declare to make compiler happy + * Forward declaration of description of an extension object's function */ struct jerry_extension_function_t; /** * Pointer to extension function implementation */ -typedef void (*jerry_extension_function_pointer_t) (const struct jerry_extension_function_t *function_block_p); +typedef void (*jerry_extension_function_pointer_t) (struct jerry_extension_function_t *function_block_p); /** * Description of an extension object's function @@ -70,10 +70,11 @@ typedef struct jerry_extension_function_t { const char* function_name_p; /**< name of function */ - jerry_extension_function_pointer_t function_wrapper_p; /**< pointer to function implementation */ + const jerry_extension_function_pointer_t function_wrapper_p; /**< pointer to function implementation */ - jerry_api_value_t *args_p; /**< arrays of the function's arguments */ - uint32_t args_number; /**< number of arguments */ + jerry_api_value_t ret_value; /**< function's return value */ + jerry_api_value_t* args_p; /**< arrays of the function's arguments */ + const uint32_t args_number; /**< number of arguments */ } jerry_extension_function_t; /** @@ -85,7 +86,7 @@ typedef struct jerry_extension_descriptor_t const uint32_t functions_count; /**< number of functions */ const jerry_extension_field_t* const fields_p; /**< array of field descriptor */ - const jerry_extension_function_t* const functions_p; /**< array of function descriptors */ + jerry_extension_function_t* const functions_p; /**< array of function descriptors */ const char* const name_p; /**< name of the extension */ struct jerry_extension_descriptor_t *next_p; /**< next descriptor in list of registered extensions */ diff --git a/jerry-core/jerry-extension.inc.h b/jerry-core/jerry-extension.inc.h index 40d418f5d..b34265b80 100644 --- a/jerry-core/jerry-extension.inc.h +++ b/jerry-core/jerry-extension.inc.h @@ -28,7 +28,7 @@ enum /* Counting functions */ enum { -#define EXTENSION_FUNCTION(_function_name, _function_wrapper, _args_number, ... /* args */) \ +#define EXTENSION_FUNCTION(_function_name, _function_wrapper, _ret_value_type, _args_number, ... /* args */) \ JERRY_EXTENSION_ ## EXTENSION_NAME ## _ ## _function_name, # include EXTENSION_DESCRIPTION_HEADER #undef EXTENSION_FUNCTION @@ -42,9 +42,9 @@ static const jerry_extension_field_t jerry_extension_fields [JERRY_EXTENSION_FIE { # _field_name, JERRY_API_DATA_TYPE_ ## _type, _value }, # include EXTENSION_DESCRIPTION_HEADER #undef EXTENSION_FIELD - { - NULL, JERRY_API_DATA_TYPE_UNDEFINED, NULL - } +#define EMPTY_FIELD_ENTRY { NULL, JERRY_API_DATA_TYPE_UNDEFINED, NULL } + EMPTY_FIELD_ENTRY +#undef EMPTY_FIELD_ENTRY }; /* Functions wrapper definitions */ @@ -61,11 +61,18 @@ static const jerry_extension_field_t jerry_extension_fields [JERRY_EXTENSION_FIE #define EXTENSION_ARG_PASS_OBJECT(_arg_index) \ args_p [_arg_index].v_object #define EXTENSION_ARG(_arg_index, _type) EXTENSION_ARG_PASS_ ## _type(_arg_index) -#define EXTENSION_FUNCTION(_function_name, _function_to_call, _args_number, ...) \ - static void jerry_extension_ ## _function_name ## _wrapper (const jerry_extension_function_t *function_block_p) \ +#define EXTENSION_RET_VALUE_SET_VOID +#define EXTENSION_RET_VALUE_SET_BOOLEAN function_block_p->ret_value.v_bool = +#define EXTENSION_RET_VALUE_SET_UINT32 function_block_p->ret_value.v_uint32 = +#define EXTENSION_RET_VALUE_SET_FLOAT32 function_block_p->ret_value.v_float32 = +#define EXTENSION_RET_VALUE_SET_FLOAT64 function_block_p->ret_value.v_float64 = +#define EXTENSION_RET_VALUE_SET_STRING function_block_p->ret_value.v_string = +#define EXTENSION_RET_VALUE_SET_OBJECT function_block_p->ret_value.v_object = +#define EXTENSION_FUNCTION(_function_name, _function_to_call, _ret_value_type, _args_number, ...) \ + static void jerry_extension_ ## _function_name ## _wrapper (jerry_extension_function_t *function_block_p) \ { \ - const jerry_api_value_t *args_p = function_block_p->args_p; \ - _function_to_call (__VA_ARGS__); \ + const jerry_api_value_t *args_p = function_block_p->args_p; \ + EXTENSION_RET_VALUE_SET_ ## _ret_value_type _function_to_call (__VA_ARGS__); \ } # include EXTENSION_DESCRIPTION_HEADER #undef EXTENSION_FUNCTION @@ -82,7 +89,7 @@ static const jerry_extension_field_t jerry_extension_fields [JERRY_EXTENSION_FIE (JERRY_API_DATA_TYPE_ ## _type), \ false /* just for initialization, should be overwritten upon call */ \ } -#define EXTENSION_FUNCTION(_function_name, _function_to_call, _args_number, ...) \ +#define EXTENSION_FUNCTION(_function_name, _function_to_call, _ret_value_type, _args_number, ...) \ static jerry_api_value_t jerry_extension_function_ ## _function_name ## _args [_args_number] = { \ __VA_ARGS__ \ }; @@ -91,19 +98,20 @@ static const jerry_extension_field_t jerry_extension_fields [JERRY_EXTENSION_FIE #undef EXTENSION_ARG /* Functions description */ -static const jerry_extension_function_t jerry_extension_functions [JERRY_EXTENSION_FUNCTIONS_NUMBER + 1] = +static jerry_extension_function_t jerry_extension_functions [JERRY_EXTENSION_FUNCTIONS_NUMBER + 1] = { -#define EXTENSION_FUNCTION(_function_name, _function_wrapper, _args_number, ...) \ +#define EXTENSION_FUNCTION(_function_name, _function_to_call, _ret_value_type, _args_number, ...) \ { \ # _function_name, jerry_extension_ ## _function_name ## _wrapper, \ + { JERRY_API_DATA_TYPE_ ## _ret_value_type, false }, \ jerry_extension_function_ ## _function_name ## _args, \ _args_number \ }, # include EXTENSION_DESCRIPTION_HEADER #undef EXTENSION_FUNCTION - { - NULL, NULL, NULL, 0 - } +#define EMPTY_FUNCTION_ENTRY { NULL, NULL, { JERRY_API_DATA_TYPE_VOID, false }, NULL, 0 } + EMPTY_FUNCTION_ENTRY +#undef EMPTY_FUNCTION_ENTRY }; static jerry_extension_descriptor_t jerry_extension = diff --git a/plugins/io/io-extension-description.inc.h b/plugins/io/io-extension-description.inc.h index 11ddf18a6..46c52c4ea 100644 --- a/plugins/io/io-extension-description.inc.h +++ b/plugins/io/io-extension-description.inc.h @@ -25,9 +25,11 @@ #if defined (EXTENSION_FUNCTION) EXTENSION_FUNCTION (print_uint32, plugin_io_print_uint32, + VOID, 1, EXTENSION_ARG (0, UINT32)) EXTENSION_FUNCTION (print_string, plugin_io_print_string, + VOID, 1, EXTENSION_ARG (0, STRING)) #elif defined (EXTENSION_FIELD)