From 42876bdc8f9ea6fd8b9ee3ab7f7bfb98174e3257 Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Thu, 25 Sep 2014 15:57:18 +0400 Subject: [PATCH] Add support of native calls --- src/libcoreint/opcodes-native-call.c | 4 ++ src/libjsparser/parser.c | 88 +++++++++++++++++++++++++++- src/liboptimizer/pretty-printer.c | 1 + 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/libcoreint/opcodes-native-call.c b/src/libcoreint/opcodes-native-call.c index ffe80b415..ccaa61cf6 100644 --- a/src/libcoreint/opcodes-native-call.c +++ b/src/libcoreint/opcodes-native-call.c @@ -37,6 +37,10 @@ opfunc_native_call (opcode_t opdata, /**< operation data */ const idx_t native_call_id_idx = opdata.data.native_call.name; const idx_t args_number = opdata.data.native_call.arg_list; + JERRY_ASSERT (native_call_id_idx < OPCODE_NATIVE_CALL__COUNT); + + int_data->pos++; + JERRY_STATIC_ASSERT (OPCODE_NATIVE_CALL__COUNT < (1u << (sizeof (native_call_id_idx) * JERRY_BITSINBYTE))); ecma_value_t arg_values[args_number + 1 /* length of array should not be zero */]; diff --git a/src/libjsparser/parser.c b/src/libjsparser/parser.c index c05299211..7af0c7725 100644 --- a/src/libjsparser/parser.c +++ b/src/libjsparser/parser.c @@ -23,6 +23,7 @@ #include "stack.h" #include "hash-table.h" #include "deserializer.h" +#include "opcodes-native-call.h" #define INVALID_VALUE 255 #define INTRINSICS_COUNT 1 @@ -60,6 +61,7 @@ STATIC_STACK (U8, uint8_t, uint8_t) enum { + native_calls = OPCODE_NATIVE_CALL__COUNT, IDX_global_size }; STATIC_STACK (IDX, uint8_t, uint8_t) @@ -593,6 +595,40 @@ dump_intrinsic (idx_t obj, idx_t arg) JERRY_UNREACHABLE (); } +static bool +is_native_call (idx_t obj) +{ + if (obj >= lexer_get_strings_count ()) + { + return false; + } + + for (uint8_t i = 0; i < OPCODE_NATIVE_CALL__COUNT; i++) + { + if (STACK_ELEMENT (IDX, i) == obj) + { + return true; + } + } + return false; +} + +static idx_t +name_to_native_call_id (idx_t obj) +{ + JERRY_ASSERT (obj < lexer_get_strings_count ()); + + for (uint8_t i = 0; i < OPCODE_NATIVE_CALL__COUNT; i++) + { + if (STACK_ELEMENT (IDX, i) == obj) + { + return i; + } + } + + JERRY_UNREACHABLE (); +} + /* property_name : Identifier | StringLiteral @@ -782,6 +818,12 @@ parse_argument_list (argument_list_type alt, idx_t obj) { break; } + else if (is_native_call (obj)) + { + STACK_PUSH (IDX, next_temp_name ()); + DUMP_OPCODE_3 (native_call, STACK_HEAD (IDX, 1), + name_to_native_call_id (obj), INVALID_VALUE); + } else { STACK_PUSH (IDX, next_temp_name ()); @@ -895,9 +937,15 @@ next: { break; } + else if (is_native_call (obj)) + { + REWRITE_OPCODE_3 (STACK_HEAD (U16, 1), native_call, STACK_HEAD (IDX, 1), + name_to_native_call_id (obj), STACK_HEAD (U8, 1)); + } else { - REWRITE_OPCODE_3 (STACK_HEAD (U16, 1), call_n, STACK_HEAD (IDX, 1), obj, STACK_HEAD (U8, 1)); + REWRITE_OPCODE_3 (STACK_HEAD (U16, 1), call_n, STACK_HEAD (IDX, 1), obj, + STACK_HEAD (U8, 1)); } break; } @@ -2929,7 +2977,9 @@ parser_init (const char *source, size_t source_size, bool show_opcodes) lexer_adjust_num_ids (); - serializer_dump_strings_and_nums (lexer_get_strings (), lexer_get_strings_count (), + const lp_string *identifiers = lexer_get_strings (); + + serializer_dump_strings_and_nums (identifiers, lexer_get_strings_count (), lexer_get_nums (), lexer_get_nums_count ()); STACK_INIT (uint8_t, U8); @@ -2948,6 +2998,40 @@ parser_init (const char *source, size_t source_size, bool show_opcodes) MAX_TEMP_NAME () = TEMP_NAME () = MIN_TEMP_NAME () = lexer_get_reserved_ids_count (); OPCODE_COUNTER () = 0; + + TODO (/* Rewrite using hash when number of natives reaches 20 */) + for (uint8_t i = 0; i < OPCODE_NATIVE_CALL__COUNT; i++) + { + STACK_ELEMENT (IDX, i) = INVALID_VALUE; + } + + for (uint8_t i = 0, strs_count = lexer_get_strings_count (); i < strs_count; i++) + { + if (lp_string_equal_s (identifiers[i], "LEDToggle")) + { + STACK_ELEMENT (IDX, OPCODE_NATIVE_CALL_LED_TOGGLE) = i; + } + else if (lp_string_equal_s (identifiers[i], "LEDOn")) + { + STACK_ELEMENT (IDX, OPCODE_NATIVE_CALL_LED_ON) = i; + } + else if (lp_string_equal_s (identifiers[i], "LEDOff")) + { + STACK_ELEMENT (IDX, OPCODE_NATIVE_CALL_LED_OFF) = i; + } + else if (lp_string_equal_s (identifiers[i], "LEDOnce")) + { + STACK_ELEMENT (IDX, OPCODE_NATIVE_CALL_LED_ONCE) = i; + } + else if (lp_string_equal_s (identifiers[i], "wait")) + { + STACK_ELEMENT (IDX, OPCODE_NATIVE_CALL_WAIT) = i; + } + else if (lp_string_equal_s (identifiers[i], "print")) + { + STACK_ELEMENT (IDX, OPCODE_NATIVE_CALL_PRINT) = i; + } + } } void diff --git a/src/liboptimizer/pretty-printer.c b/src/liboptimizer/pretty-printer.c index 4258d5d5f..6c55080be 100644 --- a/src/liboptimizer/pretty-printer.c +++ b/src/liboptimizer/pretty-printer.c @@ -431,6 +431,7 @@ pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite) CASE_WITH (with, expr) CASE_VARG_0_NAME (var_decl, "var", variable_name, "", "") CASE_REG_VAR_DECL (reg_var_decl, min, max) + CASE_VARG_N_NAME_LHS (native_call, lhs, "=", "", name, arg_list) } if (is_rewrite)