diff --git a/src/libcoreint/opcode-structures.h b/src/libcoreint/opcode-structures.h index 1a4c024dc..2c291729b 100644 --- a/src/libcoreint/opcode-structures.h +++ b/src/libcoreint/opcode-structures.h @@ -308,6 +308,10 @@ OP_CODE_DECL (varg_3_end, T_IDX_IDX_IDX, arg2_lit_idx, arg3_lit_idx) +/** exit with status code; */ +OP_CODE_DECL (exitval, T_IDX, + status_code) + /** return value; */ OP_CODE_DECL (retval, T_IDX, ret_value) @@ -384,4 +388,4 @@ OP_CODE_DECL (var_decl, T_IDX, // TODO New constructor #endif /* OPCODE_STRUCTURES_H */ - \ No newline at end of file + diff --git a/src/libcoreint/opcodes.c b/src/libcoreint/opcodes.c index a71a68a7a..748c0f141 100644 --- a/src/libcoreint/opcodes.c +++ b/src/libcoreint/opcodes.c @@ -123,6 +123,30 @@ opfunc_jmp (OPCODE opdata, struct __int_data *int_data) ECMA_TARGET_ID_RESERVED); } +/** + * Exit from script with specified status code: + * 0 - for successful completion + * 1 - to indicate failure. + * + * Note: this is not ECMA specification-defined, but internal + * implementation-defined opcode for end of script + * and assertions inside of unit tests. + */ +ecma_CompletionValue_t +opfunc_exitval(OPCODE opdata, /**< operation data */ + struct __int_data *int_data __unused) /**< interpreter context */ +{ + JERRY_ASSERT( opdata.data.exitval.status_code == 0 + || opdata.data.exitval.status_code == 1 ); + + ecma_Value_t exit_status = ecma_MakeSimpleValue( opdata.data.exitval.status_code == 0 ? ECMA_SIMPLE_VALUE_TRUE + : ECMA_SIMPLE_VALUE_FALSE); + return ecma_MakeCompletionValue( ECMA_COMPLETION_TYPE_EXIT, + exit_status, + ECMA_TARGET_ID_RESERVED); +} /* opfunc_exitval */ + + /** Opcode generators. */ GETOP_IMPL_2 (is_true_jmp, value, opcode) GETOP_IMPL_2 (is_false_jmp, value, opcode) @@ -163,6 +187,7 @@ GETOP_IMPL_2 (varg_2, arg1_lit_idx, arg2_lit_idx) GETOP_IMPL_2 (varg_2_end, arg1_lit_idx, arg2_lit_idx) GETOP_IMPL_3 (varg_3, arg1_lit_idx, arg2_lit_idx, arg3_lit_idx) GETOP_IMPL_3 (varg_3_end, arg1_lit_idx, arg2_lit_idx, arg3_lit_idx) +GETOP_IMPL_1 (exitval, status_code) GETOP_IMPL_1 (retval, ret_value) GETOP_IMPL_0 (ret) GETOP_IMPL_0 (nop) diff --git a/src/libcoreint/opcodes.h b/src/libcoreint/opcodes.h index 7dd1d8752..5318a6db2 100644 --- a/src/libcoreint/opcodes.h +++ b/src/libcoreint/opcodes.h @@ -55,6 +55,7 @@ typedef ecma_CompletionValue_t (*opfunc)(OPCODE, struct __int_data *); op(varg_2_end) \ op(varg_3) \ op(varg_3_end) \ + op(exitval) \ op(retval) \ op(ret) diff --git a/src/libecmaobjects/ecma-globals.h b/src/libecmaobjects/ecma-globals.h index 7a47ddb84..9f833a569 100644 --- a/src/libecmaobjects/ecma-globals.h +++ b/src/libecmaobjects/ecma-globals.h @@ -93,7 +93,9 @@ typedef enum { ECMA_COMPLETION_TYPE_RETURN, /**< block completed with return */ ECMA_COMPLETION_TYPE_BREAK, /**< block completed with break */ ECMA_COMPLETION_TYPE_CONTINUE, /**< block completed with continue */ - ECMA_COMPLETION_TYPE_THROW /**< block completed with throw */ + ECMA_COMPLETION_TYPE_THROW, /**< block completed with throw */ + ECMA_COMPLETION_TYPE_EXIT /**< implementation-defined completion type + for finishing script execution */ } ecma_CompletionType_t; /**