@@ -686,7 +686,7 @@ static REBOOL parse_field_type(struct Struct_Field *field, REBVAL *spec, REBVAL
686
686
/*
687
687
* Format:
688
688
* make struct! [
689
- * field1 [type1]
689
+ * field1 [type1]
690
690
* field2: [type2] field2-init-value
691
691
* field3: [struct [field1 [type1]]] field3-init-struct-value
692
692
* field4: [type1[3]] field4-init-block-value
@@ -695,10 +695,17 @@ static REBOOL parse_field_type(struct Struct_Field *field, REBVAL *spec, REBVAL
695
695
***********************************************************************/
696
696
{
697
697
//RL_Print("%s\n", __func__);
698
- REBINT max_fields = 16 ;
698
+
699
699
if (!IS_BLOCK (data )) return FALSE; // validate early!
700
-
701
- VAL_STRUCT_FIELDS (out ) = Make_Series (max_fields , sizeof (struct Struct_Field ), FALSE);
700
+
701
+ /* Using spec block length as a prediction of fields number
702
+ (each field requires at least 2 spec values) */
703
+ REBCNT num_spec_values = VAL_TAIL (data ) - VAL_INDEX (data );
704
+ REBCNT min_fileds = num_spec_values >> 1 ;
705
+ /* Don't allow empty struct! */
706
+ if (min_fileds == 0 ) Trap_Arg (data );
707
+
708
+ VAL_STRUCT_FIELDS (out ) = Make_Series (min_fileds , sizeof (struct Struct_Field ), FALSE);
702
709
BARE_SERIES (VAL_STRUCT_FIELDS (out ));
703
710
704
711
//Reduce_Block_No_Set(VAL_SERIES(data), 0, NULL);
@@ -718,7 +725,8 @@ static REBOOL parse_field_type(struct Struct_Field *field, REBVAL *spec, REBVAL
718
725
EXPAND_SERIES_TAIL (VAL_STRUCT_DATA (out ), 1 );
719
726
BARE_SERIES (VAL_STRUCT_DATA (out ));
720
727
721
- VAL_STRUCT_DATA_BIN (out ) = Make_Series (max_fields << 2 , 1 , FALSE);
728
+ /* one byte per field as a minimum (expands when needed) */
729
+ VAL_STRUCT_DATA_BIN (out ) = Make_Series (min_fileds , 1 , FALSE);
722
730
BARE_SERIES (VAL_STRUCT_DATA_BIN (out ));
723
731
VAL_STRUCT_OFFSET (out ) = 0 ;
724
732
0 commit comments