Skip to content

Commit

Permalink
Fix prop_getters stack manipulation for assignment expression.
Browse files Browse the repository at this point in the history
Related issue: jerryscript-project#614

JerryScript-DCO-1.0-Signed-off-by: Ilyong Cho [email protected]
  • Loading branch information
ILyoan committed Nov 9, 2015
1 parent eaca37c commit 94cb6ae
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 30 deletions.
77 changes: 49 additions & 28 deletions jerry-core/parser/js/opcodes-dumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion jerry-core/parser/js/opcodes-dumper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion jerry-core/parser/js/parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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)
Expand Down
26 changes: 26 additions & 0 deletions tests/jerry/regression-test-issue-614.js
Original file line number Diff line number Diff line change
@@ -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);

0 comments on commit 94cb6ae

Please sign in to comment.