From 72d4c07bdc6c6f90ee31ec1e32fe0053bbf14349 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Fri, 31 Jul 2015 17:28:48 +0300 Subject: [PATCH] Remove 'print' instrinsic, add 'print' implementation-defined built-in routine to the Global object. JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com --- .../builtin-objects/ecma-builtin-global.cpp | 92 +++++++++++++++++++ .../builtin-objects/ecma-builtin-global.inc.h | 4 + jerry-core/lit/lit-magic-strings.inc.h | 1 + jerry-core/parser/js/opcodes-dumper.cpp | 5 +- jerry-core/vm/opcodes-native-call.cpp | 50 +--------- jerry-core/vm/opcodes-native-call.h | 1 - jerry-core/vm/pretty-printer.cpp | 2 - 7 files changed, 100 insertions(+), 55 deletions(-) diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-global.cpp b/jerry-core/ecma/builtin-objects/ecma-builtin-global.cpp index 9f77a657d..0b27095d5 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-global.cpp +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-global.cpp @@ -47,6 +47,98 @@ * @{ */ +/** + * The implementation-defined Global object's 'print' routine + * + * The routine converts all of its arguments to strings and outputs them using 'printf'. + * + * Code points, with except of character, that are representable with one utf8-byte + * are outputted as is, using '%c' format argument, and other code points are outputted as '\uhhll', + * where hh and ll are values of code point's high and low bytes, correspondingly. + * + * @return completion value + * Returned value must be freed with ecma_free_completion_value. + */ +static ecma_completion_value_t +ecma_builtin_global_object_print (ecma_value_t this_arg __attr_unused___, /**< this argument */ + const ecma_value_t args[], /**< arguments list */ + ecma_length_t args_number) /**< number of arguments */ +{ + ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); + + /* + * TODO: + * Move the 'print' routine out of engine core. + */ + + for (ecma_length_t arg_index = 0; + ecma_is_completion_value_empty (ret_value) && arg_index < args_number; + arg_index++) + { + ECMA_TRY_CATCH (str_value, + ecma_op_to_string (args[arg_index]), + ret_value); + + ecma_string_t *str_p = ecma_get_string_from_value (str_value); + + lit_utf8_size_t utf8_str_size = ecma_string_get_size (str_p); + + MEM_DEFINE_LOCAL_ARRAY (utf8_str_p, + utf8_str_size, + lit_utf8_byte_t); + + ssize_t actual_sz = ecma_string_to_utf8_string (str_p, utf8_str_p, (ssize_t) utf8_str_size); + JERRY_ASSERT (actual_sz == (ssize_t) utf8_str_size); + + lit_utf8_iterator_t str_iter = lit_utf8_iterator_create (utf8_str_p, utf8_str_size); + + while (!lit_utf8_iterator_is_eos (&str_iter)) + { + ecma_char_t code_point = lit_utf8_iterator_read_next (&str_iter); + + if (code_point == LIT_CHAR_NULL) + { + printf ("\\u0000"); + } + else if (code_point <= LIT_UTF8_1_BYTE_CODE_POINT_MAX) + { + printf ("%c", (char) code_point); + } + else + { + JERRY_STATIC_ASSERT (sizeof (code_point) == 2); + + uint32_t byte_high = (uint32_t) jrt_extract_bit_field (code_point, + JERRY_BITSINBYTE, + JERRY_BITSINBYTE); + uint32_t byte_low = (uint32_t) jrt_extract_bit_field (code_point, + 0, + JERRY_BITSINBYTE); + + printf ("\\u%02x%02x", byte_high, byte_low); + } + } + + if (arg_index < args_number - 1) + { + printf (" "); + } + + MEM_FINALIZE_LOCAL_ARRAY (utf8_str_p); + + ECMA_FINALIZE (str_value); + } + + printf ("\n"); + + if (ecma_is_completion_value_empty (ret_value)) + { + ret_value = ecma_make_normal_completion_value (ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED)); + } + + return ret_value; +} /* ecma_builtin_global_object_print */ + /** * The Global object's 'eval' routine * diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h index acec40282..3b4142741 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-global.inc.h @@ -221,6 +221,10 @@ OBJECT_VALUE (LIT_MAGIC_STRING_COMPACT_PROFILE_ERROR_UL, /* Routine properties: * (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */ + +// Implementation-defined 'print' routine +ROUTINE (LIT_MAGIC_STRING_PRINT, ecma_builtin_global_object_print, NON_FIXED, 1) + ROUTINE (LIT_MAGIC_STRING_EVAL, ecma_builtin_global_object_eval, 1, 1) ROUTINE (LIT_MAGIC_STRING_PARSE_FLOAT, ecma_builtin_global_object_parse_float, 1, 1) ROUTINE (LIT_MAGIC_STRING_IS_NAN, ecma_builtin_global_object_is_nan, 1, 1) diff --git a/jerry-core/lit/lit-magic-strings.inc.h b/jerry-core/lit/lit-magic-strings.inc.h index fc2b953b7..397897a18 100644 --- a/jerry-core/lit/lit-magic-strings.inc.h +++ b/jerry-core/lit/lit-magic-strings.inc.h @@ -215,6 +215,7 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_EXEC, "exec") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TEST, "test") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_NAME, "name") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_MESSAGE, "message") +LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_PRINT, "print") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_G_CHAR, "g") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_I_CHAR, "i") LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_M_CHAR, "m") diff --git a/jerry-core/parser/js/opcodes-dumper.cpp b/jerry-core/parser/js/opcodes-dumper.cpp index 699739b51..9d1125a12 100644 --- a/jerry-core/parser/js/opcodes-dumper.cpp +++ b/jerry-core/parser/js/opcodes-dumper.cpp @@ -248,10 +248,7 @@ name_to_native_call_id (operand obj) { return OPCODE_NATIVE_CALL_WAIT; } - else if (lit_literal_equal_type_cstr (lit_get_literal_by_cp (obj.data.lit_id), "print")) - { - return OPCODE_NATIVE_CALL_PRINT; - } + return OPCODE_NATIVE_CALL__COUNT; } diff --git a/jerry-core/vm/opcodes-native-call.cpp b/jerry-core/vm/opcodes-native-call.cpp index e9690cf7f..6bafb9bb5 100644 --- a/jerry-core/vm/opcodes-native-call.cpp +++ b/jerry-core/vm/opcodes-native-call.cpp @@ -31,10 +31,10 @@ ecma_completion_value_t opfunc_native_call (vm_instr_t instr, /**< instruction */ vm_frame_ctx_t *frame_ctx_p) /**< interpreter context */ { - const idx_t dst_var_idx = instr.data.native_call.lhs; + const idx_t dst_var_idx __attr_unused___ = instr.data.native_call.lhs; const idx_t native_call_id_idx = instr.data.native_call.name; const idx_t args_number = instr.data.native_call.arg_list; - const vm_instr_counter_t lit_oc = frame_ctx_p->pos; + const vm_instr_counter_t __attr_unused___ lit_oc = frame_ctx_p->pos; JERRY_ASSERT (native_call_id_idx < OPCODE_NATIVE_CALL__COUNT); @@ -67,52 +67,6 @@ opfunc_native_call (vm_instr_t instr, /**< instruction */ JERRY_UNIMPLEMENTED ("Device operations are not implemented."); } - case OPCODE_NATIVE_CALL_PRINT: - { - for (ecma_length_t arg_index = 0; - ecma_is_completion_value_empty (ret_value) && arg_index < args_read; - arg_index++) - { - ECMA_TRY_CATCH (str_value, - ecma_op_to_string (arg_values[arg_index]), - ret_value); - - ecma_string_t *str_p = ecma_get_string_from_value (str_value); - - lit_utf8_size_t bytes = ecma_string_get_size (str_p); - - ssize_t utf8_str_size = (ssize_t) (bytes + 1); - lit_utf8_byte_t *utf8_str_p = (lit_utf8_byte_t*) mem_heap_alloc_block ((size_t) utf8_str_size, - MEM_HEAP_ALLOC_SHORT_TERM); - if (utf8_str_p == NULL) - { - jerry_fatal (ERR_OUT_OF_MEMORY); - } - - ecma_string_to_utf8_string (str_p, utf8_str_p, utf8_str_size); - utf8_str_p[utf8_str_size - 1] = 0; - - FIXME ("Support unicode in printf."); - if (arg_index < args_read - 1) - { - printf ("%s ", (char*) utf8_str_p); - } - else - { - printf ("%s", (char*) utf8_str_p); - } - - mem_heap_free_block (utf8_str_p); - - ret_value = set_variable_value (frame_ctx_p, lit_oc, dst_var_idx, - ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED)); - - ECMA_FINALIZE (str_value); - } - printf ("\n"); - break; - } - case OPCODE_NATIVE_CALL__COUNT: { JERRY_UNREACHABLE (); diff --git a/jerry-core/vm/opcodes-native-call.h b/jerry-core/vm/opcodes-native-call.h index 5e49199f0..44712e0f6 100644 --- a/jerry-core/vm/opcodes-native-call.h +++ b/jerry-core/vm/opcodes-native-call.h @@ -26,7 +26,6 @@ typedef enum OPCODE_NATIVE_CALL_LED_OFF, OPCODE_NATIVE_CALL_LED_ONCE, OPCODE_NATIVE_CALL_WAIT, - OPCODE_NATIVE_CALL_PRINT, OPCODE_NATIVE_CALL__COUNT } opcode_native_call_t; diff --git a/jerry-core/vm/pretty-printer.cpp b/jerry-core/vm/pretty-printer.cpp index 955b1757b..3f06205eb 100644 --- a/jerry-core/vm/pretty-printer.cpp +++ b/jerry-core/vm/pretty-printer.cpp @@ -291,7 +291,6 @@ pp_op_meta (const vm_instr_t *instrs_p, case OPCODE_NATIVE_CALL_LED_OFF: printf ("LEDOff ();"); break; case OPCODE_NATIVE_CALL_LED_ONCE: printf ("LEDOnce ();"); break; case OPCODE_NATIVE_CALL_WAIT: printf ("wait ();"); break; - case OPCODE_NATIVE_CALL_PRINT: printf ("print ();"); break; default: JERRY_UNREACHABLE (); } } @@ -434,7 +433,6 @@ pp_op_meta (const vm_instr_t *instrs_p, case OPCODE_NATIVE_CALL_LED_OFF: printf ("LEDOff ("); break; case OPCODE_NATIVE_CALL_LED_ONCE: printf ("LEDOnce ("); break; case OPCODE_NATIVE_CALL_WAIT: printf ("wait ("); break; - case OPCODE_NATIVE_CALL_PRINT: printf ("print ("); break; default: JERRY_UNREACHABLE (); } break;