Skip to content
Merged
3 changes: 2 additions & 1 deletion jerry-core/ecma/base/ecma-gc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,8 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
case ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE: /* compressed pointer to a ecma_number_t */
case ECMA_INTERNAL_PROPERTY_PRIMITIVE_BOOLEAN_VALUE: /* a simple boolean value */
case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */
case ECMA_INTERNAL_PROPERTY_CODE: /* an integer */
case ECMA_INTERNAL_PROPERTY_CODE_BYTECODE: /* compressed pointer to a bytecode array */
case ECMA_INTERNAL_PROPERTY_CODE_FLAGS_AND_OFFSET: /* an integer */
case ECMA_INTERNAL_PROPERTY_NATIVE_CODE: /* an external pointer */
case ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE: /* an external pointer */
case ECMA_INTERNAL_PROPERTY_FREE_CALLBACK: /* an object's native free callback */
Expand Down
4 changes: 3 additions & 1 deletion jerry-core/ecma/base/ecma-globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,9 @@ typedef enum
ECMA_INTERNAL_PROPERTY_EXTENSIBLE, /**< [[Extensible]] */
ECMA_INTERNAL_PROPERTY_SCOPE, /**< [[Scope]] */
ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP, /**< [[ParametersMap]] */
ECMA_INTERNAL_PROPERTY_CODE, /**< [[Code]] */
ECMA_INTERNAL_PROPERTY_CODE_BYTECODE, /**< first part of [[Code]] - compressed pointer to bytecode array */
ECMA_INTERNAL_PROPERTY_CODE_FLAGS_AND_OFFSET, /**< second part of [[Code]] - offset in bytecode array and code flags
* (see also: ecma_pack_code_internal_property_value) */
ECMA_INTERNAL_PROPERTY_NATIVE_CODE, /**< native handler location descriptor */
ECMA_INTERNAL_PROPERTY_NATIVE_HANDLE, /**< native handle associated with an object */
ECMA_INTERNAL_PROPERTY_FREE_CALLBACK, /**< object's native free callback */
Expand Down
3 changes: 2 additions & 1 deletion jerry-core/ecma/base/ecma-helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,8 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
case ECMA_INTERNAL_PROPERTY_PROTOTYPE: /* the property's value is located in ecma_object_t */
case ECMA_INTERNAL_PROPERTY_EXTENSIBLE: /* the property's value is located in ecma_object_t */
case ECMA_INTERNAL_PROPERTY_CLASS: /* an enum */
case ECMA_INTERNAL_PROPERTY_CODE: /* an integer */
case ECMA_INTERNAL_PROPERTY_CODE_BYTECODE: /* compressed pointer to a bytecode array */
case ECMA_INTERNAL_PROPERTY_CODE_FLAGS_AND_OFFSET: /* an integer */
case ECMA_INTERNAL_PROPERTY_BUILT_IN_ID: /* an integer */
case ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_ID: /* an integer */
case ECMA_INTERNAL_PROPERTY_EXTENSION_ID: /* an integer */
Expand Down
134 changes: 127 additions & 7 deletions jerry-core/ecma/builtin-objects/ecma-builtin-function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,13 @@
*/

#include "ecma-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-function-object.h"
#include "ecma-lex-env.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#include "serializer.h"
#include "parser.h"

