Exemplo n.º 1
0
/**
 * Count slots needed for a scope's hash table
 *
 * Before filling literal indexes 'hash' table we shall initiate it with number of neccesary literal indexes.
 * Since bytecode is divided into blocks and id of the block is a part of hash key, we shall divide bytecode
 *  into blocks and count unique literal indexes used in each block.
 *
 * @return total number of literals in scope
 */
size_t
scopes_tree_count_literals_in_blocks (scopes_tree tree) /**< scope */
{
  assert_tree (tree);
  size_t result = 0;

  if (lit_id_to_uid != null_hash)
  {
    hash_table_free (lit_id_to_uid);
    lit_id_to_uid = null_hash;
  }
  next_uid = 0;
  global_oc = 0;

  assert_tree (tree);
  vm_instr_counter_t instr_pos;
  bool header = true;
  for (instr_pos = 0; instr_pos < tree->instrs_count; instr_pos++)
  {
    op_meta *om_p = extract_op_meta (tree->instrs, instr_pos);
    if (om_p->op.op_idx != VM_OP_META && !header)
    {
      break;
    }
    if (om_p->op.op_idx == VM_OP_REG_VAR_DECL)
    {
      header = false;
    }
    result += count_new_literals_in_instr (om_p);
  }

  for (vm_instr_counter_t var_decl_pos = 0; var_decl_pos < tree->var_decls_cout; var_decl_pos++)
  {
    op_meta *om_p = extract_op_meta (tree->var_decls, var_decl_pos);
    result += count_new_literals_in_instr (om_p);
  }

  for (uint8_t child_id = 0; child_id < tree->t.children_num; child_id++)
  {
    result += scopes_tree_count_literals_in_blocks (*(scopes_tree *) linked_list_element (tree->t.children, child_id));
  }

  for (; instr_pos < tree->instrs_count; instr_pos++)
  {
    op_meta *om_p = extract_op_meta (tree->instrs, instr_pos);
    result += count_new_literals_in_instr (om_p);
  }

  return result;
} /* scopes_tree_count_literals_in_blocks */
Exemplo n.º 2
0
//for debugging . returns black_height
int assert_tree(ptr_rbnode node) {
    if (node == NULL) return 0;
    if (node->parent) {
        assert(!(
                (node->color == RED) && (node->parent->color == RED)
        ));
    }

    int left_bh = 0, right_bh = 0;
    if (node->left) left_bh = assert_tree(node->left);
    if (node->right) right_bh = assert_tree(node->right);

    assert(left_bh == right_bh);
    return left_bh + (node->color == BLACK ? 1 : 0);
}
Exemplo n.º 3
0
/**
 * Set up a flag, indicating that scope should be executed in strict mode
 */
void
scopes_tree_set_strict_mode (scopes_tree tree, /**< scope */
                             bool strict_mode) /**< value of the strict mode flag */
{
  assert_tree (tree);
  tree->strict_mode = strict_mode;
} /* scopes_tree_set_strict_mode */
Exemplo n.º 4
0
void
scopes_tree_set_instrs_num (scopes_tree tree, vm_instr_counter_t oc)
{
  assert_tree (tree);
  JERRY_ASSERT (oc < tree->instrs_count);
  tree->instrs_count = oc;
}
Exemplo n.º 5
0
op_meta
scopes_tree_op_meta (scopes_tree tree, vm_instr_counter_t oc)
{
  assert_tree (tree);
  JERRY_ASSERT (oc < tree->instrs_count);
  return *(op_meta *) linked_list_element (tree->instrs, oc);
}
Exemplo n.º 6
0
/* Postparser.
   Init literal indexes 'hash' table.
   Reorder function declarations.
   Rewrite instructions' temporary uids with their keys in literal indexes 'hash' table. */
vm_instr_t *
scopes_tree_raw_data (scopes_tree tree, /**< scopes tree to convert to byte-code array */
                      uint8_t *buffer_p, /**< buffer for byte-code array and literal identifiers hash table */
                      size_t instructions_array_size, /**< size of space for byte-code array */
                      lit_id_hash_table *lit_ids) /**< literal identifiers hash table */
{
  JERRY_ASSERT (lit_ids);
  assert_tree (tree);
  if (lit_id_to_uid != null_hash)
  {
    hash_table_free (lit_id_to_uid);
    lit_id_to_uid = null_hash;
  }
  next_uid = 0;
  global_oc = 0;

  /* Dump bytecode and fill literal indexes 'hash' table. */
  JERRY_ASSERT (instructions_array_size >=
                sizeof (insts_data_header_t) + (size_t) (scopes_tree_count_instructions (tree)) * sizeof (vm_instr_t));

  insts_data_header_t *opcodes_data = (insts_data_header_t *) buffer_p;
  memset (opcodes_data, 0, instructions_array_size);

  vm_instr_t *instrs = (vm_instr_t *)(((uint8_t*) opcodes_data) + sizeof (insts_data_header_t));
  merge_subscopes (tree, instrs, lit_ids);
  if (lit_id_to_uid != null_hash)
  {
    hash_table_free (lit_id_to_uid);
    lit_id_to_uid = null_hash;
  }

  MEM_CP_SET_POINTER (opcodes_data->lit_id_hash_cp, lit_ids);

  return instrs;
} /* scopes_tree_raw_data */
Exemplo n.º 7
0
void
scopes_tree_set_op_meta (scopes_tree tree, vm_instr_counter_t oc, op_meta op)
{
  assert_tree (tree);
  JERRY_ASSERT (oc < tree->instrs_count);
  linked_list_set_element (tree->instrs, oc, &op);
}
Exemplo n.º 8
0
/**
 * Add variable declaration to a scope
 */
