From 6801f22bd94a3b1b5daec0352ecad3c21e404f44 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Fri, 22 Aug 2014 20:26:23 +0400 Subject: [PATCH] Introducing ECMA_FUNCTION_CALL helper macro for handling return completion values of function calls. --- src/libecmaobjects/ecma-helpers-value.c | 12 ++++++ src/libecmaobjects/ecma-helpers.h | 1 + src/libecmaoperations/ecma-function-object.c | 4 +- src/libecmaoperations/ecma-try-catch-macro.h | 40 +++++++++++++++++--- 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/libecmaobjects/ecma-helpers-value.c b/src/libecmaobjects/ecma-helpers-value.c index 7d75cbb70..03b747198 100644 --- a/src/libecmaobjects/ecma-helpers-value.c +++ b/src/libecmaobjects/ecma-helpers-value.c @@ -408,6 +408,18 @@ ecma_is_completion_value_throw (ecma_completion_value_t value) /**< completion v return (value.type == ECMA_COMPLETION_TYPE_THROW); } /* ecma_is_completion_value_throw */ +/** + * Check if the completion value is return value. + * + * @return true - if the completion type is return, + * false - otherwise. + */ +bool +ecma_is_completion_value_return (ecma_completion_value_t value) /**< completion value */ +{ + return (value.type == ECMA_COMPLETION_TYPE_RETURN); +} /* ecma_is_completion_value_return */ + /** * Check if the completion value is specified normal simple value. * diff --git a/src/libecmaobjects/ecma-helpers.h b/src/libecmaobjects/ecma-helpers.h index 7171b6722..09c457f09 100644 --- a/src/libecmaobjects/ecma-helpers.h +++ b/src/libecmaobjects/ecma-helpers.h @@ -79,6 +79,7 @@ extern void ecma_free_completion_value (ecma_completion_value_t completion_value extern bool ecma_is_completion_value_normal (ecma_completion_value_t value); extern bool ecma_is_completion_value_throw (ecma_completion_value_t value); +extern bool ecma_is_completion_value_return (ecma_completion_value_t value); extern bool ecma_is_completion_value_normal_simple_value (ecma_completion_value_t value, ecma_simple_value_t simple_value); extern bool ecma_is_completion_value_normal_true (ecma_completion_value_t value); diff --git a/src/libecmaoperations/ecma-function-object.c b/src/libecmaoperations/ecma-function-object.c index c5fe011ee..62640a0b6 100644 --- a/src/libecmaoperations/ecma-function-object.c +++ b/src/libecmaoperations/ecma-function-object.c @@ -424,7 +424,9 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */ { JERRY_ASSERT(ecma_is_empty_completion_value (completion)); - ret_value = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_UNDEFINED); + ret_value = ecma_make_completion_value (ECMA_COMPLETION_TYPE_RETURN, + ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED), + ECMA_TARGET_ID_RESERVED); } else { diff --git a/src/libecmaoperations/ecma-try-catch-macro.h b/src/libecmaoperations/ecma-try-catch-macro.h index a5ead17c4..fccdc9737 100644 --- a/src/libecmaoperations/ecma-try-catch-macro.h +++ b/src/libecmaoperations/ecma-try-catch-macro.h @@ -16,6 +16,8 @@ #ifndef ECMA_TRY_CATCH_MACRO_H #define ECMA_TRY_CATCH_MACRO_H +#include "ecma-helpers.h" + /** * The macro defines try-block that initializes variable 'var' with 'op' * and checks for exceptions that might be thrown during initialization. @@ -38,13 +40,41 @@ JERRY_ASSERT(ecma_is_completion_value_normal (var)) /** - * The macro marks end of code block that is executed if no exception - * was catched by corresponding ECMA_TRY_CATCH and frees variable, - * initialized by the ECMA_TRY_CATCH. + * The macro defines function call block that executes function call 'op', + * assigns call's completion value to 'var', and checks for exceptions + * that might be thrown during initialization. + * + * If no return values is not return completion value, + * then code after the function call block is executed. + * Otherwise, completion value is just copied to return_value. * * Note: - * Each ECMA_TRY_CATCH should be followed by ECMA_FINALIZE with same - * argument as corresponding ECMA_TRY_CATCH's first argument. + * Each ECMA_FUNCTION_CALL should have it's own corresponding ECMA_FINALIZE + * statement with same argument as corresponding ECMA_FUNCTION_CALL's first argument. + */ +#define ECMA_FUNCTION_CALL(var, op, return_value) \ + ecma_completion_value_t var = op; \ + if (unlikely (!ecma_is_completion_value_return (var))) \ + { \ + return_value = ecma_copy_completion_value (var); \ + } \ + else \ + { \ + JERRY_ASSERT(!ecma_is_completion_value_normal (var)) + +/** + * The define is not used. It is just for vera++ style checker that wants to find closing pair for all opening braces + */ +#define ECMA_FUNCTION_CALL_CLOSING_BRACKET_FOR_VERA_STYLE_CHECKER } + +/** + * The macro marks end of code block that is defined by corresponding + * ECMA_TRY_CATCH / ECMA_FUNCTION_CALL and frees variable, initialized + * by the ECMA_TRY_CATCH / ECMA_FUNCTION_CALL. + * + * Note: + * Each ECMA_TRY_CATCH / ECMA_FUNCTION_CALL should be followed by ECMA_FINALIZE with same argument + * as corresponding ECMA_TRY_CATCH's / ECMA_FUNCTION_CALL's first argument. */ #define ECMA_FINALIZE(var) } \ ecma_free_completion_value (var)