File Index Symbol Index

#include "WfEmitter.h"
namespace
vl
{
namespace
workflow
{
namespace
emitter
{
using
namespace
collections
;
using
namespace
parsing
;
using
namespace
reflection
::
description
;
using
namespace
analyzer
;
using
namespace
runtime
;
using
namespace
typeimpl
;
typedef
WfInstruction
Ins
;
#define INSTRUCTION(X) context.AddInstruction(node, X)
/*********************************************************************** GenerateInstructions(Initialize) ***********************************************************************/
class
GenerateInitializeInstructionsVisitor
:
public
Object
,
public
WfDeclaration
::
IVisitor
{
public
:
WfCodegenContext
&
context
;
GenerateInitializeInstructionsVisitor
(
WfCodegenContext
&
_context
) :context(
_context
) { }
void
Visit
(
WfNamespaceDeclaration
*
node
)
override
{ {
GenerateInitializeInstructions
(
context
,
decl
); } }
void
Visit
(
WfFunctionDeclaration
*
node
)
override
{ }
void
Visit
(
WfVariableDeclaration
*
node
)
override
{
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
auto
symbol
=
scope
->
symbols
[
node
->
name
.
value
]
[
0
];
vint
variableIndex
=
context
.
globalVariables
[
symbol
.
Obj
()];
GenerateExpressionInstructions
(
context
,
node
->
expression
); }
void
Visit
(
WfEventDeclaration
*
node
)
override
{ }
void
Visit
(
WfPropertyDeclaration
*
node
)
override
{ }
void
Visit
(
WfConstructorDeclaration
*
node
)
override
{ }
void
Visit
(
WfDestructorDeclaration
*
node
)
override
{ }
void
Visit
(
WfClassDeclaration
*
node
)
override
{ }
void
Visit
(
WfEnumDeclaration
*
node
)
override
{ }
void
Visit
(
WfStructDeclaration
*
node
)
override
{ }
void
Visit
(
WfVirtualCfeDeclaration
*
node
)
override
{ {
decl
-
>
Accept
(
this
); } }
void
Visit
(
WfVirtualCseDeclaration
*
node
)
override
{ {
decl
-
>
Accept
(
this
); } } };
void
GenerateInitializeInstructions
(
WfCodegenContext
&
context
,
Ptr
<
WfDeclaration
>
declaration
) {
GenerateInitializeInstructionsVisitor
visitor
(
context
);
declaration
-
>
Accept
(&
visitor
); }
/*********************************************************************** GenerateInstructions(Declaration) ***********************************************************************/
Ptr
<
WfCodegenFunctionContext
>
GenerateFunctionInstructions_Prolog
(
WfCodegenContext
&
context
,
WfLexicalScope
*
scope
,
Ptr
<
WfAssemblyFunction
>
meta
,
Ptr
<
ITypeInfo
>
returnType
,
Ptr
<
WfLexicalSymbol
>
recursiveLambdaSymbol
,
const
List
<
Ptr
<
WfLexicalSymbol
>>&
argumentSymbols
,
const
List
<
Ptr
<
WfLexicalSymbol
>>&
capturedSymbols
,
ParsingTreeCustomBase
*
node
) {
auto
functionContext
=
MakePtr
<
WfCodegenFunctionContext
>();
functionContext
-
>
function
=
meta
;
context
.
functionContext
=
functionContext
; { {
functionContext
-
>
arguments
.
Add
(
argumentSymbol
.
Obj
(),
index
); } {
functionContext
-
>
capturedVariables
.
Add
(
capturedSymbol
.
Obj
(),
index
); } }
if
(
recursiveLambdaSymbol
) {
vint
variableIndex
=
meta
-
>
argumentNames
.
Count
() +
meta
-
>
localVariableNames
.
Add
(
L"<recursive-lambda>"
+
recursiveLambdaSymbol
-
>
name
);
functionContext
-
>
localVariables
.
Add
(
recursiveLambdaSymbol
.
Obj
(),
variableIndex
); }
meta
-
>
firstInstruction
=
context
.
assembly
-
>
instructions
.
Count
();
if
(
recursiveLambdaSymbol
) { }
return
functionContext
; }
void
GenerateFunctionInstructions_Epilog
(
WfCodegenContext
&
context
,
WfLexicalScope
*
scope
,
Ptr
<
WfAssemblyFunction
>
meta
,
Ptr
<
ITypeInfo
>
returnType
,
Ptr
<
WfLexicalSymbol
>
recursiveLambdaSymbol
,
const
List
<
Ptr
<
WfLexicalSymbol
>>&
argumentSymbols
,
const
List
<
Ptr
<
WfLexicalSymbol
>>&
capturedSymbols
,
Ptr
<
WfCodegenFunctionContext
>
functionContext
,
ParsingTreeCustomBase
*
node
) {
meta
-
>
lastInstruction
=
context
.
assembly
-
>
instructions
.
Count
() -
1
;
context
.
functionContext
=
0
;
GenerateClosureInstructions
(
context
,
functionContext
); }
void
GenerateFunctionInstructions
(
WfCodegenContext
&
context
,
WfLexicalScope
*
scope
,
Ptr
<
WfAssemblyFunction
>
meta
,
Ptr
<
ITypeInfo
>
returnType
,
Ptr
<
WfLexicalSymbol
>
recursiveLambdaSymbol
,
const
List
<
Ptr
<
WfLexicalSymbol
>>&
argumentSymbols
,
const
List
<
Ptr
<
WfLexicalSymbol
>>&
capturedSymbols
,
Ptr
<
WfStatement
>
statementBody
,
ParsingTreeCustomBase
*
node
) {
auto
functionContext
=
GenerateFunctionInstructions_Prolog
(
context
,
scope
,
meta
,
returnType
,
recursiveLambdaSymbol
,
argumentSymbols
,
capturedSymbols
,
node
);
GenerateStatementInstructions
(
context
,
statementBody
);
GenerateFunctionInstructions_Epilog
(
context
,
scope
,
meta
,
returnType
,
recursiveLambdaSymbol
,
argumentSymbols
,
capturedSymbols
,
functionContext
,
node
); }
void
GenerateFunctionInstructions
(
WfCodegenContext
&
context
,
WfLexicalScope
*
scope
,
Ptr
<
WfAssemblyFunction
>
meta
,
Ptr
<
ITypeInfo
>
returnType
,
Ptr
<
WfLexicalSymbol
>
recursiveLambdaSymbol
,
const
List
<
Ptr
<
WfLexicalSymbol
>>&
argumentSymbols
,
const
List
<
Ptr
<
WfLexicalSymbol
>>&
capturedSymbols
,
Ptr
<
WfExpression
>
expressionBody
,
ParsingTreeCustomBase
*
node
) {
auto
functionContext
=
GenerateFunctionInstructions_Prolog
(
context
,
scope
,
meta
,
returnType
,
recursiveLambdaSymbol
,
argumentSymbols
,
capturedSymbols
,
node
);
GenerateExpressionInstructions
(
context
,
expressionBody
);
GenerateFunctionInstructions_Epilog
(
context
,
scope
,
meta
,
returnType
,
recursiveLambdaSymbol
,
argumentSymbols
,
capturedSymbols
,
functionContext
,
node
); }
void
GenerateFunctionDeclarationInstructions
(
WfCodegenContext
&
context
,
WfFunctionDeclaration
*
node
,
WfLexicalScope
*
scope
,
Ptr
<
WfAssemblyFunction
>
meta
,
Ptr
<
WfLexicalSymbol
>
recursiveLambdaSymbol
) {
List
<
Ptr
<
WfLexicalSymbol
>>
argumentSymbols
,
capturedSymbols
; { {
auto
symbol
=
scope
->
symbols
[
argument
-
>
name
.
value
]
[
0
];
argumentSymbols
.
Add
(
symbol
); }
vint
index
=
context
.
manager
->
lambdaCaptures
.
Keys
().
IndexOf
(
node
);
if
(
index
!= -
1
) {
auto
capture
=
context
.
manager
->
lambdaCaptures
.
Values
()
[
index
]; {
capturedSymbols
.
Add
(
symbol
); } } }
auto
returnType
=
CreateTypeInfoFromType
(
scope
,
node
->
returnType
);
GenerateFunctionInstructions
(
context
,
scope
,
meta
,
returnType
,
recursiveLambdaSymbol
,
argumentSymbols
,
capturedSymbols
,
node
->
statement
,
node
); }
class
GenerateClassMemberInstructionsVisitor
:
public
Object
,
public
WfDeclaration
::
IVisitor
{
public
:
WfCodegenContext
&
context
;
Ptr
<
WfClassDeclaration
>
classDecl
;
GenerateClassMemberInstructionsVisitor
(
WfCodegenContext
&
_context
,
Ptr
<
WfClassDeclaration
>
_classDecl
) :context(
_context
) , classDecl(
_classDecl
) { }
void
Visit
(
WfNamespaceDeclaration
*
node
)
override
{ }
void
Visit
(
WfFunctionDeclaration
*
node
)
override
{
if
(
node
->
classMember
-
>
kind
==
WfClassMemberKind
::
Static
) {
GenerateDeclarationInstructions
(
context
,
node
); }
else
if
(
classDecl
-
>
kind
==
WfClassKind
::
Class
) {
GenerateDeclarationInstructions
(
context
,
node
); } }
void
Visit
(
WfVariableDeclaration
*
node
)
override
{ }
void
Visit
(
WfEventDeclaration
*
node
)
override
{ }
void
Visit
(
WfPropertyDeclaration
*
node
)
override
{ }
class
InitializeFieldVisitor
:
public
empty_visitor
::
DeclarationVisitor
{
public
:
WfCodegenContext
&
context
;
InitializeFieldVisitor
(
WfCodegenContext
&
_context
) :context(
_context
) { }
void
Dispatch
(
WfVirtualCfeDeclaration
*
node
)
override
{ {
decl
-
>
Accept
(
this
); } }
void
Dispatch
(
WfVirtualCseDeclaration
*
node
)
override
{ {
decl
-
>
Accept
(
this
); } }
void
Visit
(
WfVariableDeclaration
*
node
)
override
{
auto
info
=
context
.
manager
->
declarationMemberInfos
[
node
].
Cast
<
WfField
>().
Obj
();
GenerateExpressionInstructions
(
context
,
node
->
expression
); } };
void
Visit
(
WfConstructorDeclaration
*
node
)
override
{
auto
meta
=
context
.
assembly
-
>
functions
[
context
.
constructors
[
node
]];
auto
functionContext
=
MakePtr
<
WfCodegenFunctionContext
>();
functionContext
-
>
function
=
meta
;
context
.
functionContext
=
functionContext
;
meta
-
>
firstInstruction
=
context
.
assembly
-
>
instructions
.
Count
();
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
(); { {
auto
symbol
=
scope
->
symbols
[
argument
-
>
name
.
value
]
[
0
];
functionContext
-
>
arguments
.
Add
(
symbol
.
Obj
(),
index
); } }
if
(
classDecl
-
>
baseTypes
.
Count
() >
0
) {
auto
td
=
scope
->
parentScope
-
>
typeOfThisExpr
;
vint
count
=
td
->
GetBaseTypeDescriptorCount
();
for
(
vint
i
=
0
;
i
<
count
;
i
++) {
auto
baseTd
=
td
->
GetBaseTypeDescriptor
(
i
);
auto
ctor
=
context
.
manager
->
baseConstructorCallResolvings
[
{
node
,
baseTd
}];
if
(
ctor
.
key
) { {
GenerateExpressionInstructions
(
context
,
argument
); } }
else
{ } } } {
InitializeFieldVisitor
visitor
(
context
); {
memberDecl
-
>
Accept
(&
visitor
); } }
GenerateStatementInstructions
(
context
,
node
->
statement
);
meta
-
>
lastInstruction
=
context
.
assembly
-
>
instructions
.
Count
() -
1
;
context
.
functionContext
=
0
;
GenerateClosureInstructions
(
context
,
functionContext
); }
void
Visit
(
WfDestructorDeclaration
*
node
)
override
{
auto
meta
=
context
.
assembly
-
>
functions
[
context
.
destructors
[
node
]];
auto
functionContext
=
MakePtr
<
WfCodegenFunctionContext
>();
functionContext
-
>
function
=
meta
;
context
.
functionContext
=
functionContext
;
meta
-
>
firstInstruction
=
context
.
assembly
-
>
instructions
.
Count
();
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
GenerateStatementInstructions
(
context
,
node
->
statement
);
meta
-
>
lastInstruction
=
context
.
assembly
-
>
instructions
.
Count
() -
1
;
context
.
functionContext
=
0
;
GenerateClosureInstructions
(
context
,
functionContext
); }
void
Visit
(
WfClassDeclaration
*
node
)
override
{
GenerateDeclarationInstructions
(
context
,
node
); }
void
Visit
(
WfEnumDeclaration
*
node
)
override
{ }
void
Visit
(
WfStructDeclaration
*
node
)
override
{ }
void
Visit
(
WfVirtualCfeDeclaration
*
node
)
override
{ {
decl
-
>
Accept
(
this
); } }
void
Visit
(
WfVirtualCseDeclaration
*
node
)
override
{ {
decl
-
>
Accept
(
this
); } } };
class
GenerateDeclarationInstructionsVisitor
:
public
Object
,
public
WfDeclaration
::
IVisitor
{
public
:
WfCodegenContext
&
context
;
GenerateDeclarationInstructionsVisitor
(
WfCodegenContext
&
_context
) :context(
_context
) { }
void
Visit
(
WfNamespaceDeclaration
*
node
)
override
{ {
GenerateDeclarationInstructions
(
context
,
decl
); } }
void
Visit
(
WfFunctionDeclaration
*
node
)
override
{
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
auto
symbol
=
context
.
manager
->
GetDeclarationSymbol
(
scope
,
node
);
auto
meta
=
context
.
assembly
-
>
functions
[
context
.
globalFunctions
[
symbol
.
Obj
()]];
GenerateFunctionDeclarationInstructions
(
context
,
node
,
scope
,
meta
,
0
); }
void
Visit
(
WfVariableDeclaration
*
node
)
override
{ }
void
Visit
(
WfEventDeclaration
*
node
)
override
{ }
void
Visit
(
WfPropertyDeclaration
*
node
)
override
{ }
void
Visit
(
WfConstructorDeclaration
*
node
)
override
{ }
void
Visit
(
WfDestructorDeclaration
*
node
)
override
{ }
void
Visit
(
WfClassDeclaration
*
node
)
override
{ {
GenerateClassMemberInstructionsVisitor
visitor
(
context
,
node
);
memberDecl
-
>
Accept
(&
visitor
); } }
void
Visit
(
WfEnumDeclaration
*
node
)
override
{ }
void
Visit
(
WfStructDeclaration
*
node
)
override
{ }
void
Visit
(
WfVirtualCfeDeclaration
*
node
)
override
{ {
decl
-
>
Accept
(
this
); } }
void
Visit
(
WfVirtualCseDeclaration
*
node
)
override
{ {
decl
-
>
Accept
(
this
); } } };
void
GenerateDeclarationInstructions
(
WfCodegenContext
&
context
,
Ptr
<
WfDeclaration
>
declaration
) {
GenerateDeclarationInstructionsVisitor
visitor
(
context
);
declaration
-
>
Accept
(&
visitor
); }
/*********************************************************************** GenerateInstructions(Closure) ***********************************************************************/
void
GenerateClosureInstructions_Function
(
WfCodegenContext
&
context
,
vint
functionIndex
,
WfFunctionDeclaration
*
node
,
bool
createInterface
) {
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
auto
meta
=
context
.
assembly
-
>
functions
[
functionIndex
];
GenerateFunctionDeclarationMetadata
(
context
,
node
,
meta
);
Ptr
<
WfLexicalSymbol
>
recursiveLambdaSymbol
;
if
(!
createInterface
&&
node
->
name
.
value
!=
L""
) {
recursiveLambdaSymbol
=
scope
->
symbols
[
node
->
name
.
value
]
[
0
]; }
GenerateFunctionDeclarationInstructions
(
context
,
node
,
scope
,
meta
,
recursiveLambdaSymbol
); }
void
GenerateClosureInstructions_Ordered
(
WfCodegenContext
&
context
,
vint
functionIndex
,
WfOrderedLambdaExpression
*
node
) {
auto
scope
=
context
.
manager
->
nodeScopes
[
node
].
Obj
();
List
<
Ptr
<
WfLexicalSymbol
>>
argumentSymbols
,
capturedSymbols
;
CopyFrom
(
argumentSymbols
,
Range
<
vint
>(
0
,
scope
->
symbols
.
Count
()) .
Select
([scope](
vint
index
)->
Ptr
<
WfLexicalSymbol
>{
return
scope
->
symbols
.
GetByIndex
(
index
)
[
0
];}) .
OrderBy
([](
Ptr
<
WfLexicalSymbol
>
a
,
Ptr
<
WfLexicalSymbol
>
b
) {
vint
aId
=
wtoi
(
a
-
>
name
.
Sub
(
1
,
a
-
>
name
.
Length
() -
1
));
vint
bId
=
wtoi
(
b
-
>
name
.
Sub
(
1
,
a
-
>
name
.
Length
() -
1
));
return
aId
-
bId
; }) );
auto
meta
=
context
.
assembly
-
>
functions
[
functionIndex
]; {
meta
-
>
argumentNames
.
Add
(
symbol
-
>
name
); } {
auto
capture
=
context
.
manager
->
lambdaCaptures
.
Get
(
node
); {
meta
-
>
capturedVariableNames
.
Add
(
L"<captured>"
+
symbol
-
>
name
);
capturedSymbols
.
Add
(
symbol
); }
vint
count
=
context
.
GetThisStackCount
(
scope
);
for
(
vint
i
=
0
;
i
<
count
;
i
++) {
meta
-
>
capturedVariableNames
.
Add
(
L"<captured-this>"
+
itow
(
i
)); } }
auto
result
=
context
.
manager
->
expressionResolvings
[
node
];
auto
returnType
=
CopyTypeInfo
(
result
.
type
-
>
GetElementType
()->
GetGenericArgument
(
0
));
GenerateFunctionInstructions
(
context
,
scope
,
meta
,
returnType
,
0
,
argumentSymbols
,
capturedSymbols
,
node
->
body
,
node
); }
void
GenerateClosureInstructions
(
WfCodegenContext
&
context
,
Ptr
<
WfCodegenFunctionContext
>
functionContext
) {
for
(
vint
i
=
0
;
i
<
functionContext
-
>
closuresToCodegen
.
Count
();
i
++) {
vint
functionIndex
=
functionContext
-
>
closuresToCodegen
.
Keys
()
[
i
];
auto
closure
=
functionContext
-
>
closuresToCodegen
.
Values
()
[
i
];
if
(
closure
.
functionExpression
) {
GenerateClosureInstructions_Function
(
context
,
functionIndex
,
closure
.
functionExpression
->
function
.
Obj
(),
false
); }
else
if
(
closure
.
orderedLambdaExpression
) {
GenerateClosureInstructions_Ordered
(
context
,
functionIndex
,
closure
.
orderedLambdaExpression
); }
else
if
(
closure
.
functionDeclaration
) {
GenerateClosureInstructions_Function
(
context
,
functionIndex
,
closure
.
functionDeclaration
,
true
); } } }
#undef INSTRUCTION
} } }