Introducing 'opcode counter' type for 'meta' opcode; replacing 'jmp_down' opcodes that are used as pointers only with 'meta' opcodes of the introduced type.
This commit is contained in:
+1
-1
@@ -37,7 +37,7 @@ typedef signed long ssize_t;
|
|||||||
/**
|
/**
|
||||||
* Constants
|
* Constants
|
||||||
*/
|
*/
|
||||||
#define JERRY_BITSINBYTE 8
|
#define JERRY_BITSINBYTE 8u
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error codes
|
* Error codes
|
||||||
|
|||||||
+41
-12
@@ -467,18 +467,15 @@ function_declaration (int_data_t *int_data, /**< interpreter context */
|
|||||||
const bool is_strict = int_data->is_strict;
|
const bool is_strict = int_data->is_strict;
|
||||||
const bool is_configurable_bindings = int_data->is_eval_code;
|
const bool is_configurable_bindings = int_data->is_eval_code;
|
||||||
|
|
||||||
const opcode_counter_t jmp_down_opcode_idx = (opcode_counter_t) (int_data->pos);
|
const opcode_counter_t function_code_begin_oc = (opcode_counter_t) (int_data->pos + 1);
|
||||||
opcode_t jmp_down_opcode = read_opcode (jmp_down_opcode_idx);
|
|
||||||
JERRY_ASSERT (jmp_down_opcode.op_idx == __op__idx_jmp_down);
|
|
||||||
int_data->pos = (opcode_counter_t) (jmp_down_opcode_idx + jmp_down_opcode.data.jmp_down.opcode_count);
|
|
||||||
|
|
||||||
const opcode_counter_t function_code_opcode_idx = (opcode_counter_t) (jmp_down_opcode_idx + 1);
|
int_data->pos = read_meta_opcode_counter (int_data);
|
||||||
|
|
||||||
ecma_string_t *function_name_string_p = ecma_new_ecma_string_from_lit_index (function_name_lit_idx);
|
ecma_string_t *function_name_string_p = ecma_new_ecma_string_from_lit_index (function_name_lit_idx);
|
||||||
|
|
||||||
ecma_completion_value_t ret_value = ecma_op_function_declaration (int_data->lex_env_p,
|
ecma_completion_value_t ret_value = ecma_op_function_declaration (int_data->lex_env_p,
|
||||||
function_name_string_p,
|
function_name_string_p,
|
||||||
function_code_opcode_idx,
|
function_code_begin_oc,
|
||||||
args_names,
|
args_names,
|
||||||
args_number,
|
args_number,
|
||||||
is_strict,
|
is_strict,
|
||||||
@@ -618,12 +615,9 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */
|
|||||||
|
|
||||||
fill_params_list (int_data, params_number, params_names);
|
fill_params_list (int_data, params_number, params_names);
|
||||||
|
|
||||||
const opcode_counter_t jmp_down_opcode_idx = (opcode_counter_t) (int_data->pos);
|
const opcode_counter_t function_code_begin_oc = (opcode_counter_t) (int_data->pos + 1);
|
||||||
opcode_t jmp_down_opcode = read_opcode (jmp_down_opcode_idx);
|
|
||||||
JERRY_ASSERT (jmp_down_opcode.op_idx == __op__idx_jmp_down);
|
|
||||||
int_data->pos = (opcode_counter_t) (jmp_down_opcode_idx + jmp_down_opcode.data.jmp_down.opcode_count);
|
|
||||||
|
|
||||||
const opcode_counter_t function_code_opcode_idx = (opcode_counter_t) (jmp_down_opcode_idx + 1);
|
int_data->pos = read_meta_opcode_counter (int_data);
|
||||||
|
|
||||||
ecma_object_t *scope_p;
|
ecma_object_t *scope_p;
|
||||||
ecma_string_t *function_name_string_p = NULL;
|
ecma_string_t *function_name_string_p = NULL;
|
||||||
@@ -644,7 +638,7 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */
|
|||||||
params_number,
|
params_number,
|
||||||
scope_p,
|
scope_p,
|
||||||
is_strict,
|
is_strict,
|
||||||
function_code_opcode_idx);
|
function_code_begin_oc);
|
||||||
|
|
||||||
ecma_completion_value_t ret_value = set_variable_value (int_data,
|
ecma_completion_value_t ret_value = set_variable_value (int_data,
|
||||||
dst_var_idx,
|
dst_var_idx,
|
||||||
@@ -1752,6 +1746,7 @@ opfunc_meta (opcode_t opdata, /**< operation data */
|
|||||||
case OPCODE_META_TYPE_VARG_PROP_DATA:
|
case OPCODE_META_TYPE_VARG_PROP_DATA:
|
||||||
case OPCODE_META_TYPE_VARG_PROP_GETTER:
|
case OPCODE_META_TYPE_VARG_PROP_GETTER:
|
||||||
case OPCODE_META_TYPE_VARG_PROP_SETTER:
|
case OPCODE_META_TYPE_VARG_PROP_SETTER:
|
||||||
|
case OPCODE_META_TYPE_OPCODE_COUNTER:
|
||||||
{
|
{
|
||||||
JERRY_UNREACHABLE ();
|
JERRY_UNREACHABLE ();
|
||||||
}
|
}
|
||||||
@@ -1760,6 +1755,40 @@ opfunc_meta (opcode_t opdata, /**< operation data */
|
|||||||
JERRY_UNREACHABLE ();
|
JERRY_UNREACHABLE ();
|
||||||
} /* opfunc_meta */
|
} /* opfunc_meta */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate opcode counter from 'meta' opcode's data arguments.
|
||||||
|
*
|
||||||
|
* @return opcode counter
|
||||||
|
*/
|
||||||
|
opcode_counter_t
|
||||||
|
calc_meta_opcode_counter_from_meta_data (const idx_t data_1, /**< first data argument */
|
||||||
|
const idx_t data_2) /**< second data argument */
|
||||||
|
{
|
||||||
|
opcode_counter_t counter;
|
||||||
|
|
||||||
|
counter = data_1;
|
||||||
|
counter = (opcode_counter_t) (counter << (sizeof (data_2) * JERRY_BITSINBYTE));
|
||||||
|
counter = (opcode_counter_t) (counter | data_2);
|
||||||
|
|
||||||
|
return counter;
|
||||||
|
} /* calc_meta_opcode_counter_from_meta_data */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read opcode counter from current opcode,
|
||||||
|
* that should be 'meta' opcode of type 'opcode counter'.
|
||||||
|
*/
|
||||||
|
opcode_counter_t
|
||||||
|
read_meta_opcode_counter (int_data_t *int_data) /**< interpreter context */
|
||||||
|
{
|
||||||
|
opcode_t meta_opcode = read_opcode (int_data->pos);
|
||||||
|
JERRY_ASSERT (meta_opcode.data.meta.type == OPCODE_META_TYPE_OPCODE_COUNTER);
|
||||||
|
|
||||||
|
const idx_t data_1 = meta_opcode.data.meta.data_1;
|
||||||
|
const idx_t data_2 = meta_opcode.data.meta.data_2;
|
||||||
|
|
||||||
|
return calc_meta_opcode_counter_from_meta_data (data_1, data_2);
|
||||||
|
} /* read_meta_opcode_counter */
|
||||||
|
|
||||||
#define GETOP_DEF_1(a, name, field1) \
|
#define GETOP_DEF_1(a, name, field1) \
|
||||||
inline opcode_t getop_##name (idx_t arg1) \
|
inline opcode_t getop_##name (idx_t arg1) \
|
||||||
{ \
|
{ \
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ typedef enum
|
|||||||
OPCODE_META_TYPE_VARG_PROP_DATA, /**< name (lit_idx) and value (var_idx) for a data property descriptor */
|
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_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_END_WITH, /**< end of with statement */
|
||||||
|
OPCODE_META_TYPE_OPCODE_COUNTER /**< opcode counter */
|
||||||
} opcode_meta_type;
|
} opcode_meta_type;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -72,6 +73,9 @@ typedef struct
|
|||||||
ecma_value_t *regs_p; /**< register variables */
|
ecma_value_t *regs_p; /**< register variables */
|
||||||
} int_data_t;
|
} int_data_t;
|
||||||
|
|
||||||
|
opcode_counter_t calc_meta_opcode_counter_from_meta_data (const idx_t data_1, const idx_t data_2);
|
||||||
|
opcode_counter_t read_meta_opcode_counter (int_data_t *int_data);
|
||||||
|
|
||||||
#define OP_CALLS_AND_ARGS(p, a) \
|
#define OP_CALLS_AND_ARGS(p, a) \
|
||||||
p##_2 (a, call_0, lhs, name_lit_idx) \
|
p##_2 (a, call_0, lhs, name_lit_idx) \
|
||||||
p##_3 (a, call_1, lhs, name_lit_idx, arg1_lit_idx) \
|
p##_3 (a, call_1, lhs, name_lit_idx, arg1_lit_idx) \
|
||||||
|
|||||||
@@ -894,6 +894,20 @@ parse_argument_list (argument_list_type alt, idx_t obj)
|
|||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rewrite_meta_opcode_counter (opcode_counter_t meta_oc,
|
||||||
|
opcode_counter_t new_value)
|
||||||
|
{
|
||||||
|
JERRY_STATIC_ASSERT (sizeof (idx_t) == 1);
|
||||||
|
|
||||||
|
const idx_t data_1 = (idx_t) (new_value >> JERRY_BITSINBYTE);
|
||||||
|
const idx_t data_2 = (idx_t) (new_value & ((1 << JERRY_BITSINBYTE) - 1));
|
||||||
|
|
||||||
|
JERRY_ASSERT (new_value == calc_meta_opcode_counter_from_meta_data (data_1, data_2));
|
||||||
|
|
||||||
|
REWRITE_OPCODE_3 (meta_oc, meta, OPCODE_META_TYPE_OPCODE_COUNTER, data_1, data_2);
|
||||||
|
}
|
||||||
|
|
||||||
/* function_declaration
|
/* function_declaration
|
||||||
: 'function' LT!* Identifier LT!*
|
: 'function' LT!* Identifier LT!*
|
||||||
'(' (LT!* Identifier (LT!* ',' LT!* Identifier)*) ? LT!* ')' LT!* function_body
|
'(' (LT!* Identifier (LT!* ',' LT!* Identifier)*) ? LT!* ')' LT!* function_body
|
||||||
@@ -905,7 +919,7 @@ static void
|
|||||||
parse_function_declaration (void)
|
parse_function_declaration (void)
|
||||||
{
|
{
|
||||||
idx_t name;
|
idx_t name;
|
||||||
opcode_counter_t jmp_oc;
|
opcode_counter_t meta_oc;
|
||||||
|
|
||||||
assert_keyword (KW_FUNCTION);
|
assert_keyword (KW_FUNCTION);
|
||||||
|
|
||||||
@@ -916,8 +930,8 @@ parse_function_declaration (void)
|
|||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
parse_argument_list (AL_FUNC_DECL, name);
|
parse_argument_list (AL_FUNC_DECL, name);
|
||||||
|
|
||||||
jmp_oc = opcode_counter;
|
meta_oc = opcode_counter;
|
||||||
DUMP_OPCODE_1 (jmp_down, INVALID_VALUE);
|
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_OPCODE_COUNTER, INVALID_VALUE, INVALID_VALUE);
|
||||||
|
|
||||||
token_after_newlines_must_be (TOK_OPEN_BRACE);
|
token_after_newlines_must_be (TOK_OPEN_BRACE);
|
||||||
|
|
||||||
@@ -929,7 +943,8 @@ parse_function_declaration (void)
|
|||||||
next_token_must_be (TOK_CLOSE_BRACE);
|
next_token_must_be (TOK_CLOSE_BRACE);
|
||||||
|
|
||||||
DUMP_VOID_OPCODE (ret);
|
DUMP_VOID_OPCODE (ret);
|
||||||
REWRITE_OPCODE_1 (jmp_oc, jmp_down, opcode_counter - jmp_oc);
|
|
||||||
|
rewrite_meta_opcode_counter (meta_oc, opcode_counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* function_expression
|
/* function_expression
|
||||||
@@ -939,7 +954,7 @@ static idx_t
|
|||||||
parse_function_expression (void)
|
parse_function_expression (void)
|
||||||
{
|
{
|
||||||
idx_t name, lhs;
|
idx_t name, lhs;
|
||||||
opcode_counter_t jmp_oc;
|
opcode_counter_t meta_oc;
|
||||||
|
|
||||||
assert_keyword (KW_FUNCTION);
|
assert_keyword (KW_FUNCTION);
|
||||||
|
|
||||||
@@ -957,8 +972,8 @@ parse_function_expression (void)
|
|||||||
skip_newlines ();
|
skip_newlines ();
|
||||||
lhs = parse_argument_list (AL_FUNC_EXPR, name);
|
lhs = parse_argument_list (AL_FUNC_EXPR, name);
|
||||||
|
|
||||||
jmp_oc = opcode_counter;
|
meta_oc = opcode_counter;
|
||||||
DUMP_OPCODE_1 (jmp_down, INVALID_VALUE);
|
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_OPCODE_COUNTER, INVALID_VALUE, INVALID_VALUE);
|
||||||
|
|
||||||
token_after_newlines_must_be (TOK_OPEN_BRACE);
|
token_after_newlines_must_be (TOK_OPEN_BRACE);
|
||||||
|
|
||||||
@@ -970,7 +985,7 @@ parse_function_expression (void)
|
|||||||
token_after_newlines_must_be (TOK_CLOSE_BRACE);
|
token_after_newlines_must_be (TOK_CLOSE_BRACE);
|
||||||
|
|
||||||
DUMP_VOID_OPCODE (ret);
|
DUMP_VOID_OPCODE (ret);
|
||||||
REWRITE_OPCODE_1 (jmp_oc, jmp_down, opcode_counter - jmp_oc);
|
rewrite_meta_opcode_counter (meta_oc, opcode_counter);
|
||||||
|
|
||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,16 +30,17 @@ function f1(x)
|
|||||||
assert(t === false);
|
assert(t === false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var i;
|
||||||
var t = true;
|
var t = true;
|
||||||
|
|
||||||
for(var i = 1; i <= 10; i++)
|
for(i = 1; i <= 10; i++)
|
||||||
{
|
{
|
||||||
f1(i);
|
f1(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
t = false;
|
t = false;
|
||||||
|
|
||||||
for(var i = 11; i <= 20; i++)
|
for(i = 11; i <= 20; i++)
|
||||||
{
|
{
|
||||||
f1(i);
|
f1(i);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,14 +12,8 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
var k;
|
|
||||||
|
|
||||||
function f1()
|
function f1()
|
||||||
{
|
{
|
||||||
k = 17;
|
|
||||||
|
|
||||||
f2();
|
|
||||||
|
|
||||||
function f2()
|
function f2()
|
||||||
{
|
{
|
||||||
assert(k > 0);
|
assert(k > 0);
|
||||||
@@ -32,9 +26,16 @@ function f1()
|
|||||||
|
|
||||||
f2();
|
f2();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
k = 17;
|
||||||
|
|
||||||
|
f2();
|
||||||
}
|
}
|
||||||
|
|
||||||
for(var i = 0; i < 10000; i++)
|
var k;
|
||||||
|
var i;
|
||||||
|
|
||||||
|
for(i = 0; i < 10000; i++)
|
||||||
{
|
{
|
||||||
f1();
|
f1();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user