lowering 의 변수·정리 목록·오류 이름 세 배열은 넘치면 오류가 아니라 넘친 것을 버리고 틀린 코드를 냈다. 한계에 닿는 방식 중 최악이다. 이제 자란다. 코드 생성기는 지역이 512개를 넘으면 함수를 아예 방출하지 않고 지나갔다. 이제 지역 수만큼 자리를 잡는다. 유닛 64 -> 256, 제네릭 인스턴스 512 -> 4096. 둘 다 원래 보고는 했지만 장난감을 기준으로 고른 숫자였다. 209 -> 213 fixture, exec 25/25.
56 lines
1.9 KiB
C
56 lines
1.9 KiB
C
#ifndef FE_CHECK_H
|
|
#define FE_CHECK_H
|
|
|
|
#include "types.h"
|
|
#include "diag.h"
|
|
#include "resolve.h"
|
|
|
|
typedef struct FeScope FeScope;
|
|
|
|
/* One generic instance, identified by declaring unit, declaration and the
|
|
spelling of its type arguments (SPEC 9). The table both deduplicates
|
|
requests and bounds how long a chain of new ones can get. */
|
|
#define FE_GENERIC_KEY_MAX 320
|
|
#define FE_GENERIC_INSTANCE_MAX 4096
|
|
typedef struct FeInstance {
|
|
char key[FE_GENERIC_KEY_MAX];
|
|
/* What lowering needs to build this instance's code: the declaration, the
|
|
arguments bound while it was checked, the unit those names belong to,
|
|
and the name the linker will see. */
|
|
FeNode *decl;
|
|
FeTypeBind binds[FE_TYPE_PARAM_MAX];
|
|
unsigned bind_count;
|
|
const char *home;
|
|
const char *cname;
|
|
FeType *owner; /* set when the instance is a method */
|
|
} FeInstance;
|
|
|
|
/* The checker spans a whole build, not one file. Names cross unit boundaries,
|
|
so every unit's declarations have to exist before any unit's bodies are
|
|
looked at, and they all have to be interned in one type context or the same
|
|
spelling in two units would not be the same type. */
|
|
typedef struct FeCheck {
|
|
/* Scopes, symbols and types outlive whichever unit is current, so they
|
|
come from the checker's own arena rather than from an AST's. */
|
|
FeArena arena;
|
|
FeBuild *build;
|
|
FeAst *ast; /* the unit being checked now */
|
|
FeUnit *unit; /* its entry in the build */
|
|
FeScope *unit_scope[FE_BUILD_UNIT_MAX];
|
|
FeTypeCtx types;
|
|
FeDiags *diags;
|
|
unsigned pointer_bits;
|
|
unsigned local_serial;
|
|
int no_checks;
|
|
FeInstance *instances;
|
|
unsigned instance_count;
|
|
unsigned instance_depth;
|
|
} FeCheck;
|
|
|
|
void fe_check_init(FeCheck *c, FeBuild *build, FeDiags *diags,
|
|
unsigned pointer_bits, int no_checks);
|
|
void fe_check_destroy(FeCheck *c);
|
|
int fe_check_program(FeCheck *c);
|
|
|
|
#endif
|