Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc76f1ec

Browse files
mjp41latkin
authored andcommitted
Make mutables automatically boxed
commit 68660ecfe740cee405113676e4ae0bf1cb49701fAuthor: latkin <latkin@microsoft.com>Date: Sun Nov 9 18:13:16 2014 -0800 Updating an assortment of tests to use mutable in favor of refcommit 5b67f7c62d14103d173ca944238a0b0df0db320cAuthor: latkin <latkin@microsoft.com>Date: Sun Nov 9 16:28:53 2014 -0800 Remove dummy file optimize\autobox.fscommit 59c49079c33528a4f73fe895fad77695d0a232b6Merge:e9b6c87 f13c8c4Author: latkin <latkin@microsoft.com>Date: Sun Nov 9 15:15:24 2014 -0800 Merge branch 'mutabl' ofhttps://git01.codeplex.com/forks/matthewparkinson/visualfsharp into mutablecommit f13c8c4a53147c77e906e79ae671870fce729543Author: mattpark <mattpark@microsoft.com>Date: Fri Nov 7 14:39:36 2014 +0000 Addressing Code Review feedbackcommit 0e10283aba71cdcf676618615cff52965d93fd5cAuthor: mattpark <mattpark@microsoft.com>Date: Thu Oct 16 14:13:13 2014 +0100 Fixed up tests.commit 7381a34c65b5e1b2e531246c3343c009a4ad9d48Author: mattpark <mattpark@microsoft.com>Date: Mon Oct 13 16:10:49 2014 +0100 Fixes to make it deal correctly with loops and exception blocks, which both use Lambda internally.commit 0ce307d5b734f705c6b5abad04b838d87b6004b4Author: mattpark <mattpark@microsoft.com>Date: Fri Oct 10 18:04:53 2014 +0100 Afternoons hacking with Don. Currently has a bug to do with inlining. Fun for Monday.
1 parente9b6c87 commitc76f1ec

File tree

29 files changed

+865
-313
lines changed

29 files changed

+865
-313
lines changed

‎src/FSharpSource.Settings.targets‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<OptimizeCondition=" '$(Optimize)' == ''">false</Optimize>
2222
<ErrorReportCondition=" '$(ErrorReport)' == ''">prompt</ErrorReport>
2323
<PlatformCondition=" '$(Platform)' == ''">AnyCPU</Platform>
24-
<OtherFlags>$(OtherFlags) --no-jit-optimize --jit-tracking</OtherFlags>
24+
<OtherFlags>$(OtherFlags) --no-jit-optimize --jit-tracking /warnon:3180</OtherFlags>
2525
<DefineConstantsCondition=" '$(ProjectLanguage)' != 'VisualBasic'">DEBUG;TRACE;CODE_ANALYSIS;$(DefineConstants)</DefineConstants>
2626
<DefineConstantsCondition=" '$(ProjectLanguage)' == 'VisualBasic'">DEBUG=True,TRACE=True,CODE_ANALYSIS=True,$(DefineConstants)</DefineConstants>
2727
<SIGN_WITH_MSFT_KEYCondition=" '$(SIGN_WITH_MSFT_KEY)' == ''">false</SIGN_WITH_MSFT_KEY>

‎src/fsharp/FSComp.txt‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,6 @@ elDeprecatedOperator,"The treatment of this operator is now handled directly by
250250
# -----------------------------------------------------------------------------
251251
405,chkProtectedOrBaseCalled,"A protected member is called or 'base' is being used. This is only allowed in the direct implementation of members since they could escape their object scope."
252252
406,chkByrefUsedInInvalidWay,"The byref-typed variable '%s' is used in an invalid way. Byrefs cannot be captured by closures or passed to inner functions."
253-
407,chkMutableUsedInInvalidWay,"The mutable variable '%s' is used in an invalid way. Mutable variables cannot be captured by closures. Consider eliminating this use of mutation or using a heap-allocated mutable reference cell via 'ref' and '!'."
254253
408,chkBaseUsedInInvalidWay,"The 'base' keyword is used in an invalid way. Base calls cannot be used in closures. Consider using a private member to make base calls."
255254
chkVariableUsedInInvalidWay,"The variable '%s' is used in an invalid way"
256255
410,chkTypeLessAccessibleThanType,"The type '%s' is less accessible than the value, member or type '%s' it is used in"
@@ -1331,4 +1330,5 @@ descriptionUnavailable,"(description unavailable...)"
13311330
3176,tcFieldNameConflictsWithGeneratedNameForAnonymousField,"Named field '%s' conflicts with autogenerated name for anonymous field."
13321331
3177,tastConstantExpressionOverflow,"This literal expression or attribute argument results in an arithmetic overflow."
13331332
3178,tcIllegalStructTypeForConstantExpression,"This is not valid literal expression. The [<Literal>] attribute will be ignored."
1334-
3179,fscSystemRuntimeInteropServicesIsRequired,"System.Runtime.InteropServices assembly is required to use UnknownWrapper\DispatchWrapper classes."
1333+
3179,fscSystemRuntimeInteropServicesIsRequired,"System.Runtime.InteropServices assembly is required to use UnknownWrapper\DispatchWrapper classes."
1334+
3180,abImplicitHeapAllocation,"The mutable local '%s' is implicitly allocated as a reference cell because it has been captured by a closure. This warning is for informational purposes only to indicate where implicit allocations are performed."

