Compact Byte Code parser and executor for Jerry.
JerryScript-DCO-1.0-Signed-off-by: László Langó llango.u-szeged@partner.samsung.com JerryScript-DCO-1.0-Signed-off-by: Tamas Gergely tgergely.u-szeged@partner.samsung.com JerryScript-DCO-1.0-Signed-off-by: Zsolt Borbély zsborbely.u-szeged@partner.samsung.com JerryScript-DCO-1.0-Signed-off-by: Roland Takacs rtakacs.u-szeged@partner.samsung.com JerryScript-DCO-1.0-Signed-off-by: István Kádár ikadar@inf.u-szeged.hu JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
/* Copyright 2014-2016 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.
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "jrt.h"
|
||||
#include "jrt-libc-includes.h"
|
||||
#include "jrt-bit-fields.h"
|
||||
#include "vm-defines.h"
|
||||
#include "vm-stack.h"
|
||||
|
||||
#define JERRY_INTERNAL
|
||||
@@ -335,13 +336,11 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
|
||||
case ECMA_INTERNAL_PROPERTY_FORMAL_PARAMETERS: /* a collection of strings */
|
||||
case ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE: /* compressed pointer to a ecma_string_t */
|
||||
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_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 */
|
||||
@@ -484,25 +483,6 @@ ecma_gc_run (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* if some object is referenced from a register variable (i.e. it is root),
|
||||
* start recursive marking traverse from the object */
|
||||
for (vm_stack_frame_t *frame_iter_p = vm_stack_get_top_frame ();
|
||||
frame_iter_p != NULL;
|
||||
frame_iter_p = frame_iter_p->prev_frame_p)
|
||||
{
|
||||
for (uint32_t reg_index = 0; reg_index < frame_iter_p->regs_number; reg_index++)
|
||||
{
|
||||
ecma_value_t reg_value = vm_stack_frame_get_reg_value (frame_iter_p, VM_REG_FIRST + reg_index);
|
||||
|
||||
if (ecma_is_value_object (reg_value))
|
||||
{
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (reg_value);
|
||||
|
||||
ecma_gc_set_object_visited (obj_p, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool marked_anything_during_current_iteration = false;
|
||||
|
||||
do
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
/* Copyright 2014-2016 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.
|
||||
@@ -82,6 +82,7 @@ typedef enum
|
||||
but are stored directly in the array's property list
|
||||
(used for array elements with non-default attribute values) */
|
||||
ECMA_SIMPLE_VALUE_ARRAY_HOLE, /**< array hole, used for initialization of an array literal */
|
||||
ECMA_SIMPLE_VALUE_REGISTER_REF, /**< register reference, a special "base" value for vm */
|
||||
ECMA_SIMPLE_VALUE__COUNT /** count of simple ecma-values */
|
||||
} ecma_simple_value_t;
|
||||
|
||||
@@ -170,21 +171,12 @@ typedef uint32_t ecma_completion_value_t;
|
||||
#define ECMA_COMPLETION_VALUE_VALUE_POS (0)
|
||||
#define ECMA_COMPLETION_VALUE_VALUE_WIDTH (ECMA_VALUE_SIZE)
|
||||
|
||||
/**
|
||||
* Break / continue jump target
|
||||
*/
|
||||
#define ECMA_COMPLETION_VALUE_TARGET_POS (0)
|
||||
#define ECMA_COMPLETION_VALUE_TARGET_WIDTH ((uint32_t) sizeof (vm_instr_counter_t) * JERRY_BITSINBYTE)
|
||||
|
||||
/**
|
||||
* Type (ecma_completion_type_t)
|
||||
*/
|
||||
#define ECMA_COMPLETION_VALUE_TYPE_POS (JERRY_MAX (JERRY_ALIGNUP (ECMA_COMPLETION_VALUE_VALUE_POS + \
|
||||
#define ECMA_COMPLETION_VALUE_TYPE_POS (JERRY_ALIGNUP (ECMA_COMPLETION_VALUE_VALUE_POS + \
|
||||
ECMA_COMPLETION_VALUE_VALUE_WIDTH, \
|
||||
JERRY_BITSINBYTE), \
|
||||
JERRY_ALIGNUP (ECMA_COMPLETION_VALUE_TARGET_POS + \
|
||||
ECMA_COMPLETION_VALUE_TARGET_WIDTH, \
|
||||
JERRY_BITSINBYTE)))
|
||||
JERRY_BITSINBYTE))
|
||||
#define ECMA_COMPLETION_VALUE_TYPE_WIDTH (8)
|
||||
|
||||
/**
|
||||
@@ -218,12 +210,9 @@ typedef enum
|
||||
ECMA_INTERNAL_PROPERTY_SCOPE, /**< [[Scope]] */
|
||||
ECMA_INTERNAL_PROPERTY_PARAMETERS_MAP, /**< [[ParametersMap]] */
|
||||
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 */
|
||||
ECMA_INTERNAL_PROPERTY_FORMAL_PARAMETERS, /**< [[FormalParameters]] */
|
||||
ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE, /**< [[Primitive value]] for String objects */
|
||||
ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE, /**< [[Primitive value]] for Number objects */
|
||||
ECMA_INTERNAL_PROPERTY_PRIMITIVE_BOOLEAN_VALUE, /**< [[Primitive value]] for Boolean objects */
|
||||
@@ -837,6 +826,22 @@ typedef struct ecma_string_t
|
||||
*/
|
||||
typedef uintptr_t ecma_external_pointer_t;
|
||||
|
||||
/**
|
||||
* Compiled byte code data.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t status_flags; /**< various status flags */
|
||||
} ecma_compiled_code_t;
|
||||
|
||||
/**
|
||||
* Shift value for byte code reference counting.
|
||||
* The last 10 bit of the first uint16_t value
|
||||
* of compact byte code or regexp byte code
|
||||
* is reserved for reference counting.
|
||||
*/
|
||||
#define ECMA_BYTECODE_REF_SHIFT 6
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
/* Copyright 2014-2016 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.
|
||||
@@ -20,7 +20,6 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "bytecode-data.h"
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-globals.h"
|
||||
@@ -29,9 +28,10 @@
|
||||
#include "jrt.h"
|
||||
#include "jrt-libc-includes.h"
|
||||
#include "lit-char-helpers.h"
|
||||
#include "lit-literal.h"
|
||||
#include "lit-magic-strings.h"
|
||||
#include "vm.h"
|
||||
#include "rcs-records.h"
|
||||
#include "vm.h"
|
||||
|
||||
/**
|
||||
* Maximum length of strings' concatenation
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2015 Samsung Electronics Co., Ltd.
|
||||
/* Copyright 2015-2016 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.
|
||||
@@ -26,16 +26,16 @@
|
||||
#include "ecma-helpers.h"
|
||||
#include "jrt.h"
|
||||
#include "jrt-bit-fields.h"
|
||||
#include "vm-defines.h"
|
||||
|
||||
JERRY_STATIC_ASSERT (sizeof (ecma_value_t) * JERRY_BITSINBYTE >= ECMA_VALUE_SIZE);
|
||||
JERRY_STATIC_ASSERT (sizeof (ecma_completion_value_t) * JERRY_BITSINBYTE >= ECMA_COMPLETION_VALUE_SIZE);
|
||||
|
||||
/**
|
||||
* Get type field of ecma-value
|
||||
*
|
||||
* @return type field
|
||||
*/
|
||||
static ecma_type_t __attr_pure___
|
||||
ecma_type_t __attr_pure___
|
||||
ecma_get_value_type_field (ecma_value_t value) /**< ecma-value */
|
||||
{
|
||||
return (ecma_type_t) jrt_extract_bit_field (value,
|
||||
@@ -474,19 +474,6 @@ ecma_get_completion_value_value_field (ecma_completion_value_t completion_value)
|
||||
ECMA_COMPLETION_VALUE_VALUE_WIDTH);
|
||||
} /* ecma_get_completion_value_value_field */
|
||||
|
||||
/**
|
||||
* Get target of break / continue completion value
|
||||
*
|
||||
* @return instruction counter
|
||||
*/
|
||||
static vm_instr_counter_t
|
||||
ecma_get_completion_value_target (ecma_completion_value_t completion_value) /**< completion value */
|
||||
{
|
||||
return (vm_instr_counter_t) jrt_extract_bit_field (completion_value,
|
||||
ECMA_COMPLETION_VALUE_TARGET_POS,
|
||||
ECMA_COMPLETION_VALUE_TARGET_WIDTH);
|
||||
} /* ecma_get_completion_value_target */
|
||||
|
||||
/**
|
||||
* Set type field of completion value
|
||||
*
|
||||
@@ -519,21 +506,6 @@ ecma_set_completion_value_value_field (ecma_completion_value_t completion_value,
|
||||
ECMA_COMPLETION_VALUE_VALUE_WIDTH);
|
||||
} /* ecma_set_completion_value_value_field */
|
||||
|
||||
/**
|
||||
* Set target of break / continue completion value
|
||||
*
|
||||
* @return completion value with updated field
|
||||
*/
|
||||
static ecma_completion_value_t __attr_const___
|
||||
ecma_set_completion_value_target (ecma_completion_value_t completion_value, /**< completion value
|
||||
* to set field in */
|
||||
vm_instr_counter_t target) /**< break / continue target */
|
||||
{
|
||||
return (ecma_completion_value_t) jrt_set_bit_field_value (completion_value,
|
||||
target,
|
||||
ECMA_COMPLETION_VALUE_TARGET_POS,
|
||||
ECMA_COMPLETION_VALUE_TARGET_WIDTH);
|
||||
} /* ecma_set_completion_value_target */
|
||||
|
||||
/**
|
||||
* Normal, throw, return, exit and meta completion values constructor
|
||||
@@ -652,24 +624,6 @@ ecma_make_meta_completion_value (void)
|
||||
ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY));
|
||||
} /* ecma_make_meta_completion_value */
|
||||
|
||||
/**
|
||||
* Break / continue completion values constructor
|
||||
*
|
||||
* @return completion value
|
||||
*/
|
||||
ecma_completion_value_t __attr_const___
|
||||
ecma_make_jump_completion_value (vm_instr_counter_t target) /**< target break / continue */
|
||||
{
|
||||
ecma_completion_value_t completion_value = 0;
|
||||
|
||||
completion_value = ecma_set_completion_value_type_field (completion_value,
|
||||
ECMA_COMPLETION_TYPE_JUMP);
|
||||
completion_value = ecma_set_completion_value_target (completion_value,
|
||||
target);
|
||||
|
||||
return completion_value;
|
||||
} /* ecma_make_jump_completion_value */
|
||||
|
||||
/**
|
||||
* Get ecma-value from specified completion value
|
||||
*
|
||||
@@ -722,20 +676,6 @@ ecma_get_object_from_completion_value (ecma_completion_value_t completion_value)
|
||||
return ecma_get_object_from_value (ecma_get_completion_value_value (completion_value));
|
||||
} /* ecma_get_object_from_completion_value */
|
||||
|
||||
/**
|
||||
* Get break / continue target from completion value
|
||||
*
|
||||
* @return instruction counter
|
||||
*/
|
||||
vm_instr_counter_t
|
||||
ecma_get_jump_target_from_completion_value (ecma_completion_value_t completion_value) /**< completion
|
||||
* value */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_completion_value_type_field (completion_value) == ECMA_COMPLETION_TYPE_JUMP);
|
||||
|
||||
return ecma_get_completion_value_target (completion_value);
|
||||
} /* ecma_get_jump_target_from_completion_value */
|
||||
|
||||
/**
|
||||
* Copy ecma-completion value.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2016 University of Szeged.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -26,6 +27,8 @@
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-lcache.h"
|
||||
#include "jrt-bit-fields.h"
|
||||
#include "byte-code.h"
|
||||
#include "re-compiler.h"
|
||||
|
||||
/**
|
||||
* Create an object with specified prototype object
|
||||
@@ -763,17 +766,6 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
|
||||
break;
|
||||
}
|
||||
|
||||
case ECMA_INTERNAL_PROPERTY_FORMAL_PARAMETERS: /* a strings' collection */
|
||||
{
|
||||
if (property_value != ECMA_NULL_POINTER)
|
||||
{
|
||||
ecma_free_values_collection (ECMA_GET_NON_NULL_POINTER (ecma_collection_header_t,
|
||||
property_value),
|
||||
false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE: /* compressed pointer to a ecma_string_t */
|
||||
{
|
||||
ecma_string_t *str_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t,
|
||||
@@ -807,8 +799,6 @@ 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_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_DESC: /* an integer */
|
||||
case ECMA_INTERNAL_PROPERTY_EXTENSION_ID: /* an integer */
|
||||
@@ -840,15 +830,24 @@ ecma_free_internal_property (ecma_property_t *property_p) /**< the property */
|
||||
* but number of the real internal property types */
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
break;
|
||||
}
|
||||
case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE:
|
||||
{
|
||||
void *bytecode_p = ECMA_GET_POINTER (void, property_value);
|
||||
|
||||
if (bytecode_p)
|
||||
case ECMA_INTERNAL_PROPERTY_CODE_BYTECODE: /* compressed pointer to a bytecode array */
|
||||
{
|
||||
ecma_bytecode_deref (ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t, property_value));
|
||||
break;
|
||||
}
|
||||
|
||||
case ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE: /* compressed pointer to a regexp bytecode array */
|
||||
{
|
||||
ecma_compiled_code_t *bytecode_p = ECMA_GET_POINTER (ecma_compiled_code_t, property_value);
|
||||
|
||||
if (bytecode_p != NULL)
|
||||
{
|
||||
mem_heap_free_block (bytecode_p);
|
||||
ecma_bytecode_deref (bytecode_p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1328,6 +1327,90 @@ ecma_get_property_descriptor_from_property (ecma_property_t *prop_p) /**< proper
|
||||
return prop_desc;
|
||||
} /* ecma_get_property_descriptor_from_property */
|
||||
|
||||
/**
|
||||
* Increase reference counter of Compact
|
||||
* Byte Code or regexp byte code.
|
||||
*/
|
||||
void
|
||||
ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
|
||||
{
|
||||
/* Abort program if maximum reference number is reached.
|
||||
* Note: This is not tested for objects. */
|
||||
if ((bytecode_p->status_flags >> ECMA_BYTECODE_REF_SHIFT) >= 0x3ff)
|
||||
{
|
||||
jerry_fatal (ERR_UNIMPLEMENTED_CASE);
|
||||
}
|
||||
|
||||
bytecode_p->status_flags = (uint16_t) (bytecode_p->status_flags + (1 << ECMA_BYTECODE_REF_SHIFT));
|
||||
} /* ecma_bytecode_ref */
|
||||
|
||||
/**
|
||||
* Decrease reference counter of Compact
|
||||
* Byte Code or regexp byte code.
|
||||
*/
|
||||
void
|
||||
ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
|
||||
{
|
||||
JERRY_ASSERT ((bytecode_p->status_flags >> ECMA_BYTECODE_REF_SHIFT) > 0);
|
||||
|
||||
bytecode_p->status_flags = (uint16_t) (bytecode_p->status_flags - (1 << ECMA_BYTECODE_REF_SHIFT));
|
||||
|
||||
if (bytecode_p->status_flags >= (1 << ECMA_BYTECODE_REF_SHIFT))
|
||||
{
|
||||
/* Non-zero reference counter. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_FUNCTION)
|
||||
{
|
||||
lit_cpointer_t *literal_start_p = NULL;
|
||||
uint32_t literal_end;
|
||||
uint32_t const_literal_end;
|
||||
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_p;
|
||||
literal_start_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
|
||||
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_p;
|
||||
literal_end = args_p->literal_end;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_p;
|
||||
literal_start_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
|
||||
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_p;
|
||||
literal_end = args_p->literal_end;
|
||||
const_literal_end = args_p->const_literal_end;
|
||||
}
|
||||
|
||||
for (uint32_t i = const_literal_end; i < literal_end; i++)
|
||||
{
|
||||
mem_cpointer_t bytecode_cpointer = literal_start_p[i].value.base_cp;
|
||||
ecma_compiled_code_t *bytecode_literal_p = ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t,
|
||||
bytecode_cpointer);
|
||||
|
||||
/* Self references are ignored. */
|
||||
if (bytecode_literal_p != bytecode_p)
|
||||
{
|
||||
ecma_bytecode_deref (bytecode_literal_p);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN
|
||||
re_compiled_code_t *re_bytecode_p = (re_compiled_code_t *) bytecode_p;
|
||||
|
||||
ecma_deref_ecma_string (ECMA_GET_NON_NULL_POINTER (ecma_string_t, re_bytecode_p->pattern_cp));
|
||||
#endif /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_REGEXP_BUILTIN */
|
||||
}
|
||||
|
||||
mem_heap_free_block (bytecode_p);
|
||||
} /* ecma_bytecode_deref */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015 University of Szeged.
|
||||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015-2016 University of Szeged.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "ecma-globals.h"
|
||||
#include "lit-strings.h"
|
||||
#include "mem-allocator.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
/**
|
||||
* Get value of pointer from specified non-null compressed pointer.
|
||||
@@ -53,6 +52,8 @@
|
||||
#define ECMA_SET_POINTER(field, non_compressed_pointer) MEM_CP_SET_POINTER (field, non_compressed_pointer)
|
||||
|
||||
/* ecma-helpers-value.cpp */
|
||||
extern ecma_type_t ecma_get_value_type_field (ecma_value_t) __attr_pure___;
|
||||
|
||||
extern bool ecma_is_value_empty (ecma_value_t);
|
||||
extern bool ecma_is_value_undefined (ecma_value_t);
|
||||
extern bool ecma_is_value_null (ecma_value_t);
|
||||
@@ -84,12 +85,10 @@ extern ecma_completion_value_t ecma_make_throw_obj_completion_value (ecma_object
|
||||
extern ecma_completion_value_t ecma_make_empty_completion_value (void);
|
||||
extern ecma_completion_value_t ecma_make_return_completion_value (ecma_value_t);
|
||||
extern ecma_completion_value_t ecma_make_meta_completion_value (void);
|
||||
extern ecma_completion_value_t ecma_make_jump_completion_value (vm_instr_counter_t);
|
||||
extern ecma_value_t ecma_get_completion_value_value (ecma_completion_value_t);
|
||||
extern ecma_number_t *ecma_get_number_from_completion_value (ecma_completion_value_t) __attr_const___;
|
||||
extern ecma_string_t *ecma_get_string_from_completion_value (ecma_completion_value_t) __attr_const___;
|
||||
extern ecma_object_t *ecma_get_object_from_completion_value (ecma_completion_value_t) __attr_const___;
|
||||
extern vm_instr_counter_t ecma_get_jump_target_from_completion_value (ecma_completion_value_t);
|
||||
extern ecma_completion_value_t ecma_copy_completion_value (ecma_completion_value_t);
|
||||
extern void ecma_free_completion_value (ecma_completion_value_t);
|
||||
|
||||
@@ -254,6 +253,9 @@ extern ecma_property_descriptor_t ecma_make_empty_property_descriptor (void);
|
||||
extern void ecma_free_property_descriptor (ecma_property_descriptor_t *);
|
||||
extern ecma_property_descriptor_t ecma_get_property_descriptor_from_property (ecma_property_t *);
|
||||
|
||||
extern void ecma_bytecode_ref (ecma_compiled_code_t *);
|
||||
extern void ecma_bytecode_deref (ecma_compiled_code_t *);
|
||||
|
||||
/* ecma-helpers-external-pointers.cpp */
|
||||
extern bool
|
||||
ecma_create_external_pointer_property (ecma_object_t *, ecma_internal_property_id_t, ecma_external_pointer_t);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
/* Copyright 2014-2016 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.
|
||||
@@ -50,8 +50,8 @@ ecma_finalize (void)
|
||||
mem_unregister_a_try_give_memory_back_callback (ecma_try_to_give_back_some_memory);
|
||||
|
||||
ecma_finalize_environment ();
|
||||
ecma_finalize_builtins ();
|
||||
ecma_lcache_invalidate_all ();
|
||||
ecma_finalize_builtins ();
|
||||
ecma_gc_run ();
|
||||
} /* ecma_finalize */
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2015 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015 University of Szeged.
|
||||
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015-2016 University of Szeged.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -72,7 +72,7 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
|
||||
else
|
||||
{
|
||||
ecma_string_t *pattern_string_p = NULL;
|
||||
uint8_t flags = 0;
|
||||
uint16_t flags = 0;
|
||||
|
||||
if (ecma_is_value_object (pattern_arg)
|
||||
&& ecma_object_get_class_name (ecma_get_object_from_value (pattern_arg)) == LIT_MAGIC_STRING_REGEXP_UL)
|
||||
@@ -125,17 +125,20 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
|
||||
ecma_property_t *bc_prop_p = ecma_get_internal_property (this_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE);
|
||||
|
||||
FIXME ("We currently have to re-compile the bytecode, because we can't copy it without knowing its length.")
|
||||
re_bytecode_t *new_bc_p = NULL;
|
||||
/* FIXME: "We currently have to re-compile the bytecode, because
|
||||
* we can't copy it without knowing its length."
|
||||
*/
|
||||
re_compiled_code_t *new_bc_p = NULL;
|
||||
ecma_completion_value_t bc_comp = re_compile_bytecode (&new_bc_p, pattern_string_p, flags);
|
||||
/* Should always succeed, since we're compiling from a source that has been compiled previously. */
|
||||
JERRY_ASSERT (ecma_is_completion_value_empty (bc_comp));
|
||||
|
||||
re_bytecode_t *old_bc_p = ECMA_GET_POINTER (re_bytecode_t,
|
||||
bc_prop_p->u.internal_property.value);
|
||||
re_compiled_code_t *old_bc_p = ECMA_GET_POINTER (re_compiled_code_t,
|
||||
bc_prop_p->u.internal_property.value);
|
||||
if (old_bc_p != NULL)
|
||||
{
|
||||
mem_heap_free_block (old_bc_p);
|
||||
/* Free the old bytecode */
|
||||
ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p);
|
||||
}
|
||||
|
||||
ECMA_SET_POINTER (bc_prop_p->u.internal_property.value, new_bc_p);
|
||||
@@ -189,17 +192,18 @@ ecma_builtin_regexp_prototype_compile (ecma_value_t this_arg, /**< this argument
|
||||
ecma_property_t *bc_prop_p = ecma_get_internal_property (this_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE);
|
||||
/* Try to compile bytecode from new source. */
|
||||
re_bytecode_t *new_bc_p = NULL;
|
||||
ECMA_TRY_CATCH (bc_dummy, re_compile_bytecode (&new_bc_p, pattern_string_p, flags), ret_value);
|
||||
re_compiled_code_t *new_bc_p = NULL;
|
||||
ECMA_TRY_CATCH (bc_dummy,
|
||||
re_compile_bytecode (&new_bc_p, pattern_string_p, flags),
|
||||
ret_value);
|
||||
|
||||
|
||||
re_bytecode_t *old_bc_p = ECMA_GET_POINTER (re_bytecode_t,
|
||||
bc_prop_p->u.internal_property.value);
|
||||
re_compiled_code_t *old_bc_p = ECMA_GET_POINTER (re_compiled_code_t,
|
||||
bc_prop_p->u.internal_property.value);
|
||||
|
||||
if (old_bc_p != NULL)
|
||||
{
|
||||
/* Replace old bytecode with new one. */
|
||||
mem_heap_free_block (old_bc_p);
|
||||
/* Free the old bytecode */
|
||||
ecma_bytecode_deref ((ecma_compiled_code_t *) old_bc_p);
|
||||
}
|
||||
|
||||
ECMA_SET_POINTER (bc_prop_p->u.internal_property.value, new_bc_p);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
/* Copyright 2014-2016 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.
|
||||
@@ -271,7 +271,6 @@ ecma_finalize_builtins (void)
|
||||
if (ecma_builtin_objects[id] != NULL)
|
||||
{
|
||||
ecma_deref_object (ecma_builtin_objects[id]);
|
||||
|
||||
ecma_builtin_objects[id] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2015 Samsung Electronics Co., Ltd.
|
||||
/* Copyright 2015-2016 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.
|
||||
@@ -13,7 +13,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "bytecode-data.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-eval.h"
|
||||
@@ -93,17 +92,15 @@ ecma_op_eval_chars_buffer (const jerry_api_char_t *code_p, /**< code characters
|
||||
|
||||
ecma_completion_value_t completion;
|
||||
|
||||
const bytecode_data_header_t *bytecode_data_p;
|
||||
ecma_compiled_code_t *bytecode_data_p;
|
||||
jsp_status_t parse_status;
|
||||
|
||||
bool is_strict_call = (is_direct && is_called_from_strict_mode_code);
|
||||
|
||||
bool code_contains_functions;
|
||||
parse_status = parser_parse_eval (code_p,
|
||||
code_buffer_size,
|
||||
is_strict_call,
|
||||
&bytecode_data_p,
|
||||
&code_contains_functions);
|
||||
&bytecode_data_p);
|
||||
|
||||
if (parse_status == JSP_STATUS_SYNTAX_ERROR)
|
||||
{
|
||||
@@ -118,11 +115,6 @@ ecma_op_eval_chars_buffer (const jerry_api_char_t *code_p, /**< code characters
|
||||
JERRY_ASSERT (parse_status == JSP_STATUS_OK);
|
||||
|
||||
completion = vm_run_eval (bytecode_data_p, is_direct);
|
||||
|
||||
if (!code_contains_functions)
|
||||
{
|
||||
bc_remove_bytecode_data (bytecode_data_p);
|
||||
}
|
||||
}
|
||||
|
||||
return completion;
|
||||
|
||||
@@ -35,13 +35,13 @@
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_ERROR_COMMON, /**< Error */
|
||||
ECMA_ERROR_EVAL, /**< EvalError */
|
||||
ECMA_ERROR_RANGE, /**< RangeError */
|
||||
ECMA_ERROR_COMMON, /**< Error */
|
||||
ECMA_ERROR_EVAL, /**< EvalError */
|
||||
ECMA_ERROR_RANGE, /**< RangeError */
|
||||
ECMA_ERROR_REFERENCE, /**< ReferenceError */
|
||||
ECMA_ERROR_SYNTAX, /**< SyntaxError */
|
||||
ECMA_ERROR_TYPE, /**< TypeError */
|
||||
ECMA_ERROR_URI /**< URIError */
|
||||
ECMA_ERROR_SYNTAX, /**< SyntaxError */
|
||||
ECMA_ERROR_TYPE, /**< TypeError */
|
||||
ECMA_ERROR_URI /**< URIError */
|
||||
} ecma_standard_error_t;
|
||||
|
||||
extern ecma_object_t *ecma_new_standard_error (ecma_standard_error_t);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2016 University of Szeged.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,7 +14,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "bytecode-data.h"
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-builtin-helpers.h"
|
||||
#include "ecma-builtins.h"
|
||||
@@ -37,93 +37,6 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Pack 'is_strict', 'do_instantiate_arguments_object' flags and instruction position to value
|
||||
* that can be stored in an [[Code]] internal property.
|
||||
*
|
||||
* @return packed value
|
||||
*/
|
||||
static uint32_t
|
||||
ecma_pack_code_internal_property_value (bool is_strict, /**< is code strict? */
|
||||
bool do_instantiate_args_obj, /**< should an Arguments object be
|
||||
* instantiated for the code */
|
||||
bool is_arguments_moved_to_regs, /**< values of the function's arguments
|
||||
* are placed on registers */
|
||||
bool is_no_lex_env, /**< the function needs no lexical environment */
|
||||
vm_instr_counter_t instr_oc) /**< position of first instruction */
|
||||
{
|
||||
uint32_t value = instr_oc;
|
||||
const uint32_t is_strict_bit_offset = (uint32_t) (sizeof (value) * JERRY_BITSINBYTE - 1);
|
||||
const uint32_t do_instantiate_arguments_object_bit_offset = (uint32_t) (sizeof (value) * JERRY_BITSINBYTE - 2);
|
||||
const uint32_t arguments_moved_to_regs_bit_offset = (uint32_t) (sizeof (value) * JERRY_BITSINBYTE - 3);
|
||||
const uint32_t no_lex_env_bit_offset = (uint32_t) (sizeof (value) * JERRY_BITSINBYTE - 4);
|
||||
|
||||
JERRY_ASSERT (((value) & (1u << is_strict_bit_offset)) == 0);
|
||||
JERRY_ASSERT (((value) & (1u << do_instantiate_arguments_object_bit_offset)) == 0);
|
||||
JERRY_ASSERT (((value) & (1u << arguments_moved_to_regs_bit_offset)) == 0);
|
||||
JERRY_ASSERT (((value) & (1u << no_lex_env_bit_offset)) == 0);
|
||||
|
||||
if (is_strict)
|
||||
{
|
||||
value |= (1u << is_strict_bit_offset);
|
||||
}
|
||||
|
||||
if (do_instantiate_args_obj)
|
||||
{
|
||||
value |= (1u << do_instantiate_arguments_object_bit_offset);
|
||||
}
|
||||
|
||||
if (is_arguments_moved_to_regs)
|
||||
{
|
||||
value |= (1u << arguments_moved_to_regs_bit_offset);
|
||||
}
|
||||
|
||||
if (is_no_lex_env)
|
||||
{
|
||||
value |= (1u << no_lex_env_bit_offset);
|
||||
}
|
||||
|
||||
return value;
|
||||
} /* ecma_pack_code_internal_property_value */
|
||||
|
||||
/**
|
||||
* Unpack 'is_strict', 'do_instantiate_arguments_object' flags and instruction position from value
|
||||
* that can be stored in an [[Code]] internal property.
|
||||
*
|
||||
* @return instruction position
|
||||
*/
|
||||
static vm_instr_counter_t
|
||||
ecma_unpack_code_internal_property_value (uint32_t value, /**< packed value */
|
||||
bool* out_is_strict_p, /**< out: is code strict? */
|
||||
bool* out_do_instantiate_args_obj_p, /**< should an Arguments object be
|
||||
* instantiated for the code */
|
||||
bool* out_is_arguments_moved_to_regs_p, /**< values of the function's
|
||||
* arguments are placed
|
||||
* on registers */
|
||||
bool* out_is_no_lex_env_p) /**< the function needs no lexical environment */
|
||||
{
|
||||
JERRY_ASSERT (out_is_strict_p != NULL);
|
||||
JERRY_ASSERT (out_do_instantiate_args_obj_p != NULL);
|
||||
JERRY_ASSERT (out_is_arguments_moved_to_regs_p != NULL);
|
||||
JERRY_ASSERT (out_is_no_lex_env_p != NULL);
|
||||
|
||||
const uint32_t is_strict_bit_offset = (uint32_t) (sizeof (value) * JERRY_BITSINBYTE - 1);
|
||||
const uint32_t do_instantiate_arguments_object_bit_offset = (uint32_t) (sizeof (value) * JERRY_BITSINBYTE - 2);
|
||||
const uint32_t is_arguments_moved_to_regs_bit_offset = (uint32_t) (sizeof (value) * JERRY_BITSINBYTE - 3);
|
||||
const uint32_t is_no_lex_env_bit_offset = (uint32_t) (sizeof (value) * JERRY_BITSINBYTE - 4);
|
||||
|
||||
*out_is_strict_p = ((value & (1u << is_strict_bit_offset)) != 0);
|
||||
*out_do_instantiate_args_obj_p = ((value & (1u << do_instantiate_arguments_object_bit_offset)) != 0);
|
||||
*out_is_arguments_moved_to_regs_p = ((value & (1u << is_arguments_moved_to_regs_bit_offset)) != 0);
|
||||
*out_is_no_lex_env_p = ((value & (1u << is_no_lex_env_bit_offset)) != 0);
|
||||
value &= ~((1u << is_strict_bit_offset)
|
||||
| (1u << do_instantiate_arguments_object_bit_offset)
|
||||
| (1u << is_arguments_moved_to_regs_bit_offset)
|
||||
| (1u << is_no_lex_env_bit_offset));
|
||||
|
||||
return (vm_instr_counter_t) value;
|
||||
} /* ecma_unpack_code_internal_property_value */
|
||||
|
||||
/**
|
||||
* IsCallable operation.
|
||||
*
|
||||
@@ -238,49 +151,17 @@ ecma_function_bind_merge_arg_lists (ecma_object_t *func_obj_p, /**< Function obj
|
||||
* @return pointer to newly created Function object
|
||||
*/
|
||||
ecma_object_t*
|
||||
ecma_op_create_function_object (ecma_collection_header_t *formal_params_collection_p, /**< formal parameters collection
|
||||
* Warning:
|
||||
* the collection should not
|
||||
* be changed / used / freed
|
||||
* by caller after passing it
|
||||
* to the routine */
|
||||
ecma_object_t *scope_p, /**< function's scope */
|
||||
ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
|
||||
bool is_decl_in_strict_mode, /**< is function declared in strict mode code? */
|
||||
const bytecode_data_header_t *bytecode_header_p, /**< byte-code */
|
||||
vm_instr_counter_t first_instr_pos) /**< position of first instruction
|
||||
* of function's body */
|
||||
const ecma_compiled_code_t *bytecode_data_p) /**< byte-code array */
|
||||
{
|
||||
bool is_strict_mode_code = is_decl_in_strict_mode;
|
||||
bool do_instantiate_arguments_object = true;
|
||||
bool is_arguments_moved_to_regs = false;
|
||||
bool is_no_lex_env = false;
|
||||
|
||||
vm_instr_counter_t instr_pos = first_instr_pos;
|
||||
|
||||
if (bytecode_header_p->is_strict)
|
||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE)
|
||||
{
|
||||
is_strict_mode_code = true;
|
||||
}
|
||||
|
||||
if (!bytecode_header_p->is_ref_arguments_identifier
|
||||
&& !bytecode_header_p->is_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;
|
||||
}
|
||||
|
||||
if (bytecode_header_p->is_args_moved_to_regs)
|
||||
{
|
||||
is_arguments_moved_to_regs = true;
|
||||
}
|
||||
|
||||
if (bytecode_header_p->is_no_lex_env)
|
||||
{
|
||||
is_no_lex_env = true;
|
||||
}
|
||||
|
||||
// 1., 4., 13.
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
|
||||
|
||||
@@ -306,25 +187,12 @@ ecma_op_create_function_object (ecma_collection_header_t *formal_params_collecti
|
||||
ecma_property_t *scope_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_SCOPE);
|
||||
ECMA_SET_POINTER (scope_prop_p->u.internal_property.value, scope_p);
|
||||
|
||||
// 10., 11.
|
||||
if (formal_params_collection_p != NULL
|
||||
&& formal_params_collection_p->unit_number != 0)
|
||||
{
|
||||
ecma_property_t *formal_params_prop_p = ecma_create_internal_property (f,
|
||||
ECMA_INTERNAL_PROPERTY_FORMAL_PARAMETERS);
|
||||
ECMA_SET_POINTER (formal_params_prop_p->u.internal_property.value, formal_params_collection_p);
|
||||
}
|
||||
|
||||
// 10.
|
||||
// 11.
|
||||
// 12.
|
||||
ecma_property_t *bytecode_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE);
|
||||
MEM_CP_SET_NON_NULL_POINTER (bytecode_prop_p->u.internal_property.value, bytecode_header_p);
|
||||
|
||||
ecma_property_t *code_prop_p = ecma_create_internal_property (f, ECMA_INTERNAL_PROPERTY_CODE_FLAGS_AND_OFFSET);
|
||||
code_prop_p->u.internal_property.value = ecma_pack_code_internal_property_value (is_strict_mode_code,
|
||||
do_instantiate_arguments_object,
|
||||
is_arguments_moved_to_regs,
|
||||
is_no_lex_env,
|
||||
instr_pos);
|
||||
MEM_CP_SET_NON_NULL_POINTER (bytecode_prop_p->u.internal_property.value, bytecode_data_p);
|
||||
ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p);
|
||||
|
||||
// 14.
|
||||
// 15.
|
||||
@@ -446,37 +314,20 @@ ecma_op_function_try_lazy_instantiate_property (ecma_object_t *obj_p, /**< the f
|
||||
// 14
|
||||
ecma_number_t *len_p = ecma_alloc_number ();
|
||||
|
||||
ecma_property_t *formal_parameters_prop_p = ecma_find_internal_property (obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_FORMAL_PARAMETERS);
|
||||
if (formal_parameters_prop_p == NULL)
|
||||
ecma_property_t *bytecode_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE);
|
||||
|
||||
const ecma_compiled_code_t *bytecode_data_p;
|
||||
bytecode_data_p = MEM_CP_GET_POINTER (const ecma_compiled_code_t, bytecode_prop_p->u.internal_property.value);
|
||||
|
||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
ecma_property_t *bytecode_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE);
|
||||
ecma_property_t *code_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CODE_FLAGS_AND_OFFSET);
|
||||
|
||||
uint32_t code_prop_value = code_prop_p->u.internal_property.value;
|
||||
|
||||
bool is_strict;
|
||||
bool do_instantiate_args_obj;
|
||||
bool is_arguments_moved_to_regs;
|
||||
bool is_no_lex_env;
|
||||
|
||||
const bytecode_data_header_t *bytecode_header_p;
|
||||
bytecode_header_p = MEM_CP_GET_POINTER (const bytecode_data_header_t, bytecode_prop_p->u.internal_property.value);
|
||||
|
||||
vm_instr_counter_t code_first_instr_pos = ecma_unpack_code_internal_property_value (code_prop_value,
|
||||
&is_strict,
|
||||
&do_instantiate_args_obj,
|
||||
&is_arguments_moved_to_regs,
|
||||
&is_no_lex_env);
|
||||
|
||||
*len_p = vm_get_scope_args_num (bytecode_header_p, code_first_instr_pos);
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p;
|
||||
*len_p = args_p->argument_end;
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_collection_header_t *formal_parameters_p;
|
||||
formal_parameters_p = ECMA_GET_NON_NULL_POINTER (ecma_collection_header_t,
|
||||
formal_parameters_prop_p->u.internal_property.value);
|
||||
*len_p = ecma_uint32_to_number (formal_parameters_p->unit_number);
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p;
|
||||
*len_p = args_p->argument_end;
|
||||
}
|
||||
|
||||
// 15
|
||||
@@ -619,154 +470,6 @@ ecma_op_create_external_function_object (ecma_external_pointer_t code_p) /**< po
|
||||
return function_obj_p;
|
||||
} /* ecma_op_create_external_function_object */
|
||||
|
||||
/**
|
||||
* Setup variables for arguments listed in formal parameter list,
|
||||
* and, if necessary, Arguments object with 'arguments' binding.
|
||||
*
|
||||
* See also:
|
||||
* Declaration binding instantiation (ECMA-262 v5, 10.5), block 4 and 7
|
||||
*
|
||||
* @return completion value
|
||||
* Returned value must be freed with ecma_free_completion_value
|
||||
*/
|
||||
static ecma_completion_value_t
|
||||
ecma_function_call_setup_args_variables (ecma_object_t *func_obj_p, /**< Function object */
|
||||
ecma_object_t *env_p, /**< lexical environment */
|
||||
ecma_collection_header_t *arg_collection_p, /**< arguments collection */
|
||||
bool is_strict, /**< flag indicating strict mode */
|
||||
bool do_instantiate_arguments_object) /**< flag indicating whether
|
||||
* Arguments object should be
|
||||
* instantiated */
|
||||
{
|
||||
ecma_collection_header_t *formal_parameters_p = NULL;
|
||||
|
||||
ecma_property_t *formal_parameters_prop_p = ecma_find_internal_property (func_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_FORMAL_PARAMETERS);
|
||||
|
||||
if (formal_parameters_prop_p != NULL)
|
||||
{
|
||||
formal_parameters_p = ECMA_GET_POINTER (ecma_collection_header_t,
|
||||
formal_parameters_prop_p->u.internal_property.value);
|
||||
|
||||
ecma_length_t formal_parameters_count = formal_parameters_p->unit_number;
|
||||
|
||||
ecma_collection_iterator_t arguments_iterator, formal_params_iterator;
|
||||
|
||||
ecma_collection_iterator_init (&arguments_iterator, arg_collection_p);
|
||||
ecma_collection_iterator_init (&formal_params_iterator, formal_parameters_p);
|
||||
|
||||
/*
|
||||
* Formal parameter list is stored in reversed order
|
||||
*
|
||||
* Although, specification defines ascending order of formal parameters list enumeration,
|
||||
* implementation enumerates the parameters in descending order.
|
||||
*
|
||||
* In the case, redundant SetMutableBinding invocation could be avoided.
|
||||
*/
|
||||
for (ecma_length_t n = 0;
|
||||
n < formal_parameters_count;
|
||||
n++)
|
||||
{
|
||||
ecma_value_t arg_value;
|
||||
if (ecma_collection_iterator_next (&arguments_iterator))
|
||||
{
|
||||
arg_value = *arguments_iterator.current_value_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
arg_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
}
|
||||
|
||||
bool is_moved = ecma_collection_iterator_next (&formal_params_iterator);
|
||||
JERRY_ASSERT (is_moved);
|
||||
|
||||
ecma_value_t formal_parameter_name_value = *formal_params_iterator.current_value_p;
|
||||
ecma_string_t *formal_parameter_name_string_p = ecma_get_string_from_value (formal_parameter_name_value);
|
||||
|
||||
bool arg_already_declared = ecma_op_has_binding (env_p, formal_parameter_name_string_p);
|
||||
if (!arg_already_declared)
|
||||
{
|
||||
ecma_completion_value_t completion = ecma_op_create_mutable_binding (env_p,
|
||||
formal_parameter_name_string_p,
|
||||
false);
|
||||
if (ecma_is_completion_value_throw (completion))
|
||||
{
|
||||
return completion;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_is_completion_value_empty (completion));
|
||||
}
|
||||
|
||||
ecma_completion_value_t completion = ecma_op_set_mutable_binding (env_p,
|
||||
formal_parameter_name_string_p,
|
||||
arg_value,
|
||||
is_strict);
|
||||
|
||||
if (ecma_is_completion_value_throw (completion))
|
||||
{
|
||||
return completion;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_is_completion_value_empty (completion));
|
||||
}
|
||||
}
|
||||
|
||||
if (do_instantiate_arguments_object)
|
||||
{
|
||||
/*
|
||||
* According to ECMA-262 v5, 10.5, the Arguments object should be instantiated
|
||||
* after instantiating declared functions, and only if there is no binding named 'arguments'
|
||||
* by that time.
|
||||
*
|
||||
* However, we can setup Arguments object and 'arguments' binding here, because:
|
||||
* - instantiation of Arguments object itself doesn't have any side effects;
|
||||
* - if 'arguments' is name of a declared function in current scope,
|
||||
* value of the binding would be overwritten, execution would proceed in correct state.
|
||||
* - declaration of function, named 'arguments', is considered to be unrecommended (and so, rare) case,
|
||||
* so instantiation of Arguments object here, in general, is supposed to not affect resource consumption
|
||||
* significantly.
|
||||
*/
|
||||
|
||||
ecma_string_t *arguments_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS);
|
||||
|
||||
bool binding_already_declared = ecma_op_has_binding (env_p, arguments_string_p);
|
||||
|
||||
if (!binding_already_declared)
|
||||
{
|
||||
ecma_object_t *args_obj_p = ecma_op_create_arguments_object (func_obj_p,
|
||||
env_p,
|
||||
formal_parameters_p,
|
||||
arg_collection_p,
|
||||
is_strict);
|
||||
|
||||
if (is_strict)
|
||||
{
|
||||
ecma_op_create_immutable_binding (env_p, arguments_string_p);
|
||||
ecma_op_initialize_immutable_binding (env_p, arguments_string_p, ecma_make_object_value (args_obj_p));
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_completion_value_t completion = ecma_op_create_mutable_binding (env_p,
|
||||
arguments_string_p,
|
||||
false);
|
||||
JERRY_ASSERT (ecma_is_completion_value_empty (completion));
|
||||
|
||||
completion = ecma_op_set_mutable_binding (env_p,
|
||||
arguments_string_p,
|
||||
ecma_make_object_value (args_obj_p),
|
||||
false);
|
||||
JERRY_ASSERT (ecma_is_completion_value_empty (completion));
|
||||
}
|
||||
|
||||
ecma_deref_object (args_obj_p);
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (arguments_string_p);
|
||||
}
|
||||
|
||||
return ecma_make_empty_completion_value ();
|
||||
} /* ecma_function_call_setup_args_variables */
|
||||
|
||||
/**
|
||||
* [[Call]] implementation for Function objects,
|
||||
* created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION)
|
||||
@@ -869,27 +572,116 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object *
|
||||
ecma_completion_value_t
|
||||
ecma_op_function_call_array_args (ecma_object_t *func_obj_p, /**< Function object */
|
||||
ecma_value_t this_arg_value, /**< 'this' argument's value */
|
||||
const ecma_value_t* arguments_list_p, /**< arguments list */
|
||||
const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
ecma_length_t arguments_list_len) /**< length of arguments list */
|
||||
{
|
||||
if (arguments_list_len == 0)
|
||||
{
|
||||
return ecma_op_function_call (func_obj_p, this_arg_value, NULL);
|
||||
}
|
||||
else
|
||||
|
||||
if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION
|
||||
&& !ecma_get_object_is_builtin (func_obj_p))
|
||||
{
|
||||
ecma_collection_header_t *arg_collection_p = ecma_new_values_collection (arguments_list_p,
|
||||
arguments_list_len,
|
||||
true);
|
||||
/* Fast call. */
|
||||
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
|
||||
|
||||
ecma_completion_value_t ret_value = ecma_op_function_call (func_obj_p,
|
||||
this_arg_value,
|
||||
arg_collection_p);
|
||||
/* Entering Function Code (ECMA-262 v5, 10.4.3) */
|
||||
ecma_property_t *scope_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_SCOPE);
|
||||
ecma_property_t *bytecode_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE);
|
||||
|
||||
ecma_free_values_collection (arg_collection_p, true);
|
||||
ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t,
|
||||
scope_prop_p->u.internal_property.value);
|
||||
|
||||
// 8.
|
||||
ecma_value_t this_binding;
|
||||
bool is_strict;
|
||||
bool is_no_lex_env;
|
||||
|
||||
const ecma_compiled_code_t *bytecode_data_p;
|
||||
bytecode_data_p = MEM_CP_GET_POINTER (const ecma_compiled_code_t,
|
||||
bytecode_prop_p->u.internal_property.value);
|
||||
|
||||
is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) ? true : false;
|
||||
is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) ? true : false;
|
||||
|
||||
// 1.
|
||||
if (is_strict)
|
||||
{
|
||||
this_binding = ecma_copy_value (this_arg_value, true);
|
||||
}
|
||||
else if (ecma_is_value_undefined (this_arg_value)
|
||||
|| ecma_is_value_null (this_arg_value))
|
||||
{
|
||||
// 2.
|
||||
this_binding = ecma_make_object_value (ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 3., 4.
|
||||
ecma_completion_value_t completion = ecma_op_to_object (this_arg_value);
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal (completion));
|
||||
|
||||
this_binding = ecma_get_completion_value_value (completion);
|
||||
}
|
||||
|
||||
// 5.
|
||||
ecma_object_t *local_env_p;
|
||||
if (is_no_lex_env)
|
||||
{
|
||||
local_env_p = scope_p;
|
||||
}
|
||||
else
|
||||
{
|
||||
local_env_p = ecma_create_decl_lex_env (scope_p);
|
||||
|
||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_ARGUMENTS_NEEDED)
|
||||
{
|
||||
ecma_op_create_arguments_object_array_args (func_obj_p,
|
||||
local_env_p,
|
||||
arguments_list_p,
|
||||
arguments_list_len,
|
||||
bytecode_data_p);
|
||||
}
|
||||
}
|
||||
|
||||
ecma_completion_value_t completion = vm_run_array_args (bytecode_data_p,
|
||||
this_binding,
|
||||
local_env_p,
|
||||
false,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
|
||||
if (ecma_is_completion_value_return (completion))
|
||||
{
|
||||
ret_value = ecma_make_normal_completion_value (ecma_get_completion_value_value (completion));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = completion;
|
||||
}
|
||||
|
||||
if (!is_no_lex_env)
|
||||
{
|
||||
ecma_deref_object (local_env_p);
|
||||
}
|
||||
|
||||
ecma_free_value (this_binding, true);
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
/* Slow call. */
|
||||
|
||||
ecma_collection_header_t *arg_collection_p = ecma_new_values_collection (arguments_list_p,
|
||||
arguments_list_len,
|
||||
true);
|
||||
|
||||
ecma_completion_value_t ret_value = ecma_op_function_call (func_obj_p,
|
||||
this_arg_value,
|
||||
arg_collection_p);
|
||||
|
||||
ecma_free_values_collection (arg_collection_p, true);
|
||||
return ret_value;
|
||||
} /* ecma_op_function_call_array_args */
|
||||
|
||||
/**
|
||||
@@ -926,29 +718,21 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
|
||||
/* Entering Function Code (ECMA-262 v5, 10.4.3) */
|
||||
ecma_property_t *scope_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_SCOPE);
|
||||
ecma_property_t *bytecode_prop_p = ecma_get_internal_property (func_obj_p, ECMA_INTERNAL_PROPERTY_CODE_BYTECODE);
|
||||
ecma_property_t *code_prop_p = ecma_get_internal_property (func_obj_p,
|
||||
ECMA_INTERNAL_PROPERTY_CODE_FLAGS_AND_OFFSET);
|
||||
|
||||
ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t,
|
||||
scope_prop_p->u.internal_property.value);
|
||||
uint32_t code_prop_value = code_prop_p->u.internal_property.value;
|
||||
|
||||
// 8.
|
||||
ecma_value_t this_binding;
|
||||
bool is_strict;
|
||||
bool do_instantiate_args_obj;
|
||||
bool is_arguments_moved_to_regs;
|
||||
bool is_no_lex_env;
|
||||
|
||||
const bytecode_data_header_t *bytecode_data_p;
|
||||
bytecode_data_p = MEM_CP_GET_POINTER (const bytecode_data_header_t, bytecode_prop_p->u.internal_property.value);
|
||||
const ecma_compiled_code_t *bytecode_data_p;
|
||||
bytecode_data_p = MEM_CP_GET_POINTER (const ecma_compiled_code_t, bytecode_prop_p->u.internal_property.value);
|
||||
|
||||
vm_instr_counter_t code_first_instr_pos = ecma_unpack_code_internal_property_value (code_prop_value,
|
||||
&is_strict,
|
||||
&do_instantiate_args_obj,
|
||||
&is_arguments_moved_to_regs,
|
||||
&is_no_lex_env);
|
||||
is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) ? true : false;
|
||||
is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) ? true : false;
|
||||
|
||||
ecma_value_t this_binding;
|
||||
// 1.
|
||||
if (is_strict)
|
||||
{
|
||||
@@ -978,63 +762,32 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
|
||||
else
|
||||
{
|
||||
local_env_p = ecma_create_decl_lex_env (scope_p);
|
||||
|
||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_ARGUMENTS_NEEDED)
|
||||
{
|
||||
ecma_op_create_arguments_object (func_obj_p,
|
||||
local_env_p,
|
||||
arg_collection_p,
|
||||
bytecode_data_p);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_arguments_moved_to_regs)
|
||||
{
|
||||
ecma_completion_value_t completion = vm_run_from_pos (bytecode_data_p,
|
||||
code_first_instr_pos,
|
||||
this_binding,
|
||||
local_env_p,
|
||||
is_strict,
|
||||
false,
|
||||
arg_collection_p);
|
||||
ecma_completion_value_t completion = vm_run (bytecode_data_p,
|
||||
this_binding,
|
||||
local_env_p,
|
||||
false,
|
||||
arg_collection_p);
|
||||
|
||||
if (ecma_is_completion_value_return (completion))
|
||||
{
|
||||
ret_value = ecma_make_normal_completion_value (ecma_get_completion_value_value (completion));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = completion;
|
||||
}
|
||||
if (ecma_is_completion_value_return (completion))
|
||||
{
|
||||
ret_value = ecma_make_normal_completion_value (ecma_get_completion_value_value (completion));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 9.
|
||||
ECMA_TRY_CATCH (args_var_declaration_ret,
|
||||
ecma_function_call_setup_args_variables (func_obj_p,
|
||||
local_env_p,
|
||||
arg_collection_p,
|
||||
is_strict,
|
||||
do_instantiate_args_obj),
|
||||
ret_value);
|
||||
|
||||
ecma_completion_value_t completion = vm_run_from_pos (bytecode_data_p,
|
||||
code_first_instr_pos,
|
||||
this_binding,
|
||||
local_env_p,
|
||||
is_strict,
|
||||
false,
|
||||
NULL);
|
||||
|
||||
if (ecma_is_completion_value_return (completion))
|
||||
{
|
||||
ret_value = ecma_make_normal_completion_value (ecma_get_completion_value_value (completion));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret_value = completion;
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (args_var_declaration_ret);
|
||||
ret_value = completion;
|
||||
}
|
||||
|
||||
if (is_no_lex_env)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
else
|
||||
if (!is_no_lex_env)
|
||||
{
|
||||
ecma_deref_object (local_env_p);
|
||||
}
|
||||
@@ -1263,26 +1016,16 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
|
||||
ecma_completion_value_t
|
||||
ecma_op_function_declaration (ecma_object_t *lex_env_p, /**< lexical environment */
|
||||
ecma_string_t *function_name_p, /**< function name */
|
||||
const bytecode_data_header_t *bytecode_data_p, /**< byte-code data */
|
||||
vm_instr_counter_t function_first_instr_pos, /**< position of first instruction
|
||||
* of function code */
|
||||
ecma_collection_header_t *formal_params_collection_p, /**< formal parameters collection
|
||||
* Warning:
|
||||
* the collection should not
|
||||
* be changed / used / freed
|
||||
* by caller after passing it
|
||||
* to the routine */
|
||||
const ecma_compiled_code_t *bytecode_data_p, /**< bytecode data */
|
||||
bool is_decl_in_strict_mode, /**< flag, indicating if function is
|
||||
* declared in strict mode code */
|
||||
bool is_configurable_bindings) /**< flag indicating whether function
|
||||
* is declared in eval code */
|
||||
{
|
||||
// b.
|
||||
ecma_object_t *func_obj_p = ecma_op_create_function_object (formal_params_collection_p,
|
||||
lex_env_p,
|
||||
ecma_object_t *func_obj_p = ecma_op_create_function_object (lex_env_p,
|
||||
is_decl_in_strict_mode,
|
||||
bytecode_data_p,
|
||||
function_first_instr_pos);
|
||||
bytecode_data_p);
|
||||
|
||||
// c.
|
||||
bool func_already_declared = ecma_op_has_binding (lex_env_p, function_name_p);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
/* Copyright 2014-2016 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.
|
||||
@@ -30,8 +30,7 @@ extern bool ecma_op_is_callable (ecma_value_t);
|
||||
extern bool ecma_is_constructor (ecma_value_t);
|
||||
|
||||
extern ecma_object_t *
|
||||
ecma_op_create_function_object (ecma_collection_header_t *, ecma_object_t *,
|
||||
bool, const bytecode_data_header_t *, vm_instr_counter_t);
|
||||
ecma_op_create_function_object (ecma_object_t *, bool, const ecma_compiled_code_t *);
|
||||
|
||||
extern void
|
||||
ecma_op_function_list_lazy_property_names (bool,
|
||||
@@ -59,8 +58,8 @@ extern ecma_completion_value_t
|
||||
ecma_op_function_has_instance (ecma_object_t *, ecma_value_t);
|
||||
|
||||
extern ecma_completion_value_t
|
||||
ecma_op_function_declaration (ecma_object_t *, ecma_string_t *, const bytecode_data_header_t *, vm_instr_counter_t,
|
||||
ecma_collection_header_t *, bool, bool);
|
||||
ecma_op_function_declaration (ecma_object_t *, ecma_string_t *,
|
||||
const ecma_compiled_code_t *, bool, bool);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
/* Copyright 2014-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2016 University of Szeged.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -35,33 +36,24 @@
|
||||
#include "jrt.h"
|
||||
|
||||
/**
|
||||
* Arguments object creation operation.
|
||||
* Arguments object creation common part.
|
||||
*
|
||||
* See also: ECMA-262 v5, 10.6
|
||||
*
|
||||
* @return pointer to newly created Arguments object
|
||||
*/
|
||||
ecma_object_t*
|
||||
ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function */
|
||||
ecma_object_t *lex_env_p, /**< lexical environment the Arguments
|
||||
object is created for */
|
||||
ecma_collection_header_t *formal_params_p, /**< formal parameters collection */
|
||||
ecma_collection_header_t *arg_collection_p, /**< arguments collection */
|
||||
bool is_strict) /**< flag indicating whether strict mode is enabled */
|
||||
static void
|
||||
ecma_op_create_arguments_object_common (ecma_object_t *obj_p, /**< arguments object */
|
||||
ecma_object_t *func_obj_p, /**< callee function */
|
||||
ecma_object_t *lex_env_p, /**< lexical environment the Arguments
|
||||
object is created for */
|
||||
ecma_length_t arguments_number, /**< length of arguments list */
|
||||
const ecma_compiled_code_t *bytecode_data_p) /**< bytecode data */
|
||||
{
|
||||
const ecma_length_t arguments_number = arg_collection_p != NULL ? arg_collection_p->unit_number : 0;
|
||||
bool is_strict = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE) != 0;
|
||||
|
||||
// 1.
|
||||
ecma_number_t *len_p = ecma_alloc_number ();
|
||||
*len_p = ecma_uint32_to_number (arguments_number);
|
||||
|
||||
// 2., 3., 6.
|
||||
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (prototype_p, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
|
||||
ecma_deref_object (prototype_p);
|
||||
|
||||
// 4.
|
||||
ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
class_prop_p->u.internal_property.value = LIT_MAGIC_STRING_ARGUMENTS_UL;
|
||||
@@ -81,39 +73,29 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
||||
|
||||
ecma_dealloc_number (len_p);
|
||||
|
||||
// 11.a, 11.b
|
||||
ecma_collection_iterator_t args_iterator;
|
||||
ecma_collection_iterator_init (&args_iterator, arg_collection_p);
|
||||
|
||||
for (ecma_length_t indx = 0;
|
||||
indx < arguments_number;
|
||||
indx++)
|
||||
{
|
||||
bool is_moved = ecma_collection_iterator_next (&args_iterator);
|
||||
JERRY_ASSERT (is_moved);
|
||||
|
||||
ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 (indx);
|
||||
completion = ecma_builtin_helper_def_prop (obj_p,
|
||||
indx_string_p,
|
||||
*args_iterator.current_value_p,
|
||||
true, /* Writable */
|
||||
true, /* Enumerable */
|
||||
true, /* Configurable */
|
||||
false); /* Failure handling */
|
||||
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal_true (completion));
|
||||
|
||||
ecma_deref_ecma_string (indx_string_p);
|
||||
}
|
||||
|
||||
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
|
||||
|
||||
if (formal_params_p != NULL)
|
||||
if (bytecode_data_p != NULL)
|
||||
{
|
||||
const ecma_length_t formal_params_number = formal_params_p->unit_number;
|
||||
ecma_length_t formal_params_number;
|
||||
lit_cpointer_t *literal_p;
|
||||
|
||||
ecma_collection_iterator_t formal_params_iterator;
|
||||
ecma_collection_iterator_init (&formal_params_iterator, formal_params_p);
|
||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||
{
|
||||
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p;
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_data_p;
|
||||
|
||||
formal_params_number = args_p->argument_end;
|
||||
literal_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint16_arguments_t));
|
||||
}
|
||||
else
|
||||
{
|
||||
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p;
|
||||
uint8_t *byte_p = (uint8_t *) bytecode_data_p;
|
||||
|
||||
formal_params_number = args_p->argument_end;
|
||||
literal_p = (lit_cpointer_t *) (byte_p + sizeof (cbc_uint8_arguments_t));
|
||||
}
|
||||
|
||||
if (!is_strict
|
||||
&& arguments_number > 0
|
||||
@@ -123,68 +105,35 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
||||
ecma_object_t *map_p = ecma_op_create_object_object_noarg ();
|
||||
|
||||
// 11.c
|
||||
MEM_DEFINE_LOCAL_ARRAY (formal_params, formal_params_number, ecma_string_t *);
|
||||
|
||||
JERRY_ASSERT (formal_params_iterator.current_value_p == NULL);
|
||||
|
||||
uint32_t param_index;
|
||||
for (param_index = 0;
|
||||
ecma_collection_iterator_next (&formal_params_iterator);
|
||||
param_index++)
|
||||
{
|
||||
JERRY_ASSERT (formal_params_iterator.current_value_p != NULL);
|
||||
JERRY_ASSERT (param_index < formal_params_number);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_string (*formal_params_iterator.current_value_p));
|
||||
ecma_string_t *param_name_p = ecma_get_string_from_value (*formal_params_iterator.current_value_p);
|
||||
|
||||
formal_params[param_index] = param_name_p;
|
||||
}
|
||||
JERRY_ASSERT (param_index == formal_params_number);
|
||||
|
||||
for (int32_t indx = (int32_t) formal_params_number - 1;
|
||||
indx >= 0;
|
||||
indx--)
|
||||
for (uint32_t indx = 0;
|
||||
indx < formal_params_number;
|
||||
indx++)
|
||||
{
|
||||
// i.
|
||||
ecma_string_t *name_p = formal_params[indx];
|
||||
bool is_first_occurence = true;
|
||||
|
||||
// ii.
|
||||
for (int32_t indx2 = indx + 1;
|
||||
indx2 < (int32_t) formal_params_number;
|
||||
indx2++)
|
||||
if (literal_p[indx].packed_value == MEM_CP_NULL)
|
||||
{
|
||||
if (ecma_compare_ecma_strings (name_p, formal_params[indx2]))
|
||||
{
|
||||
is_first_occurence = false;
|
||||
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_first_occurence)
|
||||
{
|
||||
ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 ((uint32_t) indx);
|
||||
ecma_string_t *name_p = ecma_new_ecma_string_from_lit_cp (literal_p[indx]);
|
||||
ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 ((uint32_t) indx);
|
||||
|
||||
prop_desc.is_value_defined = true;
|
||||
prop_desc.value = ecma_make_string_value (name_p);
|
||||
prop_desc.is_value_defined = true;
|
||||
prop_desc.value = ecma_make_string_value (name_p);
|
||||
|
||||
prop_desc.is_configurable_defined = true;
|
||||
prop_desc.is_configurable = true;
|
||||
prop_desc.is_configurable_defined = true;
|
||||
prop_desc.is_configurable = true;
|
||||
|
||||
completion = ecma_op_object_define_own_property (map_p,
|
||||
indx_string_p,
|
||||
&prop_desc,
|
||||
false);
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal_true (completion));
|
||||
completion = ecma_op_object_define_own_property (map_p,
|
||||
indx_string_p,
|
||||
&prop_desc,
|
||||
false);
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal_true (completion));
|
||||
|
||||
ecma_deref_ecma_string (indx_string_p);
|
||||
}
|
||||
ecma_deref_ecma_string (indx_string_p);
|
||||
ecma_deref_ecma_string (name_p);
|
||||
}
|
||||
|
||||
MEM_FINALIZE_LOCAL_ARRAY (formal_params);
|
||||
|
||||
// 12.
|
||||
ecma_set_object_type (obj_p, ECMA_OBJECT_TYPE_ARGUMENTS);
|
||||
|
||||
@@ -264,9 +213,138 @@ ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function
|
||||
ecma_deref_object (thrower_p);
|
||||
}
|
||||
|
||||
return obj_p;
|
||||
ecma_string_t *arguments_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_ARGUMENTS);
|
||||
|
||||
if (is_strict)
|
||||
{
|
||||
ecma_op_create_immutable_binding (lex_env_p, arguments_string_p);
|
||||
ecma_op_initialize_immutable_binding (lex_env_p,
|
||||
arguments_string_p,
|
||||
ecma_make_object_value (obj_p));
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_completion_value_t completion = ecma_op_create_mutable_binding (lex_env_p,
|
||||
arguments_string_p,
|
||||
false);
|
||||
JERRY_ASSERT (ecma_is_completion_value_empty (completion));
|
||||
|
||||
completion = ecma_op_set_mutable_binding (lex_env_p,
|
||||
arguments_string_p,
|
||||
ecma_make_object_value (obj_p),
|
||||
false);
|
||||
|
||||
JERRY_ASSERT (ecma_is_completion_value_empty (completion));
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (arguments_string_p);
|
||||
ecma_deref_object (obj_p);
|
||||
} /* ecma_op_create_arguments_object_common */
|
||||
|
||||
/**
|
||||
* Arguments object creation operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 10.6
|
||||
*
|
||||
* @return pointer to newly created Arguments object
|
||||
*/
|
||||
void
|
||||
ecma_op_create_arguments_object (ecma_object_t *func_obj_p, /**< callee function */
|
||||
ecma_object_t *lex_env_p, /**< lexical environment the Arguments
|
||||
object is created for */
|
||||
ecma_collection_header_t *arg_collection_p, /**< arguments collection */
|
||||
const ecma_compiled_code_t *bytecode_data_p) /**< byte code */
|
||||
{
|
||||
const ecma_length_t arguments_number = arg_collection_p != NULL ? arg_collection_p->unit_number : 0;
|
||||
|
||||
// 2., 3., 6.
|
||||
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (prototype_p, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
|
||||
ecma_deref_object (prototype_p);
|
||||
|
||||
// 11.a, 11.b
|
||||
ecma_collection_iterator_t args_iterator;
|
||||
ecma_collection_iterator_init (&args_iterator, arg_collection_p);
|
||||
|
||||
for (ecma_length_t indx = 0;
|
||||
indx < arguments_number;
|
||||
indx++)
|
||||
{
|
||||
ecma_completion_value_t completion;
|
||||
bool is_moved = ecma_collection_iterator_next (&args_iterator);
|
||||
JERRY_ASSERT (is_moved);
|
||||
|
||||
ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 (indx);
|
||||
completion = ecma_builtin_helper_def_prop (obj_p,
|
||||
indx_string_p,
|
||||
*args_iterator.current_value_p,
|
||||
true, /* Writable */
|
||||
true, /* Enumerable */
|
||||
true, /* Configurable */
|
||||
false); /* Failure handling */
|
||||
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal_true (completion));
|
||||
|
||||
ecma_deref_ecma_string (indx_string_p);
|
||||
}
|
||||
|
||||
ecma_op_create_arguments_object_common (obj_p,
|
||||
func_obj_p,
|
||||
lex_env_p,
|
||||
arguments_number,
|
||||
bytecode_data_p);
|
||||
} /* ecma_op_create_arguments_object */
|
||||
|
||||
/**
|
||||
* Arguments object creation operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 10.6
|
||||
*/
|
||||
void
|
||||
ecma_op_create_arguments_object_array_args (ecma_object_t *func_obj_p, /**< callee function */
|
||||
ecma_object_t *lex_env_p, /**< lexical environment the Arguments
|
||||
object is created for */
|
||||
const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
ecma_length_t arguments_number, /**< length of arguments list */
|
||||
const ecma_compiled_code_t *bytecode_data_p) /**< byte code */
|
||||
{
|
||||
// 2., 3., 6.
|
||||
ecma_object_t *prototype_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (prototype_p, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
|
||||
ecma_deref_object (prototype_p);
|
||||
|
||||
// 11.a, 11.b
|
||||
for (ecma_length_t indx = 0;
|
||||
indx < arguments_number;
|
||||
indx++)
|
||||
{
|
||||
ecma_completion_value_t completion;
|
||||
ecma_string_t *indx_string_p = ecma_new_ecma_string_from_uint32 (indx);
|
||||
|
||||
completion = ecma_builtin_helper_def_prop (obj_p,
|
||||
indx_string_p,
|
||||
arguments_list_p[indx],
|
||||
true, /* Writable */
|
||||
true, /* Enumerable */
|
||||
true, /* Configurable */
|
||||
false); /* Failure handling */
|
||||
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal_true (completion));
|
||||
|
||||
ecma_deref_ecma_string (indx_string_p);
|
||||
}
|
||||
|
||||
ecma_op_create_arguments_object_common (obj_p,
|
||||
func_obj_p,
|
||||
lex_env_p,
|
||||
arguments_number,
|
||||
bytecode_data_p);
|
||||
} /* ecma_op_create_arguments_object_array_args */
|
||||
|
||||
/**
|
||||
* Get value of function's argument mapped to index of Arguments object.
|
||||
*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2014-2015 Samsung Electronics Co., Ltd.
|
||||
/* Copyright 2014-2016 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.
|
||||
@@ -19,9 +19,13 @@
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
|
||||
extern ecma_object_t *
|
||||
extern void
|
||||
ecma_op_create_arguments_object (ecma_object_t *, ecma_object_t *,
|
||||
ecma_collection_header_t *, ecma_collection_header_t *, bool);
|
||||
ecma_collection_header_t *, const ecma_compiled_code_t *);
|
||||
|
||||
extern void
|
||||
ecma_op_create_arguments_object_array_args (ecma_object_t *, ecma_object_t *, const ecma_value_t *,
|
||||
ecma_length_t, const ecma_compiled_code_t *);
|
||||
|
||||
extern ecma_completion_value_t
|
||||
ecma_op_arguments_object_get (ecma_object_t *, ecma_string_t *);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2015 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015 University of Szeged.
|
||||
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015-2016 University of Szeged.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -65,7 +65,7 @@
|
||||
*/
|
||||
ecma_completion_value_t
|
||||
re_parse_regexp_flags (ecma_string_t *flags_str_p, /**< Input string with flags */
|
||||
uint8_t *flags_p) /**< Output: parsed flag bits */
|
||||
uint16_t *flags_p) /**< Output: parsed flag bits */
|
||||
{
|
||||
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
|
||||
|
||||
@@ -129,7 +129,7 @@ re_parse_regexp_flags (ecma_string_t *flags_str_p, /**< Input string with flags
|
||||
void
|
||||
re_initialize_props (ecma_object_t *re_obj_p, /**< RegExp obejct */
|
||||
ecma_string_t *source_p, /**< source string */
|
||||
uint8_t flags) /**< flags */
|
||||
uint16_t flags) /**< flags */
|
||||
{
|
||||
/* Set source property. ECMA-262 v5, 15.10.7.1 */
|
||||
ecma_string_t *magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_SOURCE);
|
||||
@@ -218,6 +218,42 @@ re_initialize_props (ecma_object_t *re_obj_p, /**< RegExp obejct */
|
||||
ecma_dealloc_number (lastindex_num_p);
|
||||
} /* re_initialize_props */
|
||||
|
||||
/**
|
||||
* RegExp object creation operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 15.10.4.1
|
||||
*
|
||||
* @return completion value
|
||||
* Returned value must be freed with ecma_free_completion_value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_create_regexp_object_from_bytecode (re_compiled_code_t *bytecode_p) /**< input pattern */
|
||||
{
|
||||
JERRY_ASSERT (bytecode_p != NULL);
|
||||
|
||||
ecma_object_t *re_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE);
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (re_prototype_obj_p, true, ECMA_OBJECT_TYPE_GENERAL);
|
||||
ecma_deref_object (re_prototype_obj_p);
|
||||
|
||||
/* Set the internal [[Class]] property */
|
||||
ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS);
|
||||
class_prop_p->u.internal_property.value = LIT_MAGIC_STRING_REGEXP_UL;
|
||||
|
||||
/* Set bytecode internal property. */
|
||||
ecma_property_t *bytecode_prop_p;
|
||||
bytecode_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE);
|
||||
ECMA_SET_NON_NULL_POINTER (bytecode_prop_p->u.internal_property.value, bytecode_p);
|
||||
ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_p);
|
||||
|
||||
/* Initialize RegExp object properties */
|
||||
re_initialize_props (obj_p,
|
||||
ECMA_GET_NON_NULL_POINTER (ecma_string_t, bytecode_p->pattern_cp),
|
||||
bytecode_p->flags);
|
||||
|
||||
return ecma_make_object_value (obj_p);
|
||||
} /* ecma_op_create_regexp_object_from_bytecode */
|
||||
|
||||
/**
|
||||
* RegExp object creation operation.
|
||||
*
|
||||
@@ -232,7 +268,7 @@ ecma_op_create_regexp_object (ecma_string_t *pattern_p, /**< input pattern */
|
||||
{
|
||||
JERRY_ASSERT (pattern_p != NULL);
|
||||
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
|
||||
uint8_t flags = 0;
|
||||
uint16_t flags = 0;
|
||||
|
||||
if (flags_str_p != NULL)
|
||||
{
|
||||
@@ -261,7 +297,7 @@ ecma_op_create_regexp_object (ecma_string_t *pattern_p, /**< input pattern */
|
||||
bytecode_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE);
|
||||
|
||||
/* Compile bytecode. */
|
||||
re_bytecode_t *bc_p = NULL;
|
||||
re_compiled_code_t *bc_p = NULL;
|
||||
ECMA_TRY_CATCH (empty, re_compile_bytecode (&bc_p, pattern_p, flags), ret_value);
|
||||
|
||||
ECMA_SET_POINTER (bytecode_prop_p->u.internal_property.value, bc_p);
|
||||
@@ -336,7 +372,7 @@ re_canonicalize (ecma_char_t ch, /**< character */
|
||||
*/
|
||||
static ecma_completion_value_t
|
||||
re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
re_bytecode_t *bc_p, /**< pointer to the current RegExp bytecode */
|
||||
uint8_t *bc_p, /**< pointer to the current RegExp bytecode */
|
||||
lit_utf8_byte_t *str_p, /**< input string pointer */
|
||||
lit_utf8_byte_t **out_str_p) /**< Output: matching substring iterator */
|
||||
{
|
||||
@@ -651,7 +687,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
}
|
||||
case RE_OP_SAVE_AT_START:
|
||||
{
|
||||
re_bytecode_t *old_bc_p;
|
||||
uint8_t *old_bc_p;
|
||||
|
||||
JERRY_DDLOG ("Execute RE_OP_SAVE_AT_START\n");
|
||||
lit_utf8_byte_t *old_start_p = re_ctx_p->saved_p[RE_GLOBAL_START_IDX];
|
||||
@@ -717,7 +753,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
uint32_t start_idx, iter_idx, offset;
|
||||
lit_utf8_byte_t *old_start_p = NULL;
|
||||
lit_utf8_byte_t *sub_str_p = NULL;
|
||||
re_bytecode_t *old_bc_p;
|
||||
uint8_t *old_bc_p;
|
||||
|
||||
old_bc_p = bc_p; /* save the bytecode start position of the group start */
|
||||
start_idx = re_get_value (&bc_p);
|
||||
@@ -770,8 +806,8 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
{
|
||||
uint32_t start_idx, iter_idx, old_iteration_cnt, offset;
|
||||
lit_utf8_byte_t *sub_str_p = NULL;
|
||||
re_bytecode_t *old_bc_p;
|
||||
re_bytecode_t *end_bc_p = NULL;
|
||||
uint8_t *old_bc_p;
|
||||
uint8_t *end_bc_p = NULL;
|
||||
start_idx = re_get_value (&bc_p);
|
||||
|
||||
if (op != RE_OP_CAPTURE_GROUP_START
|
||||
@@ -844,7 +880,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
case RE_OP_NON_CAPTURE_NON_GREEDY_GROUP_END:
|
||||
{
|
||||
uint32_t end_idx, iter_idx, min, max;
|
||||
re_bytecode_t *old_bc_p;
|
||||
uint8_t *old_bc_p;
|
||||
|
||||
/*
|
||||
* On non-greedy iterations we have to execute the bytecode
|
||||
@@ -904,7 +940,7 @@ re_match_regexp (re_matcher_ctx_t *re_ctx_p, /**< RegExp matcher context */
|
||||
lit_utf8_byte_t *old_start_p = NULL;
|
||||
lit_utf8_byte_t *old_end_p = NULL;
|
||||
lit_utf8_byte_t *sub_str_p = NULL;
|
||||
re_bytecode_t *old_bc_p;
|
||||
uint8_t *old_bc_p;
|
||||
|
||||
end_idx = re_get_value (&bc_p);
|
||||
min = re_get_value (&bc_p);
|
||||
@@ -1217,7 +1253,8 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */
|
||||
|
||||
ecma_property_t *bytecode_prop_p = ecma_get_internal_property (regexp_object_p,
|
||||
ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE);
|
||||
re_bytecode_t *bc_p = ECMA_GET_POINTER (re_bytecode_t, bytecode_prop_p->u.internal_property.value);
|
||||
re_compiled_code_t *bc_p = ECMA_GET_POINTER (re_compiled_code_t,
|
||||
bytecode_prop_p->u.internal_property.value);
|
||||
|
||||
ecma_string_t *input_string_p = ecma_get_string_from_value (input_string);
|
||||
lit_utf8_size_t input_string_size = ecma_string_get_size (input_string_p);
|
||||
@@ -1240,11 +1277,11 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */
|
||||
re_ctx.input_end_p = input_buffer_p + input_string_size;
|
||||
|
||||
/* 1. Read bytecode header and init regexp matcher context. */
|
||||
re_ctx.flags = (uint8_t) re_get_value (&bc_p);
|
||||
re_ctx.flags = bc_p->flags;
|
||||
|
||||
if (ignore_global)
|
||||
{
|
||||
re_ctx.flags &= (uint8_t) ~RE_FLAG_GLOBAL;
|
||||
re_ctx.flags &= (uint16_t) ~RE_FLAG_GLOBAL;
|
||||
}
|
||||
|
||||
JERRY_DDLOG ("Exec with flags [global: %d, ignoreCase: %d, multiline: %d]\n",
|
||||
@@ -1252,10 +1289,9 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */
|
||||
re_ctx.flags & RE_FLAG_IGNORE_CASE,
|
||||
re_ctx.flags & RE_FLAG_MULTILINE);
|
||||
|
||||
re_ctx.num_of_captures = re_get_value (&bc_p);
|
||||
re_ctx.num_of_captures = bc_p->num_of_captures;
|
||||
JERRY_ASSERT (re_ctx.num_of_captures % 2 == 0);
|
||||
re_ctx.num_of_non_captures = re_get_value (&bc_p);
|
||||
|
||||
re_ctx.num_of_non_captures = bc_p->num_of_non_captures;
|
||||
|
||||
MEM_DEFINE_LOCAL_ARRAY (saved_p, re_ctx.num_of_captures + re_ctx.num_of_non_captures, lit_utf8_byte_t *);
|
||||
|
||||
@@ -1301,6 +1337,7 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */
|
||||
|
||||
/* 2. Try to match */
|
||||
lit_utf8_byte_t *sub_str_p = NULL;
|
||||
uint8_t *bc_start_p = (uint8_t *) (bc_p + 1);
|
||||
|
||||
while (ecma_is_completion_value_empty (ret_value))
|
||||
{
|
||||
@@ -1321,7 +1358,12 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */
|
||||
}
|
||||
else
|
||||
{
|
||||
ECMA_TRY_CATCH (match_value, re_match_regexp (&re_ctx, bc_p, input_curr_p, &sub_str_p), ret_value);
|
||||
ECMA_TRY_CATCH (match_value, re_match_regexp (&re_ctx,
|
||||
bc_start_p,
|
||||
input_curr_p,
|
||||
&sub_str_p),
|
||||
ret_value);
|
||||
|
||||
if (ecma_is_value_true (match_value))
|
||||
{
|
||||
is_match = true;
|
||||
@@ -1346,7 +1388,7 @@ ecma_regexp_exec_helper (ecma_value_t regexp_value, /**< RegExp object */
|
||||
if (sub_str_p)
|
||||
{
|
||||
*lastindex_num_p = lit_utf8_string_length (input_buffer_p,
|
||||
(lit_utf8_size_t) (sub_str_p - input_buffer_p));
|
||||
(lit_utf8_size_t) (sub_str_p - input_buffer_p));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Copyright 2015 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015 University of Szeged.
|
||||
/* Copyright 2015-2016 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2015-2016 University of Szeged.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -32,9 +32,9 @@
|
||||
/**
|
||||
* RegExp flags
|
||||
*/
|
||||
#define RE_FLAG_GLOBAL (1 << 0) /* ECMA-262 v5, 15.10.7.2 */
|
||||
#define RE_FLAG_IGNORE_CASE (1 << 1) /* ECMA-262 v5, 15.10.7.3 */
|
||||
#define RE_FLAG_MULTILINE (1 << 2) /* ECMA-262 v5, 15.10.7.4 */
|
||||
#define RE_FLAG_GLOBAL (1 << 1) /* ECMA-262 v5, 15.10.7.2 */
|
||||
#define RE_FLAG_IGNORE_CASE (1 << 2) /* ECMA-262 v5, 15.10.7.3 */
|
||||
#define RE_FLAG_MULTILINE (1 << 3) /* ECMA-262 v5, 15.10.7.4 */
|
||||
|
||||
/**
|
||||
* RegExp executor context
|
||||
@@ -47,9 +47,12 @@ typedef struct
|
||||
uint32_t num_of_captures; /**< number of capture groups */
|
||||
uint32_t num_of_non_captures; /**< number of non-capture groups */
|
||||
uint32_t *num_of_iterations_p; /**< number of iterations */
|
||||
uint8_t flags; /**< RegExp flags */
|
||||
uint16_t flags; /**< RegExp flags */
|
||||
} re_matcher_ctx_t;
|
||||
|
||||
extern ecma_value_t
|
||||
ecma_op_create_regexp_object_from_bytecode (re_compiled_code_t *);
|
||||
|
||||
extern ecma_completion_value_t
|
||||
ecma_op_create_regexp_object (ecma_string_t *, ecma_string_t *);
|
||||
|
||||
@@ -62,10 +65,10 @@ extern void
|
||||
re_set_result_array_properties (ecma_object_t *, ecma_string_t *, uint32_t, int32_t);
|
||||
|
||||
extern ecma_completion_value_t
|
||||
re_parse_regexp_flags (ecma_string_t *, uint8_t *);
|
||||
re_parse_regexp_flags (ecma_string_t *, uint16_t *);
|
||||
|
||||
extern void
|
||||
re_initialize_props (ecma_object_t *, ecma_string_t *, uint8_t);
|
||||
re_initialize_props (ecma_object_t *, ecma_string_t *, uint16_t);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
Reference in New Issue
Block a user