#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
Expand Down Expand Up @@ -59,6 +56,9 @@ ecma_builtin_function_dispatch_call (const ecma_value_t *arguments_list_p, /**<
/**
* Handle calling [[Construct]] of built-in Function object
*
* See also:
* ECMA-262 v5, 15.3.
*
* @return completion-value
*/
ecma_completion_value_t
Expand All @@ -67,7 +67,127 @@ ecma_builtin_function_dispatch_construct (const ecma_value_t *arguments_list_p,
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);

ECMA_BUILTIN_CP_UNIMPLEMENTED (arguments_list_p, arguments_list_len);
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();

/* Last string, if any, is the function's body, and the rest, if any - are the function's parameter names */
MEM_DEFINE_LOCAL_ARRAY (string_params_p,
arguments_list_len == 0 ? 1 : arguments_list_len,
ecma_string_t*);
uint32_t params_count;

size_t zt_strings_buffer_size;

if (arguments_list_len == 0)
{
/* 3. */
string_params_p[0] = ecma_new_ecma_string_from_magic_string_id (ECMA_MAGIC_STRING__EMPTY);
zt_strings_buffer_size = sizeof (ecma_char_t);
params_count = 1;
}
else
{
/* 4., 5., 6. */
zt_strings_buffer_size = 0;

params_count = 0;
while (params_count < arguments_list_len
&& ecma_is_completion_value_empty (ret_value))
{
ECMA_TRY_CATCH (str_arg_value,
ecma_op_to_string (arguments_list_p[params_count]),
ret_value);

string_params_p[params_count] = ecma_copy_or_ref_ecma_string (ecma_get_string_from_value (str_arg_value));
zt_strings_buffer_size += ((size_t) ecma_string_get_length (string_params_p[params_count]) +
sizeof (ecma_char_t));
params_count++;

ECMA_FINALIZE (str_arg_value);
}
}

if (ecma_is_completion_value_empty (ret_value))
{
JERRY_ASSERT (params_count >= 1);

MEM_DEFINE_LOCAL_ARRAY (zt_string_params_p,
params_count,
ecma_char_t*);
MEM_DEFINE_LOCAL_ARRAY (zt_string_buffer_p,
zt_strings_buffer_size,
ecma_char_t);

ssize_t zt_string_buffer_pos = 0;
for (uint32_t i = 0; i < params_count; i++)
{
ssize_t sz = ecma_string_to_zt_string (string_params_p[i],
&zt_string_buffer_p[zt_string_buffer_pos],
(ssize_t) zt_strings_buffer_size - zt_string_buffer_pos);
JERRY_ASSERT (sz > 0);

zt_string_params_p[i] = zt_string_buffer_p + zt_string_buffer_pos;

zt_string_buffer_pos += sz;
}

parser_init ();

/*
* FIXME:
* Handle syntax errors
*/
parser_parse_new_function ((const char **) zt_string_params_p, params_count);
const opcode_t* opcodes_p = (const opcode_t*) serializer_get_bytecode ();
serializer_print_opcodes ();
parser_free ();

bool is_strict = false;
bool do_instantiate_arguments_object = true;

opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (opcodes_p,
0);

if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT)
{
is_strict = true;
}

if ((scope_flags & OPCODE_SCOPE_CODE_FLAGS_NOT_REF_ARGUMENTS_IDENTIFIER)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing empty line.

&& (scope_flags & OPCODE_SCOPE_CODE_FLAGS_NOT_REF_EVAL_IDENTIFIER))
{
/* the code doesn't use 'arguments' identifier
* and doesn't perform direct call to eval,
* so Arguments object can't be referenced */
do_instantiate_arguments_object = false;
}

/* 11. */
ecma_object_t *glob_lex_env_p = ecma_get_global_environment ();

ecma_object_t *func_obj_p = ecma_op_create_function_object (params_count > 1u ? string_params_p : NULL,
(ecma_length_t) (params_count - 1u),
glob_lex_env_p,
is_strict,
do_instantiate_arguments_object,
opcodes_p,
1);

ecma_deref_object (glob_lex_env_p);

ret_value = ecma_make_normal_completion_value (ecma_make_object_value (func_obj_p));

MEM_FINALIZE_LOCAL_ARRAY (zt_string_buffer_p);
MEM_FINALIZE_LOCAL_ARRAY (zt_string_params_p);
}

for (uint32_t i = 0; i < params_count; i++)
{
ecma_deref_ecma_string (string_params_p[i]);
}

MEM_FINALIZE_LOCAL_ARRAY (string_params_p);

return ret_value;
} /* ecma_builtin_function_dispatch_construct */

/**
Expand Down
34 changes: 33 additions & 1 deletion jerry-core/ecma/builtin-objects/ecma-builtin-global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
#include "ecma-alloc.h"
#include "ecma-builtins.h"
#include "ecma-conversion.h"
#include "ecma-eval.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#include "vm.h"

#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
Expand Down Expand Up @@ -52,7 +54,37 @@ static ecma_completion_value_t
ecma_builtin_global_object_eval (ecma_value_t this_arg, /**< this argument */
ecma_value_t x) /**< routine's first argument */
{
ECMA_BUILTIN_CP_UNIMPLEMENTED (this_arg, x);
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();

bool is_direct_eval = vm_is_direct_eval_form_call ();
JERRY_ASSERT (!(is_direct_eval
&& !ecma_is_value_undefined (this_arg)));

/* See also: ECMA-262 v5, 10.1.1 */
bool is_called_from_strict_mode_code;
if (is_direct_eval)
{
is_called_from_strict_mode_code = vm_is_strict_mode ();
}
else
{
is_called_from_strict_mode_code = false;
}

if (!ecma_is_value_string (x))
{
/* step 1 */
ret_value = ecma_make_normal_completion_value (ecma_copy_value (x, true));
}
else
{
/* steps 2 to 8 */
ret_value = ecma_op_eval (ecma_get_string_from_value (x),
is_direct_eval,
is_called_from_strict_mode_code);
}

return ret_value;
} /* ecma_builtin_global_object_eval */

