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
This commit is contained in:
@@ -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 <NUL> 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
|
* The Global object's 'eval' routine
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -221,6 +221,10 @@ OBJECT_VALUE (LIT_MAGIC_STRING_COMPACT_PROFILE_ERROR_UL,
|
|||||||
|
|
||||||
/* Routine properties:
|
/* Routine properties:
|
||||||
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
|
* (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_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_PARSE_FLOAT, ecma_builtin_global_object_parse_float, 1, 1)
|
||||||
ROUTINE (LIT_MAGIC_STRING_IS_NAN, ecma_builtin_global_object_is_nan, 1, 1)
|
ROUTINE (LIT_MAGIC_STRING_IS_NAN, ecma_builtin_global_object_is_nan, 1, 1)
|
||||||
|
|||||||
@@ -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_TEST, "test")
|
||||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_NAME, "name")
|
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_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_G_CHAR, "g")
|
||||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_I_CHAR, "i")
|
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_I_CHAR, "i")
|
||||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_M_CHAR, "m")
|
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_M_CHAR, "m")
|
||||||
|
|||||||
@@ -248,10 +248,7 @@ name_to_native_call_id (operand obj)
|
|||||||
{
|
{
|
||||||
return OPCODE_NATIVE_CALL_WAIT;
|
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;
|
return OPCODE_NATIVE_CALL__COUNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,10 +31,10 @@ ecma_completion_value_t
|
|||||||
opfunc_native_call (vm_instr_t instr, /**< instruction */
|
opfunc_native_call (vm_instr_t instr, /**< instruction */
|
||||||
vm_frame_ctx_t *frame_ctx_p) /**< interpreter context */
|
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 native_call_id_idx = instr.data.native_call.name;
|
||||||
const idx_t args_number = instr.data.native_call.arg_list;
|
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);
|
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.");
|
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:
|
case OPCODE_NATIVE_CALL__COUNT:
|
||||||
{
|
{
|
||||||
JERRY_UNREACHABLE ();
|
JERRY_UNREACHABLE ();
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ typedef enum
|
|||||||
OPCODE_NATIVE_CALL_LED_OFF,
|
OPCODE_NATIVE_CALL_LED_OFF,
|
||||||
OPCODE_NATIVE_CALL_LED_ONCE,
|
OPCODE_NATIVE_CALL_LED_ONCE,
|
||||||
OPCODE_NATIVE_CALL_WAIT,
|
OPCODE_NATIVE_CALL_WAIT,
|
||||||
OPCODE_NATIVE_CALL_PRINT,
|
|
||||||
OPCODE_NATIVE_CALL__COUNT
|
OPCODE_NATIVE_CALL__COUNT
|
||||||
} opcode_native_call_t;
|
} opcode_native_call_t;
|
||||||
|
|
||||||
|
|||||||
@@ -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_OFF: printf ("LEDOff ();"); break;
|
||||||
case OPCODE_NATIVE_CALL_LED_ONCE: printf ("LEDOnce ();"); break;
|
case OPCODE_NATIVE_CALL_LED_ONCE: printf ("LEDOnce ();"); break;
|
||||||
case OPCODE_NATIVE_CALL_WAIT: printf ("wait ();"); break;
|
case OPCODE_NATIVE_CALL_WAIT: printf ("wait ();"); break;
|
||||||
case OPCODE_NATIVE_CALL_PRINT: printf ("print ();"); break;
|
|
||||||
default: JERRY_UNREACHABLE ();
|
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_OFF: printf ("LEDOff ("); break;
|
||||||
case OPCODE_NATIVE_CALL_LED_ONCE: printf ("LEDOnce ("); break;
|
case OPCODE_NATIVE_CALL_LED_ONCE: printf ("LEDOnce ("); break;
|
||||||
case OPCODE_NATIVE_CALL_WAIT: printf ("wait ("); break;
|
case OPCODE_NATIVE_CALL_WAIT: printf ("wait ("); break;
|
||||||
case OPCODE_NATIVE_CALL_PRINT: printf ("print ("); break;
|
|
||||||
default: JERRY_UNREACHABLE ();
|
default: JERRY_UNREACHABLE ();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user