‎src/fsharp/FSharp.Compiler-proto/FSharp.Compiler-proto.fsproj‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,9 @@
358358
<CompileInclude="..\opt.fsi">
359359
<Link>opt.fsi</Link>
360360
</Compile>
361+
<CompileInclude="..\autobox.fs">
362+
<Link>autobox.fs</Link>
363+
</Compile>
361364
<CompileInclude="..\opt.fs">
362365
<Link>opt.fs</Link>
363366
</Compile>

‎src/fsharp/FSharp.Compiler/FSharp.Compiler.fsproj‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<!-- Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.-->
33
<ProjectToolsVersion="4.0"DefaultTargets="Build"xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
44
<PropertyGroup>
@@ -410,6 +410,9 @@
410410
<CompileInclude="..\lowertop.fs">
411411
<Link>Optimize\lowertop.fs</Link>
412412
</Compile>
413+
<CompileInclude="..\autobox.fs">
414+
<Link>Optimize\autobox.fs</Link>
415+
</Compile>
413416
<CompileInclude="..\ilxgen.fsi">
414417
<Link>CodeGen\ilxgen.fsi</Link>
415418
</Compile>
@@ -485,7 +488,7 @@
485488
<CompileInclude="..\vs\service.fs">
486489
<Link>Service\service.fs</Link>
487490
</Compile>
488-
<!--
491+
<!--
489492
<Compile Include="..\vs\SimpleServices.fs">
490493
<Link>SimpleServices.fs</Link>
491494
</Compile>
@@ -500,18 +503,18 @@
500503
<ReferenceInclude="System.Core" />
501504
<ReferenceInclude="System.Drawing" />
502505
<ReferenceInclude="System.Windows.Forms" />
503-
<ReferenceInclude="System.Runtime.Remoting" />
506+
<ReferenceInclude="System.Runtime.Remoting" />
504507
<ReferenceInclude="Microsoft.Build.Framework, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
505508
<ReferenceInclude="Microsoft.Build.Engine, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
506509
<ReferenceInclude="ISymWrapper, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
507510
<ReferenceInclude="Microsoft.Build, Version=12.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
508511
<ReferenceInclude="Microsoft.Build.Utilities.v12.0" />
509512
<ReferenceInclude="Microsoft.Build.Tasks.v12.0" />
510-
<ProjectReferenceInclude="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
513+
<ProjectReferenceInclude="$(FSharpSourcesRoot)\fsharp\FSharp.Core\FSharp.Core.fsproj">
511514
<Project>{DED3BBD7-53F4-428A-8C9F-27968E768605}</Project>
512515
<Name>FSharp.Core</Name>
513516
</ProjectReference>
514517
</ItemGroup>
515518
<ImportProject="$(FSharpSourcesRoot)\FSharpSource.targets" />
516519
<ImportProject="$(FSharpSourcesRoot)\..\lkg\FSharp-$(LkgVersion)\bin\FSharp.PowerPack.targets" />
517-
</Project>
520+
</Project>

