mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Implementing 'with' opcode; replacing 'end_with' opcode with 'meta' opcode of corresponding type.
This commit is contained in:
parent
f08c242156
commit
5d2b535cec
@ -45,8 +45,6 @@
|
||||
*/
|
||||
|
||||
#define OP_UNIMPLEMENTED_LIST(op) \
|
||||
op (with) \
|
||||
op (end_with) \
|
||||
static char __unused unimplemented_list_end
|
||||
|
||||
#define DEFINE_UNIMPLEMENTED_OP(op) \
|
||||
@ -1402,6 +1400,68 @@ opfunc_this (opcode_t opdata, /**< operation data */
|
||||
return ret_value;
|
||||
} /* opfunc_this */
|
||||
|
||||
/**
|
||||
* 'With' opcode handler.
|
||||
*
|
||||
* See also: ECMA-262 v5, 12.10
|
||||
*
|
||||
* @return completion value
|
||||
* Returned value must be freed with ecma_free_completion_value
|
||||
*/
|
||||
ecma_completion_value_t
|
||||
opfunc_with (opcode_t opdata, /**< operation data */
|
||||
int_data_t *int_data) /**< interpreter context */
|
||||
{
|
||||
const idx_t expr_var_idx = opdata.data.with.expr;
|
||||
|
||||
int_data->pos++;
|
||||
|
||||
ecma_completion_value_t ret_value;
|
||||
|
||||
ECMA_TRY_CATCH (expr_value,
|
||||
get_variable_value (int_data,
|
||||
expr_var_idx,
|
||||
false),
|
||||
ret_value);
|
||||
ECMA_TRY_CATCH (obj_expr_value,
|
||||
ecma_op_to_object (expr_value.value),
|
||||
ret_value);
|
||||
|
||||
ecma_object_t *obj_p = ECMA_GET_POINTER (obj_expr_value.value.value);
|
||||
|
||||
ecma_object_t *old_env_p = int_data->lex_env_p;
|
||||
ecma_object_t *new_env_p = ecma_create_object_lex_env (old_env_p,
|
||||
obj_p,
|
||||
true);
|
||||
int_data->lex_env_p = new_env_p;
|
||||
|
||||
ecma_completion_value_t evaluation_completion = run_int_loop (int_data);
|
||||
|
||||
if (evaluation_completion.type == ECMA_COMPLETION_TYPE_META)
|
||||
{
|
||||
opcode_t meta_opcode = read_opcode (int_data->pos);
|
||||
JERRY_ASSERT (meta_opcode.op_idx == __op__idx_meta);
|
||||
JERRY_ASSERT (meta_opcode.data.meta.type == OPCODE_META_TYPE_END_WITH);
|
||||
|
||||
int_data->pos++;
|
||||
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = evaluation_completion;
|
||||
}
|
||||
|
||||
int_data->lex_env_p = old_env_p;
|
||||
|
||||
ecma_deref_object (new_env_p);
|
||||
|
||||
ECMA_FINALIZE (obj_expr_value);
|
||||
ECMA_FINALIZE (expr_value);
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_with */
|
||||
|
||||
/**
|
||||
* Evaluate argument of typeof.
|
||||
*
|
||||
@ -1682,6 +1742,7 @@ opfunc_meta (opcode_t opdata, /**< operation data */
|
||||
switch (type)
|
||||
{
|
||||
case OPCODE_META_TYPE_VARG:
|
||||
case OPCODE_META_TYPE_END_WITH:
|
||||
{
|
||||
return ecma_make_completion_value (ECMA_COMPLETION_TYPE_META,
|
||||
ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY),
|
||||
|
||||
@ -56,7 +56,8 @@ typedef enum
|
||||
OPCODE_META_TYPE_VARG, /**< element (var_idx) of arguments' list */
|
||||
OPCODE_META_TYPE_VARG_PROP_DATA, /**< name (lit_idx) and value (var_idx) for a data property descriptor */
|
||||
OPCODE_META_TYPE_VARG_PROP_GETTER, /**< name (lit_idx) and getter (var_idx) for an accessor property descriptor */
|
||||
OPCODE_META_TYPE_VARG_PROP_SETTER /**< name (lit_idx) and setter (var_idx) for an accessor property descriptor */
|
||||
OPCODE_META_TYPE_VARG_PROP_SETTER, /**< name (lit_idx) and setter (var_idx) for an accessor property descriptor */
|
||||
OPCODE_META_TYPE_END_WITH /**< end of with statement */
|
||||
} opcode_meta_type;
|
||||
|
||||
typedef struct
|
||||
@ -95,8 +96,7 @@ typedef struct
|
||||
p##_2 (a, delete_var, lhs, name) \
|
||||
p##_3 (a, delete_prop, lhs, base, name) \
|
||||
p##_2 (a, typeof, lhs, obj) \
|
||||
p##_1 (a, with, expr) \
|
||||
p##_0 (a, end_with)
|
||||
p##_1 (a, with, expr)
|
||||
|
||||
#define OP_ASSIGNMENTS(p, a) \
|
||||
p##_3 (a, assignment, var_left, type_value_right, value_right)
|
||||
|
||||
@ -93,7 +93,8 @@ ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< out
|
||||
ecma_object_t *binding_obj_p, /**< binding object */
|
||||
bool provide_this) /**< provideThis flag */
|
||||
{
|
||||
JERRY_ASSERT(binding_obj_p != NULL);
|
||||
JERRY_ASSERT(binding_obj_p != NULL
|
||||
&& !binding_obj_p->is_lexical_environment);
|
||||
|
||||
ecma_object_t *new_lexical_environment_p = ecma_alloc_object ();
|
||||
ecma_init_gc_info (new_lexical_environment_p);
|
||||
|
||||
@ -391,7 +391,24 @@ ecma_op_to_string (ecma_value_t value) /**< ecma-value */
|
||||
ecma_completion_value_t
|
||||
ecma_op_to_object (ecma_value_t value) /**< ecma-value */
|
||||
{
|
||||
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS(value);
|
||||
switch ((ecma_type_t)value.value_type)
|
||||
{
|
||||
case ECMA_TYPE_SIMPLE:
|
||||
case ECMA_TYPE_NUMBER:
|
||||
case ECMA_TYPE_STRING:
|
||||
{
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
}
|
||||
|
||||
case ECMA_TYPE_OBJECT:
|
||||
{
|
||||
return ecma_make_completion_value (ECMA_COMPLETION_TYPE_NORMAL,
|
||||
ecma_copy_value (value, true),
|
||||
ECMA_TARGET_ID_RESERVED);
|
||||
}
|
||||
}
|
||||
|
||||
JERRY_UNREACHABLE ();
|
||||
} /* ecma_op_to_object */
|
||||
|
||||
/**
|
||||
|
||||
@ -36,6 +36,9 @@
|
||||
ecma_object_t*
|
||||
ecma_new_standard_error (ecma_standard_error_t error_type) /**< native error type */
|
||||
{
|
||||
/* SyntaxError should be treated as an early error */
|
||||
JERRY_ASSERT (error_type != ECMA_ERROR_SYNTAX);
|
||||
|
||||
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS(error_type);
|
||||
} /* ecma_new_standard_error */
|
||||
|
||||
|
||||
@ -2083,7 +2083,7 @@ parse_with_statement (void)
|
||||
skip_newlines ();
|
||||
parse_statement ();
|
||||
|
||||
DUMP_VOID_OPCODE (end_with);
|
||||
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_END_WITH, INVALID_VALUE, INVALID_VALUE);
|
||||
}
|
||||
|
||||
/* switch_statement
|
||||
|
||||
@ -347,8 +347,7 @@ pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite)
|
||||
uint8_t opcode_num = opcode.op_idx;
|
||||
|
||||
__printf ("%3d: %20s ", oc, opcode_names[opcode_num]);
|
||||
if (opcode_num != NAME_TO_ID (nop) && opcode_num != NAME_TO_ID (ret)
|
||||
&& opcode_num != NAME_TO_ID (end_with))
|
||||
if (opcode_num != NAME_TO_ID (nop) && opcode_num != NAME_TO_ID (ret))
|
||||
{
|
||||
for (i = 1; i < opcode_sizes[opcode_num]; i++)
|
||||
{
|
||||
@ -415,7 +414,6 @@ pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite)
|
||||
CASE_EXIT (exitval, "exit", status_code)
|
||||
CASE_SINGLE_ADDRESS (retval, "return", ret_value)
|
||||
CASE_ZERO_ADDRESS (ret, "return")
|
||||
CASE_ZERO_ADDRESS (end_with, "")
|
||||
CASE_ZERO_ADDRESS (nop, "")
|
||||
TODO (Refine to match new opcodes)
|
||||
CASE_VARG_1_LHS (array_decl, lhs, "=", "[", list, "]")
|
||||
|
||||
@ -38,8 +38,7 @@ opcodes_equal (const opcode_t *opcodes1, opcode_t *opcodes2, uint16_t size)
|
||||
if (opcode_num1 != opcode_num2)
|
||||
return false;
|
||||
|
||||
if (opcode_num1 == NAME_TO_ID (nop) || opcode_num1 == NAME_TO_ID (ret)
|
||||
|| opcode_num1 == NAME_TO_ID (end_with))
|
||||
if (opcode_num1 == NAME_TO_ID (nop) || opcode_num1 == NAME_TO_ID (ret))
|
||||
return true;
|
||||
|
||||
for (j = 1; j < opcode_sizes[opcode_num1]; j++)
|
||||
@ -50,4 +49,4 @@ opcodes_equal (const opcode_t *opcodes1, opcode_t *opcodes2, uint16_t size)
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // COMMON_H
|
||||
#endif // COMMON_H
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user