void
scopes_tree_add_var_decl (scopes_tree tree, /**< scope, to which variable declaration is added */
                          op_meta op) /**< variable declaration instruction */
{
  assert_tree (tree);
  linked_list_set_element (tree->var_decls, tree->var_decls_cout++, &op);
} /* scopes_tree_add_var_decl */
Exemplo n.º 9
0
/**
 * Get variable declaration for the specified scope
 *
 * @return instruction, declaring a variable
 */
op_meta
scopes_tree_var_decl (scopes_tree tree, /**< scope, from which variable declaration is retrieved */
                      vm_instr_counter_t oc) /**< number of variable declaration in the scope */
{
  assert_tree (tree);
  JERRY_ASSERT (oc < tree->var_decls_cout);
  return *(op_meta *) linked_list_element (tree->var_decls, oc);
} /* scopes_tree_var_decl */
Exemplo n.º 10
0
vm_instr_counter_t
scopes_tree_count_instructions (scopes_tree t)
{
  assert_tree (t);
  vm_instr_counter_t res = (vm_instr_counter_t) (t->instrs_count + t->var_decls_cout);
  for (uint8_t i = 0; i < t->t.children_num; i++)
  {
    res = (vm_instr_counter_t) (
      res + scopes_tree_count_instructions (
        *(scopes_tree *) linked_list_element (t->t.children, i)));
  }
  return res;
}
Exemplo n.º 11
0
void
scopes_tree_free (scopes_tree tree)
{
  assert_tree (tree);
  if (tree->t.children_num != 0)
  {
    for (uint8_t i = 0; i < tree->t.children_num; ++i)
    {
      scopes_tree_free (*(scopes_tree *) linked_list_element (tree->t.children, i));
    }
    linked_list_free (tree->t.children);
  }
  linked_list_free (tree->instrs);
  linked_list_free (tree->var_decls);
  jsp_mm_free (tree);
}
Exemplo n.º 12
0
/*
 * This function performs functions hoisting.
 *
 *  Each scope consists of four parts:
 *  1) Header with 'use strict' marker and reg_var_decl opcode
 *  2) Variable declarations, dumped by the preparser
 *  3) Function declarations
 *  4) Computational code
 *
 *  Header and var_decls are dumped first,
 *  then we shall recursively dump function declaration,
 *  and finally, other instructions.
 *
 *  For each instructions block (size of block is defined in bytecode-data.h)
 *  literal indexes 'hash' table is filled.
 */
static void
merge_subscopes (scopes_tree tree, /**< scopes tree to merge */
                 vm_instr_t *data_p, /**< instruction array, where the scopes are merged to */
                 lit_id_hash_table *lit_ids_p) /**< literal indexes 'hash' table */
{
  assert_tree (tree);
  JERRY_ASSERT (data_p);
  vm_instr_counter_t instr_pos;
  bool header = true;
  for (instr_pos = 0; instr_pos < tree->instrs_count; instr_pos++)
  {
    op_meta *om_p = extract_op_meta (tree->instrs, instr_pos);
    if (om_p->op.op_idx != VM_OP_VAR_DECL
        && om_p->op.op_idx != VM_OP_META && !header)
    {
      break;
    }
    if (om_p->op.op_idx == VM_OP_REG_VAR_DECL)
    {
      header = false;
    }
    data_p[global_oc] = generate_instr (tree->instrs, instr_pos, lit_ids_p);
    global_oc++;
  }

  for (vm_instr_counter_t var_decl_pos = 0; var_decl_pos < tree->var_decls_cout; var_decl_pos++)
  {
    data_p[global_oc] = generate_instr (tree->var_decls, var_decl_pos, lit_ids_p);
    global_oc++;
  }

  for (uint8_t child_id = 0; child_id < tree->t.children_num; child_id++)
  {
    merge_subscopes (*(scopes_tree *) linked_list_element (tree->t.children, child_id),
                     data_p, lit_ids_p);
  }

  for (; instr_pos < tree->instrs_count; instr_pos++)
  {
    data_p[global_oc] = generate_instr (tree->instrs, instr_pos, lit_ids_p);
    global_oc++;
  }
} /* merge_subscopes */
Exemplo n.º 13
0
bool
scopes_tree_strict_mode (scopes_tree tree)
{
  assert_tree (tree);
  return (bool) tree->strict_mode;
}
Exemplo n.º 14
0
/**
 * Set up a flag, indicating that "eval" is used inside a scope
 */
void
scopes_tree_set_eval_used (scopes_tree tree) /**< scope */
{
  assert_tree (tree);
  tree->ref_eval = true;
} /* scopes_tree_set_eval_used */
Exemplo n.º 15
0
/**
 * Set up a flag, indicating that "arguments" is used inside a scope
 */
void
scopes_tree_set_arguments_used (scopes_tree tree) /**< scope */
{
  assert_tree (tree);
  tree->ref_arguments = true;
} /* merge_subscopes */
Exemplo n.º 16
0
void
scopes_tree_add_op_meta (scopes_tree tree, op_meta op)
{
  assert_tree (tree);
  linked_list_set_element (tree->instrs, tree->instrs_count++, &op);
}
Exemplo n.º 17
0
/**
 * Get number of variable declarations in the scope
 *
 * @return number of variable declarations
 */
vm_instr_counter_t
scopes_tree_var_decls_num (scopes_tree t) /**< scope */
{
  assert_tree (t);
  return t->var_decls_cout;
} /* scopes_tree_var_decls_num */
Exemplo n.º 18
0
vm_instr_counter_t
scopes_tree_instrs_num (scopes_tree t)
{
  assert_tree (t);
  return t->instrs_count;
}