Split parser into parser itself, opcodes dumper and syntax errors checker.

Add internal hash map of literal indexes:
  In this hash map key is pair of block number and literal's unique identifier in the block, and the value is a literal index that unique in the whole program.
  Block is a continues array of opcodes. So, bytecode is splitted into blocks.
  Each block has its own uid counter. To get literal index the interpreter looks up it in the hash map.
  Thus, now JS program is able to have more than 255 identifiers/string literals.
  The first 128 (0-127) uids are reserved for block's uid counter, the other 128 (128-255) are reserved for tmp variables.
This commit is contained in:
Ilmir Usmanov 2014-12-10 18:31:59 +03:00
parent fc9e83d290
commit dc8ab27900
37 changed files with 5015 additions and 3086 deletions

View File

@ -71,6 +71,11 @@
*/
#define CONFIG_MEM_HEAP_OFFSET_LOG 16
/**
* Number of lower bits in key of literal hash table.
*/
#define CONFIG_LITERAL_HASH_TABLE_KEY_BITS 7
/**
* Width of fields used for holding counter of references to ecma-strings and ecma-objects
*

View File

@ -428,6 +428,8 @@ mem_heap_alloc_block (size_t size_in_bytes, /**< size of region to all
}
else
{
JERRY_ASSERT (alloc_term == MEM_HEAP_ALLOC_SHORT_TERM);
block_p = mem_heap.last_block_p;
direction = MEM_DIRECTION_PREV;
}

View File

@ -88,7 +88,7 @@ do_number_arithmetic (int_data_t *int_data, /**< interpreter context */
}
}
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, int_data->pos,
dst_var_idx,
ecma_make_number_value (res_p));
@ -114,8 +114,6 @@ opfunc_addition (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.addition.var_left;
const idx_t right_var_idx = opdata.data.addition.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -140,7 +138,7 @@ opfunc_addition (opcode_t opdata, /**< operation data */
ecma_string_t *concat_str_p = ecma_concat_ecma_strings (string1_p, string2_p);
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_string_value (concat_str_p));
ret_value = set_variable_value (int_data, int_data->pos, dst_var_idx, ecma_make_string_value (concat_str_p));
ecma_deref_ecma_string (concat_str_p);
@ -161,6 +159,8 @@ opfunc_addition (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_addition */
@ -180,8 +180,6 @@ opfunc_substraction (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.substraction.var_left;
const idx_t right_var_idx = opdata.data.substraction.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -196,6 +194,8 @@ opfunc_substraction (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_substraction */
@ -215,8 +215,6 @@ opfunc_multiplication (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.multiplication.var_left;
const idx_t right_var_idx = opdata.data.multiplication.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -231,6 +229,8 @@ opfunc_multiplication (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_multiplication */
@ -250,8 +250,6 @@ opfunc_division (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.division.var_left;
const idx_t right_var_idx = opdata.data.division.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -266,6 +264,8 @@ opfunc_division (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_division */
@ -285,8 +285,6 @@ opfunc_remainder (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.remainder.var_left;
const idx_t right_var_idx = opdata.data.remainder.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -301,6 +299,8 @@ opfunc_remainder (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_remainder */
@ -319,21 +319,21 @@ opfunc_unary_plus (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.remainder.dst;
const idx_t var_idx = opdata.data.remainder.var_left;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (var_value, get_variable_value (int_data, var_idx, false), ret_value);
ECMA_TRY_CATCH (num_value, ecma_op_to_number (ecma_get_completion_value_value (var_value)), ret_value);
ecma_number_t *var_p = ecma_get_number_from_completion_value (num_value);
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, int_data->pos,
dst_var_idx,
ecma_make_number_value (var_p));
ECMA_FINALIZE (num_value);
ECMA_FINALIZE (var_value);
int_data->pos++;
return ret_value;
} /* opfunc_unary_plus */
@ -352,8 +352,6 @@ opfunc_unary_minus (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.remainder.dst;
const idx_t var_idx = opdata.data.remainder.var_left;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (var_value, get_variable_value (int_data, var_idx, false), ret_value);
@ -365,12 +363,14 @@ opfunc_unary_minus (opcode_t opdata, /**< operation data */
res_p = int_data->tmp_num_p;
*res_p = ecma_number_negate (*var_p);
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, int_data->pos,
dst_var_idx,
ecma_make_number_value (res_p));
ECMA_FINALIZE (num_value);
ECMA_FINALIZE (var_value);
int_data->pos++;
return ret_value;
} /* opfunc_unary_minus */

View File

@ -104,7 +104,7 @@ do_number_bitwise_logic (int_data_t *int_data, /**< interpreter context */
}
}
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, int_data->pos,
dst_var_idx,
ecma_make_number_value (res_p));
@ -130,8 +130,6 @@ opfunc_b_and (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.b_and.var_left;
const idx_t right_var_idx = opdata.data.b_and.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -146,6 +144,8 @@ opfunc_b_and (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_b_and */
@ -165,8 +165,6 @@ opfunc_b_or (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.b_or.var_left;
const idx_t right_var_idx = opdata.data.b_or.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -181,6 +179,8 @@ opfunc_b_or (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_b_or */
@ -200,8 +200,6 @@ opfunc_b_xor (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.b_xor.var_left;
const idx_t right_var_idx = opdata.data.b_xor.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -216,6 +214,8 @@ opfunc_b_xor (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_b_xor */
@ -235,8 +235,6 @@ opfunc_b_shift_left (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.b_shift_left.var_left;
const idx_t right_var_idx = opdata.data.b_shift_left.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -251,6 +249,8 @@ opfunc_b_shift_left (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_b_shift_left */
@ -270,8 +270,6 @@ opfunc_b_shift_right (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.b_shift_right.var_left;
const idx_t right_var_idx = opdata.data.b_shift_right.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -286,6 +284,8 @@ opfunc_b_shift_right (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_b_shift_right */
@ -305,8 +305,6 @@ opfunc_b_shift_uright (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.b_shift_uright.var_left;
const idx_t right_var_idx = opdata.data.b_shift_uright.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -321,6 +319,8 @@ opfunc_b_shift_uright (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_b_shift_uright */
@ -339,8 +339,6 @@ opfunc_b_not (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.b_not.dst;
const idx_t right_var_idx = opdata.data.b_not.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
@ -353,5 +351,7 @@ opfunc_b_not (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (right_value);
int_data->pos++;
return ret_value;
} /* opfunc_b_not */

View File

@ -32,8 +32,6 @@ opfunc_equal_value (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.equal_value.var_left;
const idx_t right_var_idx = opdata.data.equal_value.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -46,12 +44,15 @@ opfunc_equal_value (opcode_t opdata, /**< operation data */
JERRY_ASSERT (ecma_is_completion_value_normal_true (compare_result)
|| ecma_is_completion_value_normal_false (compare_result));
ret_value = set_variable_value (int_data, dst_var_idx, ecma_get_completion_value_value (compare_result));
ret_value = set_variable_value (int_data, int_data->pos, dst_var_idx,
ecma_get_completion_value_value (compare_result));
ECMA_FINALIZE (compare_result);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_equal_value */
@ -71,8 +72,6 @@ opfunc_not_equal_value (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.not_equal_value.var_left;
const idx_t right_var_idx = opdata.data.not_equal_value.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -87,13 +86,16 @@ opfunc_not_equal_value (opcode_t opdata, /**< operation data */
bool is_equal = ecma_is_completion_value_normal_true (compare_result);
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE
: ECMA_SIMPLE_VALUE_TRUE));
ret_value = set_variable_value (int_data, int_data->pos, dst_var_idx,
ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE
: ECMA_SIMPLE_VALUE_TRUE));
ECMA_FINALIZE (compare_result);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_not_equal_value */
@ -113,8 +115,6 @@ opfunc_equal_value_type (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.equal_value_type.var_left;
const idx_t right_var_idx = opdata.data.equal_value_type.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -123,12 +123,15 @@ opfunc_equal_value_type (opcode_t opdata, /**< operation data */
bool is_equal = ecma_op_strict_equality_compare (ecma_get_completion_value_value (left_value),
ecma_get_completion_value_value (right_value));
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE));
ret_value = set_variable_value (int_data, int_data->pos, dst_var_idx,
ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE));
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_equal_value_type */
@ -148,8 +151,6 @@ opfunc_not_equal_value_type (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.not_equal_value_type.var_left;
const idx_t right_var_idx = opdata.data.not_equal_value_type.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -158,12 +159,15 @@ opfunc_not_equal_value_type (opcode_t opdata, /**< operation data */
bool is_equal = ecma_op_strict_equality_compare (ecma_get_completion_value_value (left_value),
ecma_get_completion_value_value (right_value));
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE
: ECMA_SIMPLE_VALUE_TRUE));
ret_value = set_variable_value (int_data, int_data->pos, dst_var_idx,
ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE
: ECMA_SIMPLE_VALUE_TRUE));
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_not_equal_value_type */

View File

@ -32,8 +32,6 @@ opfunc_less_than (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.less_than.var_left;
const idx_t right_var_idx = opdata.data.less_than.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -57,12 +55,14 @@ opfunc_less_than (opcode_t opdata, /**< operation data */
res = (ecma_is_completion_value_normal_true (compare_result) ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE);
}
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res));
ret_value = set_variable_value (int_data, int_data->pos, dst_var_idx, ecma_make_simple_value (res));
ECMA_FINALIZE (compare_result);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_less_than */
@ -82,8 +82,6 @@ opfunc_greater_than (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.greater_than.var_left;
const idx_t right_var_idx = opdata.data.greater_than.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -107,12 +105,14 @@ opfunc_greater_than (opcode_t opdata, /**< operation data */
res = (ecma_is_completion_value_normal_true (compare_result) ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE);
}
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res));
ret_value = set_variable_value (int_data, int_data->pos, dst_var_idx, ecma_make_simple_value (res));
ECMA_FINALIZE (compare_result);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_greater_than */
@ -132,8 +132,6 @@ opfunc_less_or_equal_than (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.less_or_equal_than.var_left;
const idx_t right_var_idx = opdata.data.less_or_equal_than.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -164,12 +162,14 @@ opfunc_less_or_equal_than (opcode_t opdata, /**< operation data */
}
}
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res));
ret_value = set_variable_value (int_data, int_data->pos, dst_var_idx, ecma_make_simple_value (res));
ECMA_FINALIZE (compare_result);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_less_or_equal_than */
@ -189,8 +189,6 @@ opfunc_greater_or_equal_than (opcode_t opdata, /**< operation data */
const idx_t left_var_idx = opdata.data.greater_or_equal_than.var_left;
const idx_t right_var_idx = opdata.data.greater_or_equal_than.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -221,12 +219,14 @@ opfunc_greater_or_equal_than (opcode_t opdata, /**< operation data */
}
}
ret_value = set_variable_value (int_data, dst_var_idx, ecma_make_simple_value (res));
ret_value = set_variable_value (int_data, int_data->pos, dst_var_idx, ecma_make_simple_value (res));
ECMA_FINALIZE (compare_result);
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_greater_or_equal_than */
@ -246,8 +246,6 @@ opfunc_instanceof (opcode_t opdata __unused, /**< operation data */
const idx_t left_var_idx = opdata.data.instanceof.var_left;
const idx_t right_var_idx = opdata.data.instanceof.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -266,7 +264,7 @@ opfunc_instanceof (opcode_t opdata __unused, /**< operation data */
ecma_get_completion_value_value (left_value)),
ret_value);
ret_value = set_variable_value (int_data, dst_idx, ecma_get_completion_value_value (is_instance_of));
ret_value = set_variable_value (int_data, int_data->pos, dst_idx, ecma_get_completion_value_value (is_instance_of));
ECMA_FINALIZE (is_instance_of);
}
@ -274,6 +272,8 @@ opfunc_instanceof (opcode_t opdata __unused, /**< operation data */
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_instanceof */
@ -293,8 +293,6 @@ opfunc_in (opcode_t opdata __unused, /**< operation data */
const idx_t left_var_idx = opdata.data.in.var_left;
const idx_t right_var_idx = opdata.data.in.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (left_value, get_variable_value (int_data, left_var_idx, false), ret_value);
@ -321,7 +319,7 @@ opfunc_in (opcode_t opdata __unused, /**< operation data */
is_in = ECMA_SIMPLE_VALUE_FALSE;
}
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, int_data->pos,
dst_idx,
ecma_make_simple_value (is_in));
@ -331,5 +329,7 @@ opfunc_in (opcode_t opdata __unused, /**< operation data */
ECMA_FINALIZE (right_value);
ECMA_FINALIZE (left_value);
int_data->pos++;
return ret_value;
} /* opfunc_in */

View File

@ -31,10 +31,11 @@
#include "ecma-operations.h"
#include "ecma-reference.h"
#include "ecma-try-catch-macro.h"
#include "deserializer.h"
bool is_reg_variable (int_data_t *int_data, idx_t var_idx);
ecma_completion_value_t get_variable_value (int_data_t *, idx_t, bool);
ecma_completion_value_t set_variable_value (int_data_t *, idx_t, ecma_value_t);
ecma_completion_value_t set_variable_value (int_data_t *, opcode_counter_t, idx_t, ecma_value_t);
ecma_completion_value_t fill_varg_list (int_data_t *int_data,
ecma_length_t args_number,
ecma_value_t args_values[],

View File

@ -58,11 +58,14 @@ opfunc_try (opcode_t opdata, /**< operation data */
if (ecma_is_completion_value_throw (try_completion))
{
next_opcode = read_opcode (int_data->pos++);
next_opcode = read_opcode (int_data->pos);
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta);
JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER);
const idx_t catch_exc_val_var_name_lit_idx = next_opcode.data.meta.data_1;
const literal_index_t catch_exc_val_var_name_lit_idx = deserialize_lit_id_by_uid (next_opcode.data.meta.data_1,
int_data->pos);
int_data->pos++;
ecma_string_t *catch_exc_var_name_str_p = ecma_new_ecma_string_from_lit_index (catch_exc_val_var_name_lit_idx);
ecma_object_t *old_env_p = int_data->lex_env_p;

View File

@ -90,7 +90,9 @@ get_variable_value (int_data_t *int_data, /**< interpreter context */
else
{
ecma_string_t var_name_string;
ecma_new_ecma_string_on_stack_from_lit_index (&var_name_string, var_idx);
const literal_index_t lit_id = deserialize_lit_id_by_uid (var_idx, int_data->pos);
JERRY_ASSERT (lit_id != INVALID_LITERAL);
ecma_new_ecma_string_on_stack_from_lit_index (&var_name_string, lit_id);
ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (int_data->lex_env_p,
&var_name_string);
@ -122,6 +124,7 @@ get_variable_value (int_data_t *int_data, /**< interpreter context */
*/
ecma_completion_value_t
set_variable_value (int_data_t *int_data, /**< interpreter context */
opcode_counter_t lit_oc, /**< opcode counter for literal */
idx_t var_idx, /**< variable identifier */
ecma_value_t value) /**< value to set */
{
@ -143,7 +146,9 @@ set_variable_value (int_data_t *int_data, /**< interpreter context */
else
{
ecma_string_t var_name_string;
ecma_new_ecma_string_on_stack_from_lit_index (&var_name_string, var_idx);
const literal_index_t lit_id = deserialize_lit_id_by_uid (var_idx, lit_oc);
JERRY_ASSERT (lit_id != INVALID_LITERAL);
ecma_new_ecma_string_on_stack_from_lit_index (&var_name_string, lit_id);
ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (int_data->lex_env_p,
&var_name_string);

View File

@ -96,7 +96,7 @@ fill_params_list (int_data_t *int_data, /**< interpreter context */
JERRY_ASSERT (next_opcode.op_idx == __op__idx_meta);
JERRY_ASSERT (next_opcode.data.meta.type == OPCODE_META_TYPE_VARG);
const idx_t param_name_lit_idx = next_opcode.data.meta.data_1;
const literal_index_t param_name_lit_idx = deserialize_lit_id_by_uid (next_opcode.data.meta.data_1, int_data->pos);
params_names [param_index] = ecma_new_ecma_string_from_lit_index (param_name_lit_idx);

View File

@ -87,30 +87,29 @@ opfunc_assignment (opcode_t opdata, /**< operation data */
const opcode_arg_type_operand type_value_right = opdata.data.assignment.type_value_right;
const idx_t src_val_descr = opdata.data.assignment.value_right;
int_data->pos++;
ecma_completion_value_t ret_value;
if (type_value_right == OPCODE_ARG_TYPE_SIMPLE)
{
return set_variable_value (int_data,
dst_var_idx,
ecma_make_simple_value (src_val_descr));
ret_value = set_variable_value (int_data,
int_data->pos,
dst_var_idx,
ecma_make_simple_value (src_val_descr));
}
else if (type_value_right == OPCODE_ARG_TYPE_STRING)
{
ecma_string_t *string_p = ecma_new_ecma_string_from_lit_index (src_val_descr);
const literal_index_t lit_id = deserialize_lit_id_by_uid (src_val_descr, int_data->pos);
ecma_string_t *string_p = ecma_new_ecma_string_from_lit_index (lit_id);
ecma_completion_value_t completion = set_variable_value (int_data,
dst_var_idx,
ecma_make_string_value (string_p));
ret_value = set_variable_value (int_data,
int_data->pos,
dst_var_idx,
ecma_make_string_value (string_p));
ecma_deref_ecma_string (string_p);
return completion;
}
else if (type_value_right == OPCODE_ARG_TYPE_VARIABLE)
{
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (get_value_completion,
get_variable_value (int_data,
src_val_descr,
@ -118,33 +117,69 @@ opfunc_assignment (opcode_t opdata, /**< operation data */
ret_value);
ret_value = set_variable_value (int_data,
int_data->pos,
dst_var_idx,
ecma_get_completion_value_value (get_value_completion));
ECMA_FINALIZE (get_value_completion);
return ret_value;
}
else if (type_value_right == OPCODE_ARG_TYPE_NUMBER)
{
ecma_number_t *num_p = int_data->tmp_num_p;
const literal lit = deserialize_literal_by_id (src_val_descr);
const literal_index_t lit_id = deserialize_lit_id_by_uid (src_val_descr, int_data->pos);
const literal lit = deserialize_literal_by_id (lit_id);
JERRY_ASSERT (lit.type == LIT_NUMBER);
*num_p = lit.data.num;
return set_variable_value (int_data, dst_var_idx, ecma_make_number_value (num_p));
ret_value = set_variable_value (int_data,
int_data->pos,
dst_var_idx,
ecma_make_number_value (num_p));
}
else
else if (type_value_right == OPCODE_ARG_TYPE_NUMBER_NEGATE)
{
ecma_number_t *num_p = int_data->tmp_num_p;
const literal_index_t lit_id = deserialize_lit_id_by_uid (src_val_descr, int_data->pos);
const literal lit = deserialize_literal_by_id (lit_id);
JERRY_ASSERT (lit.type == LIT_NUMBER);
*num_p = ecma_number_negate (lit.data.num);
ret_value = set_variable_value (int_data,
int_data->pos,
dst_var_idx,
ecma_make_number_value (num_p));
}
else if (type_value_right == OPCODE_ARG_TYPE_SMALLINT)
{
JERRY_ASSERT (type_value_right == OPCODE_ARG_TYPE_SMALLINT);
ecma_number_t *num_p = int_data->tmp_num_p;
*num_p = src_val_descr;
return set_variable_value (int_data, dst_var_idx, ecma_make_number_value (num_p));
ret_value = set_variable_value (int_data,
int_data->pos,
dst_var_idx,
ecma_make_number_value (num_p));
}
else
{
JERRY_ASSERT (type_value_right == OPCODE_ARG_TYPE_SMALLINT_NEGATE);
ecma_number_t *num_p = int_data->tmp_num_p;
*num_p = ecma_number_negate (src_val_descr);
ret_value = set_variable_value (int_data,
int_data->pos,
dst_var_idx,
ecma_make_number_value (num_p));
}
int_data->pos++;
return ret_value;
} /* opfunc_assignment */
/**
@ -162,8 +197,6 @@ opfunc_pre_incr (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.pre_incr.dst;
const idx_t incr_var_idx = opdata.data.pre_incr.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
// 1., 2., 3.
@ -179,12 +212,12 @@ opfunc_pre_incr (opcode_t opdata, /**< operation data */
ecma_value_t new_num_value = ecma_make_number_value (new_num_p);
// 5.
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, int_data->pos,
incr_var_idx,
new_num_value);
// assignment of operator result to register variable
ecma_completion_value_t reg_assignment_res = set_variable_value (int_data,
ecma_completion_value_t reg_assignment_res = set_variable_value (int_data, int_data->pos,
dst_var_idx,
new_num_value);
JERRY_ASSERT (ecma_is_completion_value_empty (reg_assignment_res));
@ -192,6 +225,8 @@ opfunc_pre_incr (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (old_num_value);
ECMA_FINALIZE (old_value);
int_data->pos++;
return ret_value;
} /* opfunc_pre_incr */
@ -210,8 +245,6 @@ opfunc_pre_decr (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.pre_decr.dst;
const idx_t decr_var_idx = opdata.data.pre_decr.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
// 1., 2., 3.
@ -227,12 +260,12 @@ opfunc_pre_decr (opcode_t opdata, /**< operation data */
ecma_value_t new_num_value = ecma_make_number_value (new_num_p);
// 5.
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, int_data->pos,
decr_var_idx,
new_num_value);
// assignment of operator result to register variable
ecma_completion_value_t reg_assignment_res = set_variable_value (int_data,
ecma_completion_value_t reg_assignment_res = set_variable_value (int_data, int_data->pos,
dst_var_idx,
new_num_value);
JERRY_ASSERT (ecma_is_completion_value_empty (reg_assignment_res));
@ -240,6 +273,8 @@ opfunc_pre_decr (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (old_num_value);
ECMA_FINALIZE (old_value);
int_data->pos++;
return ret_value;
} /* opfunc_pre_decr */
@ -258,8 +293,6 @@ opfunc_post_incr (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.post_incr.dst;
const idx_t incr_var_idx = opdata.data.post_incr.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
// 1., 2., 3.
@ -273,12 +306,12 @@ opfunc_post_incr (opcode_t opdata, /**< operation data */
*new_num_p = ecma_number_add (*old_num_p, ECMA_NUMBER_ONE);
// 5.
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, int_data->pos,
incr_var_idx,
ecma_make_number_value (new_num_p));
// assignment of operator result to register variable
ecma_completion_value_t reg_assignment_res = set_variable_value (int_data,
ecma_completion_value_t reg_assignment_res = set_variable_value (int_data, int_data->pos,
dst_var_idx,
ecma_get_completion_value_value (old_num_value));
JERRY_ASSERT (ecma_is_completion_value_empty (reg_assignment_res));
@ -286,6 +319,8 @@ opfunc_post_incr (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (old_num_value);
ECMA_FINALIZE (old_value);
int_data->pos++;
return ret_value;
} /* opfunc_post_incr */
@ -304,8 +339,6 @@ opfunc_post_decr (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.post_decr.dst;
const idx_t decr_var_idx = opdata.data.post_decr.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
// 1., 2., 3.
@ -319,12 +352,12 @@ opfunc_post_decr (opcode_t opdata, /**< operation data */
*new_num_p = ecma_number_substract (*old_num_p, ECMA_NUMBER_ONE);
// 5.
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, int_data->pos,
decr_var_idx,
ecma_make_number_value (new_num_p));
// assignment of operator result to register variable
ecma_completion_value_t reg_assignment_res = set_variable_value (int_data,
ecma_completion_value_t reg_assignment_res = set_variable_value (int_data, int_data->pos,
dst_var_idx,
ecma_get_completion_value_value (old_num_value));
JERRY_ASSERT (ecma_is_completion_value_empty (reg_assignment_res));
@ -332,6 +365,8 @@ opfunc_post_decr (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (old_num_value);
ECMA_FINALIZE (old_value);
int_data->pos++;
return ret_value;
} /* opfunc_post_decr */
@ -360,7 +395,11 @@ ecma_completion_value_t
opfunc_var_decl (opcode_t opdata, /**< operation data */
int_data_t *int_data) /**< interpreter context */
{
ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_index (opdata.data.var_decl.variable_name);
const literal_index_t lit_id = deserialize_lit_id_by_uid (opdata.data.var_decl.variable_name,
int_data->pos);
JERRY_ASSERT (lit_id != INVALID_LITERAL);
ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_index (lit_id);
if (!ecma_op_has_binding (int_data->lex_env_p, var_name_string_p))
{
@ -396,7 +435,8 @@ opfunc_var_decl (opcode_t opdata, /**< operation data */
*/
static ecma_completion_value_t
function_declaration (int_data_t *int_data, /**< interpreter context */
idx_t function_name_lit_idx, /**< identifier of literal with function name */
literal_index_t function_name_lit_id, /**< index of literal
with function name */
ecma_string_t* args_names[], /**< names of arguments */
ecma_length_t args_number) /**< number of arguments */
{
@ -416,7 +456,7 @@ function_declaration (int_data_t *int_data, /**< interpreter context */
int_data->pos++;
}
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_id);
ecma_completion_value_t ret_value = ecma_op_function_declaration (int_data->lex_env_p,
function_name_string_p,
@ -442,16 +482,19 @@ ecma_completion_value_t
opfunc_func_decl_n (opcode_t opdata, /**< operation data */
int_data_t *int_data) /**< interpreter context */
{
int_data->pos++;
const idx_t function_name_idx = opdata.data.func_decl_n.name_lit_idx;
const ecma_length_t params_number = opdata.data.func_decl_n.arg_list;
literal_index_t function_name_lit_id = deserialize_lit_id_by_uid (function_name_idx,
int_data->pos);
int_data->pos++;
ecma_string_t *params_names[params_number + 1 /* length of array should not be zero */];
fill_params_list (int_data, params_number, params_names);
ecma_completion_value_t ret_value = function_declaration (int_data,
function_name_idx,
function_name_lit_id,
params_names,
params_number);
@ -475,12 +518,14 @@ ecma_completion_value_t
opfunc_func_expr_n (opcode_t opdata, /**< operation data */
int_data_t *int_data) /**< interpreter context */
{
const opcode_counter_t lit_oc = int_data->pos;
int_data->pos++;
const idx_t dst_var_idx = opdata.data.func_expr_n.lhs;
const idx_t function_name_lit_idx = opdata.data.func_expr_n.name_lit_idx;
const ecma_length_t params_number = opdata.data.func_expr_n.arg_list;
const bool is_named_func_expr = (!is_reg_variable (int_data, function_name_lit_idx));
const bool is_named_func_expr = (function_name_lit_idx != INVALID_VALUE);
ecma_string_t *params_names[params_number + 1 /* length of array should not be zero */];
fill_params_list (int_data, params_number, params_names);
@ -505,7 +550,11 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */
if (is_named_func_expr)
{
scope_p = ecma_create_decl_lex_env (int_data->lex_env_p);
function_name_string_p = ecma_new_ecma_string_from_lit_index (function_name_lit_idx);
const literal_index_t lit_id = deserialize_lit_id_by_uid (function_name_lit_idx, lit_oc);
JERRY_ASSERT (lit_id != INVALID_LITERAL);
function_name_string_p = ecma_new_ecma_string_from_lit_index (lit_id);
ecma_op_create_immutable_binding (scope_p,
function_name_string_p);
}
@ -521,7 +570,7 @@ opfunc_func_expr_n (opcode_t opdata, /**< operation data */
is_strict,
int_data->pos);
ecma_completion_value_t ret_value = set_variable_value (int_data,
ecma_completion_value_t ret_value = set_variable_value (int_data, lit_oc,
dst_var_idx,
ecma_make_object_value (func_obj_p));
@ -563,13 +612,14 @@ opfunc_call_n (opcode_t opdata, /**< operation data */
const idx_t lhs_var_idx = opdata.data.call_n.lhs;
const idx_t func_name_lit_idx = opdata.data.call_n.name_lit_idx;
const idx_t args_number_idx = opdata.data.call_n.arg_list;
int_data->pos++;
const opcode_counter_t lit_oc = int_data->pos;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (func_value, get_variable_value (int_data, func_name_lit_idx, false), ret_value);
int_data->pos++;
bool this_arg_var_idx_set = false;
idx_t this_arg_var_idx;
idx_t args_number;
@ -632,7 +682,7 @@ opfunc_call_n (opcode_t opdata, /**< operation data */
args_number),
ret_value);
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, lit_oc,
lhs_var_idx,
ecma_get_completion_value_value (call_completion));
@ -676,14 +726,17 @@ opfunc_construct_n (opcode_t opdata, /**< operation data */
const idx_t lhs_var_idx = opdata.data.construct_n.lhs;
const idx_t constructor_name_lit_idx = opdata.data.construct_n.name_lit_idx;
const idx_t args_number = opdata.data.construct_n.arg_list;
int_data->pos++;
const opcode_counter_t lit_oc = int_data->pos;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (constructor_value, get_variable_value (int_data, constructor_name_lit_idx, false), ret_value);
ECMA_TRY_CATCH (constructor_value,
get_variable_value (int_data, constructor_name_lit_idx, false),
ret_value);
ecma_value_t arg_values[args_number + 1 /* length of array should not be zero */];
int_data->pos++;
ecma_length_t args_read;
ecma_completion_value_t get_arg_completion = fill_varg_list (int_data,
args_number,
@ -708,7 +761,8 @@ opfunc_construct_n (opcode_t opdata, /**< operation data */
args_number),
ret_value);
ret_value = set_variable_value (int_data, lhs_var_idx, ecma_get_completion_value_value (construction_completion));
ret_value = set_variable_value (int_data, lit_oc, lhs_var_idx,
ecma_get_completion_value_value (construction_completion));
ECMA_FINALIZE (construction_completion);
}
@ -746,6 +800,7 @@ opfunc_array_decl (opcode_t opdata, /**< operation data */
{
const idx_t lhs_var_idx = opdata.data.array_decl.lhs;
const idx_t args_number = opdata.data.array_decl.list;
const opcode_counter_t lit_oc = int_data->pos;
int_data->pos++;
@ -769,7 +824,7 @@ opfunc_array_decl (opcode_t opdata, /**< operation data */
false),
ret_value);
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, lit_oc,
lhs_var_idx,
ecma_get_completion_value_value (array_obj_value));
@ -806,6 +861,7 @@ opfunc_obj_decl (opcode_t opdata, /**< operation data */
{
const idx_t lhs_var_idx = opdata.data.obj_decl.lhs;
const idx_t args_number = opdata.data.obj_decl.list;
const opcode_counter_t obj_lit_oc = int_data->pos;
int_data->pos++;
@ -948,7 +1004,7 @@ opfunc_obj_decl (opcode_t opdata, /**< operation data */
if (ecma_is_completion_value_empty (completion))
{
ret_value = set_variable_value (int_data, lhs_var_idx, ecma_make_object_value (obj_p));
ret_value = set_variable_value (int_data, obj_lit_oc, lhs_var_idx, ecma_make_object_value (obj_p));
}
else
{
@ -1016,8 +1072,6 @@ opfunc_prop_getter (opcode_t opdata __unused, /**< operation data */
const idx_t base_var_idx = opdata.data.prop_getter.obj;
const idx_t prop_name_var_idx = opdata.data.prop_getter.prop;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (base_value,
@ -1040,7 +1094,7 @@ opfunc_prop_getter (opcode_t opdata __unused, /**< operation data */
ECMA_TRY_CATCH (prop_value, ecma_op_get_value_object_base (ref), ret_value);
ret_value = set_variable_value (int_data, lhs_var_idx, ecma_get_completion_value_value (prop_value));
ret_value = set_variable_value (int_data, int_data->pos, lhs_var_idx, ecma_get_completion_value_value (prop_value));
ECMA_FINALIZE (prop_value);
@ -1051,6 +1105,8 @@ opfunc_prop_getter (opcode_t opdata __unused, /**< operation data */
ECMA_FINALIZE (prop_name_value);
ECMA_FINALIZE (base_value);
int_data->pos++;
return ret_value;
} /* opfunc_prop_getter */
@ -1071,8 +1127,6 @@ opfunc_prop_setter (opcode_t opdata __unused, /**< operation data */
const idx_t prop_name_var_idx = opdata.data.prop_setter.prop;
const idx_t rhs_var_idx = opdata.data.prop_setter.rhs;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (base_value,
@ -1104,6 +1158,8 @@ opfunc_prop_setter (opcode_t opdata __unused, /**< operation data */
ECMA_FINALIZE (prop_name_value);
ECMA_FINALIZE (base_value);
int_data->pos++;
return ret_value;
} /* opfunc_prop_setter */
@ -1145,8 +1201,6 @@ opfunc_logical_not (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.logical_not.dst;
const idx_t right_var_idx = opdata.data.logical_not.var_right;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (right_value, get_variable_value (int_data, right_var_idx, false), ret_value);
@ -1159,12 +1213,14 @@ opfunc_logical_not (opcode_t opdata, /**< operation data */
old_value = ECMA_SIMPLE_VALUE_FALSE;
}
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, int_data->pos,
dst_var_idx,
ecma_make_simple_value (old_value));
ECMA_FINALIZE (right_value);
int_data->pos++;
return ret_value;
} /* opfunc_logical_not */
@ -1181,12 +1237,13 @@ opfunc_this (opcode_t opdata, /**< operation data */
int_data_t *int_data) /**< interpreter context */
{
const idx_t dst_var_idx = opdata.data.this.lhs;
const opcode_counter_t lit_oc = int_data->pos;
int_data->pos++;
ecma_completion_value_t ret_value;
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, lit_oc,
dst_var_idx,
int_data->this_binding);
@ -1207,8 +1264,6 @@ opfunc_with (opcode_t opdata, /**< operation data */
{
const idx_t expr_var_idx = opdata.data.with.expr;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (expr_value,
@ -1220,6 +1275,8 @@ opfunc_with (opcode_t opdata, /**< operation data */
ecma_op_to_object (ecma_get_completion_value_value (expr_value)),
ret_value);
int_data->pos++;
ecma_object_t *obj_p = ecma_get_object_from_completion_value (obj_expr_value);
ecma_object_t *old_env_p = int_data->lex_env_p;
@ -1271,8 +1328,6 @@ opfunc_throw (opcode_t opdata, /**< operation data */
{
const idx_t var_idx = opdata.data.throw.var;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (var_value,
@ -1285,6 +1340,8 @@ opfunc_throw (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (var_value);
int_data->pos++;
return ret_value;
} /* opfunc_throw */
@ -1312,7 +1369,10 @@ evaluate_arg_for_typeof (int_data_t *int_data, /**< interpreter context */
}
else
{
ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_index (var_idx);
const literal_index_t lit_id = deserialize_lit_id_by_uid (var_idx, int_data->pos);
JERRY_ASSERT (lit_id != INVALID_LITERAL);
ecma_string_t *var_name_string_p = ecma_new_ecma_string_from_lit_index (lit_id);
ecma_object_t *ref_base_lex_env_p = ecma_op_resolve_reference_base (int_data->lex_env_p,
var_name_string_p);
@ -1348,8 +1408,6 @@ opfunc_typeof (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.typeof.lhs;
const idx_t obj_var_idx = opdata.data.typeof.obj;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (typeof_evaluate_arg_completion,
@ -1395,7 +1453,7 @@ opfunc_typeof (opcode_t opdata, /**< operation data */
}
}
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, int_data->pos,
dst_var_idx,
ecma_make_string_value (type_str_p));
@ -1403,6 +1461,8 @@ opfunc_typeof (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (typeof_evaluate_arg_completion);
int_data->pos++;
return ret_value;
} /* opfunc_typeof */
@ -1420,12 +1480,16 @@ opfunc_delete_var (opcode_t opdata, /**< operation data */
{
const idx_t dst_var_idx = opdata.data.delete_var.lhs;
const idx_t name_lit_idx = opdata.data.delete_var.name;
const opcode_counter_t lit_oc = int_data->pos;
int_data->pos++;
ecma_completion_value_t ret_value;
ecma_string_t *name_string_p = ecma_new_ecma_string_from_lit_index (name_lit_idx);
const literal_index_t lit_id = deserialize_lit_id_by_uid (name_lit_idx, lit_oc);
JERRY_ASSERT (lit_id != INVALID_LITERAL);
ecma_string_t *name_string_p = ecma_new_ecma_string_from_lit_index (lit_id);
ecma_reference_t ref = ecma_op_get_identifier_reference (int_data->lex_env_p,
name_string_p,
@ -1440,7 +1504,7 @@ opfunc_delete_var (opcode_t opdata, /**< operation data */
{
if (ecma_is_value_undefined (ref.base))
{
ret_value = set_variable_value (int_data,
ret_value = set_variable_value (int_data, lit_oc,
dst_var_idx,
ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE));
}
@ -1454,7 +1518,8 @@ opfunc_delete_var (opcode_t opdata, /**< operation data */
ECMA_GET_NON_NULL_POINTER (ref.referenced_name_cp)),
ret_value);
ret_value = set_variable_value (int_data, dst_var_idx, ecma_get_completion_value_value (delete_completion));
ret_value = set_variable_value (int_data, lit_oc, dst_var_idx,
ecma_get_completion_value_value (delete_completion));
ECMA_FINALIZE (delete_completion);
}
@ -1484,8 +1549,6 @@ opfunc_delete_prop (opcode_t opdata, /**< operation data */
const idx_t base_var_idx = opdata.data.delete_prop.base;
const idx_t name_var_idx = opdata.data.delete_prop.name;
int_data->pos++;
ecma_completion_value_t ret_value;
ECMA_TRY_CATCH (base_value,
@ -1528,7 +1591,8 @@ opfunc_delete_prop (opcode_t opdata, /**< operation data */
ecma_op_object_delete (obj_p, name_string_p, int_data->is_strict),
ret_value);
ret_value = set_variable_value (int_data, dst_var_idx, ecma_get_completion_value_value (delete_op_completion));
ret_value = set_variable_value (int_data, int_data->pos, dst_var_idx,
ecma_get_completion_value_value (delete_op_completion));
ECMA_FINALIZE (delete_op_completion);
ECMA_FINALIZE (obj_value);
@ -1539,6 +1603,8 @@ opfunc_delete_prop (opcode_t opdata, /**< operation data */
ECMA_FINALIZE (name_value);
ECMA_FINALIZE (base_value);
int_data->pos++;
return ret_value;
} /* opfunc_delete_prop */

View File

@ -44,8 +44,10 @@ typedef uint8_t idx_t; /** index values */
typedef enum
{
OPCODE_ARG_TYPE_SIMPLE, /**< ecma_simple_value_t */
OPCODE_ARG_TYPE_SMALLINT, /**< small integer: from -128 to 127 */
OPCODE_ARG_TYPE_SMALLINT, /**< small integer: from 0 to 255 */
OPCODE_ARG_TYPE_SMALLINT_NEGATE, /**< small integer: from -255 to -0 */
OPCODE_ARG_TYPE_NUMBER, /**< index of number literal */
OPCODE_ARG_TYPE_NUMBER_NEGATE, /**< index of number literal with negation */
OPCODE_ARG_TYPE_STRING, /**< index of string literal */
OPCODE_ARG_TYPE_VARIABLE /**< index of variable name */
} opcode_arg_type_operand;
@ -270,5 +272,10 @@ OP_ARGS_LIST (GETOP_DECL)
#undef GETOP_DECL_2
#undef GETOP_DECL_3
typedef struct
{
uint8_t uids[4];
}
raw_opcode;
#endif /* OPCODES_H */

View File

@ -721,7 +721,7 @@ typedef enum
ECMA_STRING_CONTAINER_MAGIC_STRING /**< the ecma-string is equal to one of ECMA magic strings */
} ecma_string_container_t;
FIXME (Move to library that should define the type (libserializer /* ? */))
FIXME (Move to library that should define the type (literal.h /* ? */))
/**
* Index in literal table
*/

View File

@ -291,7 +291,7 @@ ecma_init_ecma_string_from_lit_index (ecma_string_t *string_p, /**< descriptor t
JERRY_ASSERT (is_stack_var == (!mem_is_heap_pointer (string_p)));
#endif /* !JERRY_NDEBUG */
const literal lit = deserialize_literal_by_id ((idx_t) lit_index);
const literal lit = deserialize_literal_by_id (lit_index);
if (lit.type == LIT_MAGIC_STR)
{
ecma_init_ecma_string_from_magic_string_id (string_p,
@ -878,7 +878,7 @@ ecma_string_to_zt_string (const ecma_string_t *string_desc_p, /**< ecma-string d
}
case ECMA_STRING_CONTAINER_LIT_TABLE:
{
const literal lit = deserialize_literal_by_id ((idx_t) string_desc_p->u.lit_index);
const literal lit = deserialize_literal_by_id (string_desc_p->u.lit_index);
JERRY_ASSERT (lit.type == LIT_STR);
const ecma_char_t *str_p = literal_to_zt (lit);
JERRY_ASSERT (str_p != NULL);
@ -1159,8 +1159,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
if (string1_p->container == ECMA_STRING_CONTAINER_LIT_TABLE)
{
FIXME (uint8_t -> literal_index_t);
const literal lit = deserialize_literal_by_id ((uint8_t) string1_p->u.lit_index);
const literal lit = deserialize_literal_by_id (string1_p->u.lit_index);
JERRY_ASSERT (lit.type == LIT_STR);
zt_string1_p = literal_to_zt (lit);
}
@ -1195,8 +1194,7 @@ ecma_compare_ecma_strings_relational (const ecma_string_t *string1_p, /**< ecma-
if (string2_p->container == ECMA_STRING_CONTAINER_LIT_TABLE)
{
FIXME (uint8_t -> literal_index_t);
const literal lit = deserialize_literal_by_id ((uint8_t) string2_p->u.lit_index);
const literal lit = deserialize_literal_by_id (string2_p->u.lit_index);
JERRY_ASSERT (lit.type == LIT_STR);
zt_string2_p = literal_to_zt (lit);
}
@ -1258,7 +1256,7 @@ ecma_string_get_length (const ecma_string_t *string_p) /**< ecma-string */
if (container == ECMA_STRING_CONTAINER_LIT_TABLE)
{
const literal lit = deserialize_literal_by_id ((idx_t) string_p->u.lit_index);
const literal lit = deserialize_literal_by_id (string_p->u.lit_index);
return lit.data.lp.length;
}

View File

@ -19,6 +19,18 @@
#include "mem-heap.h"
#include "lp-string.h"
#define LINKED_LIST_MAGIC 0x42
typedef struct linked_list_header
{
struct linked_list_header *next;
struct linked_list_header *prev;
uint16_t block_size;
uint16_t element_size;
uint8_t magic;
}
linked_list_header;
#define ASSERT_LIST(list) \
do { \
linked_list_header *header = (linked_list_header *) list; \
@ -27,7 +39,7 @@ do { \
} while (0);
linked_list
linked_list_init (size_t element_size)
linked_list_init (uint16_t element_size)
{
size_t size = mem_heap_recommend_allocation_size (element_size);
linked_list list = mem_heap_alloc_block (size, MEM_HEAP_ALLOC_SHORT_TERM);
@ -40,6 +52,7 @@ linked_list_init (size_t element_size)
linked_list_header* header = (linked_list_header *) list;
header->magic = LINKED_LIST_MAGIC;
header->prev = header->next = null_list;
header->element_size = element_size;
header->block_size = (uint8_t) (size - sizeof (linked_list_header));
return list;
}
@ -57,42 +70,42 @@ linked_list_free (linked_list list)
}
void *
linked_list_element (linked_list list, size_t element_size, size_t element_num)
linked_list_element (linked_list list, uint16_t element_num)
{
ASSERT_LIST (list);
linked_list_header *header = (linked_list_header *) list;
linked_list raw = list + sizeof (linked_list_header);
if (header->block_size < element_size * (element_num + 1))
if (header->block_size < header->element_size * (element_num + 1))
{
if (header->next)
{
return linked_list_element ((linked_list) header->next, element_size,
element_num - (header->block_size / element_size));
return linked_list_element ((linked_list) header->next,
(uint16_t) (element_num - (header->block_size / header->element_size)));
}
else
{
return NULL;
}
}
raw += element_size * element_num;
raw += header->element_size * element_num;
return raw;
}
void
linked_list_set_element (linked_list list, size_t element_size, size_t element_num, void *element)
linked_list_set_element (linked_list list, uint16_t element_num, void *element)
{
ASSERT_LIST (list);
linked_list_header *header = (linked_list_header *) list;
linked_list raw = list + sizeof (linked_list_header);
if (header->block_size < element_size * (element_num + 1))
uint8_t *raw = (uint8_t *) (header + 1);
if (header->block_size < header->element_size * (element_num + 1))
{
if (header->next == null_list)
{
header->next = (linked_list_header *) linked_list_init (element_size);
header->next = (linked_list_header *) linked_list_init (header->element_size);
header->next->prev = header;
}
linked_list_set_element ((linked_list) header->next, element_size,
element_num - (header->block_size / element_size),
linked_list_set_element ((linked_list) header->next,
(uint16_t) (element_num - (header->block_size / header->element_size)),
element);
return;
}
@ -100,32 +113,5 @@ linked_list_set_element (linked_list list, size_t element_size, size_t element_n
{
return;
}
switch (element_size)
{
case 1:
{
((uint8_t *) raw)[element_num] = *((uint8_t *) element);
break;
}
case 2:
{
((uint16_t *) raw)[element_num] = *((uint16_t *) element);
break;
}
case 4:
{
((uint32_t *) raw)[element_num] = *((uint32_t *) element);
break;
}
case 8:
{
((uint64_t *) raw)[element_num] = *((uint64_t *) element);
break;
}
default:
{
__memcpy ((uint8_t*) raw + element_num * element_size, element, element_size);
break;
}
}
__memcpy (raw + element_num * header->element_size, element, header->element_size);
}

View File

@ -18,23 +18,12 @@
#include "globals.h"
#define LINKED_LIST_MAGIC 0x42
typedef struct linked_list_header
{
struct linked_list_header *next;
struct linked_list_header *prev;
uint8_t magic;
uint8_t block_size;
}
linked_list_header;
typedef uint8_t* linked_list;
#define null_list NULL
linked_list linked_list_init (size_t);
linked_list linked_list_init (uint16_t);
void linked_list_free (linked_list);
void *linked_list_element (linked_list, size_t, size_t);
void linked_list_set_element (linked_list, size_t, size_t, void *);
void *linked_list_element (linked_list, uint16_t);
void linked_list_set_element (linked_list, uint16_t, void *);
#endif /* LINKED_LIST_H */

View File

@ -164,9 +164,7 @@ literal_equal (literal lit1, literal lit2)
}
case LIT_NUMBER:
{
ecma_char_t buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
ecma_number_to_zt_string (lit2.data.num, buff, ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER);
return literal_equal_zt (lit1, buff);
return literal_equal_num (lit1, lit2.data.num);
}
default:
{

View File

@ -42,6 +42,8 @@ typedef struct
}
literal;
#define LITERAL_TO_REWRITE (INVALID_VALUE - 1)
literal create_empty_literal (void);
literal create_literal_from_num (ecma_number_t);
literal create_literal_from_str (const char *, ecma_length_t);

View File

@ -66,104 +66,73 @@
#ifndef STACK_H
#define STACK_H
#include "linked-list.h"
#include "array-list.h"
#define DEFINE_STACK_TYPE(NAME, DATA_TYPE, TYPE) \
#define DEFINE_STACK_TYPE(NAME, TYPE) \
typedef TYPE NAME##_stack_value_type; \
typedef DATA_TYPE NAME##_stack_data_type; \
typedef struct \
{ \
linked_list blocks; \
DATA_TYPE length; \
DATA_TYPE current; \
DATA_TYPE block_len; \
array_list data; \
} \
NAME##_stack;
#define STACK_INIT(NAME) \
do { \
NAME.blocks = linked_list_init (sizeof (NAME##_stack_value_type)); \
NAME.current = NAME##_global_size; \
NAME.length = NAME.block_len = ((linked_list_header *) NAME.blocks)->block_size / sizeof (NAME##_stack_value_type); \
NAME.data = array_list_init (sizeof (NAME##_stack_value_type)); \
} while (0)
#define STACK_FREE(NAME) \
do { \
linked_list_free (NAME.blocks); \
NAME.length = NAME.current = 0; \
NAME.blocks = NULL; \
array_list_free (NAME.data); \
NAME.data = null_list; \
} while (0)
#define DEFINE_INCREASE_STACK_SIZE(NAME, TYPE) \
static void increase_##NAME##_stack_size (void) __unused; \
static void \
increase_##NAME##_stack_size (void) { \
linked_list_set_element (NAME.blocks, sizeof (TYPE), NAME.current, NULL); \
if (NAME.current >= NAME.length) \
{ \
NAME.length = (NAME##_stack_data_type) (NAME.length + NAME.block_len); \
} \
NAME.current = (NAME##_stack_data_type) (NAME.current + 1); \
}
#define DEFINE_DECREASE_STACE_SIZE(NAME, TYPE) \
static void decrease_##NAME##_stack_size (void) __unused; \
static void \
decrease_##NAME##_stack_size (void) { \
JERRY_ASSERT (NAME.current > NAME##_global_size); \
NAME.current = (NAME##_stack_data_type) (NAME.current - 1); \
}
#define DEFINE_STACK_ELEMENT(NAME, TYPE) \
static TYPE NAME##_stack_element (NAME##_stack_data_type) __unused; \
static TYPE NAME##_stack_element (NAME##_stack_data_type elem) { \
JERRY_ASSERT (elem < NAME.current); \
return *((TYPE *) linked_list_element (NAME.blocks, sizeof (TYPE), elem)); \
static TYPE NAME##_stack_element (size_t) __unused; \
static TYPE NAME##_stack_element (size_t elem) { \
return *((TYPE *) array_list_element (NAME.data, elem)); \
}
#define DEFINE_SET_STACK_ELEMENT(NAME, TYPE) \
static void set_##NAME##_stack_element (NAME##_stack_data_type, TYPE) __unused; \
static void set_##NAME##_stack_element (NAME##_stack_data_type elem, TYPE value) { \
JERRY_ASSERT (elem < NAME.current); \
linked_list_set_element (NAME.blocks, sizeof (TYPE), elem, &value); \
static void set_##NAME##_stack_element (size_t, TYPE) __unused; \
static void set_##NAME##_stack_element (size_t elem, TYPE value) { \
array_list_set_element (NAME.data, elem, &value); \
}
#define DEFINE_STACK_HEAD(NAME, TYPE) \
static TYPE NAME##_stack_head (NAME##_stack_data_type) __unused; \
static TYPE NAME##_stack_head (NAME##_stack_data_type elem) { \
JERRY_ASSERT (elem <= NAME.current); \
return *((TYPE *) linked_list_element (NAME.blocks, sizeof (TYPE), (size_t) (NAME.current - elem))); \
static TYPE NAME##_stack_head (size_t) __unused; \
static TYPE NAME##_stack_head (size_t elem) { \
return *((TYPE *) array_list_last_element (NAME.data, elem)); \
}
#define DEFINE_SET_STACK_HEAD(NAME, DATA_TYPE, TYPE) \
static void set_##NAME##_stack_head (DATA_TYPE, TYPE) __unused; \
static void set_##NAME##_stack_head (DATA_TYPE elem, TYPE value) { \
JERRY_ASSERT (elem <= NAME.current); \
linked_list_set_element (NAME.blocks, sizeof (TYPE), (size_t) (NAME.current - elem), &value); \
#define DEFINE_SET_STACK_HEAD(NAME, TYPE) \
static void set_##NAME##_stack_head (size_t, TYPE) __unused; \
static void set_##NAME##_stack_head (size_t elem, TYPE value) { \
array_list_set_last_element (NAME.data, elem, &value); \
}
#define DEFINE_STACK_PUSH(NAME, TYPE) \
static void NAME##_stack_push (TYPE) __unused; \
static void NAME##_stack_push (TYPE value) { \
linked_list_set_element (NAME.blocks, sizeof (TYPE), NAME.current, &value); \
increase_##NAME##_stack_size (); \
NAME.data = array_list_append (NAME.data, &value); \
}
#define DEFINE_CONVERT_TO_RAW_DATA(NAME, TYPE) \
static TYPE *convert_##NAME##_to_raw_data (void) __unused; \
static TYPE *convert_##NAME##_to_raw_data (void) { \
if (array_list_len (NAME.data) == 0) \
{ \
return NULL; \
} \
size_t size = mem_heap_recommend_allocation_size ( \
((size_t) (NAME.current + 1) * sizeof (NAME##_stack_value_type))); \
array_list_len (NAME.data) * sizeof (NAME##_stack_value_type)); \
TYPE *DATA = (TYPE *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM); \
if (DATA == NULL) \
{ \
__printf ("Out of memory\n"); \
JERRY_UNREACHABLE (); \
} \
__memset (DATA, 0, size); \
for (NAME##_stack_data_type i = 0; i < NAME.current; i++) { \
DATA[i] = STACK_ELEMENT (NAME, i); \
} \
__memcpy (DATA, array_list_element (NAME.data, 0), array_list_len (NAME.data) * sizeof (NAME##_stack_value_type)); \
return DATA; \
}
@ -173,16 +142,16 @@ do { NAME##_stack_push (VALUE); } while (0)
#define STACK_DROP(NAME, I) \
do { \
for (size_t i = 0, till = (size_t) (I); i < till; i++) { \
decrease_##NAME##_stack_size (); } } while (0)
array_list_drop_last (NAME.data); } } while (0)
#define STACK_CLEAN(NAME) \
STACK_DROP (NAME, NAME.current - NAME##_global_size);
#define STACK_HEAD(NAME, I) \
NAME##_stack_head ((NAME##_stack_data_type) (I))
NAME##_stack_head ((size_t) (I))
#define STACK_SET_HEAD(NAME, I, VALUE) \
do { set_##NAME##_stack_head ((NAME##_stack_data_type) (I), VALUE); } while (0)
do { set_##NAME##_stack_head ((size_t) (I), VALUE); } while (0)
#define STACK_INCR_HEAD(NAME, I) \
do { STACK_SET_HEAD (NAME, I, (NAME##_stack_value_type) (STACK_HEAD (NAME, I) + 1)); } while (0)
@ -201,13 +170,13 @@ do { \
} while (0)
#define STACK_SIZE(NAME) \
NAME.current
array_list_len (NAME.data)
#define STACK_ELEMENT(NAME, I) \
NAME##_stack_element ((NAME##_stack_data_type) (I))
NAME##_stack_element ((size_t) (I))
#define STACK_SET_ELEMENT(NAME, I, VALUE) \
do { set_##NAME##_stack_element ((NAME##_stack_data_type) I, VALUE); } while (0)
do { set_##NAME##_stack_element ((size_t) I, VALUE); } while (0)
#define STACK_CONVERT_TO_RAW_DATA(NAME, DATA) \
do { DATA = convert_##NAME##_to_raw_data (); } while (0)
@ -218,52 +187,48 @@ do { STACK_SET_ELEMENT (NAME, I, (NAME##_stack_value_type) (STACK_ELEMENT(NAME,
#define STACK_DECR_ELEMENT(NAME, I) \
do { STACK_SET_ELEMENT (NAME, I, (NAME##_stack_value_type) (STACK_ELEMENT(NAME, I) - 1)); } while (0)
#define STACK_ITERATE(NAME, FUNC, FROM) \
do { for (NAME##_stack_data_type i = FROM; i < NAME.current; i++) { \
FUNC (STACK_ELEMENT (NAME, i)); \
} } while (0)
#define STACK_ITERATE(NAME, VAL, FROM) \
for (size_t NAME##_i = FROM; \
NAME##_i < array_list_len (NAME.data); \
NAME##_i++) \
{ \
NAME##_stack_value_type VAL = STACK_ELEMENT (NAME, NAME##_i);
#define STACK_ITERATE_VARG(NAME, FUNC, FROM, ...) \
do { for (NAME##_stack_data_type i = FROM; i < NAME.current; i++) { \
FUNC (STACK_ELEMENT (NAME, i), __VA_ARGS__); \
} } while (0)
#define STACK_ITERATE_END() \
}
#define STACK_ITERATE_VARG_SET(NAME, FUNC, FROM, ...) \
do { for (NAME##_stack_data_type i = FROM; i < NAME.current; i++) { \
do { for (size_t i = FROM; i < array_list_len (NAME.data); i++) { \
STACK_SET_ELEMENT (NAME, i, FUNC (STACK_ELEMENT (NAME, i), __VA_ARGS__)); \
} } while (0)
#define STACK(NAME, DATA_TYPE, TYPE) \
DEFINE_STACK_TYPE(NAME, DATA_TYPE, TYPE) \
#define STACK(NAME, TYPE) \
DEFINE_STACK_TYPE(NAME, TYPE) \
NAME##_stack NAME; \
DEFINE_DECREASE_STACE_SIZE (NAME, TYPE) \
DEFINE_INCREASE_STACK_SIZE (NAME, TYPE) \
DEFINE_STACK_ELEMENT(NAME, TYPE) \
DEFINE_SET_STACK_ELEMENT(NAME, TYPE) \
DEFINE_STACK_HEAD(NAME, TYPE) \
DEFINE_CONVERT_TO_RAW_DATA(NAME, TYPE) \
DEFINE_SET_STACK_HEAD(NAME, DATA_TYPE, TYPE) \
DEFINE_SET_STACK_HEAD(NAME, TYPE) \
DEFINE_STACK_PUSH(NAME, TYPE)
#define STATIC_STACK(NAME, DATA_TYPE, TYPE) \
DEFINE_STACK_TYPE(NAME, DATA_TYPE, TYPE) \
#define STATIC_STACK(NAME, TYPE) \
DEFINE_STACK_TYPE(NAME, TYPE) \
static NAME##_stack NAME; \
DEFINE_DECREASE_STACE_SIZE (NAME, TYPE) \
DEFINE_INCREASE_STACK_SIZE (NAME, TYPE) \
DEFINE_STACK_ELEMENT(NAME, TYPE) \
DEFINE_SET_STACK_ELEMENT(NAME, TYPE) \
DEFINE_STACK_HEAD(NAME, TYPE) \
DEFINE_CONVERT_TO_RAW_DATA(NAME, TYPE) \
DEFINE_SET_STACK_HEAD(NAME, DATA_TYPE, TYPE) \
DEFINE_SET_STACK_HEAD(NAME, TYPE) \
DEFINE_STACK_PUSH(NAME, TYPE)
#ifndef JERRY_NDEBUG
#define STACK_DECLARE_USAGE(NAME) \
NAME##_stack_data_type NAME##_current = NAME.current;
size_t NAME##_current = array_list_len (NAME.data);
#define STACK_CHECK_USAGE(NAME) \
do { \
JERRY_ASSERT (NAME.current == NAME##_current); \
} while (0);
JERRY_ASSERT (array_list_len (NAME.data) == NAME##_current); \
} while (0)
#else
#define STACK_DECLARE_USAGE(NAME) ;
#define STACK_CHECK_USAGE(NAME) ;

View File

@ -19,7 +19,7 @@
#include "parser.h"
#include "stack.h"
#include "opcodes.h"
#include "parse-error.h"
#include "syntax-errors.h"
#include "parser.h"
#include "ecma-helpers.h"
@ -31,7 +31,7 @@ static token empty_token =
.loc = 0
};
static bool allow_dump_lines = false;
static bool allow_dump_lines = false, strict_mode;
static size_t buffer_size = 0;
/* Represents the contents of a script. */
@ -48,7 +48,7 @@ enum
{
literals_global_size
};
STATIC_STACK (literals, uint8_t, literal)
STATIC_STACK (literals, literal)
static bool
is_empty (token tok)
@ -61,7 +61,7 @@ current_locus (void)
{
if (token_start == NULL)
{
return (locus) (buffer - buffer_start - 1);
return (locus) (buffer - buffer_start);
}
else
{
@ -99,7 +99,7 @@ dump_current_line (void)
}
static token
create_token (token_type type, uint8_t uid)
create_token (token_type type, literal_index_t uid)
{
return (token)
{
@ -140,7 +140,7 @@ current_token_equals_to_literal (literal lit)
else if (lit.type == LIT_MAGIC_STR)
{
const char *str = (const char *) ecma_get_magic_string_zt (lit.data.magic_str_id);
if (__strlen (str) != /* Fucking [-Werror=sign-compare] */ (size_t) (buffer - token_start))
if (__strlen (str) != (size_t) (buffer - token_start))
{
return false;
}
@ -201,26 +201,13 @@ convert_current_token_to_token (token_type tt)
{
JERRY_ASSERT (token_start);
for (uint8_t i = 0; i < STACK_SIZE (literals); i++)
for (literal_index_t i = 0; i < STACK_SIZE (literals); i++)
{
const literal lit = STACK_ELEMENT (literals, i);
if ((lit.type == LIT_STR || lit.type == LIT_MAGIC_STR)
&& current_token_equals_to_literal (lit))
{
if (tt == TOK_STRING)
{
// locus must point to the first '"'
return (token)
{
.type = tt,
.loc = current_locus () - 1,
.uid = i
};
}
else
{
return create_token (tt, i);
}
return create_token (tt, i);
}
}
@ -233,7 +220,7 @@ convert_current_token_to_token (token_type tt)
STACK_PUSH (literals, lit);
return create_token (tt, (idx_t) (STACK_SIZE (literals) - 1));
return create_token (tt, (literal_index_t) (STACK_SIZE (literals) - 1));
}
/* If TOKEN represents a keyword, return decoded keyword,
@ -328,7 +315,7 @@ decode_keyword (void)
}
if (current_token_equals_to ("interface"))
{
if (parser_strict_mode ())
if (strict_mode)
{
return create_token (TOK_KEYWORD, KW_INTERFACE);
}
@ -343,7 +330,7 @@ decode_keyword (void)
}
if (current_token_equals_to ("implements"))
{
if (parser_strict_mode ())
if (strict_mode)
{
return create_token (TOK_KEYWORD, KW_IMPLEMENTS);
}
@ -354,7 +341,7 @@ decode_keyword (void)
}
if (current_token_equals_to ("let"))
{
if (parser_strict_mode ())
if (strict_mode)
{
return create_token (TOK_KEYWORD, KW_LET);
}
@ -373,7 +360,7 @@ decode_keyword (void)
}
if (current_token_equals_to ("package"))
{
if (parser_strict_mode ())
if (strict_mode)
{
return create_token (TOK_KEYWORD, KW_PACKAGE);
}
@ -384,7 +371,7 @@ decode_keyword (void)
}
if (current_token_equals_to ("private"))
{
if (parser_strict_mode ())
if (strict_mode)
{
return create_token (TOK_KEYWORD, KW_PRIVATE);
}
@ -395,7 +382,7 @@ decode_keyword (void)
}
if (current_token_equals_to ("protected"))
{
if (parser_strict_mode ())
if (strict_mode)
{
return create_token (TOK_KEYWORD, KW_PROTECTED);
}
@ -406,7 +393,7 @@ decode_keyword (void)
}
if (current_token_equals_to ("public"))
{
if (parser_strict_mode ())
if (strict_mode)
{
return create_token (TOK_KEYWORD, KW_PUBLIC);
}
@ -421,7 +408,7 @@ decode_keyword (void)
}
if (current_token_equals_to ("static"))
{
if (parser_strict_mode ())
if (strict_mode)
{
return create_token (TOK_KEYWORD, KW_STATIC);
}
@ -476,7 +463,7 @@ decode_keyword (void)
}
if (current_token_equals_to ("yield"))
{
if (parser_strict_mode ())
if (strict_mode)
{
return create_token (TOK_KEYWORD, KW_YIELD);
}
@ -491,7 +478,7 @@ decode_keyword (void)
static token
convert_seen_num_to_token (ecma_number_t num)
{
for (uint8_t i = 0; i < STACK_SIZE (literals); i++)
for (literal_index_t i = 0; i < STACK_SIZE (literals); i++)
{
const literal lit = STACK_ELEMENT (literals, i);
if (lit.type != LIT_NUMBER)
@ -506,27 +493,30 @@ convert_seen_num_to_token (ecma_number_t num)
STACK_PUSH (literals, create_literal_from_num (num));
return create_token (TOK_NUMBER, (idx_t) (STACK_SIZE (literals) - 1));
return create_token (TOK_NUMBER, (literal_index_t) (STACK_SIZE (literals) - 1));
}
const literal *
lexer_get_literals (void)
{
literal *data = NULL;
STACK_CONVERT_TO_RAW_DATA (literals, data);
if (STACK_SIZE (literals) > 0)
{
STACK_CONVERT_TO_RAW_DATA (literals, data);
}
return data;
}
uint8_t
literal_index_t
lexer_get_literals_count (void)
{
return STACK_SIZE (literals);
return (literal_index_t) STACK_SIZE (literals);
}
idx_t
literal_index_t
lexer_lookup_literal_uid (literal lit)
{
for (uint8_t i = 0; i < STACK_SIZE (literals); i++)
for (literal_index_t i = 0; i < STACK_SIZE (literals); i++)
{
if (literal_equal_type (STACK_ELEMENT (literals, i), lit))
{
@ -537,8 +527,9 @@ lexer_lookup_literal_uid (literal lit)
}
literal
lexer_get_literal_by_id (uint8_t id)
lexer_get_literal_by_id (literal_index_t id)
{
JERRY_ASSERT (id != INVALID_LITERAL);
JERRY_ASSERT (id < STACK_SIZE (literals));
return STACK_ELEMENT (literals, id);
}
@ -552,7 +543,7 @@ lexer_get_strings_cache (void)
void
lexer_add_literal_if_not_present (literal lit)
{
for (uint8_t i = 0; i < STACK_SIZE (literals); i++)
for (literal_index_t i = 0; i < STACK_SIZE (literals); i++)
{
if (literal_equal_type (STACK_ELEMENT (literals, i), lit))
{
@ -579,8 +570,9 @@ consume_char (void)
#define RETURN_PUNC_EX(TOK, NUM) \
do \
{ \
token tok = create_token (TOK, 0); \
buffer += NUM; \
return create_token (TOK, 0); \
return tok; \
} \
while (0)
@ -865,7 +857,7 @@ parse_number (void)
if (*token_start == '0' && tok_length != 1)
{
if (parser_strict_mode ())
if (strict_mode)
{
PARSE_ERROR ("Octal tnteger literals are not allowed in strict mode", token_start - buffer_start);
}
@ -1430,6 +1422,12 @@ lexer_token_type_to_string (token_type tt)
}
}
void
lexer_set_strict_mode (bool is_strict)
{
strict_mode = is_strict;
}
void
lexer_init (const char *source, size_t source_size, bool show_opcodes)
{
@ -1439,6 +1437,7 @@ lexer_init (const char *source, size_t source_size, bool show_opcodes)
lexer_set_source (source);
strings_cache = NULL;
strings_cache_used_size = strings_cache_size = 0;
lexer_set_strict_mode (false);
STACK_INIT (literals);
}

View File

@ -22,6 +22,8 @@
#include "opcodes.h"
#define INVALID_VALUE 255
#define INVALID_LITERAL UINT32_MAX
/* Keywords. */
typedef enum
{
@ -163,7 +165,7 @@ typedef struct
{
locus loc;
token_type type;
idx_t uid;
literal_index_t uid;
}
token;
@ -177,9 +179,9 @@ token lexer_prev_token (void);
const literal *lexer_get_literals (void);
const ecma_char_t *lexer_get_strings_cache (void);
void lexer_add_literal_if_not_present (literal);
uint8_t lexer_get_literals_count (void);
literal lexer_get_literal_by_id (uint8_t);
idx_t lexer_lookup_literal_uid (literal lit);
literal_index_t lexer_get_literals_count (void);
literal lexer_get_literal_by_id (literal_index_t);
literal_index_t lexer_lookup_literal_uid (literal lit);
void lexer_seek (locus);
void lexer_locus_to_line_and_column (locus, size_t *, size_t *);
@ -187,4 +189,6 @@ void lexer_dump_line (size_t);
const char *lexer_keyword_to_string (keyword);
const char *lexer_token_type_to_string (token_type);
void lexer_set_strict_mode (bool);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,233 @@
/* 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 OPCODES_DUMPER_H
#define OPCODES_DUMPER_H
#include "opcodes.h"
#include "ecma-globals.h"
#include "lexer.h"
typedef enum
{
OPERAND_LITERAL,
OPERAND_TMP
}
operand_type;
typedef struct
{
operand_type type;
union
{
idx_t uid;
literal_index_t lit_id;
}
data;
}
operand;
typedef enum
{
VARG_FUNC_DECL,
VARG_FUNC_EXPR,
VARG_ARRAY_DECL,
VARG_OBJ_DECL,
VARG_CONSTRUCT_EXPR,
VARG_CALL_EXPR
}
varg_list_type;
operand empty_operand (void);
operand literal_operand (literal_index_t);
bool operand_is_empty (operand);
void dumper_init (void);
void dumper_free (void);
void dumper_new_statement (void);
void dumper_new_scope (void);
void dumper_finish_scope (void);
bool dumper_is_intrinsic (operand);
operand dump_intrinsic (operand, operand);
void dump_boolean_assignment (operand, bool);
operand dump_boolean_assignment_res (bool);
void dump_string_assignment (operand, literal_index_t);
operand dump_string_assignment_res (literal_index_t);
void dump_number_assignment (operand, literal_index_t);
operand dump_number_assignment_res (literal_index_t);
void dump_smallint_assignment (operand, idx_t);
operand dump_smallint_assignment_res (idx_t);
void dump_undefined_assignment (operand);
operand dump_undefined_assignment_res (void);
void dump_null_assignment (operand);
operand dump_null_assignment_res (void);
void dump_variable_assignment (operand, operand);
operand dump_variable_assignment_res (operand);
void dump_varg_header_for_rewrite (varg_list_type, operand);
operand rewrite_varg_header_set_args_count (uint8_t);
void dump_this_arg (operand);
void dump_varg (operand);
void dump_prop_name_and_value (operand, operand);
void dump_prop_getter_decl (operand, operand);
void dump_prop_setter_decl (operand, operand);
void dump_prop_getter (operand, operand, operand);
operand dump_prop_getter_res (operand, operand);
void dump_prop_setter (operand, operand, operand);
void dump_function_end_for_rewrite (void);
void rewrite_function_end (varg_list_type);
void dump_this (operand);
operand dump_this_res (void);
void dump_post_increment (operand, operand);
operand dump_post_increment_res (operand);
void dump_post_decrement (operand, operand);
operand dump_post_decrement_res (operand);
void dump_pre_increment (operand, operand);
operand dump_pre_increment_res (operand);
void dump_pre_decrement (operand, operand);
operand dump_pre_decrement_res (operand);
void dump_unary_plus (operand, operand);
operand dump_unary_plus_res (operand);
void dump_unary_minus (operand, operand);
operand dump_unary_minus_res (operand);
void dump_bitwise_not (operand, operand);
operand dump_bitwise_not_res (operand);
void dump_logical_not (operand, operand);
operand dump_logical_not_res (operand);
void dump_multiplication (operand, operand, operand);
operand dump_multiplication_res (operand, operand);
void dump_division (operand, operand, operand);
operand dump_division_res (operand, operand);
void dump_remainder (operand, operand, operand);
operand dump_remainder_res (operand, operand);
void dump_addition (operand, operand, operand);
operand dump_addition_res (operand, operand);
void dump_substraction (operand, operand, operand);
operand dump_substraction_res (operand, operand);
void dump_left_shift (operand, operand, operand);
operand dump_left_shift_res (operand, operand);
void dump_right_shift (operand, operand, operand);
operand dump_right_shift_res (operand, operand);
void dump_right_shift_ex (operand, operand, operand);
operand dump_right_shift_ex_res (operand, operand);
void dump_less_than (operand, operand, operand);
operand dump_less_than_res (operand, operand);
void dump_greater_than (operand, operand, operand);
operand dump_greater_than_res (operand, operand);
void dump_less_or_equal_than (operand, operand, operand);
operand dump_less_or_equal_than_res (operand, operand);
void dump_greater_or_equal_than (operand, operand, operand);
operand dump_greater_or_equal_than_res (operand, operand);
void dump_instanceof (operand, operand, operand);
operand dump_instanceof_res (operand, operand);
void dump_in (operand, operand, operand);
operand dump_in_res (operand, operand);
void dump_equal_value (operand, operand, operand);
operand dump_equal_value_res (operand, operand);
void dump_not_equal_value (operand, operand, operand);
operand dump_not_equal_value_res (operand, operand);
void dump_equal_value_type (operand, operand, operand);
operand dump_equal_value_type_res (operand, operand);
void dump_not_equal_value_type (operand, operand, operand);
operand dump_not_equal_value_type_res (operand, operand);
void dump_bitwise_and (operand, operand, operand);
operand dump_bitwise_and_res (operand, operand);
void dump_bitwise_xor (operand, operand, operand);
operand dump_bitwise_xor_res (operand, operand);
void dump_bitwise_or (operand, operand, operand);
operand dump_bitwise_or_res (operand, operand);
void start_dumping_logical_and_checks (void);
void dump_logical_and_check_for_rewrite (operand);
void rewrite_logical_and_checks (void);
void start_dumping_logical_or_checks (void);
void dump_logical_or_check_for_rewrite (operand);
void rewrite_logical_or_checks (void);
void dump_conditional_check_for_rewrite (operand);
void rewrite_conditional_check (void);
void dump_jump_to_end_for_rewrite (void);
void rewrite_jump_to_end (void);
void start_dumping_assignment_expression (void);
operand dump_prop_setter_or_variable_assignment_res (operand, operand);
operand dump_prop_setter_or_addition_res (operand, operand);
operand dump_prop_setter_or_multiplication_res (operand, operand);
operand dump_prop_setter_or_division_res (operand, operand);
operand dump_prop_setter_or_remainder_res (operand, operand);
operand dump_prop_setter_or_substraction_res (operand, operand);
operand dump_prop_setter_or_left_shift_res (operand, operand);
operand dump_prop_setter_or_right_shift_res (operand, operand);
operand dump_prop_setter_or_right_shift_ex_res (operand, operand);
operand dump_prop_setter_or_bitwise_and_res (operand, operand);
operand dump_prop_setter_or_bitwise_xor_res (operand, operand);
operand dump_prop_setter_or_bitwise_or_res (operand, operand);
void start_collecting_breaks (void);
void start_collecting_continues (void);
void dumper_set_break_target (void);
void dumper_set_continue_target (void);
void dumper_set_next_interation_target (void);
void dump_continue_for_rewrite (void);
void dump_break_for_rewrite (void);
void rewrite_continues (void);
void rewrite_breaks (void);
void dump_continue_iterations_check (operand);
void start_dumping_case_clauses (void);
void dump_case_clause_check_for_rewrite (operand, operand);
void dump_default_clause_check_for_rewrite (void);
void rewrite_case_clause (void);
void rewrite_default_clause (void);
void finish_dumping_case_clauses (void);
void dump_delete (operand, operand, bool, locus);
operand dump_delete_res (operand, bool, locus);
void dump_typeof (operand, operand);
operand dump_typeof_res (operand);
void dump_with (operand);
void dump_with_end (void);
void dump_try_for_rewrite (void);
void rewrite_try (void);
void dump_catch_for_rewrite (operand);
void rewrite_catch (void);
void dump_finally_for_rewrite (void);
void rewrite_finally (void);
void dump_end_try_catch_finally (void);
void dump_throw (operand);
bool dumper_variable_declaration_exists (literal_index_t);
void dump_variable_declaration (literal_index_t);
void dump_strict_mode_header (void);
void dump_reg_var_decl_for_rewrite (void);
void rewrite_reg_var_decl (void);
void dump_ret (void);
void dump_retval (operand op);
void dump_exit (void);
#endif /* OPCODES_DUMPER_H */

File diff suppressed because it is too large Load Diff

View File

@ -21,6 +21,5 @@
void parser_init (const char *, size_t, bool);
void parser_parse_program (void);
void parser_free (void);
bool parser_strict_mode (void);
#endif

View File

@ -16,8 +16,15 @@
#include "scopes-tree.h"
#include "mem-heap.h"
#include "jerry-libc.h"
#include "lexer.h"
#include "bytecode-data.h"
#define NAME_TO_ID(op) (__op__idx_##op)
#define OPCODE(op) (__op__idx_##op)
#define HASH_SIZE 128
static hash_table lit_id_to_uid = null_hash;
static opcode_counter_t global_oc = 0;
static idx_t next_uid;
static void
assert_tree (scopes_tree t)
@ -26,6 +33,22 @@ assert_tree (scopes_tree t)
JERRY_ASSERT (t->t.magic == TREE_MAGIC);
}
static idx_t
get_uid (op_meta *op, uint8_t i)
{
JERRY_ASSERT (i < 4);
raw_opcode *raw = (raw_opcode *) &op->op;
return raw->uids[i + 1];
}
static void
set_uid (op_meta *op, uint8_t i, idx_t uid)
{
JERRY_ASSERT (i < 4);
raw_opcode *raw = (raw_opcode *) &op->op;
raw->uids[i + 1] = uid;
}
opcode_counter_t
scopes_tree_opcodes_num (scopes_tree t)
{
@ -34,18 +57,18 @@ scopes_tree_opcodes_num (scopes_tree t)
}
void
scopes_tree_add_opcode (scopes_tree tree, opcode_t op)
scopes_tree_add_op_meta (scopes_tree tree, op_meta op)
{
assert_tree (tree);
linked_list_set_element (tree->opcodes, sizeof (opcode_t), tree->opcodes_num++, &op);
linked_list_set_element (tree->opcodes, tree->opcodes_num++, &op);
}
void
scopes_tree_set_opcode (scopes_tree tree, opcode_counter_t oc, opcode_t op)
scopes_tree_set_op_meta (scopes_tree tree, opcode_counter_t oc, op_meta op)
{
assert_tree (tree);
JERRY_ASSERT (oc < tree->opcodes_num);
linked_list_set_element (tree->opcodes, sizeof (opcode_t), oc, &op);
linked_list_set_element (tree->opcodes, oc, &op);
}
void
@ -56,12 +79,12 @@ scopes_tree_set_opcodes_num (scopes_tree tree, opcode_counter_t oc)
tree->opcodes_num = oc;
}
opcode_t
scopes_tree_opcode (scopes_tree tree, opcode_counter_t oc)
op_meta
scopes_tree_op_meta (scopes_tree tree, opcode_counter_t oc)
{
assert_tree (tree);
JERRY_ASSERT (oc < tree->opcodes_num);
return *(opcode_t *) linked_list_element (tree->opcodes, sizeof (opcode_t), oc);
return *(op_meta *) linked_list_element (tree->opcodes, oc);
}
opcode_counter_t
@ -71,64 +94,295 @@ scopes_tree_count_opcodes (scopes_tree t)
opcode_counter_t res = t->opcodes_num;
for (uint8_t i = 0; i < t->t.children_num; i++)
{
res = (opcode_counter_t) (res
+ scopes_tree_count_opcodes (*(scopes_tree *) linked_list_element (t->t.children,
sizeof (scopes_tree),
i)));
res = (opcode_counter_t) (
res + scopes_tree_count_opcodes (
*(scopes_tree *) linked_list_element (t->t.children, i)));
}
return res;
}
static opcode_counter_t
merge_subscopes (scopes_tree tree, opcode_t *data)
static uint16_t
lit_id_hash (void * lit_id)
{
return *(literal_index_t *) lit_id % HASH_SIZE;
}
static void
start_new_block_if_necessary (void)
{
if (global_oc % BLOCK_SIZE == 0)
{
next_uid = 0;
if (lit_id_to_uid != null_hash)
{
hash_table_free (lit_id_to_uid);
lit_id_to_uid = null_hash;
}
lit_id_to_uid = hash_table_init (sizeof (literal_index_t), sizeof (idx_t), HASH_SIZE, lit_id_hash,
MEM_HEAP_ALLOC_SHORT_TERM);
}
}
static bool
is_possible_literal (uint16_t mask, uint8_t index)
{
int res;
switch (index)
{
case 0:
{
res = mask >> 8;
break;
}
case 1:
{
res = (mask & 0xF0) >> 4;
break;
}
default:
{
JERRY_ASSERT (index = 2);
res = mask & 0x0F;
}
}
JERRY_ASSERT (res == 0 || res == 1);
return res == 1;
}
static void
change_uid (op_meta *om, hash_table lit_ids, uint16_t mask)
{
for (uint8_t i = 0; i < 3; i++)
{
if (is_possible_literal (mask, i))
{
if (get_uid (om, i) == LITERAL_TO_REWRITE)
{
JERRY_ASSERT (om->lit_id[i] != NOT_A_LITERAL);
literal_index_t lit_id = om->lit_id[i];
idx_t *uid = hash_table_lookup (lit_id_to_uid, &lit_id);
if (uid == NULL)
{
hash_table_insert (lit_id_to_uid, &lit_id, &next_uid);
lit_id_table_key key = create_lit_id_table_key (next_uid, global_oc);
hash_table_insert (lit_ids, &key, &lit_id);
uid = hash_table_lookup (lit_id_to_uid, &lit_id);
JERRY_ASSERT (uid != NULL);
JERRY_ASSERT (*uid == next_uid);
next_uid++;
}
set_uid (om, i, *uid);
}
else
{
JERRY_ASSERT (om->lit_id[i] == NOT_A_LITERAL);
}
}
else
{
JERRY_ASSERT (om->lit_id[i] == NOT_A_LITERAL);
}
}
}
static op_meta *
extract_op_meta (scopes_tree tree, opcode_counter_t opc_index)
{
return (op_meta *) linked_list_element (tree->opcodes, opc_index);
}
static opcode_t
generate_opcode (scopes_tree tree, opcode_counter_t opc_index, hash_table lit_ids)
{
start_new_block_if_necessary ();
op_meta *om = extract_op_meta (tree, opc_index);
/* Now we should change uids of opcodes.
Since different opcodes has different literals/tmps in different places,
we should change only them.
For each case possible literal positions are shown as 0xYYY literal,
where Y is set to '1' when there is a possible literal in this position,
and '0' otherwise. */
switch (om->op.op_idx)
{
case OPCODE (prop_getter):
case OPCODE (prop_setter):
case OPCODE (delete_prop):
case OPCODE (b_shift_left):
case OPCODE (b_shift_right):
case OPCODE (b_shift_uright):
case OPCODE (b_and):
case OPCODE (b_or):
case OPCODE (b_xor):
case OPCODE (equal_value):
case OPCODE (not_equal_value):
case OPCODE (equal_value_type):
case OPCODE (not_equal_value_type):
case OPCODE (less_than):
case OPCODE (greater_than):
case OPCODE (less_or_equal_than):
case OPCODE (greater_or_equal_than):
case OPCODE (instanceof):
case OPCODE (in):
case OPCODE (addition):
case OPCODE (substraction):
case OPCODE (division):
case OPCODE (multiplication):
case OPCODE (remainder):
{
change_uid (om, lit_ids, 0x111);
break;
}
case OPCODE (call_n):
case OPCODE (native_call):
case OPCODE (construct_n):
case OPCODE (func_expr_n):
case OPCODE (delete_var):
case OPCODE (typeof):
case OPCODE (b_not):
case OPCODE (logical_not):
case OPCODE (post_incr):
case OPCODE (post_decr):
case OPCODE (pre_incr):
case OPCODE (pre_decr):
case OPCODE (unary_plus):
case OPCODE (unary_minus):
{
change_uid (om, lit_ids, 0x110);
break;
}
case OPCODE (assignment):
{
switch (om->op.data.assignment.type_value_right)
{
case OPCODE_ARG_TYPE_SIMPLE:
case OPCODE_ARG_TYPE_SMALLINT:
case OPCODE_ARG_TYPE_SMALLINT_NEGATE:
{
change_uid (om, lit_ids, 0x100);
break;
}
case OPCODE_ARG_TYPE_NUMBER:
case OPCODE_ARG_TYPE_NUMBER_NEGATE:
case OPCODE_ARG_TYPE_STRING:
case OPCODE_ARG_TYPE_VARIABLE:
{
change_uid (om, lit_ids, 0x101);
break;
}
}
break;
}
case OPCODE (func_decl_n):
case OPCODE (array_decl):
case OPCODE (obj_decl):
case OPCODE (this):
case OPCODE (with):
case OPCODE (throw):
case OPCODE (is_true_jmp_up):
case OPCODE (is_true_jmp_down):
case OPCODE (is_false_jmp_up):
case OPCODE (is_false_jmp_down):
case OPCODE (var_decl):
case OPCODE (retval):
{
change_uid (om, lit_ids, 0x100);
break;
}
case OPCODE (exitval):
case OPCODE (ret):
case OPCODE (try):
case OPCODE (jmp_up):
case OPCODE (jmp_down):
case OPCODE (nop):
case OPCODE (reg_var_decl):
{
change_uid (om, lit_ids, 0x000);
break;
}
case OPCODE (meta):
{
switch (om->op.data.meta.type)
{
case OPCODE_META_TYPE_VARG_PROP_DATA:
case OPCODE_META_TYPE_VARG_PROP_GETTER:
case OPCODE_META_TYPE_VARG_PROP_SETTER:
{
change_uid (om, lit_ids, 0x011);
break;
}
case OPCODE_META_TYPE_THIS_ARG:
case OPCODE_META_TYPE_VARG:
case OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER:
{
change_uid (om, lit_ids, 0x010);
break;
}
case OPCODE_META_TYPE_UNDEFINED:
case OPCODE_META_TYPE_END_WITH:
case OPCODE_META_TYPE_FUNCTION_END:
case OPCODE_META_TYPE_CATCH:
case OPCODE_META_TYPE_FINALLY:
case OPCODE_META_TYPE_END_TRY_CATCH_FINALLY:
case OPCODE_META_TYPE_STRICT_CODE:
{
change_uid (om, lit_ids, 0x000);
break;
}
}
break;
}
}
return om->op;
}
static void
merge_subscopes (scopes_tree tree, opcode_t *data, hash_table lit_ids)
{
assert_tree (tree);
JERRY_ASSERT (data);
opcode_counter_t opc_index, data_index;
opcode_counter_t opc_index;
bool header = true;
for (opc_index = 0, data_index = 0; opc_index < tree->opcodes_num; opc_index++, data_index++)
for (opc_index = 0; opc_index < tree->opcodes_num; opc_index++)
{
opcode_t *op = (opcode_t *) linked_list_element (tree->opcodes, sizeof (opcode_t), opc_index);
JERRY_ASSERT (op);
if (op->op_idx != NAME_TO_ID (var_decl)
&& op->op_idx != NAME_TO_ID (nop)
&& op->op_idx != NAME_TO_ID (meta) && !header)
op_meta *om = extract_op_meta (tree, opc_index);
if (om->op.op_idx != OPCODE (var_decl)
&& om->op.op_idx != OPCODE (meta) && !header)
{
break;
}
if (op->op_idx == NAME_TO_ID (reg_var_decl))
if (om->op.op_idx == OPCODE (reg_var_decl))
{
header = false;
}
data[data_index] = *op;
data[global_oc] = generate_opcode (tree, opc_index, lit_ids);
global_oc++;
}
for (uint8_t child_id = 0; child_id < tree->t.children_num; child_id++)
{
data_index = (opcode_counter_t) (data_index
+ merge_subscopes (*(scopes_tree *) linked_list_element (tree->t.children,
sizeof (scopes_tree),
child_id),
data + data_index));
merge_subscopes (*(scopes_tree *) linked_list_element (tree->t.children, child_id),
data, lit_ids);
}
for (; opc_index < tree->opcodes_num; opc_index++, data_index++)
for (; opc_index < tree->opcodes_num; opc_index++)
{
opcode_t *op = (opcode_t *) linked_list_element (tree->opcodes, sizeof (opcode_t), opc_index);
data[data_index] = *op;
data[global_oc] = generate_opcode (tree, opc_index, lit_ids);
global_oc++;
}
return data_index;
}
opcode_t *
scopes_tree_raw_data (scopes_tree tree, opcode_counter_t *num)
scopes_tree_raw_data (scopes_tree tree, hash_table lit_ids)
{
assert_tree (tree);
opcode_counter_t res = scopes_tree_count_opcodes (tree);
size_t size = ((size_t) (res + 1) * sizeof (opcode_t)); // +1 for valgrind
opcode_counter_t opcodes_count = scopes_tree_count_opcodes (tree);
size_t size = ((size_t) (opcodes_count + 1) * sizeof (opcode_t)); // +1 for valgrind
opcode_t *opcodes = (opcode_t *) mem_heap_alloc_block (size, MEM_HEAP_ALLOC_LONG_TERM);
__memset (opcodes, 0, size);
opcode_counter_t merged = merge_subscopes (tree, opcodes);
JERRY_ASSERT (merged == res);
*num = res;
merge_subscopes (tree, opcodes, lit_ids);
if (lit_id_to_uid != null_hash)
{
hash_table_free (lit_id_to_uid);
lit_id_to_uid = null_hash;
}
return opcodes;
}
@ -150,7 +404,7 @@ scopes_tree
scopes_tree_init (scopes_tree parent)
{
scopes_tree tree = (scopes_tree) mem_heap_alloc_block (sizeof (scopes_tree_int), MEM_HEAP_ALLOC_SHORT_TERM);
__memset (tree, 0, sizeof (scopes_tree));
__memset (tree, 0, sizeof (scopes_tree_int));
tree->t.magic = TREE_MAGIC;
tree->t.parent = (tree_header *) parent;
tree->t.children = null_list;
@ -161,14 +415,14 @@ scopes_tree_init (scopes_tree parent)
{
parent->t.children = linked_list_init (sizeof (scopes_tree));
}
linked_list_set_element (parent->t.children, sizeof (scopes_tree), parent->t.children_num, &tree);
void *added = linked_list_element (parent->t.children, sizeof (scopes_tree), parent->t.children_num);
linked_list_set_element (parent->t.children, parent->t.children_num, &tree);
void *added = linked_list_element (parent->t.children, parent->t.children_num);
JERRY_ASSERT (*(scopes_tree *) added == tree);
parent->t.children_num++;
}
tree->opcodes_num = 0;
tree->strict_mode = 0;
tree->opcodes = linked_list_init (sizeof (opcode_t));
tree->opcodes = linked_list_init (sizeof (op_meta));
return tree;
}
@ -180,7 +434,7 @@ scopes_tree_free (scopes_tree tree)
{
for (uint8_t i = 0; i < tree->t.children_num; ++i)
{
scopes_tree_free (*(scopes_tree *) linked_list_element (tree->t.children, sizeof (scopes_tree), i));
scopes_tree_free (*(scopes_tree *) linked_list_element (tree->t.children, i));
}
linked_list_free (tree->t.children);
}

View File

@ -18,8 +18,20 @@
#include "tree.h"
#include "linked-list.h"
#include "lexer.h"
#include "ecma-globals.h"
#include "hash-table.h"
#include "opcodes.h"
#define NOT_A_LITERAL (INVALID_LITERAL - 1)
typedef struct
{
literal_index_t lit_id[3];
opcode_t op;
}
op_meta;
typedef struct
{
tree_header t;
@ -34,12 +46,12 @@ typedef scopes_tree_int * scopes_tree;
scopes_tree scopes_tree_init (scopes_tree);
void scopes_tree_free (scopes_tree);
opcode_counter_t scopes_tree_opcodes_num (scopes_tree);
void scopes_tree_add_opcode (scopes_tree, opcode_t);
void scopes_tree_set_opcode (scopes_tree, opcode_counter_t, opcode_t);
void scopes_tree_add_op_meta (scopes_tree, op_meta);
void scopes_tree_set_op_meta (scopes_tree, opcode_counter_t, op_meta);
void scopes_tree_set_opcodes_num (scopes_tree, opcode_counter_t);
opcode_t scopes_tree_opcode (scopes_tree, opcode_counter_t);
op_meta scopes_tree_op_meta (scopes_tree, opcode_counter_t);
opcode_counter_t scopes_tree_count_opcodes (scopes_tree);
opcode_t *scopes_tree_raw_data (scopes_tree, opcode_counter_t *);
opcode_t *scopes_tree_raw_data (scopes_tree, hash_table);
void scopes_tree_set_strict_mode (scopes_tree, bool);
bool scopes_tree_strict_mode (scopes_tree);

View File

@ -0,0 +1,223 @@
/* 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 "syntax-errors.h"
#include "stack.h"
#include "globals.h"
#include "parser.h"
#include "jerry-libc.h"
#include "ecma-helpers.h"
typedef struct
{
prop_type type;
literal lit;
}
prop_literal;
enum
{
props_global_size
};
STATIC_STACK (props, prop_literal)
enum
{
U8_global_size
};
STATIC_STACK (U8, uint8_t)
static prop_literal
create_prop_literal (literal lit, prop_type type)
{
return (prop_literal)
{
.type = type,
.lit = lit
};
}
void
syntax_start_checking_of_prop_names (void)
{
STACK_PUSH (U8, (uint8_t) STACK_SIZE (props));
}
void
syntax_add_prop_name (operand op, prop_type pt)
{
JERRY_ASSERT (op.type == OPERAND_LITERAL);
STACK_PUSH (props, create_prop_literal (lexer_get_literal_by_id (op.data.lit_id), pt));
}
void
syntax_check_for_duplication_of_prop_names (bool is_strict, locus loc)
{
if (STACK_SIZE (props) - STACK_TOP (U8) < 2)
{
STACK_DROP (U8, 1);
return;
}
for (uint8_t i = (uint8_t) (STACK_TOP (U8) + 1);
i < STACK_SIZE (props);
i++)
{
const prop_literal previous = STACK_ELEMENT (props, i);
if (previous.type == VARG)
{
continue;
}
JERRY_ASSERT (previous.type == PROP_DATA
|| previous.type == PROP_GET
|| previous.type == PROP_SET);
for (uint8_t j = STACK_TOP (U8); j < i; j = (uint8_t) (j + 1))
{
/*4*/
const prop_literal current = STACK_ELEMENT (props, j);
if (current.type == VARG)
{
continue;
}
JERRY_ASSERT (current.type == PROP_DATA
|| current.type == PROP_GET
|| current.type == PROP_SET);
if (literal_equal (previous.lit, current.lit))
{
/*a*/
if (is_strict && previous.type == PROP_DATA && current.type == PROP_DATA)
{
PARSE_ERROR_VARG ("Duplication of parameter name '%s' in ObjectDeclaration is not allowed in strict mode",
loc, (const char *) literal_to_zt (current.lit));
}
/*b*/
if (previous.type == PROP_DATA
&& (current.type == PROP_SET || current.type == PROP_GET))
{
PARSE_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be both data and accessor",
loc, (const char *) literal_to_zt (current.lit));
}
/*c*/
if (current.type == PROP_DATA
&& (previous.type == PROP_SET || previous.type == PROP_GET))
{
PARSE_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be both data and accessor",
loc, (const char *) literal_to_zt (current.lit));
}
/*d*/
if ((previous.type == PROP_SET && current.type == PROP_SET)
|| (previous.type == PROP_GET && current.type == PROP_GET))
{
PARSE_ERROR_VARG ("Parameter name '%s' in ObjectDeclaration may not be accessor of same type",
loc, (const char *) literal_to_zt (current.lit));
}
}
}
}
STACK_DROP (props, (uint8_t) (STACK_SIZE (props) - STACK_TOP (U8)));
STACK_DROP (U8, 1);
}
void
syntax_start_checking_of_vargs (void)
{
STACK_PUSH (U8, (uint8_t) STACK_SIZE (props));
}
void syntax_add_varg (operand op)
{
JERRY_ASSERT (op.type == OPERAND_LITERAL);
STACK_PUSH (props, create_prop_literal (lexer_get_literal_by_id (op.data.lit_id), VARG));
}
static void
emit_error_on_eval_and_arguments (operand op, locus loc)
{
if (op.type == OPERAND_LITERAL)
{
if (literal_equal_type_zt (lexer_get_literal_by_id (op.data.lit_id),
ecma_get_magic_string_zt (ECMA_MAGIC_STRING_ARGUMENTS))
|| literal_equal_type_zt (lexer_get_literal_by_id (op.data.lit_id),
ecma_get_magic_string_zt (ECMA_MAGIC_STRING_EVAL)))
{
PARSE_ERROR ("'eval' and 'arguments' are not allowed here in strict mode", loc);
}
}
}
void
syntax_check_for_eval_and_arguments_in_strict_mode (operand op, bool is_strict, locus loc)
{
if (is_strict)
{
emit_error_on_eval_and_arguments (op, loc);
}
}
/* 13.1, 15.3.2 */
void
syntax_check_for_syntax_errors_in_formal_param_list (bool is_strict, locus loc)
{
if (STACK_SIZE (props) - STACK_TOP (U8) < 2 || !is_strict)
{
STACK_DROP (U8, 1);
return;
}
for (uint8_t i = (uint8_t) (STACK_TOP (U8) + 1); i < STACK_SIZE (props); i = (uint8_t) (i + 1))
{
JERRY_ASSERT (STACK_ELEMENT (props, i).type == VARG);
const literal previous = STACK_ELEMENT (props, i).lit;
JERRY_ASSERT (previous.type == LIT_STR || previous.type == LIT_MAGIC_STR);
for (uint8_t j = STACK_TOP (U8); j < i; j = (uint8_t) (j + 1))
{
JERRY_ASSERT (STACK_ELEMENT (props, j).type == VARG);
const literal current = STACK_ELEMENT (props, j).lit;
JERRY_ASSERT (current.type == LIT_STR || current.type == LIT_MAGIC_STR);
if (literal_equal_type (previous, current))
{
PARSE_ERROR_VARG ("Duplication of literal '%s' in FormalParameterList is not allowed in strict mode",
loc, (const char *) literal_to_zt (previous));
}
}
}
STACK_DROP (props, (uint8_t) (STACK_SIZE (props) - STACK_TOP (U8)));
STACK_DROP (U8, 1);
}
void
syntax_check_delete (bool is_strict, locus loc)
{
if (is_strict)
{
PARSE_ERROR ("'delete' operator shall not apply on identifier in strict mode.", loc);
}
}
void
syntax_init (void)
{
STACK_INIT (props);
STACK_INIT (U8);
}
void
syntax_free (void)
{
STACK_FREE (U8);
STACK_FREE (props);
}

View File

@ -13,8 +13,12 @@
* limitations under the License.
*/
#ifndef PARSE_ERROR_H
#define PARSE_ERROR_H
#ifndef SYNTAX_ERRORS_H
#define SYNTAX_ERRORS_H
#include "literal.h"
#include "opcodes-dumper.h"
#include "lexer.h"
#define PARSE_ERROR(MESSAGE, LOCUS) do { \
size_t line, column; \
@ -60,4 +64,27 @@
__exit (-1); \
} while (0)
#endif /* PARSE_ERROR_H */
typedef enum
{
PROP_DATA,
PROP_SET,
PROP_GET,
VARG
}
prop_type;
void syntax_init (void);
void syntax_free (void);
void syntax_start_checking_of_prop_names (void);
void syntax_add_prop_name (operand, prop_type);
void syntax_check_for_duplication_of_prop_names (bool, locus);
void syntax_start_checking_of_vargs (void);
void syntax_add_varg (operand);
void syntax_check_for_eval_and_arguments_in_strict_mode (operand, bool, locus);
void syntax_check_for_syntax_errors_in_formal_param_list (bool, locus);
void syntax_check_delete (bool, locus);
#endif /* SYNTAX_ERRORS_H */

View File

@ -22,26 +22,28 @@
#include "literal.h"
#include "scopes-tree.h"
/* bytecode_data contains identifiers, string and num literals.
Memory map if the following.
#define BLOCK_SIZE 64
bytecode_data {
U8 strs_count;
U8 string_offsets[str_count];
U8* strings[str_count];
typedef struct
{
opcode_counter_t oc;
idx_t uid;
uint8_t reserved;
}
lit_id_table_key;
U8 nums_count;
U32 nums[nums_count];
} */
struct
{
const literal *literals;
const opcode_t *opcodes;
uint8_t literals_count;
literal_index_t literals_count;
opcode_counter_t opcodes_count;
hash_table lit_id_hash;
}
bytecode_data;
lit_id_table_key create_lit_id_table_key (idx_t, opcode_counter_t);
scopes_tree current_scope;
#endif // BYTECODE_DATA_H

View File

@ -19,6 +19,17 @@
const ecma_char_t *strings_buffer;
lit_id_table_key
create_lit_id_table_key (idx_t id, opcode_counter_t oc)
{
return (lit_id_table_key)
{
.uid = id,
.oc = oc / BLOCK_SIZE,
.reserved = 0
};
}
void
deserializer_set_strings_buffer (const ecma_char_t *s)
{
@ -26,12 +37,31 @@ deserializer_set_strings_buffer (const ecma_char_t *s)
}
literal
deserialize_literal_by_id (uint8_t id)
deserialize_literal_by_id (literal_index_t id)
{
JERRY_ASSERT (id != INVALID_LITERAL);
JERRY_ASSERT (id < bytecode_data.literals_count);
return bytecode_data.literals[id];
}
literal_index_t
deserialize_lit_id_by_uid (uint8_t id, opcode_counter_t oc)
{
// __printf ("uid: %d, oc: %d\n", id, oc);
// if (id == 2 && oc == 64)
// {
// __printf ("HIT!\n");
// }
if (bytecode_data.lit_id_hash == null_hash)
{
return INVALID_LITERAL;
}
lit_id_table_key key = create_lit_id_table_key (id, oc);
void *res = hash_table_lookup (bytecode_data.lit_id_hash, &key);
JERRY_ASSERT (res != NULL);
return *(literal_index_t *) res;
}
const void *
deserialize_bytecode (void)
{
@ -42,18 +72,25 @@ deserialize_bytecode (void)
opcode_t
deserialize_opcode (opcode_counter_t oc)
{
if (bytecode_data.opcodes)
if (bytecode_data.opcodes == NULL)
{
JERRY_ASSERT (oc < bytecode_data.opcodes_count);
return bytecode_data.opcodes[oc];
return deserialize_op_meta (oc).op;
}
return scopes_tree_opcode (current_scope, oc);
JERRY_ASSERT (oc < bytecode_data.opcodes_count);
return bytecode_data.opcodes[oc];
}
op_meta
deserialize_op_meta (opcode_counter_t oc)
{
JERRY_ASSERT (current_scope);
return scopes_tree_op_meta (current_scope, oc);
}
uint8_t
deserialize_min_temp (void)
{
return bytecode_data.literals_count;
return 128;
}
void
@ -71,6 +108,13 @@ deserializer_free (void)
{
mem_heap_free_block ((uint8_t *) strings_buffer);
}
mem_heap_free_block ((uint8_t *) bytecode_data.literals);
if (bytecode_data.lit_id_hash != null_hash)
{
hash_table_free (bytecode_data.lit_id_hash);
}
if (bytecode_data.literals != NULL)
{
mem_heap_free_block ((uint8_t *) bytecode_data.literals);
}
mem_heap_free_block ((uint8_t *) bytecode_data.opcodes);
}

View File

@ -19,13 +19,16 @@
#include "globals.h"
#include "ecma-globals.h"
#include "opcodes.h"
#include "scopes-tree.h"
#include "literal.h"
void deserializer_init (void);
void deserializer_set_strings_buffer (const ecma_char_t *);
literal deserialize_literal_by_id (uint8_t);
literal deserialize_literal_by_id (literal_index_t);
literal_index_t deserialize_lit_id_by_uid (uint8_t, opcode_counter_t);
const void *deserialize_bytecode (void);
opcode_t deserialize_opcode (opcode_counter_t);
op_meta deserialize_op_meta (opcode_counter_t);
uint8_t deserialize_min_temp (void);
void deserializer_free (void);

View File

@ -21,12 +21,11 @@
#include "deserializer.h"
#include "opcodes-native-call.h"
#include "ecma-helpers.h"
#include "ecma-globals.h"
#include <stdarg.h>
#define NAME_TO_ID(op) (__op__idx_##op)
#define FIELD(op, field) (opcode.data.op.field)
#define __OPCODE_STR(name, arg1, arg2, arg3) \
#name,
@ -52,7 +51,14 @@ dump_literal (literal lit)
{
case LIT_NUMBER:
{
__printf ("%d : NUMBER", lit.data.num);
if (ecma_number_is_nan (lit.data.num))
{
__printf ("%s : NUMBER", "NaN");
}
else
{
__printf ("%d : NUMBER", lit.data.num);
}
break;
}
case LIT_MAGIC_STR:
@ -73,10 +79,10 @@ dump_literal (literal lit)
}
void
pp_literals (const literal lits[], uint8_t size)
pp_literals (const literal lits[], literal_index_t size)
{
__printf ("LITERALS %d:\n", size);
for (uint8_t i = 0; i < size; i++)
for (literal_index_t i = 0; i < size; i++)
{
__printf ("%3d ", i);
dump_literal (lits[i]);
@ -84,52 +90,84 @@ pp_literals (const literal lits[], uint8_t size)
}
}
static const char *
var_id_to_string (char *res, idx_t id)
static char buff[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER];
static void
clear_temp_buffer (void)
{
__memset (buff, 0, ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER);
}
static const char *
lit_id_to_str (literal_index_t id)
{
if (id >= lexer_get_literals_count ())
{
__strncpy (res, "tmp", 3);
if (id / 100 != 0)
{
res[3] = (char) (id / 100 + '0');
res[4] = (char) ((id % 100) / 10 + '0');
res[5] = (char) (id % 10 + '0');
return res;
}
else if (id / 10 != 0)
{
res[3] = (char) (id / 10 + '0');
res[4] = (char) (id % 10 + '0');
return res;
}
else
{
res[3] = (char) (id + '0');
return res;
}
}
literal lit = lexer_get_literal_by_id (id);
if (lit.type == LIT_STR || lit.type == LIT_MAGIC_STR)
{
return (char *) literal_to_zt (lit);
}
else if (lit.type == LIT_NUMBER)
else
{
ecma_number_to_zt_string (lit.data.num, (ecma_char_t *) res, ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER);
return res;
JERRY_ASSERT (lit.type == LIT_NUMBER);
clear_temp_buffer ();
ecma_number_to_zt_string (lit.data.num, (ecma_char_t *) buff, ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER);
return buff;
}
}
static const char *
tmp_id_to_str (idx_t id)
{
JERRY_ASSERT (id != LITERAL_TO_REWRITE);
JERRY_ASSERT (id >= 128);
clear_temp_buffer ();
__strncpy (buff, "tmp", 3);
if (id / 100 != 0)
{
buff[3] = (char) (id / 100 + '0');
buff[4] = (char) ((id % 100) / 10 + '0');
buff[5] = (char) (id % 10 + '0');
}
else if (id / 10 != 0)
{
buff[3] = (char) (id / 10 + '0');
buff[4] = (char) (id % 10 + '0');
}
else
{
JERRY_UNREACHABLE ();
buff[3] = (char) (id + '0');
}
return buff;
}
static const char *
var_to_str (opcode_t opcode, literal_index_t lit_ids[], opcode_counter_t oc, uint8_t current_arg)
{
raw_opcode raw = *(raw_opcode*) &opcode;
if (raw.uids[current_arg] == LITERAL_TO_REWRITE)
{
if (lit_ids == NULL)
{
return "hz";
}
JERRY_ASSERT (lit_ids[current_arg - 1] != NOT_A_LITERAL
&& lit_ids[current_arg - 1] != INVALID_LITERAL);
return lit_id_to_str (lit_ids[current_arg - 1]);
}
else if (raw.uids[current_arg] >= 128)
{
return tmp_id_to_str (raw.uids[current_arg]);
}
else
{
return lit_id_to_str (deserialize_lit_id_by_uid (raw.uids[current_arg], oc));
}
}
static void
pp_printf (const char *format, ...)
pp_printf (const char *format, opcode_t opcode, literal_index_t lit_ids[], opcode_counter_t oc)
{
va_list args;
va_start (args, format);
uint8_t current_arg = 1;
while (*format)
{
if (*format != '%')
@ -144,57 +182,46 @@ pp_printf (const char *format, ...)
{
case 'd':
{
__printf ("%d", va_arg (args, int));
raw_opcode raw = *(raw_opcode*) &opcode;
__printf ("%d", raw.uids[current_arg]);
break;
}
case 's':
{
char res[ECMA_MAX_CHARS_IN_STRINGIFIED_NUMBER] = {'\0'};
__printf ("%s", var_id_to_string (res, (idx_t) va_arg (args, int)));
break;
}
case '%':
{
__printf ("%%");
__printf ("%s", var_to_str (opcode, lit_ids, oc, current_arg));
break;
}
default:
{
JERRY_UNREACHABLE ();
__putchar ('%');
continue;
}
}
current_arg++;
format++;
}
va_end (args);
}
#define PP_OP_0(op, format) \
case NAME_TO_ID(op): pp_printf (format); break;
#define PP_OP_1(op, format, field1) \
case NAME_TO_ID(op): pp_printf (format, opcode.data.op.field1); break;
#define PP_OP_2(op, format, field1, field2) \
case NAME_TO_ID(op): pp_printf (format, opcode.data.op.field1, opcode.data.op.field2); break;
#define PP_OP_3(op, format, field1, field2, field3) \
case NAME_TO_ID(op): pp_printf (format, opcode.data.op.field1, opcode.data.op.field2, opcode.data.op.field3); break;
#define PP_OP(op_name, format) \
case NAME_TO_ID(op_name): pp_printf (format, opm.op, opm.lit_id, oc); break;
#define VAR(i) var_to_str (opm.op, opm.lit_id, oc, i)
#define OC(i, j) __extension__({ raw_opcode* raw = (raw_opcode *) &opm.op; \
calc_opcode_counter_from_idx_idx (raw->uids[i], raw->uids[j]); })
static int vargs_num = 0;
static int seen_vargs = 0;
void
pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite)
static void
dump_asm (opcode_counter_t oc, opcode_t opcode)
{
uint8_t i = 1;
uint8_t i = 0;
uint8_t opcode_id = opcode.op_idx;
__printf ("%3d: %20s ", oc, opcode_names[opcode_id]);
if (opcode_id != NAME_TO_ID (nop) && opcode_id != NAME_TO_ID (ret))
{
for (i = 1; i < opcode_sizes[opcode_id]; i++)
{
__printf ("%4d ", ((uint8_t*) & opcode)[i]);
__printf ("%4d ", ((raw_opcode *) &opcode)->uids[i]);
}
}
@ -202,255 +229,208 @@ pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite)
{
__printf (" ");
}
}
void
pp_op_meta (opcode_counter_t oc, op_meta opm, bool rewrite)
{
dump_asm (oc, opm.op);
__printf (" // ");
switch (opcode_id)
switch (opm.op.op_idx)
{
PP_OP_3 (addition, "%s = %s + %s;", dst, var_left, var_right);
PP_OP_3 (substraction, "%s = %s - %s;", dst, var_left, var_right);
PP_OP_3 (division, "%s = %s - %s;", dst, var_left, var_right);
PP_OP_3 (multiplication, "%s = %s * %s;", dst, var_left, var_right);
PP_OP_3 (remainder, "%s = %s %% %s;", dst, var_left, var_right);
PP_OP_2 (unary_minus, "%s = -%s;", dst, var);
PP_OP_2 (unary_plus, "%s = +%s;", dst, var);
PP_OP_3 (b_shift_left, "%s = %s << %s;", dst, var_left, var_right);
PP_OP_3 (b_shift_right, "%s = %s >> %s;", dst, var_left, var_right);
PP_OP_3 (b_shift_uright, "%s = %s >>> %s;", dst, var_left, var_right);
PP_OP_3 (b_and, "%s = %s & %s;", dst, var_left, var_right);
PP_OP_3 (b_or, "%s = %s | %s;", dst, var_left, var_right);
PP_OP_3 (b_xor, "%s = %s ^ %s;", dst, var_left, var_right);
PP_OP_2 (b_not, "%s = ~ %s;", dst, var_right);
PP_OP_2 (logical_not, "%s = ! %s;", dst, var_right);
PP_OP_3 (equal_value, "%s = %s == %s;", dst, var_left, var_right);
PP_OP_3 (not_equal_value, "%s = %s != %s;", dst, var_left, var_right);
PP_OP_3 (equal_value_type, "%s = %s === %s;", dst, var_left, var_right);
PP_OP_3 (not_equal_value_type, "%s = %s !== %s;", dst, var_left, var_right);
PP_OP_3 (less_than, "%s = %s < %s;", dst, var_left, var_right);
PP_OP_3 (greater_than, "%s = %s > %s;", dst, var_left, var_right);
PP_OP_3 (less_or_equal_than, "%s = %s <= %s;", dst, var_left, var_right);
PP_OP_3 (greater_or_equal_than, "%s = %s >= %s;", dst, var_left, var_right);
PP_OP_3 (instanceof, "%s = %s instanceof %s;", dst, var_left, var_right);
PP_OP_3 (in, "%s = %s in %s;", dst, var_left, var_right);
PP_OP_2 (post_incr, "%s = %s++;", dst, var_right);
PP_OP_2 (post_decr, "%s = %s--;", dst, var_right);
PP_OP_2 (pre_incr, "%s = ++%s;", dst, var_right);
PP_OP_2 (pre_decr, "%s = --%s;", dst, var_right);
PP_OP_1 (throw, "throw %s;", var);
PP_OP_2 (reg_var_decl, "var %s .. %s;", min, max);
PP_OP_1 (var_decl, "var %s;", variable_name);
PP_OP_0 (nop, ";");
PP_OP_1 (exitval, "exit %d;", status_code);
PP_OP_1 (retval, "return %s;", ret_value);
PP_OP_0 (ret, "ret;");
PP_OP_3 (prop_getter, "%s = %s[%s];", lhs, obj, prop);
PP_OP_3 (prop_setter, "%s[%s] = %s;", obj, prop, rhs);
PP_OP_1 (this, "%s = this;", lhs);
PP_OP_2 (delete_var, "%s = delete %s;", lhs, name);
PP_OP_3 (delete_prop, "%s = delete %s.%s;", lhs, base, name);
PP_OP_2 (typeof, "%s = typeof %s;", lhs, obj);
PP_OP_1 (with, "with (%s);", expr);
case NAME_TO_ID (is_true_jmp_up):
{
pp_printf ("if (%s) goto %d;", opcode.data.is_true_jmp_up.value,
oc - calc_opcode_counter_from_idx_idx (opcode.data.is_true_jmp_up.opcode_1,
opcode.data.is_true_jmp_up.opcode_2));
break;
}
case NAME_TO_ID (is_false_jmp_up):
{
pp_printf ("if (%s) goto %d;", opcode.data.is_false_jmp_up.value,
oc - calc_opcode_counter_from_idx_idx (opcode.data.is_false_jmp_up.opcode_1,
opcode.data.is_false_jmp_up.opcode_2));
break;
}
case NAME_TO_ID (is_true_jmp_down):
{
pp_printf ("if (%s) goto %d;", opcode.data.is_true_jmp_down.value,
oc + calc_opcode_counter_from_idx_idx (opcode.data.is_true_jmp_down.opcode_1,
opcode.data.is_true_jmp_down.opcode_2));
break;
}
case NAME_TO_ID (is_false_jmp_down):
{
pp_printf ("if (%s == false) goto %d;", opcode.data.is_false_jmp_down.value,
oc + calc_opcode_counter_from_idx_idx (opcode.data.is_false_jmp_down.opcode_1,
opcode.data.is_false_jmp_down.opcode_2));
break;
}
case NAME_TO_ID (jmp_up):
{
pp_printf ("goto %d;",
oc - calc_opcode_counter_from_idx_idx (opcode.data.jmp_up.opcode_1,
opcode.data.jmp_up.opcode_2));
break;
}
case NAME_TO_ID (jmp_down):
{
pp_printf ("goto %d;",
oc + calc_opcode_counter_from_idx_idx (opcode.data.jmp_down.opcode_1,
opcode.data.jmp_down.opcode_2));
break;
}
case NAME_TO_ID (try):
{
pp_printf ("try (end: %d);", oc + calc_opcode_counter_from_idx_idx (opcode.data.try.oc_idx_1,
opcode.data.try.oc_idx_2));
break;
}
PP_OP (addition, "%s = %s + %s;");
PP_OP (substraction, "%s = %s - %s;");
PP_OP (division, "%s = %s - %s;");
PP_OP (multiplication, "%s = %s * %s;");
PP_OP (remainder, "%s = %s %% %s;");
PP_OP (unary_minus, "%s = -%s;");
PP_OP (unary_plus, "%s = +%s;");
PP_OP (b_shift_left, "%s = %s << %s;");
PP_OP (b_shift_right, "%s = %s >> %s;");
PP_OP (b_shift_uright, "%s = %s >>> %s;");
PP_OP (b_and, "%s = %s & %s;");
PP_OP (b_or, "%s = %s | %s;");
PP_OP (b_xor, "%s = %s ^ %s;");
PP_OP (b_not, "%s = ~ %s;");
PP_OP (logical_not, "%s = ! %s;");
PP_OP (equal_value, "%s = %s == %s;");
PP_OP (not_equal_value, "%s = %s != %s;");
PP_OP (equal_value_type, "%s = %s === %s;");
PP_OP (not_equal_value_type, "%s = %s !== %s;");
PP_OP (less_than, "%s = %s < %s;");
PP_OP (greater_than, "%s = %s > %s;");
PP_OP (less_or_equal_than, "%s = %s <= %s;");
PP_OP (greater_or_equal_than, "%s = %s >= %s;");
PP_OP (instanceof, "%s = %s instanceof %s;");
PP_OP (in, "%s = %s in %s;");
PP_OP (post_incr, "%s = %s++;");
PP_OP (post_decr, "%s = %s--;");
PP_OP (pre_incr, "%s = ++%s;");
PP_OP (pre_decr, "%s = --%s;");
PP_OP (throw, "throw %s;");
PP_OP (reg_var_decl, "var %s .. %s;");
PP_OP (var_decl, "var %s;");
PP_OP (nop, ";");
PP_OP (exitval, "exit %d;");
PP_OP (retval, "return %s;");
PP_OP (ret, "ret;");
PP_OP (prop_getter, "%s = %s[%s];");
PP_OP (prop_setter, "%s[%s] = %s;");
PP_OP (this, "%s = this;");
PP_OP (delete_var, "%s = delete %s;");
PP_OP (delete_prop, "%s = delete %s.%s;");
PP_OP (typeof, "%s = typeof %s;");
PP_OP (with, "with (%s);");
case NAME_TO_ID (is_true_jmp_up): __printf ("if (%s) goto %d;", VAR (1), oc - OC (2, 3)); break;
case NAME_TO_ID (is_false_jmp_up): __printf ("if (%s == false) goto %d;", VAR (1), oc - OC (2, 3)); break;
case NAME_TO_ID (is_true_jmp_down): __printf ("if (%s) goto %d;", VAR (1), oc + OC (2, 3)); break;
case NAME_TO_ID (is_false_jmp_down): __printf ("if (%s == false) goto %d;", VAR (1), oc + OC (2, 3)); break;
case NAME_TO_ID (jmp_up): __printf ("goto %d;", oc - OC (1, 2)); break;
case NAME_TO_ID (jmp_down): __printf ("goto %d;", oc + OC (1, 2)); break;
case NAME_TO_ID (try): __printf ("try (end: %d);", oc + OC (1, 2)); break;
case NAME_TO_ID (assignment):
{
pp_printf ("%s = ", opcode.data.assignment.var_left);
switch (opcode.data.assignment.type_value_right)
__printf ("%s = ", VAR (1));
switch (opm.op.data.assignment.type_value_right)
{
case OPCODE_ARG_TYPE_STRING: __printf ("'%s': STRING;", VAR (3)); break;
case OPCODE_ARG_TYPE_NUMBER: __printf ("%s: NUMBER;", VAR (3)); break;
case OPCODE_ARG_TYPE_NUMBER_NEGATE: __printf ("-%s: NUMBER;", VAR (3)); break;
case OPCODE_ARG_TYPE_SMALLINT: __printf ("%d: SMALLINT;", opm.op.data.assignment.value_right); break;
case OPCODE_ARG_TYPE_SMALLINT_NEGATE: __printf ("-%d: SMALLINT;", opm.op.data.assignment.value_right); break;
case OPCODE_ARG_TYPE_VARIABLE: __printf ("%s : TYPEOF(%s);", VAR (3), VAR (3)); break;
case OPCODE_ARG_TYPE_SIMPLE:
{
switch (opcode.data.assignment.value_right)
switch (opm.op.data.assignment.value_right)
{
case ECMA_SIMPLE_VALUE_NULL: pp_printf ("null"); break;
case ECMA_SIMPLE_VALUE_FALSE: pp_printf ("false"); break;
case ECMA_SIMPLE_VALUE_TRUE: pp_printf ("true"); break;
case ECMA_SIMPLE_VALUE_UNDEFINED: pp_printf ("undefined"); break;
case ECMA_SIMPLE_VALUE_NULL: __printf ("null"); break;
case ECMA_SIMPLE_VALUE_FALSE: __printf ("false"); break;
case ECMA_SIMPLE_VALUE_TRUE: __printf ("true"); break;
case ECMA_SIMPLE_VALUE_UNDEFINED: __printf ("undefined"); break;
default: JERRY_UNREACHABLE ();
}
pp_printf (": SIMPLE;");
__printf (": SIMPLE;");
break;
}
case OPCODE_ARG_TYPE_STRING:
{
pp_printf ("'%s': STRING;", opcode.data.assignment.value_right);
break;
}
case OPCODE_ARG_TYPE_NUMBER:
{
pp_printf ("%s: NUMBER;", opcode.data.assignment.value_right);
break;
}
case OPCODE_ARG_TYPE_SMALLINT:
{
pp_printf ("%d: SMALLINT;", opcode.data.assignment.value_right);
break;
}
case OPCODE_ARG_TYPE_VARIABLE:
{
pp_printf ("%s : TYPEOF(%s);", opcode.data.assignment.value_right, opcode.data.assignment.value_right);
break;
}
default:
{
JERRY_UNREACHABLE ();
}
}
break;
}
case NAME_TO_ID (call_n):
{
if (opcode.data.call_n.arg_list == 0)
if (opm.op.data.call_n.arg_list == 0)
{
pp_printf ("%s = %s ();", opcode.data.call_n.lhs, opcode.data.call_n.name_lit_idx);
__printf ("%s = %s ();", VAR (1), VAR (2));
}
else
{
vargs_num = opcode.data.call_n.arg_list;
vargs_num = opm.op.data.call_n.arg_list;
seen_vargs = 0;
}
break;
}
case NAME_TO_ID (native_call):
{
if (opcode.data.native_call.arg_list == 0)
if (opm.op.data.native_call.arg_list == 0)
{
pp_printf ("%s = ", opcode.data.native_call.lhs);
switch (opcode.data.native_call.name)
__printf ("%s = ", VAR (1));
switch (opm.op.data.native_call.name)
{
case OPCODE_NATIVE_CALL_LED_TOGGLE: pp_printf ("LEDToggle ();"); break;
case OPCODE_NATIVE_CALL_LED_ON: pp_printf ("LEDOn ();"); break;
case OPCODE_NATIVE_CALL_LED_OFF: pp_printf ("LEDOff ();"); break;
case OPCODE_NATIVE_CALL_LED_ONCE: pp_printf ("LEDOnce ();"); break;
case OPCODE_NATIVE_CALL_WAIT: pp_printf ("wait ();"); break;
case OPCODE_NATIVE_CALL_PRINT: pp_printf ("print ();"); break;
case OPCODE_NATIVE_CALL_LED_TOGGLE: __printf ("LEDToggle ();"); break;
case OPCODE_NATIVE_CALL_LED_ON: __printf ("LEDOn ();"); break;
case OPCODE_NATIVE_CALL_LED_OFF: __printf ("LEDOff ();"); break;
case OPCODE_NATIVE_CALL_LED_ONCE: __printf ("LEDOnce ();"); break;
case OPCODE_NATIVE_CALL_WAIT: __printf ("wait ();"); break;
case OPCODE_NATIVE_CALL_PRINT: __printf ("print ();"); break;
default: JERRY_UNREACHABLE ();
}
}
else
{
vargs_num = opcode.data.native_call.arg_list;
vargs_num = opm.op.data.native_call.arg_list;
seen_vargs = 0;
}
break;
}
case NAME_TO_ID (construct_n):
{
if (opcode.data.construct_n.arg_list == 0)
if (opm.op.data.construct_n.arg_list == 0)
{
pp_printf ("%s = new %s;", opcode.data.construct_n.lhs, opcode.data.construct_n.name_lit_idx);
__printf ("%s = new %s;", VAR (1), VAR (2));
}
else
{
vargs_num = opcode.data.construct_n.arg_list;
vargs_num = opm.op.data.construct_n.arg_list;
seen_vargs = 0;
}
break;
}
case NAME_TO_ID (func_decl_n):
{
if (opcode.data.func_decl_n.arg_list == 0)
if (opm.op.data.func_decl_n.arg_list == 0)
{
pp_printf ("function %s ();", opcode.data.func_decl_n.name_lit_idx);
__printf ("function %s ();", VAR (1));
}
else
{
vargs_num = opcode.data.func_decl_n.arg_list;
vargs_num = opm.op.data.func_decl_n.arg_list;
seen_vargs = 0;
}
break;
}
case NAME_TO_ID (func_expr_n):
{
if (opcode.data.func_expr_n.arg_list == 0)
if (opm.op.data.func_expr_n.arg_list == 0)
{
pp_printf ("%s = function %s ();", opcode.data.func_expr_n.lhs, opcode.data.func_expr_n.name_lit_idx);
if (opm.op.data.func_expr_n.name_lit_idx == INVALID_VALUE)
{
__printf ("%s = function ();", VAR (1));
}
else
{
__printf ("%s = function %s ();", VAR (1), VAR (2));
}
}
else
{
vargs_num = opcode.data.func_expr_n.arg_list;
vargs_num = opm.op.data.func_expr_n.arg_list;
seen_vargs = 0;
}
break;
}
case NAME_TO_ID (array_decl):
{
if (opcode.data.array_decl.list == 0)
if (opm.op.data.array_decl.list == 0)
{
pp_printf ("%s = [];", opcode.data.array_decl.lhs);
__printf ("%s = [];", VAR (1));
}
else
{
vargs_num = opcode.data.array_decl.list;
vargs_num = opm.op.data.array_decl.list;
seen_vargs = 0;
}
break;
}
case NAME_TO_ID (obj_decl):
{
if (opcode.data.obj_decl.list == 0)
if (opm.op.data.obj_decl.list == 0)
{
pp_printf ("%s = {};", opcode.data.obj_decl.lhs);
__printf ("%s = {};", VAR (1));
}
else
{
vargs_num = opcode.data.obj_decl.list;
vargs_num = opm.op.data.obj_decl.list;
seen_vargs = 0;
}
break;
}
case NAME_TO_ID (meta):
{
switch (opcode.data.meta.type)
switch (opm.op.data.meta.type)
{
case OPCODE_META_TYPE_UNDEFINED:
{
pp_printf ("unknown meta;");
__printf ("unknown meta;");
break;
}
case OPCODE_META_TYPE_THIS_ARG:
@ -487,48 +467,57 @@ pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite)
{
case NAME_TO_ID (call_n):
{
pp_printf ("%s = %s (", start_op.data.call_n.lhs, start_op.data.call_n.name_lit_idx);
__printf ("%s = %s (", var_to_str (start_op, NULL, start, 1),
var_to_str (start_op, NULL, start, 2));
break;
}
case NAME_TO_ID (native_call):
{
pp_printf ("%s = ", start_op.data.native_call.lhs);
__printf ("%s = ", var_to_str (start_op, NULL, start, 1));
switch (start_op.data.native_call.name)
{
case OPCODE_NATIVE_CALL_LED_TOGGLE: pp_printf ("LEDToggle ("); break;
case OPCODE_NATIVE_CALL_LED_ON: pp_printf ("LEDOn ("); break;
case OPCODE_NATIVE_CALL_LED_OFF: pp_printf ("LEDOff ("); break;
case OPCODE_NATIVE_CALL_LED_ONCE: pp_printf ("LEDOnce ("); break;
case OPCODE_NATIVE_CALL_WAIT: pp_printf ("wait ("); break;
case OPCODE_NATIVE_CALL_PRINT: pp_printf ("print ("); break;
case OPCODE_NATIVE_CALL_LED_TOGGLE: __printf ("LEDToggle ("); break;
case OPCODE_NATIVE_CALL_LED_ON: __printf ("LEDOn ("); break;
case OPCODE_NATIVE_CALL_LED_OFF: __printf ("LEDOff ("); break;
case OPCODE_NATIVE_CALL_LED_ONCE: __printf ("LEDOnce ("); break;
case OPCODE_NATIVE_CALL_WAIT: __printf ("wait ("); break;
case OPCODE_NATIVE_CALL_PRINT: __printf ("print ("); break;
default: JERRY_UNREACHABLE ();
}
break;
}
case NAME_TO_ID (construct_n):
{
pp_printf ("%s = new %s (", start_op.data.construct_n.lhs, start_op.data.construct_n.name_lit_idx);
__printf ("%s = new %s (", var_to_str (start_op, NULL, start, 1),
var_to_str (start_op, NULL, start, 2));
break;
}
case NAME_TO_ID (func_decl_n):
{
pp_printf ("function %s (", start_op.data.func_decl_n.name_lit_idx);
__printf ("function %s (", var_to_str (start_op, NULL, start, 1));
break;
}
case NAME_TO_ID (func_expr_n):
{
pp_printf ("%s = function %s (", start_op.data.func_expr_n.lhs,
start_op.data.func_expr_n.name_lit_idx);
if (start_op.data.func_expr_n.name_lit_idx == INVALID_VALUE)
{
__printf ("%s = function (", var_to_str (start_op, NULL, start, 1));
}
else
{
__printf ("%s = function %s (", var_to_str (start_op, NULL, start, 1),
var_to_str (start_op, NULL, start, 2));
}
break;
}
case NAME_TO_ID (array_decl):
{
pp_printf ("%s = [", start_op.data.array_decl.lhs);
__printf ("%s = [", var_to_str (start_op, NULL, start, 1));
break;
}
case NAME_TO_ID (obj_decl):
{
pp_printf ("%s = {", start_op.data.obj_decl.lhs);
__printf ("%s = {", var_to_str (start_op, NULL, start, 1));
break;
}
default:
@ -543,41 +532,44 @@ pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite)
{
case NAME_TO_ID (meta):
{
switch (opcode.data.meta.type)
switch (meta_op.data.meta.type)
{
case OPCODE_META_TYPE_THIS_ARG:
{
pp_printf ("this_arg = %s", meta_op.data.meta.data_1);
__printf ("this_arg = %s", var_to_str (meta_op, NULL, counter, 2));
break;
}
case OPCODE_META_TYPE_VARG:
{
pp_printf ("%s", meta_op.data.meta.data_1);
__printf ("%s", var_to_str (meta_op, NULL, counter, 2));
break;
}
case OPCODE_META_TYPE_VARG_PROP_DATA:
{
pp_printf ("%s:%s", meta_op.data.meta.data_1, meta_op.data.meta.data_2);
__printf ("%s:%s", var_to_str (meta_op, NULL, counter, 2),
var_to_str (meta_op, NULL, counter, 3));
break;
}
case OPCODE_META_TYPE_VARG_PROP_GETTER:
{
pp_printf ("%s = get ();", meta_op.data.meta.data_1);
__printf ("%s = get %s ();", var_to_str (meta_op, NULL, counter, 2),
var_to_str (meta_op, NULL, counter, 3));
break;
}
case OPCODE_META_TYPE_VARG_PROP_SETTER:
{
pp_printf ("%s = set (%s);", meta_op.data.meta.data_1, meta_op.data.meta.data_2);
__printf ("%s = set (%s);", var_to_str (meta_op, NULL, counter, 2),
var_to_str (meta_op, NULL, counter, 3));
break;
}
default:
{
JERRY_UNREACHABLE ();
continue;
}
}
if (counter != oc)
{
pp_printf (", ");
__printf (", ");
}
break;
}
@ -587,17 +579,17 @@ pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite)
{
case NAME_TO_ID (array_decl):
{
pp_printf ("];");
__printf ("];");
break;
}
case NAME_TO_ID (obj_decl):
{
pp_printf ("};");
__printf ("};");
break;
}
default:
{
pp_printf (");");
__printf (");");
}
}
}
@ -605,40 +597,37 @@ pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite)
}
case OPCODE_META_TYPE_END_WITH:
{
pp_printf ("end with;");
__printf ("end with;");
break;
}
case OPCODE_META_TYPE_FUNCTION_END:
{
pp_printf ("function end: %d;", oc + calc_opcode_counter_from_idx_idx (opcode.data.meta.data_1,
opcode.data.meta.data_2));
__printf ("function end: %d;", oc + OC (2, 3));
break;
}
case OPCODE_META_TYPE_CATCH:
{
pp_printf ("catch end: %d;", oc + calc_opcode_counter_from_idx_idx (opcode.data.meta.data_1,
opcode.data.meta.data_2));
__printf ("catch end: %d;", oc + OC (2, 3));
break;
}
case OPCODE_META_TYPE_CATCH_EXCEPTION_IDENTIFIER:
{
pp_printf ("catch (%s);", opcode.data.meta.data_1);
__printf ("catch (%s);", VAR (2));
break;
}
case OPCODE_META_TYPE_FINALLY:
{
pp_printf ("finally end: %d;", oc + calc_opcode_counter_from_idx_idx (opcode.data.meta.data_1,
opcode.data.meta.data_2));
__printf ("finally end: %d;", oc + OC (2, 3));
break;
}
case OPCODE_META_TYPE_END_TRY_CATCH_FINALLY:
{
pp_printf ("end try");
__printf ("end try");
break;
}
case OPCODE_META_TYPE_STRICT_CODE:
{
pp_printf ("use strict;");
__printf ("use strict;");
break;
}
default:
@ -654,7 +643,7 @@ pp_opcode (opcode_counter_t oc, opcode_t opcode, bool is_rewrite)
}
}
if (is_rewrite)
if (rewrite)
{
__printf (" // REWRITE");
}

View File

@ -20,9 +20,11 @@
#ifdef JERRY_ENABLE_PP
#include "interpreter.h"
#include "literal.h"
#include "scopes-tree.h"
void pp_opcode (opcode_counter_t, opcode_t, bool);
void pp_literals (const literal *, uint8_t);
void pp_op_meta (opcode_counter_t, op_meta, bool);
void pp_literals (const literal *, literal_index_t);
#endif // JERRY_ENABLE_PP
#endif // PRETTY_PRINTER

View File

@ -29,15 +29,27 @@ serializer_set_scope (scopes_tree new_scope)
current_scope = new_scope;
}
static uint16_t
hash_function (void *raw_key)
{
lit_id_table_key *key = (lit_id_table_key *) raw_key;
JERRY_ASSERT (bytecode_data.opcodes_count > 0);
return (uint16_t) (key->oc + key->uid) & ((1u << CONFIG_LITERAL_HASH_TABLE_KEY_BITS) - 1);
}
void
serializer_merge_scopes_into_bytecode (void)
{
bytecode_data.opcodes = scopes_tree_raw_data (current_scope, &bytecode_data.opcodes_count);
JERRY_ASSERT (bytecode_data.lit_id_hash == null_hash);
bytecode_data.opcodes_count = scopes_tree_count_opcodes (current_scope);
bytecode_data.lit_id_hash = hash_table_init (sizeof (lit_id_table_key), sizeof (literal_index_t),
1u << CONFIG_LITERAL_HASH_TABLE_KEY_BITS, hash_function,
MEM_HEAP_ALLOC_LONG_TERM);
bytecode_data.opcodes = scopes_tree_raw_data (current_scope, bytecode_data.lit_id_hash);
}
void
serializer_dump_literals (const literal literals[], uint8_t literals_count)
serializer_dump_literals (const literal literals[], literal_index_t literals_count)
{
#ifdef JERRY_ENABLE_PP
if (print_opcodes)
@ -51,20 +63,32 @@ serializer_dump_literals (const literal literals[], uint8_t literals_count)
}
void
serializer_dump_opcode (opcode_t opcode)
serializer_dump_op_meta (op_meta op)
{
JERRY_ASSERT (scopes_tree_opcodes_num (current_scope) < MAX_OPCODES);
scopes_tree_add_opcode (current_scope, opcode);
scopes_tree_add_op_meta (current_scope, op);
#ifdef JERRY_ENABLE_PP
if (print_opcodes)
{
pp_opcode ((opcode_counter_t) (scopes_tree_opcodes_num (current_scope) - 1), opcode, false);
pp_op_meta ((opcode_counter_t) (scopes_tree_opcodes_num (current_scope) - 1), op, false);
}
#endif
}
opcode_counter_t
serializer_get_current_opcode_counter (void)
{
return scopes_tree_opcodes_num (current_scope);
}
opcode_counter_t
serializer_count_opcodes_in_subscopes (void)
{
return (opcode_counter_t) (scopes_tree_count_opcodes (current_scope) - scopes_tree_opcodes_num (current_scope));
}
void
serializer_set_writing_position (opcode_counter_t oc)
{
@ -72,14 +96,14 @@ serializer_set_writing_position (opcode_counter_t oc)
}
void
serializer_rewrite_opcode (const opcode_counter_t loc, opcode_t opcode)
serializer_rewrite_op_meta (const opcode_counter_t loc, op_meta op)
{
scopes_tree_set_opcode (current_scope, loc, opcode);
scopes_tree_set_op_meta (current_scope, loc, op);
#ifdef JERRY_ENABLE_PP
if (print_opcodes)
{
pp_opcode (loc, opcode, true);
pp_op_meta (loc, op, true);
}
#endif
}
@ -99,7 +123,15 @@ serializer_print_opcodes (void)
for (loc = 0; loc < bytecode_data.opcodes_count; loc++)
{
pp_opcode (loc, bytecode_data.opcodes[loc], false);
const op_meta opm = (op_meta)
{
.op = bytecode_data.opcodes[loc],
.lit_id =
{
NOT_A_LITERAL
}
};
pp_op_meta (loc, opm, false);
}
#endif
}

View File

@ -17,18 +17,21 @@
#define SERIALIZER_H
#include "globals.h"
#include "ecma-globals.h"
#include "opcodes.h"
#include "interpreter.h"
#include "literal.h"
#include "scopes-tree.h"
void serializer_init (bool show_opcodes);
void serializer_dump_literals (const literal *, uint8_t);
void serializer_dump_literals (const literal *, literal_index_t);
void serializer_set_scope (scopes_tree);
void serializer_merge_scopes_into_bytecode (void);
void serializer_dump_opcode (opcode_t);
void serializer_dump_op_meta (op_meta);
opcode_counter_t serializer_get_current_opcode_counter (void);
opcode_counter_t serializer_count_opcodes_in_subscopes (void);
void serializer_set_writing_position (opcode_counter_t);
void serializer_rewrite_opcode (const opcode_counter_t, opcode_t);
void serializer_rewrite_op_meta (opcode_counter_t, op_meta);
void serializer_print_opcodes (void);
void serializer_free (void);

View File

@ -28,21 +28,21 @@ int
main( int __unused argc,
char __unused **argv)
{
char program[] = {'a','=','1',';','v','a','r',' ','a',';','\0'};
char program[] = "a=1;var a;";
bool is_ok;
mem_init();
mem_init ();
deserializer_init ();
parser_init (program, __strlen (program), true);
parser_parse_program ();
parser_free ();
if (!opcodes_equal(deserialize_bytecode (), (opcode_t[]) {
[0] = getop_reg_var_decl (1, 2), // var tmp1 .. tmp2;
[1] = getop_var_decl (0), // var a;
[2] = getop_assignment (1, 1, 1), // tmp1 = 1: SMALLINT;
[3] = getop_assignment (0, 4, 1), // a = tmp1: TYPEOF(tmp1);
[4] = getop_exitval (0) // exit 0;
[0] = getop_reg_var_decl (128, 129), // var tmp128 .. tmp129;
[1] = getop_var_decl (0), // var a;
[2] = getop_assignment (129, 1, 1), // tmp129 = 1: SMALLINT;
[3] = getop_assignment (0, 6, 129), // a = tmp129 : TYPEOF(tmp129);
[4] = getop_exitval (0) // exit 0;
}, 5))
{
is_ok = false;