‎src/fsharp/autobox.fs‎

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
2+
3+
moduleinternalMicrosoft.FSharp.Compiler.AutoBox
4+
5+
openInternal.Utilities
6+
openMicrosoft.FSharp.Compiler.AbstractIL.Internal
7+
openMicrosoft.FSharp.Compiler
8+
openMicrosoft.FSharp.Compiler.Range
9+
openMicrosoft.FSharp.Compiler.ErrorLogger
10+
openMicrosoft.FSharp.Compiler.Tast
11+
openMicrosoft.FSharp.Compiler.Tastops
12+
openMicrosoft.FSharp.Compiler.Lib
13+
openMicrosoft.FSharp.Compiler.Env
14+
openMicrosoft.FSharp.Compiler.Typrelns
15+
16+
//----------------------------------------------------------------------------
17+
// Decide the set of mutable locals to promote to heap-allocated reference cells
18+
19+
typecenv=
20+
{ g:TcGlobals;
21+
amap:Import.ImportMap}
22+
23+
/// Find all the mutable locals that escape a method, function or lambda expression
24+
letDecideEscapes syntacticArgs body=
25+
letcantBeFree v=
26+
letpassedIn= ListSet.contains valEq v syntacticArgs
27+
not passedIn&&(v.IsMutable&& v.ValReprInfo.IsNone)
28+
29+
letfrees= freeInExpr CollectLocals body
30+
frees.FreeLocals|> Zset.filter cantBeFree
31+
32+
/// Find all the mutable locals that escape a lambda expression, ignoring the arguments to the lambda
33+
letDecideLambda exprF cenv topValInfo expr ety z=
34+
match exprwith
35+
| Expr.Lambda_
36+
| Expr.TyLambda_->
37+
let_tps,ctorThisValOpt,baseValOpt,vsl,body,_bodyty= destTopLambda cenv.g cenv.amap topValInfo(expr, ety)
38+
letsnoc=fun x y-> y:: x
39+
letargs= List.concat vsl
40+
letargs= Option.fold snoc args baseValOpt
41+
letsyntacticArgs= Option.fold snoc args ctorThisValOpt
42+
43+
letz= Zset.union z(DecideEscapes syntacticArgs body)
44+
letz=match exprFwith Some f-> f z body| None-> z
45+
z
46+
|_-> z
47+
48+
///Special cases where representation uses Lambda.
49+
letDecideExprOp exprF z(op,tyargs,args)=
50+
(* Special cases*)
51+
match op,tyargs,argswith
52+
// Handle these as special cases since mutables are allowed inside their bodies
53+
| TOp.While_,_,[Expr.Lambda(_,_,_,[_],e1,_,_);Expr.Lambda(_,_,_,[_],e2,_,_)]->
54+
Some(exprF(exprF z e1) e2)
55+
56+
| TOp.TryFinally_,[_],[Expr.Lambda(_,_,_,[_],e1,_,_); Expr.Lambda(_,_,_,[_],e2,_,_)]->
57+
Some(exprF(exprF z e1) e2)
58+
59+
| TOp.For(_),_,[Expr.Lambda(_,_,_,[_],e1,_,_);Expr.Lambda(_,_,_,[_],e2,_,_);Expr.Lambda(_,_,_,[_],e3,_,_)]->
60+
Some(exprF(exprF(exprF z e1) e2) e3)
61+
62+
| TOp.TryCatch_,[_],[Expr.Lambda(_,_,_,[_],e1,_,_); Expr.Lambda(_,_,_,[_],_e2,_,_); Expr.Lambda(_,_,_,[_],e3,_,_)]->
63+
Some(exprF(exprF(exprF z e1)_e2) e3)
64+
// In Check code it said
65+
// e2; -- don't check filter body - duplicates logic in 'catch' body
66+
// Is that true for this code too?
67+
|_-> None
68+
69+
70+
/// Find all the mutable locals that escape a lambda expression or object expression
71+
letDecideExpr cenv exprF z expr=
72+
match exprwith
73+
| Expr.Lambda(_,_ctorThisValOpt,_baseValOpt,argvs,_,m,rty)->
74+
lettopValInfo= ValReprInfo([],[argvs|> List.map(fun _-> ValReprInfo.unnamedTopArg1)],ValReprInfo.unnamedRetVal)
75+
letty= mkMultiLambdaTy m argvs rty
76+
letz= DecideLambda(Some exprF) cenv topValInfo expr ty z
77+
Some z
78+
79+
| Expr.TyLambda(_,tps,_,_m,rty)->
80+
lettopValInfo= ValReprInfo(ValReprInfo.InferTyparInfo tps,[],ValReprInfo.unnamedRetVal)
81+
letty= tryMkForallTy tps rty
82+
letz= DecideLambda(Some exprF) cenv topValInfo expr ty z
83+
Some z
84+
85+
| Expr.Obj(_,_,baseValOpt,superInitCall,overrides,iimpls,_m)->
86+
letCheckMethod z(TObjExprMethod(_,_attribs,_tps,vs,body,_m))=
87+
letvs= List.concat vs
88+
letsyntacticArgs=(match baseValOptwith Some x-> x:: vs| None-> vs)
89+
letz= Zset.union z(DecideEscapes syntacticArgs body)
90+
exprF z body
91+
92+
letCheckMethods z l=(z,l)||> List.fold CheckMethod
93+
94+
letCheckInterfaceImpl z(_ty,overrides)= CheckMethods z overrides
95+
96+
letz= exprF z superInitCall
97+
letz= CheckMethods z overrides
98+
letz=(z,iimpls)||> List.fold CheckInterfaceImpl
99+
Some z
100+
101+
| Expr.Op(c,tyargs,args,_m)->
102+
DecideExprOp exprF z(c,tyargs,args)
103+
104+
|_-> None
105+
106+
/// Find all the mutable locals that escape a binding
107+
letDecideBinding cenv z(TBind(v,expr,_m)as bind)=
108+
lettopValInfo=match bind.Var.ValReprInfowith Some info-> info|_-> ValReprInfo.emptyValData
109+
DecideLambda None cenv topValInfo expr v.Type z
110+
111+
/// Find all the mutable locals that escape a set of bindings
112+
letDecideBindings cenv z binds=(z,binds)||> List.fold(DecideBinding cenv)
113+
114+
/// Find all the mutable locals to promote to reference cells in an implementation file
115+
letDecideImplFile g amap implFile=
116+
117+
letcenv={ g= g; amap= amap}
118+
119+
letfolder=
120+
{ExprFolder0with
121+
nonRecBindingsIntercept= DecideBinding cenv
122+
recBindingsIntercept= DecideBindings cenv
123+
exprIntercept= DecideExpr cenv
124+
}
125+
126+
letz= FoldImplFile folder emptyFreeLocals implFile
127+
128+
z
129+
130+
131+
//----------------------------------------------------------------------------
132+
// Apply the transform
133+
134+
/// Rewrite fetches, stores and address-of expressions for mutable locals which we are transforming
135+
letTransformExpr g(nvs:ValMap<_>)exprF expr=
136+
137+
match exprwith
138+
// Rewrite uses of mutable values
139+
| Expr.Val(ValDeref(v),_,m)when nvs.ContainsVal v->
140+
141+
let_nv,nve= nvs.[v]
142+
Some(mkRefCellGet g m v.Type nve)
143+
144+
// Rewrite assignments to mutable values
145+
| Expr.Op(TOp.LValueOp(LSet, ValDeref(v)),[],[arg],m)when nvs.ContainsVal v->
146+
147+
let_nv,nve= nvs.[v]
148+
letarg= exprF arg
149+
Some(mkRefCellSet g m v.Type nve arg)
150+
151+
// Rewrite taking the address of mutable values
152+
| Expr.Op(TOp.LValueOp(LGetAddr,ValDeref(v)),[],[],m)when nvs.ContainsVal v->
153+
let_nv,nve= nvs.[v]
154+
Some(mkRecdFieldGetAddrViaExprAddr(nve,mkRefCellContentsRef g,[v.Type],m))
155+
156+
|_-> None
157+
158+
159+
/// Rewrite bindings for mutable locals which we are transforming
160+
letTransformBinding g(nvs:ValMap<_>)exprF(TBind(v,expr,m))=
161+
if nvs.ContainsVal vthen
162+
letnv,_nve= nvs.[v]
163+
letexprRange= expr.Range
164+
letexpr= exprF expr
165+
Some(TBind(nv, mkRefCell g exprRange v.Type expr,m))
166+
else
167+
None
168+
169+
/// Rewrite mutable locals to reference cells across an entire implementation file
170+
letTransformImplFile g amap implFile=
171+
letfvs= DecideImplFile g amap implFile
172+
if Zset.isEmpty fvsthen
173+
implFile
174+
else
175+
for fvin fvsdo
176+
warning(Error(FSComp.SR.abImplicitHeapAllocation(fv.DisplayName),fv.Range))
177+
178+
letnvs=
179+
[for fvin fvsdo
180+
letnty= mkRefCellTy g fv.Type
181+
letnv,nve=
182+
if fv.IsCompilerGeneratedthen mkCompGenLocal fv.Range fv.LogicalName nty
183+
else mkLocal fv.Range fv.LogicalName nty
184+
yield(fv,(nv, nve))]
185+
|> ValMap.OfList
186+
187+
implFile|>
188+
RewriteImplFile{ PreIntercept= Some(TransformExpr g nvs)
189+
PreInterceptBinding= Some(TransformBinding g nvs)
190+
PostTransform=(fun _-> None)
191+
IsUnderQuotations=false}
192+
193+

