Fix prop_getters stack manipulation for assignment expression.
Related issue: #614 JerryScript-DCO-1.0-Signed-off-by: Ilyong Cho ily.cho@samsung.com
This commit is contained in:
@@ -628,25 +628,23 @@ dump_prop_setter_or_triple_address_res (vm_op_t opcode,
|
||||
jsp_operand_t res,
|
||||
jsp_operand_t op)
|
||||
{
|
||||
const op_meta last = STACK_TOP (prop_getters);
|
||||
if (last.op.op_idx == VM_OP_PROP_GETTER)
|
||||
if (res.is_register_operand ())
|
||||
{
|
||||
/*
|
||||
* Left-hand-side must be a member expression and corresponding prop_getter
|
||||
* op is on top of the stack.
|
||||
*/
|
||||
const op_meta last = STACK_TOP (prop_getters);
|
||||
JERRY_ASSERT (last.op.op_idx == VM_OP_PROP_GETTER);
|
||||
|
||||
res = dump_triple_address_and_prop_setter_res (opcode, last, op);
|
||||
|
||||
STACK_DROP (prop_getters, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (res.is_register_operand ())
|
||||
{
|
||||
/*
|
||||
* FIXME:
|
||||
* Implement correct handling of references through parser operands
|
||||
*/
|
||||
PARSE_ERROR (JSP_EARLY_ERROR_REFERENCE, "Invalid left-hand-side expression", LIT_ITERATOR_POS_ZERO);
|
||||
}
|
||||
|
||||
dump_triple_address (opcode, res, res, op);
|
||||
}
|
||||
STACK_DROP (prop_getters, 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1865,37 +1863,60 @@ rewrite_jump_to_end (void)
|
||||
}
|
||||
|
||||
void
|
||||
start_dumping_assignment_expression (void)
|
||||
start_dumping_assignment_expression (jsp_operand_t lhs, locus loc __attr_unused___)
|
||||
{
|
||||
const op_meta last = last_dumped_op_meta ();
|
||||
if (last.op.op_idx == VM_OP_PROP_GETTER)
|
||||
if (lhs.is_register_operand ())
|
||||
{
|
||||
serializer_set_writing_position ((vm_instr_counter_t) (serializer_get_current_instr_counter () - 1));
|
||||
/*
|
||||
* Having left-handside of assignment expression as a temporary register
|
||||
* means it's either a member expression or something else. Under the condition,
|
||||
* only member expression could be a L-value for assignment expression, otherwise
|
||||
* it's an invalid lhs expression.
|
||||
*/
|
||||
|
||||
const op_meta last = last_dumped_op_meta ();
|
||||
|
||||
if (last.op.op_idx == VM_OP_PROP_GETTER)
|
||||
{
|
||||
/*
|
||||
* If lhs is a member expression, last dumped op code should be
|
||||
* prop_getter. For we are going to use the expression as L-value, it will
|
||||
* be a prop_setter later, save the op to stack.
|
||||
*/
|
||||
serializer_set_writing_position ((vm_instr_counter_t) (serializer_get_current_instr_counter () - 1));
|
||||
STACK_PUSH (prop_getters, last);
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* If lhs is a temporary register operand but not a member expression, It
|
||||
* is an invalid left-hand-side expression.
|
||||
*/
|
||||
PARSE_ERROR (JSP_EARLY_ERROR_REFERENCE, "Invalid left-hand-side expression", loc);
|
||||
}
|
||||
}
|
||||
STACK_PUSH (prop_getters, last);
|
||||
}
|
||||
|
||||
jsp_operand_t
|
||||
dump_prop_setter_or_variable_assignment_res (jsp_operand_t res, jsp_operand_t op)
|
||||
{
|
||||
const op_meta last = STACK_TOP (prop_getters);
|
||||
if (last.op.op_idx == VM_OP_PROP_GETTER)
|
||||
if (res.is_register_operand ())
|
||||
{
|
||||
/*
|
||||
* Left-hand-side must be a member expression and corresponding prop_getter
|
||||
* op is on top of the stack.
|
||||
*/
|
||||
const op_meta last = STACK_TOP (prop_getters);
|
||||
JERRY_ASSERT (last.op.op_idx == VM_OP_PROP_GETTER);
|
||||
|
||||
dump_prop_setter_op_meta (last, op);
|
||||
|
||||
STACK_DROP (prop_getters, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (res.is_register_operand ())
|
||||
{
|
||||
/*
|
||||
* FIXME:
|
||||
* Implement correct handling of references through parser operands
|
||||
*/
|
||||
PARSE_ERROR (JSP_EARLY_ERROR_REFERENCE, "Invalid left-hand-side expression", LIT_ITERATOR_POS_ZERO);
|
||||
}
|
||||
dump_variable_assignment (res, op);
|
||||
}
|
||||
STACK_DROP (prop_getters, 1);
|
||||
return op;
|
||||
}
|
||||
|
||||
|
||||
@@ -425,7 +425,7 @@ void rewrite_conditional_check (void);
|
||||
void dump_jump_to_end_for_rewrite (void);
|
||||
void rewrite_jump_to_end (void);
|
||||
|
||||
void start_dumping_assignment_expression (void);
|
||||
void start_dumping_assignment_expression (jsp_operand_t, locus);
|
||||
jsp_operand_t dump_prop_setter_or_variable_assignment_res (jsp_operand_t, jsp_operand_t);
|
||||
jsp_operand_t dump_prop_setter_or_addition_res (jsp_operand_t, jsp_operand_t);
|
||||
jsp_operand_t dump_prop_setter_or_multiplication_res (jsp_operand_t, jsp_operand_t);
|
||||
|
||||
@@ -1730,6 +1730,7 @@ static jsp_operand_t
|
||||
parse_assignment_expression (bool in_allowed)
|
||||
{
|
||||
bool is_conditional = false;
|
||||
locus loc_expr = tok.loc;
|
||||
jsp_operand_t expr = parse_conditional_expression (in_allowed, &is_conditional);
|
||||
if (is_conditional)
|
||||
{
|
||||
@@ -1755,7 +1756,7 @@ parse_assignment_expression (bool in_allowed)
|
||||
{
|
||||
jsp_early_error_check_for_eval_and_arguments_in_strict_mode (expr, is_strict_mode (), tok.loc);
|
||||
skip_newlines ();
|
||||
start_dumping_assignment_expression ();
|
||||
start_dumping_assignment_expression (expr, loc_expr);
|
||||
const jsp_operand_t assign_expr = parse_assignment_expression (in_allowed);
|
||||
|
||||
if (tt == TOK_EQ)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright 2015 Samsung Electronics Co., Ltd.
|
||||
// Copyright 2015 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.
|
||||
// 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.
|
||||
|
||||
JSON.stringify & (Date = 1);
|
||||
|
||||
b = 1;
|
||||
this.a = 2;
|
||||
this.a
|
||||
b = 3;
|
||||
assert(b == 3);
|
||||
assert(a == 2);
|
||||
this.a & (b = 4);
|
||||
assert(b == 4);
|
||||
assert(a == 2);
|
||||
Reference in New Issue
Block a user