Skip to content

Commit a343fd8

Browse files
committed
Use a single list of internal commands
1 parent ca9caef commit a343fd8

File tree

6 files changed

+82
-27
lines changed

6 files changed

+82
-27
lines changed

lib/Parser/InternalCommands.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
// This file is designed to be included repeatedly to provide a list of internal commands
7+
// The Command macro should be defined each time before inclusion
8+
9+
// command name, expected parameters
10+
Command(Conv_Num, 1)
11+
Command(Conv_Obj, 1)
12+
13+
#undef Command

lib/Parser/Parse.cpp

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2646,17 +2646,18 @@ ParseNodePtr Parser::ParseInternalCommand()
26462646

26472647
// find the command type
26482648
InternalCommandType type;
2649+
uint32 expectedParams = 0;
26492650
IdentPtr id = m_token.GetIdentifier(GetHashTbl());
26502651

2651-
if (id == internalCommandPids.Conv_Num)
2652-
{
2653-
type = InternalCommandType::Conv_Num;
2654-
}
2655-
else if (id == internalCommandPids.Conv_Obj)
2656-
{
2657-
type = InternalCommandType::Conv_Obj;
2658-
}
2659-
else
2652+
#define Command(name, params) \
2653+
if (id == internalCommandPids.##name) \
2654+
{ \
2655+
type = InternalCommandType::##name; \
2656+
expectedParams = params; \
2657+
} \
2658+
else
2659+
2660+
#include "InternalCommands.h"
26602661
{
26612662
Error(ERRTokenAfter, m_token.GetIdentifier(GetHashTbl())->Psz(), _u("@@"));
26622663
}
@@ -2670,7 +2671,13 @@ ParseNodePtr Parser::ParseInternalCommand()
26702671

26712672
for (;;)
26722673
{
2673-
currentParam = ParseExpr<buildAST>(0);
2674+
currentParam = ParseExpr<buildAST>(koplCma);
2675+
if (expectedParams-- == 0)
2676+
{
2677+
// throw during parse phase if internal command has too many parameters
2678+
// as the excess would be ignored upon execution
2679+
Error(ERRsyntax);
2680+
}
26742681
if (buildAST)
26752682
{
26762683
AddToNodeListEscapedUse(&params, &lastParam, currentParam);
@@ -2691,6 +2698,13 @@ ParseNodePtr Parser::ParseInternalCommand()
26912698
}
26922699
}
26932700

2701+
if (expectedParams != 0)
2702+
{
2703+
// throw during parse phase if internal command has too few parameters
2704+
// as could produce undefined behaviour if executed
2705+
Error(ERRsyntax);
2706+
}
2707+
26942708
ParseNodePtr command = nullptr;
26952709
if (buildAST)
26962710
{
@@ -11863,8 +11877,10 @@ void Parser::InitPids()
1186311877
#ifdef ENABLE_TEST_HOOKS
1186411878
void Parser::InitInternalCommandPids()
1186511879
{
11866-
internalCommandPids.Conv_Num = this->GetHashTbl()->PidHashNameLen(_u("Conv_Num"), sizeof("Conv_Num") - 1);
11867-
internalCommandPids.Conv_Obj = this->GetHashTbl()->PidHashNameLen(_u("Conv_Obj"), sizeof("Conv_Obj") - 1);
11880+
#define Command(name, params) \
11881+
internalCommandPids.##name = this->GetHashTbl()->PidHashNameLen(_u(#name), sizeof(#name) - 1);
11882+
11883+
#include "InternalCommands.h"
1186811884
}
1186911885
#endif
1187011886

lib/Parser/Parse.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,8 +511,10 @@ class Parser
511511
#ifdef ENABLE_TEST_HOOKS
512512
struct InternalCommandPids
513513
{
514-
IdentPtr Conv_Num;
515-
IdentPtr Conv_Obj;
514+
#define Command(name, params) \
515+
IdentPtr name;
516+
517+
#include "InternalCommands.h"
516518
};
517519
InternalCommandPids internalCommandPids;
518520
#endif

lib/Parser/ptree.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -446,8 +446,10 @@ class ParseNodeObjLit : public ParseNodeUni
446446

447447
typedef enum InternalCommandType
448448
{
449-
Conv_Num,
450-
Conv_Obj
449+
#define Command(name, params) \
450+
name, //params
451+
452+
#include "InternalCommands.h"
451453
} InternalCommandType;
452454

453455
class ParseNodeInternalCommand : public ParseNode
@@ -458,6 +460,8 @@ class ParseNodeInternalCommand : public ParseNode
458460

459461
InternalCommandType commandType;
460462
ParseNodePtr params;
463+
464+
DISABLE_SELF_CAST(ParseNodeInternalCommand);
461465
};
462466
#endif
463467

lib/Runtime/ByteCode/ByteCodeEmitter.cpp

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12301,22 +12301,43 @@ void Emit(ParseNode* pnode, ByteCodeGenerator* byteCodeGenerator, FuncInfo* func
1230112301
byteCodeGenerator->StartStatement(pnode);
1230212302
funcInfo->AcquireLoc(pnode);
1230312303
ParseNodeInternalCommand* command = pnode->AsParseNodeInternalCommand();
12304-
ParseNode* params = command->params;
12305-
//ParseNode* param1 = params->AsParseNodeBin()->pnode1;
12306-
Emit(params, byteCodeGenerator, funcInfo, false);
12304+
12305+
Js::OpCode opcode = Js::OpCode::Nop;
12306+
uint32 expectedParams = 0;
12307+
12308+
#define Command(name, params) \
12309+
case InternalCommandType::##name: \
12310+
opcode = Js::OpCode::##name; \
12311+
expectedParams = params; \
12312+
break;
1230712313

1230812314
switch (command->commandType)
1230912315
{
12310-
case InternalCommandType::Conv_Num:
12311-
byteCodeGenerator->Writer()->Reg2(Js::OpCode::Conv_Num, pnode->location, params->location);
12316+
#include "InternalCommands.h"
12317+
default:
12318+
AssertOrFailFast(0);
12319+
}
12320+
12321+
ParseNode* params = command->params;
12322+
switch (expectedParams)
12323+
{
12324+
case 1:
12325+
Emit(params, byteCodeGenerator, funcInfo, false);
12326+
byteCodeGenerator->Writer()->Reg2(opcode, pnode->location, params->location);
1231212327
break;
12313-
case InternalCommandType::Conv_Obj:
12314-
byteCodeGenerator->Writer()->Reg2(Js::OpCode::Conv_Obj, pnode->location, params->location);
12328+
case 2:
12329+
{
12330+
ParseNode* param1 = params->AsParseNodeBin()->pnode1;
12331+
ParseNode* param2 = params->AsParseNodeBin()->pnode2;
12332+
Emit(param1, byteCodeGenerator, funcInfo, false);
12333+
Emit(param2, byteCodeGenerator, funcInfo, false);
12334+
byteCodeGenerator->Writer()->Reg3(opcode, pnode->location, param1->location, param2->location);
1231512335
break;
12316-
12336+
}
1231712337
default:
12318-
AssertOrFailFast(0);
12338+
AssertOrFailFast(0); //currently only support Internal Commands with 1 or 2 parameters
1231912339
}
12340+
1232012341
funcInfo->ReleaseLoc(params);
1232112342
byteCodeGenerator->EndStatement(pnode);
1232212343
break;

lib/Runtime/Library/JsBuiltIn/JsBuiltIn.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,8 +396,7 @@
396396
// this is FlattenIntoArray from the flat/flatMap proposal BUT with:
397397
// depth = 1 and the presence of a mapperFunction guaranteed
398398
// both these conditions are always met when this is called from flatMap
399-
// Additionally this is slightly refactored rather than taking a thisArg
400-
// the calling function binds the thisArg if it's required
399+
401400
//1. Let targetIndex be start.
402401
let targetIndex = start;
403402
//2. Let sourceIndex be 0.

0 commit comments

Comments
 (0)