‎src/fsharp/build.fs‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,8 @@ let warningOn err level specificWarnOn =
390390
List.mem n specificWarnOn||
391391
// Some specific warnings are never on by default, i.e. unused variable warnings
392392
match nwith
393-
|1182->false
393+
|1182->false// chkUnusedValue - off by default
394+
|3180->false// abImplicitHeapAllocation - off by default
394395
|_-> level>= GetWarningLevel err
395396

396397
letSplitRelatedErrors(err:PhasedError)=

‎src/fsharp/check.fs‎

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -261,19 +261,16 @@ let CheckEscapes cenv allowProtected m syntacticArgs body = (* m is a range suit
261261
letcantBeFree v=
262262
// First, if v is a syntactic argument, then it can be free since it was passed in.
263263
// The following can not be free:
264-
// a) "Local" mutables, being mutables such that:
265-
// i) the mutable has no arity (since arity implies top-level storage, top level mutables...)
266-
// Note: "this" arguments to instance members on mutable structs are mutable arguments.
267-
// b) BaseVal can never escape.
268-
// c) Byref typed values can never escape.
264+
// a) BaseVal can never escape.
265+
// b) Byref typed values can never escape.
266+
// Note that: Local mutables can be free, as they will be boxed later.
269267

270268
// These checks must correspond to the tests governing the error messages below.
271269
letpassedIn= ListSet.contains valEq v syntacticArgs
272270
if passedInthen
273271
false
274272
else
275-
(v.IsMutable&& v.ValReprInfo.IsNone)||
276-
(v.BaseOrThisInfo= BaseVal&&not passedIn)||
273+
(v.BaseOrThisInfo= BaseVal)||
277274
(isByrefLikeTy cenv.g v.Type)
278275

279276
letfrees= freeInExpr CollectLocals body
@@ -288,8 +285,6 @@ let CheckEscapes cenv allowProtected m syntacticArgs body = (* m is a range suit
288285
// As such, partial applications involving byref arguments could lead to closures containing byrefs.
289286
// For safety, such functions are assumed to have no known arity, and so can not accept byrefs.
290287
errorR(Error(FSComp.SR.chkByrefUsedInInvalidWay(v.DisplayName), m))
291-
elif v.IsMutablethen
292-
errorR(Error(FSComp.SR.chkMutableUsedInInvalidWay(v.DisplayName), m))
293288
elif v.BaseOrThisInfo= BaseValthen
294289
errorR(Error(FSComp.SR.chkBaseUsedInInvalidWay(), m))
295290
else

‎src/fsharp/detuple.fs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,7 @@ let postTransformExpr (penv:penv) expr =
927927

928928
letpassImplFile penv ass=
929929
ass|> RewriteImplFile{PreIntercept=None(* Some (preInterceptExpr penv)*);
930+
PreInterceptBinding=None
930931
PostTransform= postTransformExpr penv(* (fun _ -> None)*);
931932
IsUnderQuotations=false}
932933

‎src/fsharp/fscopts.fs‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,8 @@ let ApplyAllOptimizations (tcConfig:TcConfig, tcGlobals, tcVal, outfile, importM
861861
letoptEnvFirstLoop,implFile,implFileOptData=
862862
Opt.OptimizeImplFile(optSettings,ccu,tcGlobals,tcVal, importMap,optEnvFirstLoop,isIncrementalFragment,tcConfig.emitTailcalls,implFile)
863863

864+
letimplFile= AutoBox.TransformImplFile tcGlobals importMap implFile
865+
864866
// Only do this on the first pass!
865867
letoptSettings={ optSettingswith abstractBigTargets=false}
866868
letoptSettings={ optSettingswith reportingPhase=false}
@@ -892,7 +894,7 @@ let ApplyAllOptimizations (tcConfig:TcConfig, tcGlobals, tcVal, outfile, importM
892894

893895
letimplFile=
894896
Lowertop.LowerImplFile tcGlobals implFile
895-
897+
896898
letimplFile,optEnvFinalSimplify=
897899
if tcConfig.doFinalSimplifythen
898900
//ReportTime tcConfig ("Final simplify pass");

‎src/fsharp/lowertop.fs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ let InterceptExpr g cont expr =
5656
/// optimizer in opt.fs
5757
letLowerImplFile g ass=
5858
RewriteImplFile{ PreIntercept= Some(InterceptExpr g);
59+
PreInterceptBinding=None
5960
PostTransform=(fun _-> None);
6061
IsUnderQuotations=false} ass
6162

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp