Add 'assert' intrinsic
This commit is contained in:
@@ -343,6 +343,55 @@ rewrite_rewritable_opcodes (rewritable_opcode_type type, opcode_counter_t oc)
|
|||||||
op.head = op.size = 0;
|
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
|
/* property_name
|
||||||
: Identifier
|
: Identifier
|
||||||
| StringLiteral
|
| StringLiteral
|
||||||
@@ -502,10 +551,20 @@ parse_argument_list (argument_list_type alt, T_IDX obj)
|
|||||||
|
|
||||||
case AL_FUNC_EXPR:
|
case AL_FUNC_EXPR:
|
||||||
case AL_CONSTRUCT_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:
|
case AL_CALL_EXPR:
|
||||||
open_tt = TOK_OPEN_PAREN;
|
open_tt = TOK_OPEN_PAREN;
|
||||||
close_tt = TOK_CLOSE_PAREN;
|
close_tt = TOK_CLOSE_PAREN;
|
||||||
first_opcode_args_count = 1;
|
first_opcode_args_count = 1;
|
||||||
|
if (is_intrinsic (obj))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
lhs = next_temp_name ();
|
lhs = next_temp_name ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -562,6 +621,10 @@ parse_argument_list (argument_list_type alt, T_IDX obj)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case AL_CALL_EXPR:
|
case AL_CALL_EXPR:
|
||||||
|
if (is_intrinsic (obj))
|
||||||
|
{
|
||||||
|
parser_fatal (ERR_PARSER);
|
||||||
|
}
|
||||||
DUMP_OPCODE_3 (call_n, lhs, obj, args[0]);
|
DUMP_OPCODE_3 (call_n, lhs, obj, args[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -635,7 +698,14 @@ parse_argument_list (argument_list_type alt, T_IDX obj)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case AL_CALL_EXPR:
|
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;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -901,7 +971,9 @@ parse_member_expression (void)
|
|||||||
{
|
{
|
||||||
T_IDX lhs, obj, prop;
|
T_IDX lhs, obj, prop;
|
||||||
if (is_keyword (KW_FUNCTION))
|
if (is_keyword (KW_FUNCTION))
|
||||||
obj = parse_function_expression ();
|
{
|
||||||
|
obj = parse_function_expression ();
|
||||||
|
}
|
||||||
else if (is_keyword (KW_NEW))
|
else if (is_keyword (KW_NEW))
|
||||||
{
|
{
|
||||||
T_IDX member;
|
T_IDX member;
|
||||||
@@ -911,7 +983,9 @@ parse_member_expression (void)
|
|||||||
obj = parse_argument_list (AL_CONSTRUCT_EXPR, member);
|
obj = parse_argument_list (AL_CONSTRUCT_EXPR, member);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
obj = parse_primary_expression ();
|
{
|
||||||
|
obj = parse_primary_expression ();
|
||||||
|
}
|
||||||
|
|
||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
while (tok.type == TOK_OPEN_SQUARE || tok.type == TOK_DOT)
|
while (tok.type == TOK_OPEN_SQUARE || tok.type == TOK_DOT)
|
||||||
|
|||||||
@@ -120,7 +120,38 @@ dump_variable (T_IDX id)
|
|||||||
case NAME_TO_ID (op): \
|
case NAME_TO_ID (op): \
|
||||||
dump_variable (opcode.data.op.lhs); \
|
dump_variable (opcode.data.op.lhs); \
|
||||||
__printf (" " equals " "); \
|
__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 (";"); \
|
__printf (";"); \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -331,7 +362,7 @@ pp_opcode (opcode_counter_t oc, OPCODE opcode, bool is_rewrite)
|
|||||||
switch (opcode_num)
|
switch (opcode_num)
|
||||||
{
|
{
|
||||||
CASE_CONDITIONAL_JUMP (is_true_jmp, "if (", value, ") goto", opcode)
|
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, "goto", 0, +, opcode_idx)
|
||||||
CASE_UNCONDITIONAL_JUMP (jmp_up, "goto", oc, -, opcode_count)
|
CASE_UNCONDITIONAL_JUMP (jmp_up, "goto", oc, -, opcode_count)
|
||||||
|
|||||||
@@ -15,5 +15,6 @@
|
|||||||
var a = 1;
|
var a = 1;
|
||||||
var b = 2;
|
var b = 2;
|
||||||
|
|
||||||
assertEquals(a+b, 3);
|
assert(a+b == 3);
|
||||||
assertEquals(b+a, 3);
|
assert(b+a == 3);
|
||||||
|
assert(b+a != 4);
|
||||||
|
|||||||
Reference in New Issue
Block a user