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
0b7b8d55
Commit
0b7b8d55
authored
Aug 20, 2014
by
Travis Hance
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add truediv support
parent
ccb7cff9
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
114 additions
and
25 deletions
+114
-25
src/codegen/compvars.cpp
src/codegen/compvars.cpp
+4
-1
src/codegen/irgen/future.cpp
src/codegen/irgen/future.cpp
+16
-1
src/codegen/irgen/future.h
src/codegen/irgen/future.h
+0
-15
src/codegen/irgen/hooks.cpp
src/codegen/irgen/hooks.cpp
+1
-1
src/codegen/irgen/irgenerator.cpp
src/codegen/irgen/irgenerator.cpp
+4
-0
src/codegen/runtime_hooks.cpp
src/codegen/runtime_hooks.cpp
+1
-0
src/codegen/runtime_hooks.h
src/codegen/runtime_hooks.h
+1
-1
src/core/ast.cpp
src/core/ast.cpp
+4
-6
src/core/ast.h
src/core/ast.h
+1
-0
src/runtime/float.cpp
src/runtime/float.cpp
+17
-0
src/runtime/float.h
src/runtime/float.h
+1
-0
src/runtime/inline/link_forcer.cpp
src/runtime/inline/link_forcer.cpp
+1
-0
src/runtime/int.cpp
src/runtime/int.cpp
+32
-0
src/runtime/types.h
src/runtime/types.h
+2
-0
test/tests/future_division.py
test/tests/future_division.py
+23
-0
tools/tester.py
tools/tester.py
+6
-0
No files found.
src/codegen/compvars.cpp
View file @
0b7b8d55
...
...
@@ -1037,9 +1037,12 @@ public:
if
(
op_type
==
AST_TYPE
::
Mod
)
{
v
=
emitter
.
createCall2
(
info
.
exc_info
,
g
.
funcs
.
mod_float_float
,
var
->
getValue
(),
converted_right
->
getValue
()).
getInstruction
();
}
else
if
(
op_type
==
AST_TYPE
::
Div
||
op_type
==
AST_TYPE
::
Floor
Div
)
{
}
else
if
(
op_type
==
AST_TYPE
::
Div
||
op_type
==
AST_TYPE
::
True
Div
)
{
v
=
emitter
.
createCall2
(
info
.
exc_info
,
g
.
funcs
.
div_float_float
,
var
->
getValue
(),
converted_right
->
getValue
()).
getInstruction
();
}
else
if
(
op_type
==
AST_TYPE
::
FloorDiv
)
{
v
=
emitter
.
createCall2
(
info
.
exc_info
,
g
.
funcs
.
floordiv_float_float
,
var
->
getValue
(),
converted_right
->
getValue
()).
getInstruction
();
}
else
if
(
op_type
==
AST_TYPE
::
Pow
)
{
v
=
emitter
.
createCall2
(
info
.
exc_info
,
g
.
funcs
.
pow_float_float
,
var
->
getValue
(),
converted_right
->
getValue
()).
getInstruction
();
...
...
src/codegen/irgen/future.cpp
View file @
0b7b8d55
...
...
@@ -16,6 +16,21 @@
namespace
pyston
{
struct
FutureOption
{
int
optional_version_hex
;
int
mandatory_version_hex
;
int
ff_mask
;
};
const
std
::
map
<
std
::
string
,
FutureOption
>
future_options
=
{
{
"absolute_import"
,
{
version_hex
(
2
,
5
,
0
),
version_hex
(
3
,
0
,
0
),
FF_ABSOLUTE_IMPORT
}
},
{
"division"
,
{
version_hex
(
2
,
2
,
0
),
version_hex
(
3
,
0
,
0
),
FF_DIVISION
}
},
{
"generators"
,
{
version_hex
(
2
,
2
,
0
),
version_hex
(
3
,
0
,
0
),
FF_GENERATOR
}
},
{
"unicode_literals"
,
{
version_hex
(
2
,
6
,
0
),
version_hex
(
3
,
0
,
0
),
FF_UNICODE_LITERALS
}
},
{
"print_functions"
,
{
version_hex
(
2
,
6
,
0
),
version_hex
(
3
,
0
,
0
),
FF_PRINT_FUNCTIONS
}
},
{
"nested_scopes"
,
{
version_hex
(
2
,
1
,
0
),
version_hex
(
2
,
2
,
0
),
FF_NESTED_SCOPES
}
},
{
"with_statement"
,
{
version_hex
(
2
,
5
,
0
),
version_hex
(
3
,
6
,
0
),
FF_WITH_STATEMENT
}
}
};
// Helper function:
void
raiseSyntaxError
(
const
char
*
file
,
AST
*
node_at
,
const
char
*
msg
,
...)
{
va_list
ap
;
...
...
@@ -105,7 +120,7 @@ FutureFlags getFutureFlags(AST_Module* m, const char* file) {
raiseFutureImportErrorNotFound
(
file
,
alias
,
option_name
.
c_str
());
}
else
{
const
FutureOption
&
fo
=
iter
->
second
;
if
(
PYTHON_VERSION_HEX
>=
fo
.
mandatory
_version_hex
)
{
if
(
PYTHON_VERSION_HEX
>=
fo
.
optional
_version_hex
)
{
ff
|=
fo
.
ff_mask
;
}
else
{
raiseFutureImportErrorNotFound
(
file
,
alias
,
option_name
.
c_str
());
...
...
src/codegen/irgen/future.h
View file @
0b7b8d55
...
...
@@ -31,23 +31,8 @@ namespace pyston {
#define FF_NESTED_SCOPES 0x20
#define FF_WITH_STATEMENT 0x40
struct
FutureOption
{
int
optional_version_hex
;
int
mandatory_version_hex
;
int
ff_mask
;
};
typedef
int
FutureFlags
;
const
std
::
map
<
std
::
string
,
FutureOption
>
future_options
=
{
{
"absolute_import"
,
{
version_hex
(
2
,
5
,
0
),
version_hex
(
3
,
0
,
0
),
FF_ABSOLUTE_IMPORT
}
},
{
"division"
,
{
version_hex
(
2
,
2
,
0
),
version_hex
(
3
,
0
,
0
),
FF_DIVISION
}
},
{
"generators"
,
{
version_hex
(
2
,
2
,
0
),
version_hex
(
3
,
0
,
0
),
FF_GENERATOR
}
},
{
"unicode_literals"
,
{
version_hex
(
2
,
6
,
0
),
version_hex
(
3
,
0
,
0
),
FF_UNICODE_LITERALS
}
},
{
"print_functions"
,
{
version_hex
(
2
,
6
,
0
),
version_hex
(
3
,
0
,
0
),
FF_PRINT_FUNCTIONS
}
},
{
"nested_scopes"
,
{
version_hex
(
2
,
1
,
0
),
version_hex
(
2
,
2
,
0
),
FF_NESTED_SCOPES
}
},
{
"with_statement"
,
{
version_hex
(
2
,
5
,
0
),
version_hex
(
3
,
6
,
0
),
FF_WITH_STATEMENT
}
}
};
// Loop through import statements to find __future__ imports throwing errors for
// bad __future__ imports. Returns the futures that are turned on. This is used
// for irgeneration; the parser still has to handle some futures on its own,
...
...
src/codegen/irgen/hooks.cpp
View file @
0b7b8d55
...
...
@@ -237,7 +237,7 @@ void compileAndRunModule(AST_Module* m, BoxedModule* bm) {
Timer
_t
(
"for compileModule()"
);
FutureFlags
ff
=
getFutureFlags
(
m
,
bm
->
fn
.
c_str
());
bm
->
future_flags
=
getFutureFlags
(
m
,
bm
->
fn
.
c_str
());
ScopingAnalysis
*
scoping
=
runScopingAnalysis
(
m
);
...
...
src/codegen/irgen/irgenerator.cpp
View file @
0b7b8d55
...
...
@@ -405,6 +405,10 @@ private:
assert
(
left
);
assert
(
right
);
if
(
type
==
AST_TYPE
::
Div
&&
(
irstate
->
getSourceInfo
()
->
parent_module
->
future_flags
&
FF_DIVISION
))
{
type
=
AST_TYPE
::
TrueDiv
;
}
return
left
->
binexp
(
emitter
,
getOpInfoForNode
(
node
,
exc_info
),
right
,
type
,
exp_type
);
}
...
...
src/codegen/runtime_hooks.cpp
View file @
0b7b8d55
...
...
@@ -235,6 +235,7 @@ void initGlobalFuncs(GlobalState& g) {
GET
(
raise3
);
GET
(
div_float_float
);
GET
(
floordiv_float_float
);
GET
(
mod_float_float
);
GET
(
pow_float_float
);
}
...
...
src/codegen/runtime_hooks.h
View file @
0b7b8d55
...
...
@@ -49,7 +49,7 @@ struct GlobalFuncs {
llvm
::
Value
*
__cxa_begin_catch
,
*
__cxa_end_catch
;
llvm
::
Value
*
raise0
,
*
raise3
;
llvm
::
Value
*
div_float_float
,
*
mod_float_float
,
*
pow_float_float
;
llvm
::
Value
*
div_float_float
,
*
floordiv_float_float
,
*
mod_float_float
,
*
pow_float_float
;
};
}
...
...
src/core/ast.cpp
View file @
0b7b8d55
...
...
@@ -22,8 +22,6 @@
#include "core/cfg.h"
#define FUTURE_DIVISION 0
namespace
pyston
{
llvm
::
StringRef
getOpSymbol
(
int
op_type
)
{
...
...
@@ -37,6 +35,7 @@ llvm::StringRef getOpSymbol(int op_type) {
case
AST_TYPE
:
:
BitXor
:
return
"^"
;
case
AST_TYPE
:
:
Div
:
case
AST_TYPE
:
:
TrueDiv
:
return
"/"
;
case
AST_TYPE
:
:
Eq
:
return
"=="
;
...
...
@@ -110,10 +109,9 @@ const std::string& getOpName(int op_type) {
case
AST_TYPE
:
:
BitXor
:
return
strBitXor
;
case
AST_TYPE
:
:
Div
:
if
(
FUTURE_DIVISION
)
return
strTrueDiv
;
else
return
strDiv
;
return
strDiv
;
case
AST_TYPE
:
:
TrueDiv
:
return
strTrueDiv
;
case
AST_TYPE
:
:
Eq
:
return
strEq
;
case
AST_TYPE
:
:
FloorDiv
:
...
...
src/core/ast.h
View file @
0b7b8d55
...
...
@@ -125,6 +125,7 @@ enum AST_TYPE {
Invoke
=
204
,
LangPrimitive
=
205
,
Unreachable
=
206
,
TrueDiv
=
207
,
};
};
...
...
src/runtime/float.cpp
View file @
0b7b8d55
...
...
@@ -52,6 +52,11 @@ extern "C" double div_float_float(double lhs, double rhs) {
return
lhs
/
rhs
;
}
extern
"C"
double
floordiv_float_float
(
double
lhs
,
double
rhs
)
{
raiseDivZeroExcIfZero
(
rhs
);
return
floor
(
lhs
/
rhs
);
}
extern
"C"
Box
*
floatAddFloat
(
BoxedFloat
*
lhs
,
BoxedFloat
*
rhs
)
{
assert
(
lhs
->
cls
==
float_cls
);
assert
(
rhs
->
cls
==
float_cls
);
...
...
@@ -100,6 +105,17 @@ extern "C" Box* floatDiv(BoxedFloat* lhs, Box* rhs) {
}
}
extern
"C"
Box
*
floatTruediv
(
BoxedFloat
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
float_cls
);
if
(
rhs
->
cls
==
int_cls
)
{
return
floatDivInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
floatDivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
{
return
NotImplemented
;
}
}
extern
"C"
Box
*
floatRDivFloat
(
BoxedFloat
*
lhs
,
BoxedFloat
*
rhs
)
{
assert
(
lhs
->
cls
==
float_cls
);
assert
(
rhs
->
cls
==
float_cls
);
...
...
@@ -563,6 +579,7 @@ void setupFloat() {
_addFunc
(
"__div__"
,
BOXED_FLOAT
,
(
void
*
)
floatDivFloat
,
(
void
*
)
floatDivInt
,
(
void
*
)
floatDiv
);
_addFunc
(
"__rdiv__"
,
BOXED_FLOAT
,
(
void
*
)
floatRDivFloat
,
(
void
*
)
floatRDivInt
,
(
void
*
)
floatRDiv
);
float_cls
->
giveAttr
(
"__floordiv__"
,
new
BoxedFunction
(
boxRTFunction
((
void
*
)
floatFloorDiv
,
UNKNOWN
,
2
)));
_addFunc
(
"__truediv__"
,
BOXED_FLOAT
,
(
void
*
)
floatDivFloat
,
(
void
*
)
floatDivInt
,
(
void
*
)
floatTruediv
);
_addFunc
(
"__eq__"
,
BOXED_BOOL
,
(
void
*
)
floatEqFloat
,
(
void
*
)
floatEqInt
,
(
void
*
)
floatEq
);
_addFunc
(
"__ge__"
,
BOXED_BOOL
,
(
void
*
)
floatGeFloat
,
(
void
*
)
floatGeInt
,
(
void
*
)
floatGe
);
...
...
src/runtime/float.h
View file @
0b7b8d55
...
...
@@ -19,6 +19,7 @@ namespace pyston {
extern
"C"
double
mod_float_float
(
double
lhs
,
double
rhs
);
extern
"C"
double
div_float_float
(
double
lhs
,
double
rhs
);
extern
"C"
double
floordiv_float_float
(
double
lhs
,
double
rhs
);
extern
"C"
double
pow_float_float
(
double
lhs
,
double
rhs
);
class
BoxedFloat
;
...
...
src/runtime/inline/link_forcer.cpp
View file @
0b7b8d55
...
...
@@ -110,6 +110,7 @@ void force() {
FORCE
(
pow_i64_i64
);
FORCE
(
div_float_float
);
FORCE
(
floordiv_float_float
);
FORCE
(
mod_float_float
);
FORCE
(
pow_float_float
);
...
...
src/runtime/int.cpp
View file @
0b7b8d55
...
...
@@ -317,6 +317,37 @@ extern "C" Box* intFloordiv(BoxedInt* lhs, Box* rhs) {
}
}
extern
"C"
Box
*
intTruedivInt
(
BoxedInt
*
lhs
,
BoxedInt
*
rhs
)
{
assert
(
lhs
->
cls
==
int_cls
);
assert
(
rhs
->
cls
==
int_cls
);
if
(
rhs
->
n
==
0
)
{
raiseExcHelper
(
ZeroDivisionError
,
"division by zero"
);
}
return
boxFloat
(
lhs
->
n
/
(
float
)
rhs
->
n
);
}
extern
"C"
Box
*
intTruedivFloat
(
BoxedInt
*
lhs
,
BoxedFloat
*
rhs
)
{
assert
(
lhs
->
cls
==
int_cls
);
assert
(
rhs
->
cls
==
float_cls
);
if
(
rhs
->
d
==
0
)
{
raiseExcHelper
(
ZeroDivisionError
,
"division by zero"
);
}
return
boxFloat
(
lhs
->
n
/
rhs
->
d
);
}
extern
"C"
Box
*
intTruediv
(
BoxedInt
*
lhs
,
Box
*
rhs
)
{
assert
(
lhs
->
cls
==
int_cls
);
if
(
rhs
->
cls
==
int_cls
)
{
return
intTruedivInt
(
lhs
,
static_cast
<
BoxedInt
*>
(
rhs
));
}
else
if
(
rhs
->
cls
==
float_cls
)
{
return
intTruedivFloat
(
lhs
,
static_cast
<
BoxedFloat
*>
(
rhs
));
}
else
{
return
NotImplemented
;
}
}
extern
"C"
Box
*
intEqInt
(
BoxedInt
*
lhs
,
BoxedInt
*
rhs
)
{
assert
(
lhs
->
cls
==
int_cls
);
assert
(
rhs
->
cls
==
int_cls
);
...
...
@@ -685,6 +716,7 @@ void setupInt() {
_addFuncIntFloatUnknown
(
"__sub__"
,
(
void
*
)
intSubInt
,
(
void
*
)
intSubFloat
,
(
void
*
)
intSub
);
_addFuncIntFloatUnknown
(
"__div__"
,
(
void
*
)
intDivInt
,
(
void
*
)
intDivFloat
,
(
void
*
)
intDiv
);
_addFuncIntFloatUnknown
(
"__floordiv__"
,
(
void
*
)
intFloordivInt
,
(
void
*
)
intFloordivFloat
,
(
void
*
)
intFloordiv
);
_addFuncIntFloatUnknown
(
"__truediv__"
,
(
void
*
)
intTruedivInt
,
(
void
*
)
intDivFloat
,
(
void
*
)
intTruediv
);
_addFuncIntFloatUnknown
(
"__mul__"
,
(
void
*
)
intMulInt
,
(
void
*
)
intMulFloat
,
(
void
*
)
intMul
);
_addFuncIntUnknown
(
"__mod__"
,
BOXED_INT
,
(
void
*
)
intModInt
,
(
void
*
)
intMod
);
_addFuncIntFloatUnknown
(
"__pow__"
,
(
void
*
)
intPowInt
,
(
void
*
)
intPowFloat
,
(
void
*
)
intPow
);
...
...
src/runtime/types.h
View file @
0b7b8d55
...
...
@@ -20,6 +20,7 @@
#include "Python.h"
#include "structmember.h"
#include "codegen/irgen/future.h"
#include "core/threading.h"
#include "core/types.h"
#include "gc/gc_alloc.h"
...
...
@@ -307,6 +308,7 @@ class BoxedModule : public Box {
public:
HCAttrs
attrs
;
std
::
string
fn
;
// for traceback purposes; not the same as __file__
FutureFlags
future_flags
;
BoxedModule
(
const
std
::
string
&
name
,
const
std
::
string
&
fn
);
std
::
string
name
();
...
...
test/tests/future_division.py
0 → 100644
View file @
0b7b8d55
# allow-warning
# The __future__ module has an old-style class, so we allow warnings for now
"docstring"
from
__future__
import
division
def
test
(
a
,
b
):
print
a
,
'/'
,
b
,
'='
,
a
/
b
t
=
a
t
/=
b
print
a
,
'/'
,
b
,
'='
,
t
print
a
,
'//'
,
b
,
'='
,
a
//
b
t
=
a
t
//=
b
print
a
,
'//'
,
b
,
'='
,
t
test
(
3
,
2
)
test
(
3
,
2.0
)
test
(
3.0
,
2
)
test
(
3.0
,
2.0
)
tools/tester.py
View file @
0b7b8d55
...
...
@@ -106,6 +106,7 @@ def run_test(fn, check_stats, run_memcheck):
statchecks
=
[]
jit_args
=
[
"-csrq"
]
+
EXTRA_JIT_ARGS
expected
=
"success"
allow_warning
=
False
for
l
in
open
(
fn
):
l
=
l
.
strip
()
if
not
l
:
...
...
@@ -125,6 +126,8 @@ def run_test(fn, check_stats, run_memcheck):
skip
=
eval
(
skip_if
)
if
skip
:
return
r
+
" (skipped due to 'skip-if: %s')"
%
skip_if
[:
30
]
elif
l
.
startswith
(
"# allow-warning"
):
allow_warning
=
True
assert
expected
in
(
"success"
,
"fail"
,
"statfail"
),
expected
...
...
@@ -143,6 +146,9 @@ def run_test(fn, check_stats, run_memcheck):
elapsed
=
time
.
time
()
-
start
stats
=
{}
if
allow_warning
:
out_lines
=
[
l
for
l
in
out
.
split
(
'
\
n
'
)
if
not
l
.
startswith
(
"Warning: "
)]
out
=
"
\
n
"
.
join
(
out_lines
)
if
code
==
0
and
not
TEST_PYPY
:
assert
out
.
count
(
"Stats:"
)
==
1
out
,
stats_str
=
out
.
split
(
"Stats:"
)
...
...
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