Goose  Diff

Differences From Artifact [37f902f580]:

  • File bs/builtins/types/localvar/localvar.cpp — part of check-in [c2b2425c0c] at 2019-08-26 00:18:30 on branch trunk — Implemented local variable destruction (through the DestroyValue() extension point), and setup proper visibility and lifetime rules for variables declared inside of statements. (user: achavasse size: 8890)

To Artifact [7efd693088]:

  • File bs/builtins/types/localvar/localvar.cpp — part of check-in [39cabb3447] at 2019-08-27 19:46:07 on branch trunk — Live values are now identified by an unique id to avoid using a fragile, non future proof way to extend the lifetime of local variables beyond their containing statements. (user: achavasse size: 9089)

20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34







-
+







    }

    Value DeclareLocalVar( Parser& p, const Term& type, StringId name, const optional< Value >& initializer )
    {
        auto cfgId = p.cfg()->uniqueId();
        auto index = p.cfg()->getNewTemporaryIndex();

        LocalVar lv( name, type, cfgId, index );
        LocalVar lv( name, type, p.resolver()->context().env()->NewUniqueId(), cfgId, index );

        auto bb = p.cfg()->currentBB();
        if( !bb )
            return PoisonValue();

        auto typeVal = *ValueFromIRExpr( type );
        bb->emplace_back( AllocVar( typeVal, cfgId, index ) );
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66







-
+








        auto locVar = ToValue( lv );
        auto identity = AppendToVectorTerm( p.resolver()->context().identity(), name );

        p.resolver()->context().env()->storeValue( identity, ANYTERM( _ ),
            ValueToIRExpr( locVar ) );

        p.pushLiveValue( locVar );
        p.pushLiveValue( locVar, lv.uniqueId() );
        p.resolver()->clearLookAheadCache();
        return locVar;
    }

    Value DeclareLocalVarWithTypeInference( Parser& p, const Term& typeTExpr, StringId name, const Value& initVal )
    {
        auto bb = p.cfg()->currentBB();
172
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
172
173
174
175
176
177
178

179
180
181
182
183
184
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199







-
+












-
+







        auto cfgId = p.cfg()->uniqueId();
        auto index = p.cfg()->getNewTemporaryIndex();

        // Retrieve the texpr's location and set it on the inferred type. This way if an
        // error occurs later with it, for instance when calling LowerType on it during codegen,
        // it will have a meaningful location for the error message to attach itself on.
        uint32_t typeLoc = ValueFromIRExpr( typeTExpr )->locationId();
        LocalVar lv( name, type, cfgId, index );
        LocalVar lv( name, type, p.resolver()->context().env()->NewUniqueId(), cfgId, index );

        bb->emplace_back( AllocVar( ValueFromIRExpr( lv.type() )->setLocationId( typeLoc ), cfgId, index ) );

        p.pushValue( ResolveInvocation( c, GetInvocationRule( *c.env(), initializerVal ), initializerVal,
            MakeTuple( ToValue( lv ), initVal ) ) );

        auto locVar = ToValue( lv );
        auto identity = AppendToVectorTerm( p.resolver()->context().identity(), name );

        p.resolver()->context().env()->storeValue( identity, ANYTERM( _ ),
            ValueToIRExpr( locVar ) );

        p.pushLiveValue( locVar );
        p.pushLiveValue( locVar, lv.uniqueId() );
        p.resolver()->clearLookAheadCache();
        return locVar;
    }
}

namespace empathy::ir
{
231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

254
255
256
257
258
259
260
261

262
263

264
265
231
232
233
234
235
236
237

238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

262
263

264
265
266







-
+















+







-
+

-
+


    Term Bridge< LocalVar >::Type( const Term& type )
    {
        return ValueToIRExpr( ToValue< LocalVarType >( type ) );
    }

    Value Bridge< LocalVar >::ToValue( const LocalVar& lv )
    {
        return Value( Type( lv.type() ), VEC( TERM( lv.name() ), TERM( lv.cfgId() ), TERM( lv.index() ) ) );
        return Value( Type( lv.type() ), VEC( TERM( lv.name() ), TERM( lv.uniqueId() ), TERM( lv.cfgId() ), TERM( lv.index() ) ) );
    }

    optional< LocalVar > Bridge< LocalVar >::FromValue( const Value& v )
    {
        if( !v.isConstant() )
            return nullopt;

        auto t = FromValue< LocalVarType >( *ValueFromIRExpr( v.type() ) );
        if( !t )
            return nullopt;

        auto result = Decompose( v.val(),
            Vec(
                Val< StringId >(),
                Val< uint32_t >(),
                Val< uint32_t >(),
                Val< uint32_t >()
            )
        );

        if( !result )
            return nullopt;

        auto&& [name,cfgId,index] = *result;
        auto&& [name,uniqueId,cfgId,index] = *result;

        return LocalVar( name, move( t->type() ), cfgId, index );
        return LocalVar( name, move( t->type() ), uniqueId, cfgId, index );
    }
}