Add 'assert' intrinsic

This commit is contained in:
Ilmir Usmanov 2014-08-06 14:17:53 +04:00
parent 137ace24db
commit 4a7bb710fa
3 changed files with 113 additions and 7 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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);