Add this_arg dumping in parser

This commit is contained in:
Ilmir Usmanov
2014-10-02 19:30:36 +04:00
parent eff5e1a80b
commit af00691d1d
2 changed files with 73 additions and 14 deletions
+47 -14
View File
@@ -281,7 +281,7 @@ static void parse_expression (void);
static void parse_statement (void); static void parse_statement (void);
static void parse_assignment_expression (void); static void parse_assignment_expression (void);
static void parse_source_element_list (void); static void parse_source_element_list (void);
static void parse_argument_list (argument_list_type, idx_t); static void parse_argument_list (argument_list_type, idx_t, idx_t);
static uint8_t static uint8_t
lp_string_hash (lp_string str) lp_string_hash (lp_string str)
@@ -744,7 +744,7 @@ parse_property_assignment (void)
NEXT (property_name); // push name NEXT (property_name); // push name
skip_newlines (); skip_newlines ();
parse_argument_list (AL_FUNC_EXPR, next_temp_name ()); // push lhs parse_argument_list (AL_FUNC_EXPR, next_temp_name (), INVALID_VALUE); // push lhs
STACK_PUSH (U16, opcode_counter); STACK_PUSH (U16, opcode_counter);
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_FUNCTION_END, INVALID_VALUE, INVALID_VALUE); DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_FUNCTION_END, INVALID_VALUE, INVALID_VALUE);
@@ -767,7 +767,7 @@ parse_property_assignment (void)
NEXT (property_name); // push name NEXT (property_name); // push name
skip_newlines (); skip_newlines ();
parse_argument_list (AL_FUNC_EXPR, next_temp_name ()); // push lhs parse_argument_list (AL_FUNC_EXPR, next_temp_name (), INVALID_VALUE); // push lhs
STACK_PUSH (U16, opcode_counter); STACK_PUSH (U16, opcode_counter);
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_FUNCTION_END, INVALID_VALUE, INVALID_VALUE); DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_FUNCTION_END, INVALID_VALUE, INVALID_VALUE);
@@ -797,7 +797,7 @@ parse_property_assignment (void)
For each ALT dumps appropriate bytecode. Uses OBJ during dump if neccesary. For each ALT dumps appropriate bytecode. Uses OBJ during dump if neccesary.
Returns temp var if expression has lhs, or 0 otherwise. */ Returns temp var if expression has lhs, or 0 otherwise. */
static void static void
parse_argument_list (argument_list_type alt, idx_t obj) parse_argument_list (argument_list_type alt, idx_t obj, idx_t this_arg)
{ {
// U8 open_tt, close_tt, args_count // U8 open_tt, close_tt, args_count
// IDX lhs, current_arg // IDX lhs, current_arg
@@ -879,6 +879,12 @@ parse_argument_list (argument_list_type alt, idx_t obj)
current_token_must_be (STACK_HEAD (U8, 3)); current_token_must_be (STACK_HEAD (U8, 3));
if (alt == AL_CALL_EXPR && this_arg != INVALID_VALUE)
{
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_THIS_ARG, this_arg, INVALID_VALUE);
STACK_INCR_HEAD (U8, 1);
}
skip_newlines (); skip_newlines ();
while (!token_is (STACK_HEAD (U8, 2))) while (!token_is (STACK_HEAD (U8, 2)))
{ {
@@ -1041,7 +1047,7 @@ parse_function_declaration (void)
STACK_PUSH (IDX, token_data ()); STACK_PUSH (IDX, token_data ());
skip_newlines (); skip_newlines ();
parse_argument_list (AL_FUNC_DECL, ID(1)); parse_argument_list (AL_FUNC_DECL, ID(1), INVALID_VALUE);
STACK_PUSH (U16, OPCODE_COUNTER ()); STACK_PUSH (U16, OPCODE_COUNTER ());
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_UNDEFINED, INVALID_VALUE, INVALID_VALUE); DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_UNDEFINED, INVALID_VALUE, INVALID_VALUE);
@@ -1093,7 +1099,7 @@ parse_function_expression (void)
} }
skip_newlines (); skip_newlines ();
parse_argument_list (AL_FUNC_EXPR, ID(1)); // push lhs parse_argument_list (AL_FUNC_EXPR, ID(1), INVALID_VALUE); // push lhs
STACK_PUSH (U16, OPCODE_COUNTER ()); STACK_PUSH (U16, OPCODE_COUNTER ());
DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_UNDEFINED, INVALID_VALUE, INVALID_VALUE); DUMP_OPCODE_3 (meta, OPCODE_META_TYPE_UNDEFINED, INVALID_VALUE, INVALID_VALUE);
@@ -1127,7 +1133,7 @@ parse_array_literal (void)
{ {
STACK_DECLARE_USAGE (IDX) STACK_DECLARE_USAGE (IDX)
parse_argument_list (AL_ARRAY_DECL, 0); parse_argument_list (AL_ARRAY_DECL, 0, INVALID_VALUE);
STACK_CHECK_USAGE_LHS (); STACK_CHECK_USAGE_LHS ();
} }
@@ -1140,7 +1146,7 @@ parse_object_literal (void)
{ {
STACK_DECLARE_USAGE (IDX) STACK_DECLARE_USAGE (IDX)
parse_argument_list (AL_OBJ_DECL, 0); parse_argument_list (AL_OBJ_DECL, 0, INVALID_VALUE);
STACK_CHECK_USAGE_LHS ();; STACK_CHECK_USAGE_LHS ();;
} }
@@ -1197,6 +1203,7 @@ parse_literal (void)
: 'this' : 'this'
| Identifier | Identifier
| literal | literal
| 'undefined'
| '[' LT!* array_literal LT!* ']' | '[' LT!* array_literal LT!* ']'
| '{' LT!* object_literal LT!* '}' | '{' LT!* object_literal LT!* '}'
| '(' LT!* expression LT!* ')' | '(' LT!* expression LT!* ')'
@@ -1289,7 +1296,7 @@ cleanup:
: '.' LT!* Identifier : '.' LT!* Identifier
; */ ; */
static void static void
parse_member_expression (void) parse_member_expression (idx_t *this_arg)
{ {
// IDX obj, lhs, prop; // IDX obj, lhs, prop;
STACK_DECLARE_USAGE (IDX) STACK_DECLARE_USAGE (IDX)
@@ -1300,10 +1307,18 @@ parse_member_expression (void)
} }
else if (is_keyword (KW_NEW)) else if (is_keyword (KW_NEW))
{ {
NEXT (member_expression); // push member skip_newlines ();
parse_member_expression (this_arg);
skip_newlines (); skip_newlines ();
parse_argument_list (AL_CONSTRUCT_EXPR, ID(1)); // push obj if (this_arg)
{
parse_argument_list (AL_CONSTRUCT_EXPR, ID(1), *this_arg); // push obj
}
else
{
parse_argument_list (AL_CONSTRUCT_EXPR, ID(1), INVALID_VALUE); // push obj
}
STACK_SWAP (IDX); STACK_SWAP (IDX);
STACK_DROP (IDX, 1); STACK_DROP (IDX, 1);
@@ -1316,6 +1331,11 @@ parse_member_expression (void)
skip_newlines (); skip_newlines ();
while (token_is (TOK_OPEN_SQUARE) || token_is (TOK_DOT)) while (token_is (TOK_OPEN_SQUARE) || token_is (TOK_DOT))
{ {
if (this_arg)
{
*this_arg = ID (1);
}
STACK_PUSH (IDX, next_temp_name ()); STACK_PUSH (IDX, next_temp_name ());
if (token_is (TOK_OPEN_SQUARE)) if (token_is (TOK_OPEN_SQUARE))
@@ -1370,8 +1390,9 @@ parse_call_expression (void)
{ {
// IDX obj, lhs, prop; // IDX obj, lhs, prop;
STACK_DECLARE_USAGE (IDX) STACK_DECLARE_USAGE (IDX)
idx_t this_arg = INVALID_VALUE;
parse_member_expression (); parse_member_expression (NULL);
skip_newlines (); skip_newlines ();
if (!token_is (TOK_OPEN_PAREN)) if (!token_is (TOK_OPEN_PAREN))
@@ -1380,7 +1401,17 @@ parse_call_expression (void)
goto cleanup; goto cleanup;
} }
parse_argument_list (AL_CALL_EXPR, ID(1)); // push lhs TODO (/* Uncomment when interpreter will catch this properly. */)
// if (this_arg < lexer_get_reserved_ids_count ())
// {
// STACK_PUSH (IDX, next_temp_name ());
// DUMP_OPCODE_3 (assignment, ID(1), OPCODE_ARG_TYPE_VARIABLE, this_arg);
// this_arg = ID(1);
// STACK_DROP (IDX, 1);
// }
parse_argument_list (AL_CALL_EXPR, ID(1), this_arg); // push lhs
this_arg = INVALID_VALUE;
STACK_SWAP (IDX); STACK_SWAP (IDX);
skip_newlines (); skip_newlines ();
@@ -1392,12 +1423,13 @@ parse_call_expression (void)
case TOK_OPEN_PAREN: case TOK_OPEN_PAREN:
{ {
STACK_DROP (IDX, 1); STACK_DROP (IDX, 1);
parse_argument_list (AL_CALL_EXPR, ID(1)); // push lhs parse_argument_list (AL_CALL_EXPR, ID(1), this_arg); // push lhs
skip_newlines (); skip_newlines ();
break; break;
} }
case TOK_OPEN_SQUARE: case TOK_OPEN_SQUARE:
{ {
this_arg = ID (1);
NEXT (expression); // push prop NEXT (expression); // push prop
next_token_must_be (TOK_CLOSE_SQUARE); next_token_must_be (TOK_CLOSE_SQUARE);
@@ -1409,6 +1441,7 @@ parse_call_expression (void)
} }
case TOK_DOT: case TOK_DOT:
{ {
this_arg = ID (1);
token_after_newlines_must_be (TOK_NAME); token_after_newlines_must_be (TOK_NAME);
STACK_PUSH (IDX, token_data ()); STACK_PUSH (IDX, token_data ());
+26
View File
@@ -0,0 +1,26 @@
// 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.
var i = 0;
function a() {}
a.prototype.b = function() { i++; }
a.prototype.c = function() { this.b(); i++; }
var aa = new a();
aa.c();
assert (i === 2);