Skip to content

Commit 47e2d4c

Browse files
committed
Fixed field binding bug
1 parent 57e638b commit 47e2d4c

File tree

8 files changed

+24
-25
lines changed

8 files changed

+24
-25
lines changed

proto/autotest/lang/arraybasictest.tx

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,13 @@ ret_array()->&[]UByte {
88
s : [4]UByte = FOO_STR;
99
t : &[]UByte = FOO_STR;
1010
#experr 1: u : [4]UByte = t^; ## TODO: support dynamically checked array initializer assignment
11-
puts(s);
1211
assert s.C == 4;
1312
assert t.C == 4;
1413
return t;
1514
}
1615

17-
puts(cstr : &[]UByte) {
18-
tx.c.puts(cstr);
19-
}
20-
2116
basic_array_syntax()->Int {
2217
ra := ret_array();
23-
puts( ra );
2418
assert ra.C == 4;
2519

2620
a : ~Array<~UByte,10>;
@@ -30,9 +24,9 @@ basic_array_syntax()->Int {
3024
b[1] = c[1];
3125
b[2] = c[0];
3226
b[3] = UByte(0);
33-
puts(b); ## expect "321"
27+
##puts(b); ## expect "321"
3428
a = b;
35-
puts(a); ## expect "321"
29+
##puts(a); ## expect "321"
3630
return c[2]-48; ## 48 is ASCII '0'
3731
}
3832

@@ -53,7 +47,7 @@ array_modifiability() {
5347
#experr: setelem(crcs, 2, 'C');
5448
#experr: setelem(mrcs, 2, 'C');
5549

56-
puts(mrcs); ## expect "cst"
50+
##puts(mrcs); ## expect "cst"
5751

5852
ms : ~[4]~UByte = c"mod";
5953
crms : &~[]UByte = &ms; ## explicit reference required
@@ -71,16 +65,16 @@ array_modifiability() {
7165
#experr: mrms = crcs;
7266
#experr: mrms = mrcs;
7367

74-
puts(mrms); ## expect "ABC"
68+
##puts(mrms); ## expect "ABC"
7569

7670
ms = c"qqq";
77-
puts(mrms); ## expect "qqq"
71+
##puts(mrms); ## expect "qqq"
7872

7973
##crms^ = mrcs^; ## TODO: dynamic concrete type resolution of array sizes?
8074
crms_ : &~[4]UByte = &ms;
8175
mrcs_ : ~&[4]UByte = cs;
8276
crms_^ = mrcs_^;
83-
puts(ms); ## expect "cst"
77+
##puts(ms); ## expect "cst"
8478

8579
conststr := c"1234567890";
8680
assert conststr.C == 11;

proto/src/ast/ast_fielddef_codegen.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,17 @@ void TxLocalFieldDefNode::code_gen_field( LlvmGenerationContext& context, GenSco
3939
ASSERT( this->declaration, "NULL declaration in " << this );
4040
ASSERT( this->declaration->get_storage() == TXS_STACK, "Local field gen can only apply to TX_STACK storage fields: " << this );
4141

42-
// If init expression does a stack allocation of this field's type (instance-equivalent type),
42+
// If init expression performs a stack allocation (unbound) of this field's type (instance-equivalent type),
4343
// this field shall bind to that allocation.
4444

4545
auto acttype = this->qtype();
4646
Value* fieldPtrV;
4747
if ( this->initExpression ) {
48-
if ( this->initExpression->get_storage() == TXS_STACK ) {
48+
if ( this->initExpression->get_storage() == TXS_UNBOUND_STACK ) {
4949
fieldPtrV = this->initExpression->code_gen_addr( context, scope );
5050
}
5151
else {
52+
// (if storage is TXS_STACK, we allocate new stack space for making copy of already bound stack value)
5253
fieldPtrV = acttype->gen_alloca( context, scope, this->declaration->get_symbol()->get_name() );
5354
// create implicit assignment statement
5455
if ( this->cachedConstantInitializer )
@@ -184,8 +185,7 @@ void TxNonLocalFieldDefNode::inner_code_gen_field( LlvmGenerationContext& contex
184185
// just a type definition; field storage isn't created until parent object is allocated
185186
return;
186187

187-
case TXS_NOSTORAGE:
188-
case TXS_STACK:
188+
default:
189189
THROW_LOGIC( "TxFieldDeclNode can not apply to fields with storage " << fieldDecl->get_storage() << ": " << fieldDecl );
190190
}
191191
}

proto/src/ast/expr/ast_exprs.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ class TxStackConstructionNode : public TxMakeObjectNode {
275275

276276
virtual TxFieldStorage get_storage() const override {
277277
// performs stack allocation unless this is an inlined value expression
278-
return ( this->initializationExpression ? TXS_NOSTORAGE : TXS_STACK );
278+
return ( this->initializationExpression ? TXS_NOSTORAGE : TXS_UNBOUND_STACK );
279279
}
280280

281281
virtual llvm::Value* code_gen_dyn_value( LlvmGenerationContext& context, GenScope* scope ) const override;

proto/src/ast/expr/ast_exprs_codegen.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ Value* TxFunctionCallNode::code_gen_dyn_value( LlvmGenerationContext& context, G
107107

108108
Value* TxFunctionCallNode::code_gen_dyn_address( LlvmGenerationContext& context, GenScope* scope ) const {
109109
TRACE_CODEGEN( this, context );
110-
if ( this->get_storage() == TXS_STACK ) { // only true if there is an inlined expression
110+
auto storage = this->get_storage();
111+
if ( storage == TXS_STACK || storage == TXS_UNBOUND_STACK ) { // only true if there is an inlined expression
111112
return this->inlinedExpression->code_gen_dyn_address( context, scope );
112113
}
113114
else {

proto/src/ast/expr/ast_range.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ class TxERangeLitNode final : public TxTypeDefiningValExprNode {
9797
// }
9898

9999
virtual TxFieldStorage get_storage() const {
100-
return TXS_STACK;
100+
return TXS_UNBOUND_STACK;
101101
}
102102

103103
virtual llvm::Value* code_gen_dyn_address( LlvmGenerationContext& context, GenScope* scope ) const override;

proto/src/ast/expr/ast_string.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class TxConcatenateStringsNode : public TxExpressionNode {
8484
}
8585

8686
virtual TxFieldStorage get_storage() const {
87-
return TXS_STACK;
87+
return TXS_UNBOUND_STACK;
8888
}
8989

9090
virtual llvm::Value* code_gen_dyn_value( LlvmGenerationContext& context, GenScope* scope ) const override;
@@ -142,7 +142,7 @@ class TxStringFormatNode : public TxExpressionNode {
142142
}
143143

144144
virtual TxFieldStorage get_storage() const {
145-
return TXS_STACK;
145+
return TXS_UNBOUND_STACK;
146146
}
147147

148148
virtual llvm::Value* code_gen_dyn_value( LlvmGenerationContext& context, GenScope* scope ) const override;

proto/src/symbol/declaration.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ class TxFieldDeclaration : public TxEntityDeclaration {
8181
storage( storage ),
8282
dataspace( dataspace ) {
8383
ASSERT( ( declFlags | LEGAL_FIELD_DECL_FLAGS ) == LEGAL_FIELD_DECL_FLAGS, "Illegal field declFlags: " << declFlags );
84+
ASSERT( storage != TXS_NOSTORAGE && storage != TXS_UNBOUND_STACK, "Illegal field storage: " << storage );
8485
}
8586

8687
virtual TxFieldDefiningNode* get_definer() const override {

proto/src/tx_field_storage.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@
22

33
#include <string>
44

5-
/** Specifies the storage type for a field entity.
5+
/** Specifies the storage type for a field entity / value.
66
* GLOBAL are globally declared fields, i.e. outside of any type definition.
77
* STATIC and VIRTUAL are statically allocated fields within a type definition.
88
* VIRTUAL fields are like STATIC but subject to polymorphic lookup.
99
* INSTANCEMETHOD is a special case, where the function pointer is static/virtual and the 'self' ref is provided in runtime
1010
* INSTANCE fields are members of type instances (i.e. object members).
11-
* STACK fields are regular "auto" variables, including function arguments.
12-
* GLOBAL, STATIC, VIRTUAL are compile-time-allocated.
11+
* STACK fields are regular "auto" variables, including function arguments, bound to a field declaration.
12+
* UNBOUND_STACK indicates a value that is allocated on the stack, but not (yet) bound to a field declaration.
13+
* NOSTORAGE indicates an unallocated / temporary / register value, also known as rvalue.
1314
*/
1415
enum TxFieldStorage : int {
15-
TXS_NOSTORAGE, TXS_GLOBAL, TXS_STATIC, TXS_VIRTUAL, TXS_INSTANCEMETHOD, TXS_INSTANCE, TXS_STACK
16+
TXS_NOSTORAGE, TXS_GLOBAL, TXS_STATIC, TXS_VIRTUAL, TXS_INSTANCEMETHOD, TXS_INSTANCE, TXS_STACK, TXS_UNBOUND_STACK,
1617
};
1718

1819
inline std::string to_string( TxFieldStorage storage ) {
@@ -31,6 +32,8 @@ inline std::string to_string( TxFieldStorage storage ) {
3132
return "TXS_INSTANCE";
3233
case TXS_STACK:
3334
return "TXS_STACK";
35+
case TXS_UNBOUND_STACK:
36+
return "TXS_UNBOUND_STACK";
3437
}
3538
return "-unknown TxFieldStorage value " + std::to_string((int)storage) + "-";
3639
}

0 commit comments

Comments
 (0)