mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Implementing 'native_call' opcode handler.
This commit is contained in:
parent
bc2f827447
commit
05185bb2e9
@ -32,5 +32,8 @@
|
||||
bool is_reg_variable (int_data_t *int_data, idx_t var_idx);
|
||||
ecma_completion_value_t get_variable_value (int_data_t *, idx_t, bool);
|
||||
ecma_completion_value_t set_variable_value (int_data_t *, idx_t, ecma_value_t);
|
||||
|
||||
ecma_completion_value_t fill_varg_list (int_data_t *int_data,
|
||||
ecma_length_t args_number,
|
||||
ecma_value_t args_values[],
|
||||
ecma_length_t *out_arg_number_p);
|
||||
#endif /* OPCODES_ECMA_SUPPORT_H */
|
||||
|
||||
132
src/libcoreint/opcodes-native-call.c
Normal file
132
src/libcoreint/opcodes-native-call.c
Normal file
@ -0,0 +1,132 @@
|
||||
/* Copyright 2014 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "opcodes-ecma-support.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "interpreter.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
#include "opcodes-native-call.h"
|
||||
|
||||
#include "actuators.h"
|
||||
#include "common-io.h"
|
||||
#include "sensors.h"
|
||||
|
||||
/**
|
||||
* 'Native call' opcode handler.
|
||||
*/
|
||||
ecma_completion_value_t
|
||||
opfunc_native_call (opcode_t opdata, /**< operation data */
|
||||
int_data_t *int_data) /**< interpreter context */
|
||||
{
|
||||
// const idx_t dst_var_idx = opdata.data.native_call.lhs;
|
||||
const idx_t native_call_id_idx = opdata.data.native_call.name;
|
||||
const idx_t args_number = opdata.data.native_call.arg_list;
|
||||
|
||||
JERRY_STATIC_ASSERT (OPCODE_NATIVE_CALL__COUNT < (1u << (sizeof (native_call_id_idx) * JERRY_BITSINBYTE)));
|
||||
|
||||
ecma_value_t arg_values[args_number + 1 /* length of array should not be zero */];
|
||||
|
||||
ecma_completion_value_t ret_value;
|
||||
|
||||
ecma_length_t args_read;
|
||||
ecma_completion_value_t get_arg_completion = fill_varg_list (int_data,
|
||||
args_number,
|
||||
arg_values,
|
||||
&args_read);
|
||||
|
||||
if (ecma_is_empty_completion_value (get_arg_completion))
|
||||
{
|
||||
switch ((opcode_native_call_t)native_call_id_idx)
|
||||
{
|
||||
case OPCODE_NATIVE_CALL_LED_TOGGLE:
|
||||
{
|
||||
JERRY_ASSERT (args_number == 1);
|
||||
JERRY_ASSERT (arg_values[0].value_type == ECMA_TYPE_NUMBER);
|
||||
ecma_number_t* num_p = (ecma_number_t*) ECMA_GET_POINTER (arg_values[0].value);
|
||||
uint32_t int_num = ecma_number_to_uint32 (*num_p);
|
||||
led_toggle (int_num);
|
||||
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
break;
|
||||
}
|
||||
case OPCODE_NATIVE_CALL_LED_ON:
|
||||
{
|
||||
JERRY_ASSERT (args_number == 1);
|
||||
JERRY_ASSERT (arg_values[0].value_type == ECMA_TYPE_NUMBER);
|
||||
ecma_number_t* num_p = (ecma_number_t*) ECMA_GET_POINTER (arg_values[0].value);
|
||||
uint32_t int_num = ecma_number_to_uint32 (*num_p);
|
||||
led_on (int_num);
|
||||
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
break;
|
||||
}
|
||||
case OPCODE_NATIVE_CALL_LED_OFF:
|
||||
{
|
||||
JERRY_ASSERT (args_number == 1);
|
||||
JERRY_ASSERT (arg_values[0].value_type == ECMA_TYPE_NUMBER);
|
||||
ecma_number_t* num_p = (ecma_number_t*) ECMA_GET_POINTER (arg_values[0].value);
|
||||
uint32_t int_num = ecma_number_to_uint32 (*num_p);
|
||||
led_off (int_num);
|
||||
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
break;
|
||||
}
|
||||
case OPCODE_NATIVE_CALL_LED_ONCE:
|
||||
{
|
||||
JERRY_ASSERT (args_number == 1);
|
||||
JERRY_ASSERT (arg_values[0].value_type == ECMA_TYPE_NUMBER);
|
||||
ecma_number_t* num_p = (ecma_number_t*) ECMA_GET_POINTER (arg_values[0].value);
|
||||
uint32_t int_num = ecma_number_to_uint32 (*num_p);
|
||||
led_blink_once (int_num);
|
||||
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
break;
|
||||
}
|
||||
case OPCODE_NATIVE_CALL_WAIT:
|
||||
{
|
||||
JERRY_ASSERT (args_number == 1);
|
||||
JERRY_ASSERT (arg_values[0].value_type == ECMA_TYPE_NUMBER);
|
||||
ecma_number_t* num_p = (ecma_number_t*) ECMA_GET_POINTER (arg_values[0].value);
|
||||
uint32_t int_num = ecma_number_to_uint32 (*num_p);
|
||||
wait_ms (int_num);
|
||||
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
break;
|
||||
}
|
||||
|
||||
case OPCODE_NATIVE_CALL__COUNT:
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (!ecma_is_completion_value_normal (get_arg_completion));
|
||||
|
||||
ret_value = get_arg_completion;
|
||||
}
|
||||
|
||||
for (ecma_length_t arg_index = 0;
|
||||
arg_index < args_read;
|
||||
arg_index++)
|
||||
{
|
||||
ecma_free_value (arg_values[arg_index], true);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* opfunc_native_call */
|
||||
32
src/libcoreint/opcodes-native-call.h
Normal file
32
src/libcoreint/opcodes-native-call.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* Copyright 2014 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OPCODES_NATIVE_CALL_H
|
||||
#define OPCODES_NATIVE_CALL_H
|
||||
|
||||
/**
|
||||
* Identifier of a native call
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
OPCODE_NATIVE_CALL_LED_TOGGLE,
|
||||
OPCODE_NATIVE_CALL_LED_ON,
|
||||
OPCODE_NATIVE_CALL_LED_OFF,
|
||||
OPCODE_NATIVE_CALL_LED_ONCE,
|
||||
OPCODE_NATIVE_CALL_WAIT,
|
||||
OPCODE_NATIVE_CALL__COUNT
|
||||
} opcode_native_call_t;
|
||||
|
||||
#endif /* !OPCODES_NATIVE_CALL_H */
|
||||
110
src/libcoreint/opcodes-varg.c
Normal file
110
src/libcoreint/opcodes-varg.c
Normal file
@ -0,0 +1,110 @@
|
||||
/* Copyright 2014 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "opcodes-ecma-support.h"
|
||||
|
||||
#include "globals.h"
|
||||
#include "interpreter.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
/**
|
||||
* Fill arguments' list
|
||||
*
|
||||
* @return empty completion value if argument list was filled successfully,
|
||||
* otherwise - not normal completion value indicating completion type
|
||||
* of last expression evaluated
|
||||
*/
|
||||
ecma_completion_value_t
|
||||
fill_varg_list (int_data_t *int_data, /**< interpreter context */
|
||||
ecma_length_t args_number, /**< number of arguments */
|
||||
ecma_value_t arg_values[], /**< out: arguments' values */
|
||||
ecma_length_t *out_arg_number_p) /**< out: number of arguments
|
||||
successfully read */
|
||||
{
|
||||
ecma_completion_value_t get_arg_completion = ecma_make_empty_completion_value ();
|
||||
|
||||
ecma_length_t arg_index;
|
||||
for (arg_index = 0;
|
||||
arg_index < args_number;
|
||||
arg_index++)
|
||||
{
|
||||
opcode_t next_opcode = read_opcode (int_data->pos);
|
||||
if (next_opcode.op_idx == __op__idx_varg)
|
||||
{
|
||||
get_arg_completion = get_variable_value (int_data, next_opcode.data.varg.arg_lit_idx, false);
|
||||
if (unlikely (ecma_is_completion_value_throw (get_arg_completion)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal (get_arg_completion));
|
||||
arg_values[arg_index] = get_arg_completion.value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
get_arg_completion = run_int_loop (int_data);
|
||||
|
||||
if (get_arg_completion.type == ECMA_COMPLETION_TYPE_VARG)
|
||||
{
|
||||
arg_values[arg_index] = get_arg_completion.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int_data->pos++;
|
||||
}
|
||||
|
||||
*out_arg_number_p = arg_index;
|
||||
|
||||
if (get_arg_completion.type == ECMA_COMPLETION_TYPE_NORMAL
|
||||
|| get_arg_completion.type == ECMA_COMPLETION_TYPE_VARG)
|
||||
{
|
||||
/* values are copied to arg_values */
|
||||
return ecma_make_empty_completion_value ();
|
||||
}
|
||||
else
|
||||
{
|
||||
return get_arg_completion;
|
||||
}
|
||||
} /* fill_varg_list */
|
||||
|
||||
/**
|
||||
* 'varg' opcode handler
|
||||
*
|
||||
* @return completion value
|
||||
* Returned value must be freed with ecma_free_completion_value.
|
||||
*/
|
||||
ecma_completion_value_t
|
||||
opfunc_varg (opcode_t opdata, /**< operation data */
|
||||
int_data_t *int_data) /**< interpreter context */
|
||||
{
|
||||
const idx_t arg_lit_idx = opdata.data.varg.arg_lit_idx;
|
||||
|
||||
ecma_completion_value_t completion = get_variable_value (int_data,
|
||||
arg_lit_idx,
|
||||
false);
|
||||
|
||||
if (ecma_is_completion_value_normal (completion))
|
||||
{
|
||||
completion.type = ECMA_COMPLETION_TYPE_VARG;
|
||||
}
|
||||
|
||||
return completion;
|
||||
} /* opfunc_varg */
|
||||
@ -21,11 +21,6 @@
|
||||
#include "mem-heap.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
#include "actuators.h"
|
||||
#include "common-io.h"
|
||||
#include "sensors.h"
|
||||
#include "ecma-objects.h"
|
||||
|
||||
/**
|
||||
* Note:
|
||||
* The note describes exception handling in opcode handlers that perform operations,
|
||||
@ -49,75 +44,7 @@
|
||||
* 5. No other operations with opcode handler's 'return value' variable should be performed.
|
||||
*/
|
||||
|
||||
/**
|
||||
* String literal copy descriptor.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
ecma_char_t *str_p; /**< pointer to copied string literal */
|
||||
ecma_char_t literal_copy[32]; /**< buffer with string literal,
|
||||
if it is stored locally
|
||||
(i.e. not in the heap) */
|
||||
} string_literal_copy;
|
||||
|
||||
/**
|
||||
* Initialize string literal copy.
|
||||
*/
|
||||
static void
|
||||
init_string_literal_copy (idx_t idx, /**< literal identifier */
|
||||
string_literal_copy *str_lit_descr_p) /**< pointer to string literal copy descriptor */
|
||||
{
|
||||
JERRY_ASSERT (str_lit_descr_p != NULL);
|
||||
|
||||
ssize_t sz = try_get_string_by_idx (idx,
|
||||
str_lit_descr_p->literal_copy,
|
||||
sizeof (str_lit_descr_p->literal_copy));
|
||||
if (sz > 0)
|
||||
{
|
||||
str_lit_descr_p->str_p = str_lit_descr_p->literal_copy;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (sz < 0);
|
||||
|
||||
ssize_t req_sz = -sz;
|
||||
|
||||
str_lit_descr_p->str_p = mem_heap_alloc_block ((size_t) req_sz,
|
||||
MEM_HEAP_ALLOC_SHORT_TERM);
|
||||
|
||||
sz = try_get_string_by_idx (idx,
|
||||
str_lit_descr_p->str_p,
|
||||
req_sz);
|
||||
|
||||
JERRY_ASSERT (sz > 0);
|
||||
}
|
||||
} /* init_string_literal */
|
||||
|
||||
/**
|
||||
* Free string literal copy.
|
||||
*/
|
||||
static void
|
||||
free_string_literal_copy (string_literal_copy *str_lit_descr_p) /**< string literal copy descriptor */
|
||||
{
|
||||
JERRY_ASSERT (str_lit_descr_p != NULL);
|
||||
JERRY_ASSERT (str_lit_descr_p->str_p != NULL);
|
||||
|
||||
if (str_lit_descr_p->str_p == str_lit_descr_p->literal_copy)
|
||||
{
|
||||
/* copy is inside descriptor */
|
||||
}
|
||||
else
|
||||
{
|
||||
mem_heap_free_block (str_lit_descr_p->str_p);
|
||||
}
|
||||
|
||||
str_lit_descr_p->str_p = NULL;
|
||||
|
||||
return;
|
||||
} /* free_string_literal */
|
||||
|
||||
#define OP_UNIMPLEMENTED_LIST(op) \
|
||||
op (native_call) \
|
||||
op (array_decl) \
|
||||
op (prop) \
|
||||
op (prop_get_decl) \
|
||||
@ -152,125 +79,38 @@ opfunc_nop (opcode_t opdata __unused, /**< operation data */
|
||||
ecma_completion_value_t
|
||||
opfunc_call_1 (opcode_t opdata __unused, int_data_t *int_data)
|
||||
{
|
||||
ecma_completion_value_t ret_value;
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
const idx_t func_name_lit_idx = opdata.data.call_1.name_lit_idx;
|
||||
const idx_t lhs_var_idx = opdata.data.call_1.lhs;
|
||||
|
||||
int_data->pos++;
|
||||
|
||||
ecma_completion_value_t ret_value;
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
|
||||
ECMA_TRY_CATCH (func_value, get_variable_value (int_data, func_name_lit_idx, false), ret_value);
|
||||
ECMA_TRY_CATCH (arg_value, get_variable_value (int_data, opdata.data.call_1.arg1_lit_idx, false), ret_value);
|
||||
|
||||
|
||||
/**********************************************************/
|
||||
|
||||
FIXME (/* Native call, i.e. opfunc_native_call */);
|
||||
bool is_native_call = true;
|
||||
|
||||
string_literal_copy function_name;
|
||||
init_string_literal_copy (opdata.data.call_1.name_lit_idx, &function_name);
|
||||
|
||||
if (!__strcmp ((const char*) function_name.str_p, "LEDToggle"))
|
||||
if (!ecma_op_is_callable (func_value.value))
|
||||
{
|
||||
JERRY_ASSERT (arg_value.value.value_type == ECMA_TYPE_NUMBER);
|
||||
ecma_number_t * num_p = (ecma_number_t*) ECMA_GET_POINTER (arg_value.value.value);
|
||||
uint32_t int_num = (uint32_t) * num_p;
|
||||
led_toggle (int_num);
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
}
|
||||
else if (!__strcmp ((const char*) function_name.str_p, "LEDOn"))
|
||||
{
|
||||
JERRY_ASSERT (arg_value.value.value_type == ECMA_TYPE_NUMBER);
|
||||
ecma_number_t * num_p = (ecma_number_t*) ECMA_GET_POINTER (arg_value.value.value);
|
||||
uint32_t int_num = (uint32_t) * num_p;
|
||||
led_on (int_num);
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
}
|
||||
else if (!__strcmp ((const char*) function_name.str_p, "LEDOff"))
|
||||
{
|
||||
JERRY_ASSERT (arg_value.value.value_type == ECMA_TYPE_NUMBER);
|
||||
ecma_number_t * num_p = (ecma_number_t*) ECMA_GET_POINTER (arg_value.value.value);
|
||||
uint32_t int_num = (uint32_t) * num_p;
|
||||
led_off (int_num);
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
}
|
||||
else if (!__strcmp ((const char*) function_name.str_p, "LEDOnce"))
|
||||
{
|
||||
JERRY_ASSERT (arg_value.value.value_type == ECMA_TYPE_NUMBER);
|
||||
ecma_number_t * num_p = (ecma_number_t*) ECMA_GET_POINTER (arg_value.value.value);
|
||||
uint32_t int_num = (uint32_t) * num_p;
|
||||
led_blink_once (int_num);
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
}
|
||||
else if (!__strcmp ((const char*) function_name.str_p, "wait"))
|
||||
{
|
||||
JERRY_ASSERT (arg_value.value.value_type == ECMA_TYPE_NUMBER);
|
||||
ecma_number_t * num_p = (ecma_number_t*) ECMA_GET_POINTER (arg_value.value.value);
|
||||
uint32_t int_num = (uint32_t) * num_p;
|
||||
wait_ms (int_num);
|
||||
ret_value = ecma_make_empty_completion_value ();
|
||||
}
|
||||
else if (!__strcmp ((const char *) function_name.str_p, "exit"))
|
||||
{
|
||||
JERRY_ASSERT (arg_value.value.value_type == ECMA_TYPE_NUMBER);
|
||||
ecma_number_t * num_p = (ecma_number_t*) ECMA_GET_POINTER (arg_value.value.value);
|
||||
uint32_t int_num = (uint32_t) * num_p;
|
||||
ecma_value_t exit_status = ecma_make_simple_value (int_num == 0 ? ECMA_SIMPLE_VALUE_TRUE
|
||||
: ECMA_SIMPLE_VALUE_FALSE);
|
||||
ret_value = ecma_make_completion_value (ECMA_COMPLETION_TYPE_EXIT,
|
||||
exit_status,
|
||||
ECMA_TARGET_ID_RESERVED);
|
||||
ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
|
||||
}
|
||||
else
|
||||
{
|
||||
is_native_call = false;
|
||||
}
|
||||
ecma_object_t *func_obj_p = ECMA_GET_POINTER (func_value.value.value);
|
||||
|
||||
if (is_native_call)
|
||||
{
|
||||
#ifdef __TARGET_HOST_x64
|
||||
__printf ("%d::op_call_1:idx:%d:%d\t",
|
||||
int_data->pos,
|
||||
opdata.data.call_1.name_lit_idx,
|
||||
opdata.data.call_1.arg1_lit_idx);
|
||||
ECMA_TRY_CATCH (this_value, ecma_op_implicit_this_value (int_data->lex_env_p), ret_value);
|
||||
ECMA_FUNCTION_CALL (call_completion,
|
||||
ecma_op_function_call (func_obj_p, this_value.value, &arg_value.value, 1),
|
||||
ret_value);
|
||||
|
||||
__printf ("%s\n", function_name.str_p);
|
||||
#endif
|
||||
}
|
||||
ret_value = set_variable_value (int_data, lhs_var_idx, call_completion.value);
|
||||
|
||||
free_string_literal_copy (&function_name);
|
||||
|
||||
/**********************************************************/
|
||||
|
||||
|
||||
if (!is_native_call)
|
||||
{
|
||||
const idx_t func_name_lit_idx = opdata.data.call_1.name_lit_idx;
|
||||
const idx_t lhs_var_idx = opdata.data.call_1.lhs;
|
||||
|
||||
ECMA_TRY_CATCH (func_value, get_variable_value (int_data, func_name_lit_idx, false), ret_value);
|
||||
|
||||
if (!ecma_op_is_callable (func_value.value))
|
||||
{
|
||||
ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
|
||||
}
|
||||
else
|
||||
{
|
||||
ecma_object_t *func_obj_p = ECMA_GET_POINTER (func_value.value.value);
|
||||
|
||||
ECMA_TRY_CATCH (this_value, ecma_op_implicit_this_value (int_data->lex_env_p), ret_value);
|
||||
ECMA_FUNCTION_CALL (call_completion,
|
||||
ecma_op_function_call (func_obj_p, this_value.value, &arg_value.value, 1),
|
||||
ret_value);
|
||||
|
||||
ret_value = set_variable_value (int_data, lhs_var_idx, call_completion.value);
|
||||
|
||||
ECMA_FINALIZE (call_completion);
|
||||
ECMA_FINALIZE (this_value);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (func_value);
|
||||
ECMA_FINALIZE (call_completion);
|
||||
ECMA_FINALIZE (this_value);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE (arg_value);
|
||||
ECMA_FINALIZE (func_value);
|
||||
|
||||
return ret_value;
|
||||
}
|
||||
@ -909,72 +749,6 @@ opfunc_call_0 (opcode_t opdata, /**< operation data */
|
||||
return ret_value;
|
||||
} /* opfunc_call_0 */
|
||||
|
||||
/**
|
||||
* Fill arguments' list
|
||||
*
|
||||
* @return empty completion value if argument list was filled successfully,
|
||||
* otherwise - not normal completion value indicating completion type
|
||||
* of last expression evaluated
|
||||
*/
|
||||
static ecma_completion_value_t
|
||||
fill_varg_list (int_data_t *int_data, /**< interpreter context */
|
||||
ecma_length_t args_number, /**< number of arguments */
|
||||
ecma_value_t arg_values[], /**< out: arguments' values */
|
||||
ecma_length_t *out_arg_number_p) /**< out: number of arguments
|
||||
successfully read */
|
||||
{
|
||||
ecma_completion_value_t get_arg_completion = ecma_make_empty_completion_value ();
|
||||
|
||||
ecma_length_t arg_index;
|
||||
for (arg_index = 0;
|
||||
arg_index < args_number;
|
||||
arg_index++)
|
||||
{
|
||||
opcode_t next_opcode = read_opcode (int_data->pos);
|
||||
if (next_opcode.op_idx == __op__idx_varg)
|
||||
{
|
||||
get_arg_completion = get_variable_value (int_data, next_opcode.data.varg.arg_lit_idx, false);
|
||||
if (unlikely (ecma_is_completion_value_throw (get_arg_completion)))
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal (get_arg_completion));
|
||||
arg_values[arg_index] = get_arg_completion.value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
get_arg_completion = run_int_loop (int_data);
|
||||
|
||||
if (get_arg_completion.type == ECMA_COMPLETION_TYPE_VARG)
|
||||
{
|
||||
arg_values[arg_index] = get_arg_completion.value;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int_data->pos++;
|
||||
}
|
||||
|
||||
*out_arg_number_p = arg_index;
|
||||
|
||||
if (get_arg_completion.type == ECMA_COMPLETION_TYPE_NORMAL
|
||||
|| get_arg_completion.type == ECMA_COMPLETION_TYPE_VARG)
|
||||
{
|
||||
/* values are copied to arg_values */
|
||||
return ecma_make_empty_completion_value ();
|
||||
}
|
||||
else
|
||||
{
|
||||
return get_arg_completion;
|
||||
}
|
||||
} /* fill_varg_list */
|
||||
|
||||
/**
|
||||
* 'Function call' opcode handler.
|
||||
*
|
||||
@ -1021,8 +795,8 @@ opfunc_call_n (opcode_t opdata, /**< operation data */
|
||||
else
|
||||
{
|
||||
this_value = ecma_op_implicit_this_value (int_data->lex_env_p);
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal (this_value));
|
||||
}
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal (this_value));
|
||||
|
||||
if (!ecma_op_is_callable (func_value.value))
|
||||
{
|
||||
@ -1094,23 +868,6 @@ opfunc_construct_n (opcode_t opdata, /**< operation data */
|
||||
|
||||
if (ecma_is_empty_completion_value (get_arg_completion))
|
||||
{
|
||||
ecma_completion_value_t this_value;
|
||||
|
||||
opcode_t next_opcode = read_opcode (int_data->pos);
|
||||
if (next_opcode.op_idx == __op__idx_meta
|
||||
&& next_opcode.data.meta.type == OPCODE_META_TYPE_THIS_ARG)
|
||||
{
|
||||
const idx_t this_arg_var_idx = next_opcode.data.meta.data_1;
|
||||
|
||||
JERRY_ASSERT (is_reg_variable (int_data, this_arg_var_idx));
|
||||
this_value = get_variable_value (int_data, this_arg_var_idx, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
this_value = ecma_op_implicit_this_value (int_data->lex_env_p);
|
||||
JERRY_ASSERT (ecma_is_completion_value_normal (this_value));
|
||||
}
|
||||
|
||||
if (!ecma_is_constructor (constructor_value.value))
|
||||
{
|
||||
ret_value = ecma_make_throw_value (ecma_new_standard_error (ECMA_ERROR_TYPE));
|
||||
@ -1128,8 +885,6 @@ opfunc_construct_n (opcode_t opdata, /**< operation data */
|
||||
ret_value = set_variable_value (int_data, lhs_var_idx, construction_completion.value);
|
||||
|
||||
ECMA_FINALIZE (construction_completion);
|
||||
|
||||
ecma_free_completion_value (this_value);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1151,30 +906,6 @@ opfunc_construct_n (opcode_t opdata, /**< operation data */
|
||||
return ret_value;
|
||||
} /* opfunc_construct_n */
|
||||
|
||||
/**
|
||||
* 'varg' opcode handler
|
||||
*
|
||||
* @return completion value
|
||||
* Returned value must be freed with ecma_free_completion_value.
|
||||
*/
|
||||
ecma_completion_value_t
|
||||
opfunc_varg (opcode_t opdata, /**< operation data */
|
||||
int_data_t *int_data) /**< interpreter context */
|
||||
{
|
||||
const idx_t arg_lit_idx = opdata.data.varg.arg_lit_idx;
|
||||
|
||||
ecma_completion_value_t completion = get_variable_value (int_data,
|
||||
arg_lit_idx,
|
||||
false);
|
||||
|
||||
if (ecma_is_completion_value_normal (completion))
|
||||
{
|
||||
completion.type = ECMA_COMPLETION_TYPE_VARG;
|
||||
}
|
||||
|
||||
return completion;
|
||||
} /* opfunc_varg */
|
||||
|
||||
/**
|
||||
* 'Return with no expression' opcode handler.
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user