/**
Expand Down
76 changes: 57 additions & 19 deletions jerry-core/ecma/operations/ecma-eval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-lex-env.h"
#include "parser.h"
#include "serializer.h"
#include "vm.h"

/** \addtogroup ecma ECMA
Expand All @@ -29,10 +31,11 @@
*/

/**
* eval
* Perform 'eval' with code stored in ecma-string
*
* See also:
* ECMA-262 v5, 15.1.2.1
* ecma_op_eval_chars_buffer
* ECMA-262 v5, 15.1.2.1 (steps 2 to 8)
*
* @return completion value
*/
Expand All @@ -41,7 +44,7 @@ ecma_op_eval (ecma_string_t *code_p, /**< code string */
bool is_direct, /**< is eval called directly (ECMA-262 v5, 15.1.2.1.1) */
bool is_called_from_strict_mode_code) /**< is eval is called from strict mode code */
{
ecma_completion_value_t completion;
ecma_completion_value_t ret_value;

int32_t chars_num = ecma_string_get_length (code_p);
MEM_DEFINE_LOCAL_ARRAY (code_zt_buffer_p,
Expand All @@ -54,15 +57,51 @@ ecma_op_eval (ecma_string_t *code_p, /**< code string */
buf_size);
JERRY_ASSERT (buffer_size_req == buf_size);

// FIXME: Get parser feedback about syntax correctness
bool is_syntax_correct = true;
bool is_strict_prologue;
ret_value = ecma_op_eval_chars_buffer (code_zt_buffer_p,
(size_t) buf_size,
is_direct,
is_called_from_strict_mode_code);

MEM_FINALIZE_LOCAL_ARRAY (code_zt_buffer_p);

return ret_value;
} /* ecma_op_eval */

/**
* Perform 'eval' with code stored in continuous character buffer
*
* See also:
* ecma_op_eval
* ECMA-262 v5, 15.1.2.1 (steps 2 to 8)
*
* @return completion value
*/
ecma_completion_value_t
ecma_op_eval_chars_buffer (const ecma_char_t *code_p, /**< code characters buffer */
size_t code_buffer_size, /**< size of the buffer */
bool is_direct, /**< is eval called directly (ECMA-262 v5, 15.1.2.1.1) */
bool is_called_from_strict_mode_code) /**< is eval is called from strict mode code */
{
JERRY_ASSERT (code_p != NULL);

ecma_completion_value_t completion;

// FIXME: Call parser
JERRY_UNIMPLEMENTED ("eval operation is not implemented");
parser_init ();
bool is_syntax_correct = parser_parse_eval ((const char *) code_p, code_buffer_size);
const opcode_t* opcodes_p = (const opcode_t*) serializer_get_bytecode ();
serializer_print_opcodes ();
parser_free ();

opcode_counter_t first_opcode_index = 0u;
bool is_strict_prologue = false;
opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (opcodes_p,
first_opcode_index++);
if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT)
{
is_strict_prologue = true;
}

// FIXME:
is_strict_prologue = false;
bool is_strict = (is_strict_prologue || (is_direct && is_called_from_strict_mode_code));

if (!is_syntax_correct)
{
Expand All @@ -85,18 +124,20 @@ ecma_op_eval (ecma_string_t *code_p, /**< code string */
lex_env_p = ecma_get_global_environment ();
}

if (is_strict_prologue
|| (is_direct && is_called_from_strict_mode_code))
if (is_strict)
{
ecma_object_t *strict_lex_env_p = ecma_create_decl_lex_env (lex_env_p);
ecma_deref_object (lex_env_p);

lex_env_p = strict_lex_env_p;
}

// FIXME: Call interpreter
completion = ecma_make_return_completion_value (ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED));
JERRY_UNIMPLEMENTED ("eval operation is not implemented");
completion = vm_run_from_pos (opcodes_p,
first_opcode_index,
this_binding,
lex_env_p,
is_strict,
true);

if (ecma_is_completion_value_return (completion))
{
Expand All @@ -112,11 +153,8 @@ ecma_op_eval (ecma_string_t *code_p, /**< code string */
ecma_free_value (this_binding, true);
}


MEM_FINALIZE_LOCAL_ARRAY (code_zt_buffer_p);

return completion;
} /* ecma_op_eval */
} /* ecma_op_eval_chars_buffer */

/**
* @}
Expand Down
6 changes: 6 additions & 0 deletions jerry-core/ecma/operations/ecma-eval.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ ecma_op_eval (ecma_string_t *code_p,
bool is_direct,
bool is_called_from_strict_mode_code);

extern ecma_completion_value_t
ecma_op_eval_chars_buffer (const ecma_char_t *code_p,
size_t code_buffer_size,
bool is_direct,
bool is_called_from_strict_mode_code);

/**
* @}
* @}
Expand Down
Loading