mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Add opcodes for increment and decrement; add optimizer
This commit is contained in:
parent
c837c7d435
commit
3b0fef6e04
@ -162,7 +162,8 @@ SOURCES_JERRY = \
|
||||
$(wildcard ./src/libecmaobjects/*.c) \
|
||||
$(wildcard ./src/libecmaoperations/*.c) \
|
||||
$(wildcard ./src/liballocator/*.c) \
|
||||
$(wildcard ./src/libcoreint/*.c) ) \
|
||||
$(wildcard ./src/libcoreint/*.c) \
|
||||
$(wildcard ./src/liboptimizer/*.c) ) \
|
||||
$(wildcard src/libruntime/target/$(TARGET_SYSTEM)/*.c)
|
||||
|
||||
INCLUDES_JERRY = \
|
||||
@ -173,6 +174,7 @@ INCLUDES_JERRY = \
|
||||
-I src/libecmaobjects \
|
||||
-I src/libecmaoperations \
|
||||
-I src/liballocator \
|
||||
-I src/liboptimizer \
|
||||
-I src/libcoreint
|
||||
|
||||
ifeq ($(OPTION_NDEBUG),enable)
|
||||
|
||||
@ -256,6 +256,26 @@ OP_CODE_DECL (in, T_IDX_IDX_IDX,
|
||||
var_left,
|
||||
var_right)
|
||||
|
||||
/** dst = var_right++. */
|
||||
OP_CODE_DECL (post_incr, T_IDX_IDX,
|
||||
dst,
|
||||
var_right)
|
||||
|
||||
/** dst = var_right--. */
|
||||
OP_CODE_DECL (post_decr, T_IDX_IDX,
|
||||
dst,
|
||||
var_right)
|
||||
|
||||
/** dst = ++var_right. */
|
||||
OP_CODE_DECL (pre_incr, T_IDX_IDX,
|
||||
dst,
|
||||
var_right)
|
||||
|
||||
/** dst = --var_right. */
|
||||
OP_CODE_DECL (pre_decr, T_IDX_IDX,
|
||||
dst,
|
||||
var_right)
|
||||
|
||||
// Assignment operators.
|
||||
// Assign value to LEFT operand based on value of RIGHT operand.
|
||||
|
||||
|
||||
@ -372,6 +372,10 @@ do_number_arithmetic(struct __int_data *int_data, /**< interpreter context */
|
||||
op(b_not) \
|
||||
op(instanceof) \
|
||||
op(in) \
|
||||
op(post_incr) \
|
||||
op(post_decr) \
|
||||
op(pre_incr) \
|
||||
op(pre_decr) \
|
||||
op(reg_var_decl)
|
||||
|
||||
#define DEFINE_UNIMPLEMENTED_OP(op) \
|
||||
@ -879,6 +883,10 @@ GETOP_IMPL_1 (jmp, opcode_idx)
|
||||
GETOP_IMPL_1 (jmp_up, opcode_count)
|
||||
GETOP_IMPL_1 (jmp_down, opcode_count)
|
||||
GETOP_IMPL_3 (addition, dst, var_left, var_right)
|
||||
GETOP_IMPL_2 (post_incr, dst, var_right)
|
||||
GETOP_IMPL_2 (post_decr, dst, var_right)
|
||||
GETOP_IMPL_2 (pre_incr, dst, var_right)
|
||||
GETOP_IMPL_2 (pre_decr, dst, var_right)
|
||||
GETOP_IMPL_3 (substraction, dst, var_left, var_right)
|
||||
GETOP_IMPL_3 (division, dst, var_left, var_right)
|
||||
GETOP_IMPL_3 (multiplication, dst, var_left, var_right)
|
||||
|
||||
@ -110,6 +110,10 @@ typedef ecma_completion_value_t (*opfunc)(OPCODE, struct __int_data *);
|
||||
op(in)
|
||||
|
||||
#define OP_ARITHMETIC(op) \
|
||||
op(post_incr) \
|
||||
op(post_decr) \
|
||||
op(pre_incr) \
|
||||
op(pre_decr) \
|
||||
op(addition) \
|
||||
op(substraction) \
|
||||
op(division) \
|
||||
|
||||
@ -23,9 +23,8 @@
|
||||
#define INVALID_VALUE 255
|
||||
|
||||
static token tok;
|
||||
static OPCODE opcode, opcodes_buffer[MAX_OPCODES];
|
||||
static uint8_t current_opcode_in_buffer = 0;
|
||||
static uint8_t opcode_counter = 0;
|
||||
static OPCODE opcode;
|
||||
static T_IDX opcode_counter = 0;
|
||||
static T_IDX temp_name_stack[MAX_OPCODES], temp_name_stack_head = 0, max_temp_name;
|
||||
|
||||
#ifdef __HOST
|
||||
@ -172,23 +171,6 @@ integer_one (void)
|
||||
return lhs;
|
||||
}
|
||||
|
||||
static void
|
||||
save_opcode (void)
|
||||
{
|
||||
JERRY_ASSERT (current_opcode_in_buffer < MAX_OPCODES);
|
||||
|
||||
opcodes_buffer[current_opcode_in_buffer++] = opcode;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_saved_opcodes (void)
|
||||
{
|
||||
uint8_t i;
|
||||
for (i = 0; i < current_opcode_in_buffer; i++)
|
||||
serializer_dump_opcode (&opcodes_buffer[i]);
|
||||
current_opcode_in_buffer = 0;
|
||||
}
|
||||
|
||||
/* property_name
|
||||
: Identifier
|
||||
| StringLiteral
|
||||
@ -859,18 +841,18 @@ parse_left_hand_side_expression (void)
|
||||
static T_IDX
|
||||
parse_postfix_expression (void)
|
||||
{
|
||||
T_IDX expr = parse_left_hand_side_expression ();
|
||||
T_IDX expr = parse_left_hand_side_expression (), lhs;
|
||||
|
||||
tok = lexer_next_token ();
|
||||
if (tok.type == TOK_DOUBLE_PLUS)
|
||||
{
|
||||
opcode = getop_addition (expr, expr, integer_one ());
|
||||
save_opcode ();
|
||||
lhs = next_temp_name ();
|
||||
DUMP_OPCODE (post_incr, lhs, expr);
|
||||
}
|
||||
else if (tok.type == TOK_DOUBLE_MINUS)
|
||||
{
|
||||
opcode = getop_substraction (expr, expr, integer_one ());
|
||||
save_opcode ();
|
||||
lhs = next_temp_name ();
|
||||
DUMP_OPCODE (post_decr, lhs, expr);
|
||||
}
|
||||
else
|
||||
lexer_save_token (tok);
|
||||
@ -890,13 +872,15 @@ parse_unary_expression (void)
|
||||
switch (tok.type)
|
||||
{
|
||||
case TOK_DOUBLE_PLUS:
|
||||
lhs = next_temp_name ();
|
||||
NEXT (expr, unary_expression);
|
||||
DUMP_OPCODE (addition, expr, expr, integer_one ());
|
||||
DUMP_OPCODE (pre_incr, lhs, expr);
|
||||
return expr;
|
||||
|
||||
case TOK_DOUBLE_MINUS:
|
||||
lhs = next_temp_name ();
|
||||
NEXT (expr, unary_expression);
|
||||
DUMP_OPCODE (substraction, expr, expr, integer_one ());
|
||||
DUMP_OPCODE (pre_decr, lhs, expr);
|
||||
return expr;
|
||||
|
||||
case TOK_PLUS:
|
||||
@ -1198,7 +1182,7 @@ parse_assignment_expression (void)
|
||||
lhs = parse_conditional_expression (&was_conditional);
|
||||
if (was_conditional)
|
||||
{
|
||||
goto end;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
skip_newlines ();
|
||||
@ -1268,8 +1252,6 @@ parse_assignment_expression (void)
|
||||
lexer_save_token (tok);
|
||||
}
|
||||
|
||||
end:
|
||||
dump_saved_opcodes ();
|
||||
return lhs;
|
||||
}
|
||||
|
||||
|
||||
57
src/liboptimizer/optimizer-passes.c
Normal file
57
src/liboptimizer/optimizer-passes.c
Normal file
@ -0,0 +1,57 @@
|
||||
/* Copyright 2014 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "optimizer-passes.h"
|
||||
#include "opcodes.h"
|
||||
#include "deserializer.h"
|
||||
|
||||
#define NAME_TO_ID(op) (__op__idx_##op)
|
||||
|
||||
/* Reorder bytecode like
|
||||
|
||||
call_n ...
|
||||
assignment ... +
|
||||
var_?_end
|
||||
|
||||
to
|
||||
|
||||
assignment ... +
|
||||
call_n ...
|
||||
var_?_end
|
||||
*/
|
||||
static void
|
||||
optimize_calls (OPCODE *opcodes)
|
||||
{
|
||||
OPCODE *current_opcode;
|
||||
|
||||
for (current_opcode = opcodes;
|
||||
current_opcode->op_idx != NAME_TO_ID (exitval);
|
||||
current_opcode++)
|
||||
{
|
||||
if (current_opcode->op_idx == NAME_TO_ID (call_n)
|
||||
&& (current_opcode + 1)->op_idx == NAME_TO_ID (assignment))
|
||||
{
|
||||
OPCODE temp = *current_opcode;
|
||||
*current_opcode = *(current_opcode + 1);
|
||||
*(current_opcode + 1) = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
optimizer_run_passes (OPCODE* opcodes)
|
||||
{
|
||||
optimize_calls (opcodes);
|
||||
}
|
||||
24
src/liboptimizer/optimizer-passes.h
Normal file
24
src/liboptimizer/optimizer-passes.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* Copyright 2014 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OPTIMIZER_PASSES_H
|
||||
#define OPTIMIZER_PASSES_H
|
||||
|
||||
#include "globals.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
void optimizer_run_passes (OPCODE *);
|
||||
|
||||
#endif // OPTIMIZER_PASSES_H
|
||||
@ -28,4 +28,6 @@ void serializer_dump_opcode (const void *);
|
||||
|
||||
void serializer_rewrite_opcode (const uint8_t, const void *);
|
||||
|
||||
void serializer_print_opcodes (void);
|
||||
|
||||
#endif // SERIALIZER_H
|
||||
|
||||
@ -146,3 +146,27 @@ serializer_rewrite_opcode (const uint8_t loc, const void *opcode)
|
||||
|
||||
__printf ("// REWRITE\n");
|
||||
}
|
||||
|
||||
void
|
||||
serializer_print_opcodes (void)
|
||||
{
|
||||
int loc = -1, i;
|
||||
OPCODE* opcode;
|
||||
int opcode_num;
|
||||
|
||||
__printf ("AFTER OPTIMIZER:\n");
|
||||
|
||||
do
|
||||
{
|
||||
loc++;
|
||||
|
||||
opcode = bytecode_opcodes + loc;
|
||||
opcode_num = (int)((char*)opcode)[0];
|
||||
|
||||
__printf ("%03d: %20s ", loc, opcode_names[opcode_num]);
|
||||
for (i = 1; i < opcode_sizes[opcode_num]; i++)
|
||||
__printf ("%4d ", ((char*)opcode)[i]);
|
||||
__printf ("\n");
|
||||
}
|
||||
while (opcode->op_idx != __op__idx_exitval);
|
||||
}
|
||||
|
||||
@ -46,5 +46,10 @@ serializer_rewrite_opcode (const uint8_t offset, const void *opcode)
|
||||
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS( offset, opcode);
|
||||
}
|
||||
|
||||
void
|
||||
serializer_print_opcodes (void)
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
|
||||
TODO (Dump memory)
|
||||
|
||||
12
src/main.c
12
src/main.c
@ -37,6 +37,7 @@
|
||||
#include "parser.h"
|
||||
#include "serializer.h"
|
||||
#include "deserializer.h"
|
||||
#include "optimizer-passes.h"
|
||||
|
||||
#define MAX_STRINGS 100
|
||||
#define MAX_NUMS 25
|
||||
@ -49,6 +50,7 @@ jerry_run( const char *script_source,
|
||||
int nums[MAX_NUMS];
|
||||
uint8_t strings_num, nums_count;
|
||||
uint8_t offset;
|
||||
const OPCODE *opcodes;
|
||||
|
||||
mem_init();
|
||||
|
||||
@ -68,7 +70,15 @@ jerry_run( const char *script_source,
|
||||
parser_init ();
|
||||
parser_parse_program ();
|
||||
|
||||
init_int (deserialize_bytecode ());
|
||||
opcodes = deserialize_bytecode ();
|
||||
|
||||
optimizer_run_passes ((OPCODE *) opcodes);
|
||||
|
||||
#ifdef __HOST
|
||||
serializer_print_opcodes ();
|
||||
#endif
|
||||
|
||||
init_int (opcodes);
|
||||
run_int ();
|
||||
} /* jerry_run */
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user