Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
2affae97
Commit
2affae97
authored
Sep 02, 2016
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Get rid of source->ast
parent
bcd80646
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
163 additions
and
150 deletions
+163
-150
src/codegen/ast_interpreter.cpp
src/codegen/ast_interpreter.cpp
+1
-1
src/codegen/codegen.cpp
src/codegen/codegen.cpp
+3
-3
src/codegen/irgen.cpp
src/codegen/irgen.cpp
+2
-5
src/codegen/irgen/hooks.cpp
src/codegen/irgen/hooks.cpp
+6
-32
src/codegen/irgen/irgenerator.cpp
src/codegen/irgen/irgenerator.cpp
+3
-3
src/core/ast.cpp
src/core/ast.cpp
+73
-0
src/core/ast.h
src/core/ast.h
+8
-0
src/core/cfg.cpp
src/core/cfg.cpp
+26
-50
src/core/cfg.h
src/core/cfg.h
+0
-3
src/core/types.h
src/core/types.h
+6
-4
src/runtime/code.cpp
src/runtime/code.cpp
+20
-40
src/runtime/types.cpp
src/runtime/types.cpp
+2
-2
src/runtime/types.h
src/runtime/types.h
+7
-6
src/runtime/util.cpp
src/runtime/util.cpp
+1
-1
test/tests/docstrings.py
test/tests/docstrings.py
+5
-0
No files found.
src/codegen/ast_interpreter.cpp
View file @
2affae97
...
@@ -929,7 +929,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
...
@@ -929,7 +929,7 @@ Value ASTInterpreter::visit_langPrimitive(AST_LangPrimitive* node) {
assert
(
node
->
args
.
size
()
==
1
);
assert
(
node
->
args
.
size
()
==
1
);
assert
(
node
->
args
[
0
]
->
type
==
AST_TYPE
::
Name
);
assert
(
node
->
args
[
0
]
->
type
==
AST_TYPE
::
Name
);
RELEASE_ASSERT
(
source_info
->
ast
->
type
==
AST_TYPE
::
Module
||
source_info
->
ast
->
type
==
AST_TYPE
::
Suite
,
RELEASE_ASSERT
(
source_info
->
ast
_type
==
AST_TYPE
::
Module
||
source_info
->
ast_
type
==
AST_TYPE
::
Suite
,
"import * not supported in functions"
);
"import * not supported in functions"
);
Value
module
=
visit_expr
(
node
->
args
[
0
]);
Value
module
=
visit_expr
(
node
->
args
[
0
]);
...
...
src/codegen/codegen.cpp
View file @
2affae97
...
@@ -59,9 +59,9 @@ void BoxedCode::addVersion(CompiledFunction* compiled) {
...
@@ -59,9 +59,9 @@ void BoxedCode::addVersion(CompiledFunction* compiled) {
}
}
SourceInfo
::
SourceInfo
(
BoxedModule
*
m
,
ScopingResults
scoping
,
FutureFlags
future_flags
,
AST
*
ast
)
SourceInfo
::
SourceInfo
(
BoxedModule
*
m
,
ScopingResults
scoping
,
FutureFlags
future_flags
,
AST
*
ast
)
:
parent_module
(
m
),
scoping
(
std
::
move
(
scoping
)),
ast
(
ast
),
cfg
(
NULL
),
future_flags
(
future_flags
)
{
:
parent_module
(
m
),
scoping
(
std
::
move
(
scoping
)),
cfg
(
NULL
),
future_flags
(
future_flags
),
ast_type
(
ast
->
type
)
{
switch
(
ast
->
type
)
{
switch
(
ast
_
type
)
{
case
AST_TYPE
:
:
ClassDef
:
case
AST_TYPE
:
:
ClassDef
:
case
AST_TYPE
:
:
Module
:
case
AST_TYPE
:
:
Module
:
case
AST_TYPE
:
:
Expression
:
case
AST_TYPE
:
:
Expression
:
...
@@ -73,7 +73,7 @@ SourceInfo::SourceInfo(BoxedModule* m, ScopingResults scoping, FutureFlags futur
...
@@ -73,7 +73,7 @@ SourceInfo::SourceInfo(BoxedModule* m, ScopingResults scoping, FutureFlags futur
is_generator
=
containsYield
(
ast
);
is_generator
=
containsYield
(
ast
);
break
;
break
;
default:
default:
RELEASE_ASSERT
(
0
,
"Unknown type: %d"
,
ast
->
type
);
RELEASE_ASSERT
(
0
,
"Unknown type: %d"
,
ast
_
type
);
break
;
break
;
}
}
}
}
...
...
src/codegen/irgen.cpp
View file @
2affae97
...
@@ -551,8 +551,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
...
@@ -551,8 +551,7 @@ static void emitBBs(IRGenState* irstate, TypeAnalysis* types, const OSREntryDesc
if
(
block
==
cfg
->
getStartingBlock
())
{
if
(
block
==
cfg
->
getStartingBlock
())
{
assert
(
entry_descriptor
==
NULL
);
assert
(
entry_descriptor
==
NULL
);
if
(
ENABLE_REOPT
&&
effort
<
EffortLevel
::
MAXIMAL
&&
source
->
ast
!=
NULL
if
(
ENABLE_REOPT
&&
effort
<
EffortLevel
::
MAXIMAL
&&
source
->
ast_type
!=
AST_TYPE
::
Module
)
{
&&
source
->
ast
->
type
!=
AST_TYPE
::
Module
)
{
llvm
::
BasicBlock
*
preentry_bb
=
llvm
::
BasicBlock
::
Create
(
llvm
::
BasicBlock
*
preentry_bb
=
llvm
::
BasicBlock
::
Create
(
g
.
context
,
"pre_entry"
,
irstate
->
getLLVMFunction
(),
llvm_entry_blocks
[
cfg
->
getStartingBlock
()]);
g
.
context
,
"pre_entry"
,
irstate
->
getLLVMFunction
(),
llvm_entry_blocks
[
cfg
->
getStartingBlock
()]);
llvm
::
BasicBlock
*
reopt_bb
=
llvm
::
BasicBlock
::
Create
(
g
.
context
,
"reopt"
,
irstate
->
getLLVMFunction
());
llvm
::
BasicBlock
*
reopt_bb
=
llvm
::
BasicBlock
::
Create
(
g
.
context
,
"reopt"
,
irstate
->
getLLVMFunction
());
...
@@ -989,9 +988,7 @@ static void computeBlockSetClosure(BlockSet& blocks) {
...
@@ -989,9 +988,7 @@ static void computeBlockSetClosure(BlockSet& blocks) {
}
}
// returns a pointer to the function-info mdnode
// returns a pointer to the function-info mdnode
static
llvm
::
MDNode
*
setupDebugInfo
(
BoxedCode
*
code
,
llvm
::
Function
*
f
,
std
::
string
origname
)
{
static
llvm
::
MDNode
*
setupDebugInfo
(
BoxedCode
*
code
,
llvm
::
Function
*
f
,
std
::
string
origname
)
{
int
lineno
=
0
;
int
lineno
=
code
->
firstlineno
;
if
(
code
->
source
->
ast
)
lineno
=
code
->
source
->
ast
->
lineno
;
llvm
::
DIBuilder
builder
(
*
g
.
cur_module
);
llvm
::
DIBuilder
builder
(
*
g
.
cur_module
);
...
...
src/codegen/irgen/hooks.cpp
View file @
2affae97
...
@@ -54,31 +54,6 @@
...
@@ -54,31 +54,6 @@
namespace
pyston
{
namespace
pyston
{
llvm
::
ArrayRef
<
AST_stmt
*>
SourceInfo
::
getBody
()
const
{
switch
(
ast
->
type
)
{
case
AST_TYPE
:
:
ClassDef
:
return
((
AST_ClassDef
*
)
ast
)
->
body
;
case
AST_TYPE
:
:
Expression
:
return
((
AST_Expression
*
)
ast
)
->
body
;
case
AST_TYPE
:
:
FunctionDef
:
return
((
AST_FunctionDef
*
)
ast
)
->
body
;
case
AST_TYPE
:
:
Module
:
return
((
AST_Module
*
)
ast
)
->
body
;
default:
RELEASE_ASSERT
(
0
,
"unknown %d"
,
ast
->
type
);
};
}
Box
*
SourceInfo
::
getDocString
()
{
auto
body
=
getBody
();
if
(
body
.
size
()
>
0
&&
body
[
0
]
->
type
==
AST_TYPE
::
Expr
&&
static_cast
<
AST_Expr
*>
(
body
[
0
])
->
value
->
type
==
AST_TYPE
::
Str
)
{
return
boxString
(
static_cast
<
AST_Str
*>
(
static_cast
<
AST_Expr
*>
(
body
[
0
])
->
value
)
->
str_data
);
}
return
incref
(
Py_None
);
}
LivenessAnalysis
*
SourceInfo
::
getLiveness
()
{
LivenessAnalysis
*
SourceInfo
::
getLiveness
()
{
if
(
!
liveness_info
)
if
(
!
liveness_info
)
liveness_info
=
computeLivenessInfo
(
cfg
);
liveness_info
=
computeLivenessInfo
(
cfg
);
...
@@ -258,11 +233,11 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
...
@@ -258,11 +233,11 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
FutureFlags
future_flags
=
getFutureFlags
(
m
->
body
,
fn
);
FutureFlags
future_flags
=
getFutureFlags
(
m
->
body
,
fn
);
computeAllCFGs
(
m
,
/* globals_from_module */
true
,
future_flags
,
autoDecref
(
boxString
(
fn
)),
bm
);
computeAllCFGs
(
m
,
/* globals_from_module */
true
,
future_flags
,
autoDecref
(
boxString
(
fn
)),
bm
);
BoxedCode
*
code
=
codeForAST
(
m
);
BoxedCode
*
code
=
m
->
getCode
(
);
assert
(
code
);
assert
(
code
);
static
BoxedString
*
doc_str
=
getStaticString
(
"__doc__"
);
static
BoxedString
*
doc_str
=
getStaticString
(
"__doc__"
);
bm
->
setattr
(
doc_str
,
autoDecref
(
code
->
source
->
getDocString
())
,
NULL
);
bm
->
setattr
(
doc_str
,
code
->
_doc
,
NULL
);
static
BoxedString
*
builtins_str
=
getStaticString
(
"__builtins__"
);
static
BoxedString
*
builtins_str
=
getStaticString
(
"__builtins__"
);
if
(
!
bm
->
hasattr
(
builtins_str
))
if
(
!
bm
->
hasattr
(
builtins_str
))
...
@@ -279,12 +254,11 @@ Box* evalOrExec(BoxedCode* code, Box* globals, Box* boxedLocals) {
...
@@ -279,12 +254,11 @@ Box* evalOrExec(BoxedCode* code, Box* globals, Box* boxedLocals) {
assert
(
globals
&&
(
globals
->
cls
==
module_cls
||
globals
->
cls
==
dict_cls
));
assert
(
globals
&&
(
globals
->
cls
==
module_cls
||
globals
->
cls
==
dict_cls
));
Box
*
doc_string
=
code
->
source
->
getDocString
();
// TODO: we're supposed to embed this directly into the bytecode
Box
*
doc_string
=
code
->
_doc
;
if
(
doc_string
!=
Py_None
)
{
if
(
doc_string
!=
Py_None
)
{
static
BoxedString
*
doc_box
=
getStaticString
(
"__doc__"
);
static
BoxedString
*
doc_box
=
getStaticString
(
"__doc__"
);
setGlobal
(
boxedLocals
,
doc_box
,
doc_string
);
setGlobal
(
boxedLocals
,
doc_box
,
incref
(
doc_string
));
}
else
{
Py_DECREF
(
doc_string
);
}
}
return
astInterpretFunctionEval
(
code
,
globals
,
boxedLocals
);
return
astInterpretFunctionEval
(
code
,
globals
,
boxedLocals
);
...
@@ -306,7 +280,7 @@ static BoxedCode* compileForEvalOrExec(AST* source, llvm::ArrayRef<AST_stmt*> bo
...
@@ -306,7 +280,7 @@ static BoxedCode* compileForEvalOrExec(AST* source, llvm::ArrayRef<AST_stmt*> bo
}
}
computeAllCFGs
(
source
,
/* globals_from_module */
false
,
future_flags
,
fn
,
getCurrentModule
());
computeAllCFGs
(
source
,
/* globals_from_module */
false
,
future_flags
,
fn
,
getCurrentModule
());
return
codeForAST
(
source
);
return
source
->
getCode
(
);
}
}
static
BoxedCode
*
compileExec
(
AST_Module
*
parsedModule
,
BoxedString
*
fn
,
PyCompilerFlags
*
flags
)
{
static
BoxedCode
*
compileExec
(
AST_Module
*
parsedModule
,
BoxedString
*
fn
,
PyCompilerFlags
*
flags
)
{
...
...
src/codegen/irgen/irgenerator.cpp
View file @
2affae97
...
@@ -988,7 +988,7 @@ private:
...
@@ -988,7 +988,7 @@ private:
assert
(
node
->
args
.
size
()
==
1
);
assert
(
node
->
args
.
size
()
==
1
);
assert
(
node
->
args
[
0
]
->
type
==
AST_TYPE
::
Name
);
assert
(
node
->
args
[
0
]
->
type
==
AST_TYPE
::
Name
);
RELEASE_ASSERT
(
irstate
->
getSourceInfo
()
->
ast
->
type
==
AST_TYPE
::
Module
,
RELEASE_ASSERT
(
irstate
->
getSourceInfo
()
->
ast
_
type
==
AST_TYPE
::
Module
,
"import * not supported in functions (yet)"
);
"import * not supported in functions (yet)"
);
CompilerVariable
*
module
=
evalExpr
(
node
->
args
[
0
],
unw_info
);
CompilerVariable
*
module
=
evalExpr
(
node
->
args
[
0
],
unw_info
);
...
@@ -1709,8 +1709,8 @@ private:
...
@@ -1709,8 +1709,8 @@ private:
// I think it's better to just not generate bad speculations:
// I think it's better to just not generate bad speculations:
if
(
rtn
->
canConvertTo
(
speculated_type
))
{
if
(
rtn
->
canConvertTo
(
speculated_type
))
{
auto
source
=
irstate
->
getSourceInfo
();
auto
source
=
irstate
->
getSourceInfo
();
printf
(
"On %s:%d, function %s:
\n
"
,
irstate
->
getCode
()
->
filename
->
c_str
(),
source
->
getBody
()[
0
]
->
lineno
,
printf
(
"On %s:%d, function %s:
\n
"
,
irstate
->
getCode
()
->
filename
->
c_str
(),
irstate
->
getCode
()
->
name
->
c_str
());
irstate
->
getCode
()
->
firstlineno
,
irstate
->
getCode
()
->
name
->
c_str
());
irstate
->
getSourceInfo
()
->
cfg
->
print
();
irstate
->
getSourceInfo
()
->
cfg
->
print
();
}
}
RELEASE_ASSERT
(
!
rtn
->
canConvertTo
(
speculated_type
),
"%s %s"
,
rtn
->
getType
()
->
debugName
().
c_str
(),
RELEASE_ASSERT
(
!
rtn
->
canConvertTo
(
speculated_type
),
"%s %s"
,
rtn
->
getType
()
->
debugName
().
c_str
(),
...
...
src/core/ast.cpp
View file @
2affae97
...
@@ -2261,4 +2261,77 @@ void flatten(AST_expr* root, std::vector<AST*>& output, bool expand_scopes) {
...
@@ -2261,4 +2261,77 @@ void flatten(AST_expr* root, std::vector<AST*>& output, bool expand_scopes) {
root
->
accept
(
&
visitor
);
root
->
accept
(
&
visitor
);
}
}
BoxedCode
*&
AST
::
getCode
()
{
switch
(
this
->
type
)
{
case
AST_TYPE
:
:
Expression
:
return
ast_cast
<
AST_Expression
>
(
this
)
->
code
;
case
AST_TYPE
:
:
FunctionDef
:
return
ast_cast
<
AST_FunctionDef
>
(
this
)
->
code
;
case
AST_TYPE
:
:
ClassDef
:
return
ast_cast
<
AST_ClassDef
>
(
this
)
->
code
;
case
AST_TYPE
:
:
Module
:
return
ast_cast
<
AST_Module
>
(
this
)
->
code
;
default:
break
;
}
RELEASE_ASSERT
(
0
,
"%d"
,
this
->
type
);
}
InternedStringPool
&
AST
::
getStringpool
()
{
switch
(
this
->
type
)
{
case
AST_TYPE
:
:
Expression
:
return
*
ast_cast
<
AST_Expression
>
(
this
)
->
interned_strings
;
case
AST_TYPE
:
:
Module
:
return
*
ast_cast
<
AST_Module
>
(
this
)
->
interned_strings
;
default:
break
;
}
RELEASE_ASSERT
(
0
,
"%d"
,
this
->
type
);
}
llvm
::
ArrayRef
<
AST_stmt
*>
AST
::
getBody
()
{
switch
(
this
->
type
)
{
case
AST_TYPE
:
:
ClassDef
:
return
((
AST_ClassDef
*
)
this
)
->
body
;
case
AST_TYPE
:
:
Expression
:
return
((
AST_Expression
*
)
this
)
->
body
;
case
AST_TYPE
:
:
FunctionDef
:
return
((
AST_FunctionDef
*
)
this
)
->
body
;
case
AST_TYPE
:
:
Module
:
return
((
AST_Module
*
)
this
)
->
body
;
default:
RELEASE_ASSERT
(
0
,
"unknown %d"
,
this
->
type
);
};
}
Box
*
AST
::
getDocString
()
{
auto
body
=
this
->
getBody
();
if
(
body
.
size
()
>
0
&&
body
[
0
]
->
type
==
AST_TYPE
::
Expr
&&
static_cast
<
AST_Expr
*>
(
body
[
0
])
->
value
->
type
==
AST_TYPE
::
Str
)
{
return
boxString
(
static_cast
<
AST_Str
*>
(
static_cast
<
AST_Expr
*>
(
body
[
0
])
->
value
)
->
str_data
);
}
return
incref
(
Py_None
);
}
BORROWED
(
BoxedString
*
)
AST
::
getName
()
noexcept
{
static
BoxedString
*
lambda_name
=
getStaticString
(
"<lambda>"
);
static
BoxedString
*
module_name
=
getStaticString
(
"<module>"
);
switch
(
this
->
type
)
{
case
AST_TYPE
:
:
ClassDef
:
return
ast_cast
<
AST_ClassDef
>
(
this
)
->
name
.
getBox
();
case
AST_TYPE
:
:
FunctionDef
:
if
(
ast_cast
<
AST_FunctionDef
>
(
this
)
->
name
!=
InternedString
())
return
ast_cast
<
AST_FunctionDef
>
(
this
)
->
name
.
getBox
();
return
lambda_name
;
case
AST_TYPE
:
:
Module
:
case
AST_TYPE
:
:
Expression
:
case
AST_TYPE
:
:
Suite
:
return
module_name
;
default:
RELEASE_ASSERT
(
0
,
"%d"
,
this
->
type
);
}
}
}
}
src/core/ast.h
View file @
2affae97
...
@@ -188,6 +188,14 @@ public:
...
@@ -188,6 +188,14 @@ public:
#endif
#endif
AST
(
AST_TYPE
::
AST_TYPE
type
,
uint32_t
lineno
,
uint32_t
col_offset
=
0
)
AST
(
AST_TYPE
::
AST_TYPE
type
,
uint32_t
lineno
,
uint32_t
col_offset
=
0
)
:
type
(
type
),
lineno
(
lineno
),
col_offset
(
col_offset
)
{}
:
type
(
type
),
lineno
(
lineno
),
col_offset
(
col_offset
)
{}
// These could be virtual methods, but since we already keep track of the type use a switch statement
// like everywhere else.
BoxedCode
*&
getCode
();
InternedStringPool
&
getStringpool
();
llvm
::
ArrayRef
<
AST_stmt
*>
getBody
();
Box
*
getDocString
();
BORROWED
(
BoxedString
*
)
getName
()
noexcept
;
};
};
class
AST_expr
:
public
AST
{
class
AST_expr
:
public
AST
{
...
...
src/core/cfg.cpp
View file @
2affae97
...
@@ -251,7 +251,7 @@ public:
...
@@ -251,7 +251,7 @@ public:
ModuleCFGProcessor
(
AST
*
ast
,
bool
globals_from_module
,
FutureFlags
future_flags
,
BoxedString
*
fn
,
BoxedModule
*
bm
)
ModuleCFGProcessor
(
AST
*
ast
,
bool
globals_from_module
,
FutureFlags
future_flags
,
BoxedString
*
fn
,
BoxedModule
*
bm
)
:
scoping
(
ast
,
globals_from_module
),
:
scoping
(
ast
,
globals_from_module
),
stringpool
(
stringpoolForAST
(
ast
)),
stringpool
(
ast
->
getStringpool
(
)),
future_flags
(
future_flags
),
future_flags
(
future_flags
),
fn
(
fn
),
fn
(
fn
),
bm
(
bm
)
{}
bm
(
bm
)
{}
...
@@ -263,7 +263,7 @@ public:
...
@@ -263,7 +263,7 @@ public:
void
runRecursively
(
AST
*
ast
,
AST_arguments
*
args
,
AST
*
orig_node
);
void
runRecursively
(
AST
*
ast
,
AST_arguments
*
args
,
AST
*
orig_node
);
};
};
static
CFG
*
computeCFG
(
BoxedString
*
fn
,
SourceInfo
*
source
,
const
ParamNames
&
param_names
,
ScopeInfo
*
scoping
,
static
CFG
*
computeCFG
(
AST
*
ast
,
BoxedString
*
fn
,
SourceInfo
*
source
,
const
ParamNames
&
param_names
,
ScopeInfo
*
scoping
,
ModuleCFGProcessor
*
cfgizer
);
ModuleCFGProcessor
*
cfgizer
);
// A class that crawls the AST of a single function and computes the CFG
// A class that crawls the AST of a single function and computes the CFG
...
@@ -361,7 +361,7 @@ private:
...
@@ -361,7 +361,7 @@ private:
unsigned
int
next_var_index
=
0
;
unsigned
int
next_var_index
=
0
;
friend
CFG
*
computeCFG
(
BoxedString
*
fn
,
SourceInfo
*
source
,
const
ParamNames
&
param_names
,
ScopeInfo
*
,
friend
CFG
*
computeCFG
(
AST
*
ast
,
BoxedString
*
fn
,
SourceInfo
*
source
,
const
ParamNames
&
param_names
,
ScopeInfo
*
,
ModuleCFGProcessor
*
);
ModuleCFGProcessor
*
);
public:
public:
...
@@ -2961,32 +2961,32 @@ void VRegInfo::assignVRegs(CFG* cfg, const ParamNames& param_names) {
...
@@ -2961,32 +2961,32 @@ void VRegInfo::assignVRegs(CFG* cfg, const ParamNames& param_names) {
}
}
static
CFG
*
computeCFG
(
BoxedString
*
filename
,
SourceInfo
*
source
,
const
ParamNames
&
param_names
,
ScopeInfo
*
scoping
,
static
CFG
*
computeCFG
(
AST
*
ast
,
BoxedString
*
filename
,
SourceInfo
*
source
,
const
ParamNames
&
param_names
,
ModuleCFGProcessor
*
cfgizer
)
{
ScopeInfo
*
scoping
,
ModuleCFGProcessor
*
cfgizer
)
{
STAT_TIMER
(
t0
,
"us_timer_computecfg"
,
0
);
STAT_TIMER
(
t0
,
"us_timer_computecfg"
,
0
);
auto
body
=
source
->
getBody
();
auto
body
=
ast
->
getBody
();
CFG
*
rtn
=
new
CFG
();
CFG
*
rtn
=
new
CFG
();
auto
&&
stringpool
=
cfgizer
->
stringpool
;
auto
&&
stringpool
=
cfgizer
->
stringpool
;
CFGVisitor
visitor
(
filename
,
source
,
stringpool
,
scoping
,
source
->
ast
->
type
,
source
->
future_flags
,
rtn
,
cfgizer
);
CFGVisitor
visitor
(
filename
,
source
,
stringpool
,
scoping
,
ast
->
type
,
source
->
future_flags
,
rtn
,
cfgizer
);
bool
skip_first
=
false
;
bool
skip_first
=
false
;
if
(
source
->
ast
->
type
==
AST_TYPE
::
ClassDef
)
{
if
(
ast
->
type
==
AST_TYPE
::
ClassDef
)
{
// A classdef always starts with "__module__ = __name__"
// A classdef always starts with "__module__ = __name__"
AST_Assign
*
module_assign
=
new
AST_Assign
();
AST_Assign
*
module_assign
=
new
AST_Assign
();
auto
module_name_target
=
new
AST_Name
(
stringpool
.
get
(
"__module__"
),
AST_TYPE
::
Store
,
source
->
ast
->
lineno
);
auto
module_name_target
=
new
AST_Name
(
stringpool
.
get
(
"__module__"
),
AST_TYPE
::
Store
,
ast
->
lineno
);
fillScopingInfo
(
module_name_target
,
scoping
);
fillScopingInfo
(
module_name_target
,
scoping
);
auto
module_name_value
=
new
AST_Name
(
stringpool
.
get
(
"__name__"
),
AST_TYPE
::
Load
,
source
->
ast
->
lineno
);
auto
module_name_value
=
new
AST_Name
(
stringpool
.
get
(
"__name__"
),
AST_TYPE
::
Load
,
ast
->
lineno
);
fillScopingInfo
(
module_name_value
,
scoping
);
fillScopingInfo
(
module_name_value
,
scoping
);
module_assign
->
targets
.
push_back
(
module_name_target
);
module_assign
->
targets
.
push_back
(
module_name_target
);
module_assign
->
value
=
module_name_value
;
module_assign
->
value
=
module_name_value
;
module_assign
->
lineno
=
source
->
ast
->
lineno
;
module_assign
->
lineno
=
ast
->
lineno
;
visitor
.
push_back
(
module_assign
);
visitor
.
push_back
(
module_assign
);
// If the first statement is just a single string, transform it to an assignment to __doc__
// If the first statement is just a single string, transform it to an assignment to __doc__
...
@@ -2994,18 +2994,18 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
...
@@ -2994,18 +2994,18 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
AST_Expr
*
first_expr
=
ast_cast
<
AST_Expr
>
(
body
[
0
]);
AST_Expr
*
first_expr
=
ast_cast
<
AST_Expr
>
(
body
[
0
]);
if
(
first_expr
->
value
->
type
==
AST_TYPE
::
Str
)
{
if
(
first_expr
->
value
->
type
==
AST_TYPE
::
Str
)
{
AST_Assign
*
doc_assign
=
new
AST_Assign
();
AST_Assign
*
doc_assign
=
new
AST_Assign
();
auto
doc_target_name
=
new
AST_Name
(
stringpool
.
get
(
"__doc__"
),
AST_TYPE
::
Store
,
source
->
ast
->
lineno
);
auto
doc_target_name
=
new
AST_Name
(
stringpool
.
get
(
"__doc__"
),
AST_TYPE
::
Store
,
ast
->
lineno
);
fillScopingInfo
(
doc_target_name
,
scoping
);
fillScopingInfo
(
doc_target_name
,
scoping
);
doc_assign
->
targets
.
push_back
(
doc_target_name
);
doc_assign
->
targets
.
push_back
(
doc_target_name
);
doc_assign
->
value
=
first_expr
->
value
;
doc_assign
->
value
=
first_expr
->
value
;
doc_assign
->
lineno
=
source
->
ast
->
lineno
;
doc_assign
->
lineno
=
ast
->
lineno
;
visitor
.
push_back
(
doc_assign
);
visitor
.
push_back
(
doc_assign
);
skip_first
=
true
;
skip_first
=
true
;
}
}
}
}
}
}
if
(
source
->
ast
->
type
==
AST_TYPE
::
FunctionDef
||
source
->
ast
->
type
==
AST_TYPE
::
Lambda
)
{
if
(
ast
->
type
==
AST_TYPE
::
FunctionDef
||
ast
->
type
==
AST_TYPE
::
Lambda
)
{
// Unpack tuple arguments
// Unpack tuple arguments
// Tuple arguments get assigned names ".0", ".1" etc. So this
// Tuple arguments get assigned names ".0", ".1" etc. So this
// def f(a, (b,c), (d,e)):
// def f(a, (b,c), (d,e)):
...
@@ -3014,10 +3014,10 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
...
@@ -3014,10 +3014,10 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
// (b, c) = .1
// (b, c) = .1
// (d, e) = .2
// (d, e) = .2
AST_arguments
*
args
;
AST_arguments
*
args
;
if
(
source
->
ast
->
type
==
AST_TYPE
::
FunctionDef
)
{
if
(
ast
->
type
==
AST_TYPE
::
FunctionDef
)
{
args
=
ast_cast
<
AST_FunctionDef
>
(
source
->
ast
)
->
args
;
args
=
ast_cast
<
AST_FunctionDef
>
(
ast
)
->
args
;
}
else
{
}
else
{
args
=
ast_cast
<
AST_Lambda
>
(
source
->
ast
)
->
args
;
args
=
ast_cast
<
AST_Lambda
>
(
ast
)
->
args
;
}
}
int
counter
=
0
;
int
counter
=
0
;
for
(
AST_expr
*
arg_expr
:
args
->
args
)
{
for
(
AST_expr
*
arg_expr
:
args
->
args
)
{
...
@@ -3044,11 +3044,11 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
...
@@ -3044,11 +3044,11 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
// The functions we create for classdefs are supposed to return a dictionary of their locals.
// The functions we create for classdefs are supposed to return a dictionary of their locals.
// This is the place that we add all of that:
// This is the place that we add all of that:
if
(
source
->
ast
->
type
==
AST_TYPE
::
ClassDef
)
{
if
(
ast
->
type
==
AST_TYPE
::
ClassDef
)
{
AST_LangPrimitive
*
locals
=
new
AST_LangPrimitive
(
AST_LangPrimitive
::
LOCALS
);
AST_LangPrimitive
*
locals
=
new
AST_LangPrimitive
(
AST_LangPrimitive
::
LOCALS
);
AST_Return
*
rtn
=
new
AST_Return
();
AST_Return
*
rtn
=
new
AST_Return
();
rtn
->
lineno
=
getLastLineno
(
source
->
ast
);
rtn
->
lineno
=
getLastLineno
(
ast
);
rtn
->
value
=
locals
;
rtn
->
value
=
locals
;
visitor
.
push_back
(
rtn
);
visitor
.
push_back
(
rtn
);
}
else
{
}
else
{
...
@@ -3056,7 +3056,7 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
...
@@ -3056,7 +3056,7 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
// we already have to support multiple return statements in a function, but this way we can avoid
// we already have to support multiple return statements in a function, but this way we can avoid
// having to support not having a return statement:
// having to support not having a return statement:
AST_Return
*
return_stmt
=
new
AST_Return
();
AST_Return
*
return_stmt
=
new
AST_Return
();
return_stmt
->
lineno
=
getLastLineno
(
source
->
ast
);
return_stmt
->
lineno
=
getLastLineno
(
ast
);
return_stmt
->
col_offset
=
0
;
return_stmt
->
col_offset
=
0
;
return_stmt
->
value
=
NULL
;
return_stmt
->
value
=
NULL
;
visitor
.
push_back
(
return_stmt
);
visitor
.
push_back
(
return_stmt
);
...
@@ -3261,32 +3261,6 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
...
@@ -3261,32 +3261,6 @@ static CFG* computeCFG(BoxedString* filename, SourceInfo* source, const ParamNam
return
rtn
;
return
rtn
;
}
}
BoxedCode
*&
codeForAST
(
AST
*
ast
)
{
switch
(
ast
->
type
)
{
case
AST_TYPE
:
:
Expression
:
return
ast_cast
<
AST_Expression
>
(
ast
)
->
code
;
case
AST_TYPE
:
:
FunctionDef
:
return
ast_cast
<
AST_FunctionDef
>
(
ast
)
->
code
;
case
AST_TYPE
:
:
ClassDef
:
return
ast_cast
<
AST_ClassDef
>
(
ast
)
->
code
;
case
AST_TYPE
:
:
Module
:
return
ast_cast
<
AST_Module
>
(
ast
)
->
code
;
default:
break
;
}
RELEASE_ASSERT
(
0
,
"%d"
,
ast
->
type
);
}
InternedStringPool
&
stringpoolForAST
(
AST
*
ast
)
{
switch
(
ast
->
type
)
{
case
AST_TYPE
:
:
Expression
:
return
*
ast_cast
<
AST_Expression
>
(
ast
)
->
interned_strings
;
case
AST_TYPE
:
:
Module
:
return
*
ast_cast
<
AST_Module
>
(
ast
)
->
interned_strings
;
default:
break
;
}
RELEASE_ASSERT
(
0
,
"%d"
,
ast
->
type
);
}
void
ModuleCFGProcessor
::
runRecursively
(
AST
*
ast
,
AST_arguments
*
args
,
AST
*
orig_node
)
{
void
ModuleCFGProcessor
::
runRecursively
(
AST
*
ast
,
AST_arguments
*
args
,
AST
*
orig_node
)
{
ScopeInfo
*
scope_info
=
scoping
.
getScopeInfoForNode
(
orig_node
);
ScopeInfo
*
scope_info
=
scoping
.
getScopeInfoForNode
(
orig_node
);
...
@@ -3297,18 +3271,20 @@ void ModuleCFGProcessor::runRecursively(AST* ast, AST_arguments* args, AST* orig
...
@@ -3297,18 +3271,20 @@ void ModuleCFGProcessor::runRecursively(AST* ast, AST_arguments* args, AST* orig
for
(
auto
e
:
param_names
.
allArgsAsName
())
for
(
auto
e
:
param_names
.
allArgsAsName
())
fillScopingInfo
(
e
,
scope_info
);
fillScopingInfo
(
e
,
scope_info
);
si
->
cfg
=
computeCFG
(
fn
,
si
.
get
(),
param_names
,
scope_info
,
this
);
si
->
cfg
=
computeCFG
(
ast
,
fn
,
si
.
get
(),
param_names
,
scope_info
,
this
);
BoxedCode
*
code
;
BoxedCode
*
code
;
if
(
args
)
if
(
args
)
code
=
new
BoxedCode
(
args
->
args
.
size
(),
args
->
vararg
,
args
->
kwarg
,
std
::
move
(
si
),
std
::
move
(
param_names
),
fn
);
code
=
new
BoxedCode
(
args
->
args
.
size
(),
args
->
vararg
,
args
->
kwarg
,
ast
->
lineno
,
std
::
move
(
si
),
std
::
move
(
param_names
),
fn
,
ast
->
getName
(),
autoDecref
(
ast
->
getDocString
()));
else
else
code
=
new
BoxedCode
(
0
,
false
,
false
,
std
::
move
(
si
),
std
::
move
(
param_names
),
fn
);
code
=
new
BoxedCode
(
0
,
false
,
false
,
ast
->
lineno
,
std
::
move
(
si
),
std
::
move
(
param_names
),
fn
,
ast
->
getName
(),
autoDecref
(
ast
->
getDocString
()));
// XXX very bad! Should properly track this:
// XXX very bad! Should properly track this:
constants
.
push_back
(
code
);
constants
.
push_back
(
code
);
codeForAST
(
ast
)
=
code
;
ast
->
getCode
(
)
=
code
;
}
}
void
computeAllCFGs
(
AST
*
ast
,
bool
globals_from_module
,
FutureFlags
future_flags
,
BoxedString
*
fn
,
BoxedModule
*
bm
)
{
void
computeAllCFGs
(
AST
*
ast
,
bool
globals_from_module
,
FutureFlags
future_flags
,
BoxedString
*
fn
,
BoxedModule
*
bm
)
{
...
...
src/core/cfg.h
View file @
2affae97
...
@@ -330,9 +330,6 @@ public:
...
@@ -330,9 +330,6 @@ public:
iterator
end
()
const
{
return
iterator
(
*
this
,
this
->
v
.
size
());
}
iterator
end
()
const
{
return
iterator
(
*
this
,
this
->
v
.
size
());
}
};
};
BoxedCode
*&
codeForAST
(
AST
*
ast
);
InternedStringPool
&
stringpoolForAST
(
AST
*
ast
);
void
computeAllCFGs
(
AST
*
ast
,
bool
globals_from_module
,
FutureFlags
future_flags
,
BoxedString
*
fn
,
BoxedModule
*
bm
);
void
computeAllCFGs
(
AST
*
ast
,
bool
globals_from_module
,
FutureFlags
future_flags
,
BoxedString
*
fn
,
BoxedModule
*
bm
);
void
printCFG
(
CFG
*
cfg
);
void
printCFG
(
CFG
*
cfg
);
}
}
...
...
src/core/types.h
View file @
2affae97
...
@@ -491,16 +491,18 @@ private:
...
@@ -491,16 +491,18 @@ private:
public:
public:
BoxedModule
*
parent_module
;
BoxedModule
*
parent_module
;
ScopingResults
scoping
;
ScopingResults
scoping
;
AST
*
ast
;
CFG
*
cfg
;
CFG
*
cfg
;
FutureFlags
future_flags
;
FutureFlags
future_flags
;
bool
is_generator
;
bool
is_generator
;
LivenessAnalysis
*
getLiveness
();
// This should really be an AST_TYPE::AST_TYPE, using that would require resolving a circular dependency
// between ast.h and core/types.h
int
ast_type
;
llvm
::
ArrayRef
<
AST_stmt
*>
getBody
()
const
;
LivenessAnalysis
*
getLiveness
()
;
Box
*
getDocString
();
// llvm::ArrayRef<AST_stmt*> getBody() const;
// Box* getDocString();
SourceInfo
(
BoxedModule
*
m
,
ScopingResults
scoping
,
FutureFlags
future_flags
,
AST
*
ast
);
SourceInfo
(
BoxedModule
*
m
,
ScopingResults
scoping
,
FutureFlags
future_flags
,
AST
*
ast
);
~
SourceInfo
();
~
SourceInfo
();
...
...
src/runtime/code.cpp
View file @
2affae97
...
@@ -58,17 +58,11 @@ Box* BoxedCode::co_filename(Box* b, void* arg) noexcept {
...
@@ -58,17 +58,11 @@ Box* BoxedCode::co_filename(Box* b, void* arg) noexcept {
return
incref
(
code
->
filename
);
return
incref
(
code
->
filename
);
}
}
Box
*
BoxedCode
::
firstlineno
(
Box
*
b
,
void
*
)
noexcept
{
Box
*
BoxedCode
::
co_
firstlineno
(
Box
*
b
,
void
*
)
noexcept
{
RELEASE_ASSERT
(
b
->
cls
==
code_cls
,
""
);
RELEASE_ASSERT
(
b
->
cls
==
code_cls
,
""
);
BoxedCode
*
code
=
static_cast
<
BoxedCode
*>
(
b
);
BoxedCode
*
code
=
static_cast
<
BoxedCode
*>
(
b
);
if
(
!
code
||
!
code
->
source
)
return
boxInt
(
code
->
firstlineno
);
return
boxInt
(
code
->
_firstline
);
if
(
code
->
source
->
ast
->
lineno
==
(
uint32_t
)
-
1
)
return
boxInt
(
-
1
);
return
boxInt
(
code
->
source
->
ast
->
lineno
);
}
}
Box
*
BoxedCode
::
argcount
(
Box
*
b
,
void
*
)
noexcept
{
Box
*
BoxedCode
::
argcount
(
Box
*
b
,
void
*
)
noexcept
{
...
@@ -112,39 +106,21 @@ void BoxedCode::dealloc(Box* b) noexcept {
...
@@ -112,39 +106,21 @@ void BoxedCode::dealloc(Box* b) noexcept {
Py_XDECREF
(
o
->
filename
);
Py_XDECREF
(
o
->
filename
);
Py_XDECREF
(
o
->
name
);
Py_XDECREF
(
o
->
name
);
Py_XDECREF
(
o
->
_doc
);
o
->
source
.
~
decltype
(
o
->
source
)();
o
->
source
.
~
decltype
(
o
->
source
)();
o
->
cls
->
tp_free
(
o
);
o
->
cls
->
tp_free
(
o
);
}
}
BORROWED
(
BoxedString
*
)
getASTName
(
AST
*
ast
)
noexcept
{
BoxedCode
::
BoxedCode
(
int
num_args
,
bool
takes_varargs
,
bool
takes_kwargs
,
int
firstlineno
,
assert
(
ast
);
std
::
unique_ptr
<
SourceInfo
>
source
,
ParamNames
param_names
,
BoxedString
*
filename
,
BoxedString
*
name
,
Box
*
doc
)
static
BoxedString
*
lambda_name
=
getStaticString
(
"<lambda>"
);
static
BoxedString
*
module_name
=
getStaticString
(
"<module>"
);
switch
(
ast
->
type
)
{
case
AST_TYPE
:
:
ClassDef
:
return
ast_cast
<
AST_ClassDef
>
(
ast
)
->
name
.
getBox
();
case
AST_TYPE
:
:
FunctionDef
:
if
(
ast_cast
<
AST_FunctionDef
>
(
ast
)
->
name
!=
InternedString
())
return
ast_cast
<
AST_FunctionDef
>
(
ast
)
->
name
.
getBox
();
return
lambda_name
;
case
AST_TYPE
:
:
Module
:
case
AST_TYPE
:
:
Expression
:
case
AST_TYPE
:
:
Suite
:
return
module_name
;
default:
RELEASE_ASSERT
(
0
,
"%d"
,
ast
->
type
);
}
}
BoxedCode
::
BoxedCode
(
int
num_args
,
bool
takes_varargs
,
bool
takes_kwargs
,
std
::
unique_ptr
<
SourceInfo
>
source
,
ParamNames
param_names
,
BoxedString
*
filename
)
:
source
(
std
::
move
(
source
)),
:
source
(
std
::
move
(
source
)),
filename
(
incref
(
filename
)),
filename
(
incref
(
filename
)),
name
(
incref
(
getASTName
(
this
->
source
->
ast
))),
name
(
incref
(
name
)),
firstlineno
(
firstlineno
),
_doc
(
incref
(
doc
)),
param_names
(
std
::
move
(
param_names
)),
param_names
(
std
::
move
(
param_names
)),
takes_varargs
(
takes_varargs
),
takes_varargs
(
takes_varargs
),
takes_kwargs
(
takes_kwargs
),
takes_kwargs
(
takes_kwargs
),
...
@@ -153,12 +129,14 @@ BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, std::u
...
@@ -153,12 +129,14 @@ BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, std::u
internal_callable
(
NULL
,
NULL
)
{
internal_callable
(
NULL
,
NULL
)
{
}
}
BoxedCode
::
BoxedCode
(
int
num_args
,
bool
takes_varargs
,
bool
takes_kwargs
,
const
ParamNames
&
param_names
,
BoxedCode
::
BoxedCode
(
int
num_args
,
bool
takes_varargs
,
bool
takes_kwargs
,
const
ParamNames
&
param_names
)
BoxedString
*
filename
)
:
source
(
nullptr
),
:
source
(
nullptr
),
// This should probably be just an "incref"?
// TODO what to do with these?
filename
(
xincref
(
filename
)),
filename
(
nullptr
),
name
(
boxString
(
"???"
)),
name
(
nullptr
),
firstlineno
(
-
1
),
_doc
(
nullptr
),
param_names
(
param_names
),
param_names
(
param_names
),
takes_varargs
(
takes_varargs
),
takes_varargs
(
takes_varargs
),
takes_kwargs
(
takes_kwargs
),
takes_kwargs
(
takes_kwargs
),
...
@@ -171,7 +149,9 @@ BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, const
...
@@ -171,7 +149,9 @@ BoxedCode::BoxedCode(int num_args, bool takes_varargs, bool takes_kwargs, const
BoxedCode
::
BoxedCode
(
BoxedString
*
filename
,
BoxedString
*
name
,
int
firstline
)
BoxedCode
::
BoxedCode
(
BoxedString
*
filename
,
BoxedString
*
name
,
int
firstline
)
:
filename
(
filename
),
:
filename
(
filename
),
name
(
name
),
name
(
name
),
_firstline
(
firstline
),
firstlineno
(
firstline
),
_doc
(
nullptr
),
param_names
(
ParamNames
::
empty
()),
param_names
(
ParamNames
::
empty
()),
takes_varargs
(
false
),
takes_varargs
(
false
),
takes_kwargs
(
false
),
takes_kwargs
(
false
),
...
@@ -273,7 +253,7 @@ void setupCode() {
...
@@ -273,7 +253,7 @@ void setupCode() {
code_cls
->
giveAttrDescriptor
(
"co_name"
,
BoxedCode
::
co_name
,
NULL
);
code_cls
->
giveAttrDescriptor
(
"co_name"
,
BoxedCode
::
co_name
,
NULL
);
code_cls
->
giveAttrDescriptor
(
"co_filename"
,
BoxedCode
::
co_filename
,
NULL
);
code_cls
->
giveAttrDescriptor
(
"co_filename"
,
BoxedCode
::
co_filename
,
NULL
);
code_cls
->
giveAttrDescriptor
(
"co_firstlineno"
,
BoxedCode
::
firstlineno
,
NULL
);
code_cls
->
giveAttrDescriptor
(
"co_firstlineno"
,
BoxedCode
::
co_
firstlineno
,
NULL
);
code_cls
->
giveAttrDescriptor
(
"co_argcount"
,
BoxedCode
::
argcount
,
NULL
);
code_cls
->
giveAttrDescriptor
(
"co_argcount"
,
BoxedCode
::
argcount
,
NULL
);
code_cls
->
giveAttrDescriptor
(
"co_varnames"
,
BoxedCode
::
varnames
,
NULL
);
code_cls
->
giveAttrDescriptor
(
"co_varnames"
,
BoxedCode
::
varnames
,
NULL
);
code_cls
->
giveAttrDescriptor
(
"co_flags"
,
BoxedCode
::
flags
,
NULL
);
code_cls
->
giveAttrDescriptor
(
"co_flags"
,
BoxedCode
::
flags
,
NULL
);
...
...
src/runtime/types.cpp
View file @
2affae97
...
@@ -364,7 +364,7 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(BoxedCode* code, llvm::ArrayRef<
...
@@ -364,7 +364,7 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(BoxedCode* code, llvm::ArrayRef<
}
}
// It's ok for modname to be NULL
// It's ok for modname to be NULL
this
->
doc
=
code
->
source
->
getDocString
(
);
this
->
doc
=
xincref
(
code
->
_doc
);
}
else
{
}
else
{
this
->
modname
=
PyString_InternFromString
(
"__builtin__"
);
this
->
modname
=
PyString_InternFromString
(
"__builtin__"
);
this
->
doc
=
incref
(
Py_None
);
this
->
doc
=
incref
(
Py_None
);
...
@@ -379,7 +379,7 @@ BoxedFunction::BoxedFunction(BoxedCode* code, llvm::ArrayRef<Box*> defaults, Box
...
@@ -379,7 +379,7 @@ BoxedFunction::BoxedFunction(BoxedCode* code, llvm::ArrayRef<Box*> defaults, Box
:
BoxedFunctionBase
(
code
,
defaults
,
closure
,
globals
,
can_change_defaults
)
{
:
BoxedFunctionBase
(
code
,
defaults
,
closure
,
globals
,
can_change_defaults
)
{
assert
(
!
this
->
name
);
assert
(
!
this
->
name
);
this
->
name
=
incref
(
code
->
name
);
this
->
name
=
x
incref
(
code
->
name
);
}
}
BoxedBuiltinFunctionOrMethod
::
BoxedBuiltinFunctionOrMethod
(
BoxedCode
*
code
,
const
char
*
name
,
const
char
*
doc
)
BoxedBuiltinFunctionOrMethod
::
BoxedBuiltinFunctionOrMethod
(
BoxedCode
*
code
,
const
char
*
name
,
const
char
*
doc
)
...
...
src/runtime/types.h
View file @
2affae97
...
@@ -1080,7 +1080,9 @@ public:
...
@@ -1080,7 +1080,9 @@ public:
BoxedString
*
filename
=
nullptr
;
BoxedString
*
filename
=
nullptr
;
BoxedString
*
name
=
nullptr
;
BoxedString
*
name
=
nullptr
;
int
_firstline
;
int
firstlineno
;
// In CPython, this is just stored as consts[0]
Box
*
_doc
=
nullptr
;
const
ParamNames
param_names
;
const
ParamNames
param_names
;
const
bool
takes_varargs
,
takes_kwargs
;
const
bool
takes_varargs
,
takes_kwargs
;
...
@@ -1109,10 +1111,9 @@ public:
...
@@ -1109,10 +1111,9 @@ public:
Box
**
,
const
std
::
vector
<
BoxedString
*>*>
InternalCallable
;
Box
**
,
const
std
::
vector
<
BoxedString
*>*>
InternalCallable
;
InternalCallable
internal_callable
;
InternalCallable
internal_callable
;
BoxedCode
(
int
num_args
,
bool
takes_varargs
,
bool
takes_kwargs
,
std
::
unique_ptr
<
SourceInfo
>
source
,
BoxedCode
(
int
num_args
,
bool
takes_varargs
,
bool
takes_kwargs
,
int
firstlineno
,
std
::
unique_ptr
<
SourceInfo
>
source
,
ParamNames
param_names
,
BoxedString
*
filename
);
ParamNames
param_names
,
BoxedString
*
filename
,
BoxedString
*
name
,
Box
*
doc
);
BoxedCode
(
int
num_args
,
bool
takes_varargs
,
bool
takes_kwargs
,
const
ParamNames
&
param_names
=
ParamNames
::
empty
(),
BoxedCode
(
int
num_args
,
bool
takes_varargs
,
bool
takes_kwargs
,
const
ParamNames
&
param_names
=
ParamNames
::
empty
());
BoxedString
*
filename
=
nullptr
);
~
BoxedCode
();
~
BoxedCode
();
// The dummy constructor for PyCode_New:
// The dummy constructor for PyCode_New:
...
@@ -1166,7 +1167,7 @@ public:
...
@@ -1166,7 +1167,7 @@ public:
// static BORROWED(Box*) filename(Box* b, void*) noexcept;
// static BORROWED(Box*) filename(Box* b, void*) noexcept;
static
Box
*
co_name
(
Box
*
b
,
void
*
)
noexcept
;
static
Box
*
co_name
(
Box
*
b
,
void
*
)
noexcept
;
static
Box
*
co_filename
(
Box
*
b
,
void
*
)
noexcept
;
static
Box
*
co_filename
(
Box
*
b
,
void
*
)
noexcept
;
static
Box
*
firstlineno
(
Box
*
b
,
void
*
)
noexcept
;
static
Box
*
co_
firstlineno
(
Box
*
b
,
void
*
)
noexcept
;
static
Box
*
argcount
(
Box
*
b
,
void
*
)
noexcept
;
static
Box
*
argcount
(
Box
*
b
,
void
*
)
noexcept
;
static
Box
*
varnames
(
Box
*
b
,
void
*
)
noexcept
;
static
Box
*
varnames
(
Box
*
b
,
void
*
)
noexcept
;
static
Box
*
flags
(
Box
*
b
,
void
*
)
noexcept
;
static
Box
*
flags
(
Box
*
b
,
void
*
)
noexcept
;
...
...
src/runtime/util.cpp
View file @
2affae97
...
@@ -251,7 +251,7 @@ extern "C" void dumpEx(void* p, int levels) {
...
@@ -251,7 +251,7 @@ extern "C" void dumpEx(void* p, int levels) {
BoxedCode
*
code
=
f
->
code
;
BoxedCode
*
code
=
f
->
code
;
if
(
code
->
source
)
{
if
(
code
->
source
)
{
printf
(
"User-defined function '%s'
\n
"
,
code
->
name
->
c_str
());
printf
(
"User-defined function '%s'
\n
"
,
code
->
name
->
c_str
());
printf
(
"Defined at %s:%d
\n
"
,
code
->
filename
->
c_str
(),
code
->
source
->
ast
->
lineno
);
printf
(
"Defined at %s:%d
\n
"
,
code
->
filename
->
c_str
(),
code
->
first
lineno
);
if
(
code
->
source
->
cfg
&&
levels
>
0
)
{
if
(
code
->
source
->
cfg
&&
levels
>
0
)
{
code
->
source
->
cfg
->
print
();
code
->
source
->
cfg
->
print
();
...
...
test/tests/docstrings.py
View file @
2affae97
...
@@ -55,3 +55,8 @@ class C4(object):
...
@@ -55,3 +55,8 @@ class C4(object):
("a")
("a")
assert C3.__doc__ is None
assert C3.__doc__ is None
"""
"""
exec
"""
"hello world"
print __doc__
"""
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment