From 4a7bb710fadbb875f3181f3f633c64e748a6733d Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Wed, 6 Aug 2014 14:17:53 +0400 Subject: [PATCH] Add 'assert' intrinsic --- src/libjsparser/parser.c | 80 +++++++++++++++++++- src/libruntime/target/linux/pretty-printer.c | 35 ++++++++- tests/jerry/arithmetics.js | 5 +- 3 files changed, 113 insertions(+), 7 deletions(-) diff --git a/src/libjsparser/parser.c b/src/libjsparser/parser.c index 1e067f3f5..3dc2907a9 100644 --- a/src/libjsparser/parser.c +++ b/src/libjsparser/parser.c @@ -343,6 +343,55 @@ rewrite_rewritable_opcodes (rewritable_opcode_type type, opcode_counter_t oc) op.head = op.size = 0; } +static int8_t +intrinsic_argument_count (const char *intrinsic) +{ + if (!__strcmp (intrinsic, "assert")) + { + return 1; + } + + return -1; +} + +static bool +is_intrinsic (T_IDX obj) +{ + /* Every literal is represented by assignment to tmp. + so if result of parse_primary_expression less then strings count, + it is identifier, check for intrinsics. */ + uint8_t strings_count = lexer_get_strings (NULL); + if (obj < strings_count) + { + const char *string = lexer_get_string_by_id (obj); + return intrinsic_argument_count (string) >= 0; + } + + return false; +} + +static void +dump_intrinsic (T_IDX obj, T_IDX args[3]) +{ + uint8_t strings_count = lexer_get_strings (NULL); + if (obj < strings_count) + { + const char *string = lexer_get_string_by_id (obj); + if (!__strcmp (string, "assert")) + { + /* Dump opcodes like + is_true_jmp arg, +2 + exitval 1 + */ + DUMP_OPCODE_2 (is_true_jmp, args[0], opcode_counter + 2); + DUMP_OPCODE_1 (exitval, 1); + return; + } + } + + JERRY_UNREACHABLE (); +} + /* property_name : Identifier | StringLiteral @@ -502,10 +551,20 @@ parse_argument_list (argument_list_type alt, T_IDX obj) case AL_FUNC_EXPR: case AL_CONSTRUCT_EXPR: + open_tt = TOK_OPEN_PAREN; + close_tt = TOK_CLOSE_PAREN; + first_opcode_args_count = 1; + lhs = next_temp_name (); + break; + case AL_CALL_EXPR: open_tt = TOK_OPEN_PAREN; close_tt = TOK_CLOSE_PAREN; first_opcode_args_count = 1; + if (is_intrinsic (obj)) + { + break; + } lhs = next_temp_name (); break; @@ -562,6 +621,10 @@ parse_argument_list (argument_list_type alt, T_IDX obj) break; case AL_CALL_EXPR: + if (is_intrinsic (obj)) + { + parser_fatal (ERR_PARSER); + } DUMP_OPCODE_3 (call_n, lhs, obj, args[0]); break; @@ -635,7 +698,14 @@ parse_argument_list (argument_list_type alt, T_IDX obj) break; case AL_CALL_EXPR: - DUMP_OPCODE_3 (call_1, lhs, obj, args[0]); + if (is_intrinsic (obj)) + { + dump_intrinsic (obj, args); + } + else + { + DUMP_OPCODE_3 (call_1, lhs, obj, args[0]); + } break; default: @@ -901,7 +971,9 @@ parse_member_expression (void) { T_IDX lhs, obj, prop; if (is_keyword (KW_FUNCTION)) - obj = parse_function_expression (); + { + obj = parse_function_expression (); + } else if (is_keyword (KW_NEW)) { T_IDX member; @@ -911,7 +983,9 @@ parse_member_expression (void) obj = parse_argument_list (AL_CONSTRUCT_EXPR, member); } else - obj = parse_primary_expression (); + { + obj = parse_primary_expression (); + } skip_newlines (); while (tok.type == TOK_OPEN_SQUARE || tok.type == TOK_DOT) diff --git a/src/libruntime/target/linux/pretty-printer.c b/src/libruntime/target/linux/pretty-printer.c index eee7aa9d2..2535a2815 100644 --- a/src/libruntime/target/linux/pretty-printer.c +++ b/src/libruntime/target/linux/pretty-printer.c @@ -120,7 +120,38 @@ dump_variable (T_IDX id) case NAME_TO_ID (op): \ dump_variable (opcode.data.op.lhs); \ __printf (" " equals " "); \ - dump_variable (opcode.data.op.op2); \ + if (opcode.data.op.type_value_right == OPCODE_ARG_TYPE_SIMPLE) { \ + switch (opcode.data.op.op2) { \ + case ECMA_SIMPLE_VALUE_NULL: \ + __printf ("null"); \ + break; \ + case ECMA_SIMPLE_VALUE_FALSE: \ + __printf ("false"); \ + break; \ + case ECMA_SIMPLE_VALUE_TRUE: \ + __printf ("true"); \ + break; \ + default: \ + JERRY_UNREACHABLE (); \ + } \ + __printf (": SIMPLE"); \ + } else if (opcode.data.op.type_value_right == OPCODE_ARG_TYPE_STRING) { \ + __printf ("'%s'", deserialize_string_by_id (opcode.data.op.op2)); \ + __printf (": STRING"); \ + } else if (opcode.data.op.type_value_right == OPCODE_ARG_TYPE_NUMBER) {\ + __printf ("%d", deserialize_num_by_id (opcode.data.op.op2)); \ + __printf (": NUMBER"); \ + } else if (opcode.data.op.type_value_right == OPCODE_ARG_TYPE_SMALLINT) {\ + __printf ("%d", opcode.data.op.op2); \ + __printf (": NUMBER"); \ + } else if (opcode.data.op.type_value_right == OPCODE_ARG_TYPE_VARIABLE) {\ + dump_variable (opcode.data.op.op2); \ + __printf (": TYPEOF("); \ + dump_variable (opcode.data.op.op2); \ + __printf (")"); \ + } else { \ + JERRY_UNREACHABLE (); \ + } \ __printf (";"); \ break; @@ -331,7 +362,7 @@ pp_opcode (opcode_counter_t oc, OPCODE opcode, bool is_rewrite) switch (opcode_num) { CASE_CONDITIONAL_JUMP (is_true_jmp, "if (", value, ") goto", opcode) - CASE_CONDITIONAL_JUMP (is_false_jmp, "if (!", value, ") goto", opcode) + CASE_CONDITIONAL_JUMP (is_false_jmp, "if (", value, " == false) goto", opcode) CASE_UNCONDITIONAL_JUMP (jmp, "goto", 0, +, opcode_idx) CASE_UNCONDITIONAL_JUMP (jmp_up, "goto", oc, -, opcode_count) diff --git a/tests/jerry/arithmetics.js b/tests/jerry/arithmetics.js index 5400f2d16..d06c7dd79 100644 --- a/tests/jerry/arithmetics.js +++ b/tests/jerry/arithmetics.js @@ -15,5 +15,6 @@ var a = 1; var b = 2; -assertEquals(a+b, 3); -assertEquals(b+a, 3); +assert(a+b == 3); +assert(b+a == 3); +assert(b+a != 4);