From b529fc2da9307aad567b90e76d13a7029c765572 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Thu, 28 Aug 2014 20:21:32 +0400 Subject: [PATCH] Processing unhandled exception by exiting engine with ERR_UNHANDLED_EXCEPTION; determining if function's code is strict by checking for appearance of 'meta' opcode of OPCODE_META_TYPE_STRICT_CODE type at the beginning of the function's code. --- src/globals.h | 1 + src/libcoreint/interpreter.c | 16 +++--------- src/libcoreint/opcodes.c | 49 ++++++++++++++++++++++-------------- src/libcoreint/opcodes.h | 3 ++- src/libruntime/jerry-exit.c | 5 ++++ 5 files changed, 42 insertions(+), 32 deletions(-) diff --git a/src/globals.h b/src/globals.h index 46f04d8a1..bd0e1d6ef 100644 --- a/src/globals.h +++ b/src/globals.h @@ -56,6 +56,7 @@ typedef enum ERR_PARSER = -9, ERR_MEMORY = -10, ERR_SYSCALL = -11, + ERR_UNHANDLED_EXCEPTION = -12, ERR_GENERAL = -255 } jerry_status_t; diff --git a/src/libcoreint/interpreter.c b/src/libcoreint/interpreter.c index 84e52cdf0..7d8a5467c 100644 --- a/src/libcoreint/interpreter.c +++ b/src/libcoreint/interpreter.c @@ -85,15 +85,12 @@ run_int (void) case ECMA_COMPLETION_TYPE_CONTINUE: case ECMA_COMPLETION_TYPE_RETURN: { - TODO (Throw SyntaxError); - - JERRY_UNIMPLEMENTED (); + /* SyntaxError should be treated as an early error */ + JERRY_UNREACHABLE (); } case ECMA_COMPLETION_TYPE_THROW: { - TODO (Handle unhandled exception); - - JERRY_UNIMPLEMENTED (); + jerry_exit (ERR_UNHANDLED_EXCEPTION); } } @@ -197,8 +194,6 @@ try_get_string_by_idx (idx_t idx, /**< literal id */ ecma_char_t *buffer_p, /**< buffer */ ssize_t buffer_size) /**< buffer size */ { - TODO (Actual string literal retrievement); - const ecma_char_t *str_p = deserialize_string_by_id (idx); JERRY_ASSERT (str_p != NULL); @@ -228,10 +223,7 @@ try_get_string_by_idx (idx_t idx, /**< literal id */ ecma_number_t get_number_by_idx (idx_t idx) /**< literal id */ { - TODO (Actual number literal retrievement); - - FIXME (/* conversion of value returned from deserialize_num_by_id to ecma_number_t */); - ecma_number_t num = (ecma_number_t) deserialize_num_by_id (idx); + ecma_number_t num = deserialize_num_by_id (idx); return num; } /* get_number_by_idx */ diff --git a/src/libcoreint/opcodes.c b/src/libcoreint/opcodes.c index 372eef2f9..c9ce2b317 100644 --- a/src/libcoreint/opcodes.c +++ b/src/libcoreint/opcodes.c @@ -113,8 +113,6 @@ opfunc_call_1 (opcode_t opdata __unused, int_data_t *int_data) * value to a variable. Assignment to an object's property is not implemented * by this opcode. * - * FIXME: Add cross link with 'property accessor assignment` opcode. - * * See also: ECMA-262 v5, 11.13.1 * * @return completion value @@ -460,26 +458,34 @@ function_declaration (int_data_t *int_data, /**< interpreter context */ ecma_string_t* args_names[], /**< names of arguments */ ecma_length_t args_number) /**< number of arguments */ { - TODO ("Check if code of function itself is strict"); - - const bool is_strict = int_data->is_strict; + bool is_strict = int_data->is_strict; const bool is_configurable_bindings = int_data->is_eval_code; - const opcode_counter_t function_code_begin_oc = (opcode_counter_t) (int_data->pos + 1); + const opcode_counter_t function_code_end_oc = read_meta_opcode_counter (OPCODE_META_TYPE_FUNCTION_END, int_data); + int_data->pos++; - int_data->pos = read_meta_opcode_counter (OPCODE_META_TYPE_FUNCTION_END, int_data); + opcode_t next_opcode = read_opcode (int_data->pos); + if (next_opcode.op_idx == __op__idx_meta + && next_opcode.data.meta.type == OPCODE_META_TYPE_STRICT_CODE) + { + is_strict = true; + + int_data->pos++; + } ecma_string_t *function_name_string_p = ecma_new_ecma_string_from_lit_index (function_name_lit_idx); ecma_completion_value_t ret_value = ecma_op_function_declaration (int_data->lex_env_p, function_name_string_p, - function_code_begin_oc, + int_data->pos, args_names, args_number, is_strict, is_configurable_bindings); ecma_deref_ecma_string (function_name_string_p); + int_data->pos = function_code_end_oc; + return ret_value; } /* function_declaration */ @@ -597,25 +603,27 @@ ecma_completion_value_t opfunc_func_expr_n (opcode_t opdata, /**< operation data */ int_data_t *int_data) /**< interpreter context */ { - int_data->pos++; - const idx_t dst_var_idx = opdata.data.func_expr_n.lhs; const idx_t function_name_lit_idx = opdata.data.func_expr_n.name_lit_idx; const ecma_length_t params_number = opdata.data.func_expr_n.arg_list; - const bool is_named_func_expr = (!is_reg_variable (int_data, function_name_lit_idx)); - TODO ("Check if code of function itself is strict"); - - const bool is_strict = int_data->is_strict; - ecma_string_t *params_names[params_number + 1 /* length of array should not be zero */]; - fill_params_list (int_data, params_number, params_names); - const opcode_counter_t function_code_begin_oc = (opcode_counter_t) (int_data->pos + 1); + bool is_strict = int_data->is_strict; - int_data->pos = read_meta_opcode_counter (OPCODE_META_TYPE_FUNCTION_END, int_data); + const opcode_counter_t function_code_end_oc = read_meta_opcode_counter (OPCODE_META_TYPE_FUNCTION_END, int_data); + int_data->pos++; + + opcode_t next_opcode = read_opcode (int_data->pos); + if (next_opcode.op_idx == __op__idx_meta + && next_opcode.data.meta.type == OPCODE_META_TYPE_STRICT_CODE) + { + is_strict = true; + + int_data->pos++; + } ecma_object_t *scope_p; ecma_string_t *function_name_string_p = NULL; @@ -636,7 +644,7 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */ params_number, scope_p, is_strict, - function_code_begin_oc); + int_data->pos); ecma_completion_value_t ret_value = set_variable_value (int_data, dst_var_idx, @@ -660,6 +668,8 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */ ecma_deref_ecma_string (params_names[param_index]); } + int_data->pos = function_code_end_oc; + return ret_value; } /* opfunc_func_expr_n */ @@ -1783,6 +1793,7 @@ opfunc_meta (opcode_t opdata, /**< operation data */ case OPCODE_META_TYPE_VARG_PROP_SETTER: case OPCODE_META_TYPE_FUNCTION_END: case OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER: + case OPCODE_META_TYPE_STRICT_CODE: { JERRY_UNREACHABLE (); } diff --git a/src/libcoreint/opcodes.h b/src/libcoreint/opcodes.h index 51343a7f8..866ffb249 100644 --- a/src/libcoreint/opcodes.h +++ b/src/libcoreint/opcodes.h @@ -63,7 +63,8 @@ typedef enum OPCODE_META_TYPE_CATCH, /**< mark of beginning of catch block containing pointer to end of catch block */ OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER, /**< literal index containing name of variable with exception object */ OPCODE_META_TYPE_FINALLY, /**< mark of beginning of finally block containing pointer to end of finally block */ - OPCODE_META_TYPE_END_TRY_CATCH_FINALLY /**< mark of end of try-catch, try-finally, try-catch-finally blocks */ + OPCODE_META_TYPE_END_TRY_CATCH_FINALLY, /**< mark of end of try-catch, try-finally, try-catch-finally blocks */ + OPCODE_META_TYPE_STRICT_CODE /**< mark of beginning of strict code */ } opcode_meta_type; typedef struct diff --git a/src/libruntime/jerry-exit.c b/src/libruntime/jerry-exit.c index 034992e2c..ee297827d 100644 --- a/src/libruntime/jerry-exit.c +++ b/src/libruntime/jerry-exit.c @@ -96,6 +96,11 @@ jerry_exit (jerry_status_t code) /**< status code */ JERRY_UNREACHABLE(); break; } + case ERR_UNHANDLED_EXCEPTION: + { + __printf ("ERR_UNHANDLED_EXCEPTION\n"); + break; + } case ERR_GENERAL: { __printf ("ERR_GENERAL\n");