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
|
||||
*/
|
||||
#define JERRY_BITSINBYTE 8
|
||||
#define JERRY_BITSINBYTE 8u
|
||||
|
||||
/**
|
||||
* 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_configurable_bindings = int_data->is_eval_code;
|
||||
|
||||
const opcode_counter_t jmp_down_opcode_idx = (opcode_counter_t) (int_data->pos);
|
||||
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_begin_oc = (opcode_counter_t) (int_data->pos + 1);
|
||||
|
||||
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_completion_value_t ret_value = ecma_op_function_declaration (int_data->lex_env_p,
|
||||
function_name_string_p,
|
||||
function_code_opcode_idx,
|
||||
function_code_begin_oc,
|
||||
args_names,
|
||||
args_number,
|
||||
is_strict,
|
||||
@@ -618,12 +615,9 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */
|
||||
|
||||
fill_params_list (int_data, params_number, params_names);
|
||||
|
||||
const opcode_counter_t jmp_down_opcode_idx = (opcode_counter_t) (int_data->pos);
|
||||
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_begin_oc = (opcode_counter_t) (int_data->pos + 1);
|
||||
|
||||
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_string_t *function_name_string_p = NULL;
|
||||
@@ -644,7 +638,7 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */
|
||||
params_number,
|
||||
scope_p,
|
||||
is_strict,
|
||||
function_code_opcode_idx);
|
||||
function_code_begin_oc);
|
||||
|
||||
ecma_completion_value_t ret_value = set_variable_value (int_data,
|
||||
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_GETTER:
|
||||
case OPCODE_META_TYPE_VARG_PROP_SETTER:
|
||||
case OPCODE_META_TYPE_OPCODE_COUNTER:
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
@@ -1760,6 +1755,40 @@ opfunc_meta (opcode_t opdata, /**< operation data */
|
||||
JERRY_UNREACHABLE ();
|
||||
} /* 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) \
|
||||
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_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_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;
|
||||
|
||||
typedef struct
|
||||
@@ -72,6 +73,9 @@ typedef struct
|
||||
ecma_value_t *regs_p; /**< register variables */
|
||||
} 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) \
|
||||
p##_2 (a, call_0, lhs, name_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;
|
||||
}
|
||||
|
||||
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' LT!* Identifier LT!*
|
||||
'(' (LT!* Identifier (LT!* ',' LT!* Identifier)*) ? LT!* ')' LT!* function_body
|
||||
@@ -905,7 +919,7 @@ static void
|
||||
parse_function_declaration (void)
|
||||
{
|
||||
idx_t name;
|
||||
opcode_counter_t jmp_oc;
|
||||
opcode_counter_t meta_oc;
|
||||
|
||||
assert_keyword (KW_FUNCTION);
|
||||
|
||||
@@ -916,8 +930,8 @@ parse_function_declaration (void)
|
||||
skip_newlines ();
|
||||
parse_argument_list (AL_FUNC_DECL, name);
|
||||
|
||||
jmp_oc = opcode_counter;
|
||||
DUMP_OPCODE_1 (jmp_down, INVALID_VALUE);
|
||||
meta_oc = opcode_counter;
|
||||
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_OPCODE_COUNTER, INVALID_VALUE, INVALID_VALUE);
|
||||
|
||||
token_after_newlines_must_be (TOK_OPEN_BRACE);
|
||||
|
||||
@@ -929,7 +943,8 @@ parse_function_declaration (void)
|
||||
next_token_must_be (TOK_CLOSE_BRACE);
|
||||
|
||||
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
|
||||
@@ -939,7 +954,7 @@ static idx_t
|
||||
parse_function_expression (void)
|
||||
{
|
||||
idx_t name, lhs;
|
||||
opcode_counter_t jmp_oc;
|
||||
opcode_counter_t meta_oc;
|
||||
|
||||
assert_keyword (KW_FUNCTION);
|
||||
|
||||
@@ -957,8 +972,8 @@ parse_function_expression (void)
|
||||
skip_newlines ();
|
||||
lhs = parse_argument_list (AL_FUNC_EXPR, name);
|
||||
|
||||
jmp_oc = opcode_counter;
|
||||
DUMP_OPCODE_1 (jmp_down, INVALID_VALUE);
|
||||
meta_oc = opcode_counter;
|
||||
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_OPCODE_COUNTER, INVALID_VALUE, INVALID_VALUE);
|
||||
|
||||
token_after_newlines_must_be (TOK_OPEN_BRACE);
|
||||
|
||||
@@ -970,7 +985,7 @@ parse_function_expression (void)
|
||||
token_after_newlines_must_be (TOK_CLOSE_BRACE);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -30,16 +30,17 @@ function f1(x)
|
||||
assert(t === false);
|
||||
}
|
||||
|
||||
var i;
|
||||
var t = true;
|
||||
|
||||
for(var i = 1; i <= 10; i++)
|
||||
for(i = 1; i <= 10; i++)
|
||||
{
|
||||
f1(i);
|
||||
}
|
||||
|
||||
t = false;
|
||||
|
||||
for(var i = 11; i <= 20; i++)
|
||||
for(i = 11; i <= 20; i++)
|
||||
{
|
||||
f1(i);
|
||||
}
|
||||
|
||||
@@ -12,14 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
var k;
|
||||
|
||||
function f1()
|
||||
{
|
||||
k = 17;
|
||||
|
||||
f2();
|
||||
|
||||
function f2()
|
||||
{
|
||||
assert(k > 0);
|
||||
@@ -32,9 +26,16 @@ function f1()
|
||||
|
||||
f2();
|
||||
}
|
||||
|
||||
k = 17;
|
||||
|
||||
f2();
|
||||
}
|
||||
|
||||
for(var i = 0; i < 10000; i++)
|
||||
var k;
|
||||
var i;
|
||||
|
||||
for(i = 0; i < 10000; i++)
|
||||
{
|
||||
f1();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user