diff --git a/mps/code/arenacv.c b/mps/code/arenacv.c index 18b5ba3418f..cfd124ec7d1 100644 --- a/mps/code/arenacv.c +++ b/mps/code/arenacv.c @@ -337,14 +337,13 @@ static void testPageTable(ArenaClass class, Size size, Addr addr) Arena arena; Pool pool; Size pageSize; Count tractsPerPage; - ArgStruct args[4]; - args[0].key = MPS_KEY_ARENA_SIZE; - args[0].val.size = size; - args[1].key = MPS_KEY_ARENA_CL_ADDR; - args[1].val.addr = addr; - args[2].key = MPS_KEY_ARGS_END; - die(ArenaCreate(&arena, class, args), "ArenaCreate"); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, size, size); + MPS_ARGS_ADD(args, MPS_KEY_ARENA_CL_ADDR, addr, addr); + MPS_ARGS_DONE(args); + die(ArenaCreate(&arena, class, args), "ArenaCreate"); + } MPS_ARGS_END(args); die(PoolCreate(&pool, arena, PoolClassMV(), argsNone), "PoolCreate"); @@ -378,11 +377,11 @@ static void testSize(Size size) Res res; do { - ArgStruct args[2]; - args[0].key = MPS_KEY_ARENA_SIZE; - args[0].val.size = size; - args[1].key = MPS_KEY_ARGS_END; - res = ArenaCreate(&arena, class, args); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, size, size); + MPS_ARGS_DONE(args); + res = ArenaCreate(&arena, class, args); + } MPS_ARGS_END(args); if (res == ResOK) ArenaDestroy(arena); else diff --git a/mps/code/arg.h b/mps/code/arg.h index f50107b593f..2647937c201 100644 --- a/mps/code/arg.h +++ b/mps/code/arg.h @@ -37,6 +37,7 @@ extern Bool ArgCheck(Arg arg); extern Bool ArgListCheck(ArgList args); extern Bool ArgPick(ArgStruct *argOut, ArgList args, Key key); +extern void ArgRequired(ArgStruct *argOut, ArgList args, Key key); extern Bool ArgCheckCant(Arg arg); extern Bool ArgCheckFormat(Arg arg); @@ -49,6 +50,7 @@ extern Bool ArgCheckAlign(Arg arg); extern Bool ArgCheckBool(Arg arg); extern Bool ArgCheckCount(Arg arg); + #endif /* arg_h */ diff --git a/mps/code/cbs.c b/mps/code/cbs.c index 23a66699333..14e13b51b01 100644 --- a/mps/code/cbs.c +++ b/mps/code/cbs.c @@ -273,7 +273,6 @@ Res CBSInit(Arena arena, CBS cbs, void *owner, Bool mayUseInline, Bool fastFind) { Res res; - ArgStruct args[3]; AVERT(Arena, arena); AVER(new == NULL || FUNCHECK(new)); @@ -287,12 +286,12 @@ Res CBSInit(Arena arena, CBS cbs, void *owner, SplayTreeInit(splayTreeOfCBS(cbs), &cbsSplayCompare, fastFind ? &cbsUpdateNode : NULL); - args[0].key = MPS_KEY_MFS_UNIT_SIZE; - args[0].val.size = sizeof(CBSBlockStruct); - args[1].key = MPS_KEY_EXTEND_BY; - args[1].val.size = sizeof(CBSBlockStruct) * 64; - args[2].key = MPS_KEY_ARGS_END; - res = PoolCreate(&(cbs->blockPool), arena, PoolClassMFS(), args); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_MFS_UNIT_SIZE, size, sizeof(CBSBlockStruct)); + MPS_ARGS_ADD(args, MPS_KEY_EXTEND_BY, size, sizeof(CBSBlockStruct) * 64); + MPS_ARGS_DONE(args); + res = PoolCreate(&(cbs->blockPool), arena, PoolClassMFS(), args); + } MPS_ARGS_END(args); if (res != ResOK) return res; cbs->splayTreeSize = 0; diff --git a/mps/code/dbgpool.c b/mps/code/dbgpool.c index 591a7ce39de..8d416815471 100644 --- a/mps/code/dbgpool.c +++ b/mps/code/dbgpool.c @@ -185,16 +185,15 @@ static Res DebugPoolInit(Pool pool, ArgList args) /* tag init */ debug->tagInit = tagInit; if (debug->tagInit != NULL) { - ArgStruct pcArgs[3]; debug->tagSize = tagSize + sizeof(tagStruct) - 1; /* This pool has to be like the arena control pool: the blocks */ /* allocated must be accessible using void*. */ - pcArgs[0].key = MPS_KEY_EXTEND_BY; - pcArgs[0].val.size = debug->tagSize; /* FIXME: Really? */ - pcArgs[1].key = MPS_KEY_MFS_UNIT_SIZE; - pcArgs[1].val.size = debug->tagSize; - pcArgs[2].key = MPS_KEY_ARGS_END; - res = PoolCreate(&debug->tagPool, PoolArena(pool), PoolClassMFS(), pcArgs); + MPS_ARGS_BEGIN(pcArgs) { + MPS_ARGS_ADD(pcArgs, MPS_KEY_EXTEND_BY, size, debug->tagSize); /* FIXME: Check this */ + MPS_ARGS_ADD(pcArgs, MPS_KEY_MFS_UNIT_SIZE, size, debug->tagSize); + MPS_ARGS_DONE(pcArgs); + res = PoolCreate(&debug->tagPool, PoolArena(pool), PoolClassMFS(), pcArgs); + } MPS_ARGS_END(pcArgs); if (res != ResOK) goto tagFail; debug->missingTags = 0; diff --git a/mps/code/mps.h b/mps/code/mps.h index 5f320e63c51..1a82d5c149b 100644 --- a/mps/code/mps.h +++ b/mps/code/mps.h @@ -119,10 +119,6 @@ extern const struct mps_key_s _mps_key_args_end; #define MPS_KEY_ARGS_END (&_mps_key_args_end) extern mps_arg_s mps_args_none[]; -/* FIXME: This shouldn't be here */ -extern const struct mps_key_s _mps_key_vmw3_top_down; -#define MPS_KEY_VMW3_TOP_DOWN (&_mps_key_vmw3_top_down) - extern const struct mps_key_s _mps_key_arena_size; #define MPS_KEY_ARENA_SIZE (&_mps_key_arena_size) extern const struct mps_key_s _mps_key_format; @@ -131,15 +127,44 @@ extern const struct mps_key_s _mps_key_chain; #define MPS_KEY_CHAIN (&_mps_key_chain) extern const struct mps_key_s _mps_key_extend_by; -#define MPS_KEY_EXTEND_BY (&_mps_key_extend_by) +#define MPS_KEY_EXTEND_BY (&_mps_key_extend_by) extern const struct mps_key_s _mps_key_min_size; -#define MPS_KEY_MIN_SIZE (&_mps_key_min_size) +#define MPS_KEY_MIN_SIZE (&_mps_key_min_size) extern const struct mps_key_s _mps_key_mean_size; -#define MPS_KEY_MEAN_SIZE (&_mps_key_mean_size) +#define MPS_KEY_MEAN_SIZE (&_mps_key_mean_size) extern const struct mps_key_s _mps_key_max_size; -#define MPS_KEY_MAX_SIZE (&_mps_key_max_size) +#define MPS_KEY_MAX_SIZE (&_mps_key_max_size) extern const struct mps_key_s _mps_key_align; -#define MPS_KEY_ALIGN (&_mps_key_align) +#define MPS_KEY_ALIGN (&_mps_key_align) + +/* FIXME: This will only be present on Windows. */ +extern const struct mps_key_s _mps_key_vmw3_top_down; +#define MPS_KEY_VMW3_TOP_DOWN (&_mps_key_vmw3_top_down) + +#define MPS_ARGS_BEGIN(_var) \ + BEGIN \ + mps_arg_s _var[ARGS_MAX]; \ + unsigned _var##_i = 0; \ + BEGIN + +#define MPS_ARGS_ADD(_var, _key, _field, _val) \ + BEGIN \ + /* FIXME: AVER(_var_i < ARGS_MAX); */ \ + _var[_var##_i].key = (_key); \ + _var[_var##_i].val._field = (_val); \ + ++_var##_i; \ + END + +#define MPS_ARGS_DONE(_var) \ + BEGIN \ + /* FIXME: AVER(_var##_i < ARGS_MAX); */ \ + _var[_var##_i].key = MPS_KEY_ARGS_END; \ + /* FIXME: _var##_i = ARGS_MAX; */ \ + END + +#define MPS_ARGS_END(_var) \ + END; \ + END /* Keep in sync with diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index d15404aad26..8235b66c05f 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c @@ -973,18 +973,10 @@ static Res amcInitComm(Pool pool, RankSet rankSet, ArgList args) amc = Pool2AMC(pool); arena = PoolArena(pool); - if (ArgPick(&arg, args, MPS_KEY_FORMAT)) - pool->format = arg.val.format; - else { - res = ResPARAM; - goto failParam; - } - if (ArgPick(&arg, args, MPS_KEY_CHAIN)) - amc->chain = arg.val.chain; - else { - res = ResPARAM; - goto failParam; - } + ArgRequired(&arg, args, MPS_KEY_FORMAT); + pool->format = arg.val.format; + ArgRequired(&arg, args, MPS_KEY_CHAIN); + amc->chain = arg.val.chain; AVERT(Format, pool->format); AVERT(Chain, amc->chain); @@ -1060,7 +1052,6 @@ failGenAlloc: } ControlFree(arena, amc->gen, genArraySize); failGensAlloc: -failParam: return res; } diff --git a/mps/code/poolmv.c b/mps/code/poolmv.c index 50af068f4ed..e827e9d69b6 100644 --- a/mps/code/poolmv.c +++ b/mps/code/poolmv.c @@ -216,7 +216,6 @@ static Res MVInit(Pool pool, ArgList args) Arena arena; Res res; ArgStruct arg; - ArgStruct piArgs[3]; if (ArgPick(&arg, args, MPS_KEY_EXTEND_BY)) extendBy = arg.val.size; @@ -241,23 +240,23 @@ static Res MVInit(Pool pool, ArgList args) blockExtendBy = sizeof(MVBlockStruct); } - piArgs[0].key = MPS_KEY_EXTEND_BY; - piArgs[0].val.size = blockExtendBy; - piArgs[1].key = MPS_KEY_MFS_UNIT_SIZE; - piArgs[1].val.size = sizeof(MVBlockStruct); - piArgs[2].key = MPS_KEY_ARGS_END; - res = PoolInit(&mv->blockPoolStruct.poolStruct, arena, PoolClassMFS(), piArgs); + MPS_ARGS_BEGIN(piArgs) { + MPS_ARGS_ADD(piArgs, MPS_KEY_EXTEND_BY, size, blockExtendBy); + MPS_ARGS_ADD(piArgs, MPS_KEY_MFS_UNIT_SIZE, size, sizeof(MVBlockStruct)); + MPS_ARGS_DONE(piArgs); + res = PoolInit(&mv->blockPoolStruct.poolStruct, arena, PoolClassMFS(), piArgs); + } MPS_ARGS_END(piArgs); if(res != ResOK) return res; spanExtendBy = sizeof(MVSpanStruct) * (maxSize/extendBy); - piArgs[0].key = MPS_KEY_EXTEND_BY; - piArgs[0].val.size = spanExtendBy; - piArgs[1].key = MPS_KEY_MFS_UNIT_SIZE; - piArgs[1].val.size = sizeof(MVSpanStruct); - piArgs[2].key = MPS_KEY_ARGS_END; - res = PoolInit(&mv->spanPoolStruct.poolStruct, arena, PoolClassMFS(), piArgs); + MPS_ARGS_BEGIN(piArgs) { + MPS_ARGS_ADD(piArgs, MPS_KEY_EXTEND_BY, size, spanExtendBy); + MPS_ARGS_ADD(piArgs, MPS_KEY_MFS_UNIT_SIZE, size, sizeof(MVSpanStruct)); + MPS_ARGS_DONE(piArgs); + res = PoolInit(&mv->spanPoolStruct.poolStruct, arena, PoolClassMFS(), piArgs); + } MPS_ARGS_END(piArgs); if(res != ResOK) return res; diff --git a/mps/code/poolncv.c b/mps/code/poolncv.c index f7598c5539a..c250e84d2cd 100644 --- a/mps/code/poolncv.c +++ b/mps/code/poolncv.c @@ -32,12 +32,12 @@ static void testit(ArenaClass class, ArgList args) int main(int argc, char *argv[]) { - mps_arg_s args[2]; testlib_unused(argc); - args[0].key = MPS_KEY_ARENA_SIZE; - args[0].val.size = (Size)600000; - args[1].key = MPS_KEY_ARGS_END; - testit((ArenaClass)mps_arena_class_vm(), args); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, size, 600000); + MPS_ARGS_DONE(args); + testit((ArenaClass)mps_arena_class_vm(), args); + } MPS_ARGS_END(args); printf("%s: Conclusion: Failed to find any defects.\n", argv[0]); return 0; } diff --git a/mps/code/segsmss.c b/mps/code/segsmss.c index 46b3e0288ee..9d69aff302a 100644 --- a/mps/code/segsmss.c +++ b/mps/code/segsmss.c @@ -766,18 +766,18 @@ static void *test(void *arg, size_t s) mps_ap_t busy_ap; mps_addr_t busy_init; char *indent = " "; - mps_arg_s args[2]; arena = (mps_arena_t)arg; (void)s; /* unused */ die(mps_fmt_create_A(&format, arena, dylan_fmt_A()), "fmt_create"); - args[0].key = MPS_KEY_FORMAT; - args[0].val.format = format; - args[1].key = MPS_KEY_ARGS_END; - die(mps_pool_create_k(&pool, arena, mps_class_amst(), args), - "pool_create(amst)"); + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_FORMAT, format, format); + MPS_ARGS_DONE(args); + die(mps_pool_create_k(&pool, arena, mps_class_amst(), args), + "pool_create(amst)"); + } MPS_ARGS_END(args); die(mps_ap_create(&ap, pool, mps_rank_exact()), "BufferCreate"); die(mps_ap_create(&busy_ap, pool, mps_rank_exact()), "BufferCreate 2"); diff --git a/mps/manual/source/topic/interface.rst b/mps/manual/source/topic/interface.rst index 088578f5275..fc59f4fd8f4 100644 --- a/mps/manual/source/topic/interface.rst +++ b/mps/manual/source/topic/interface.rst @@ -277,8 +277,18 @@ arguments are passed in a keyword argument array, like this:: args[1].val.addr = base_address; args[2].key = MPS_KEY_ARGS_END; res = mps_arena_create_k(&arena, mps_arena_class_cl(), args); + +For convenience and robustness, the MPS interface includes macros to +help with forming keyword argument lists:: + + MPS_ARGS_BEGIN(args) { + MPS_ARGS_ADD(args, MPS_KEY_ARENA_SIZE, size, 6553600); + MPS_ARGS_ADD(args, MPS_KEY_ARENA_CL_BASE, addr, base_address); + MPS_ARGS_DONE(args); + res = mps_arena_create_k(&arena, mps_arena_class_cl(), args); + } MPS_ARGS_END(args); -If you are writing C99, you can write this more concisely as:: +But if you are writing C99, you can write this more concisely as:: mps_res_t res; mps_arena_t arena;