1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-30 04:10:54 -08:00

First draft of keyword arguments. mainly checking in in order to try working with git fusion on this branch.

Copied from Perforce
 Change: 181538
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 2013-05-02 17:55:07 +01:00
parent 8d00f8dbef
commit 1bc62b27ef
14 changed files with 276 additions and 22 deletions

5
mps/.p4ignore Normal file
View file

@ -0,0 +1,5 @@
# Mac OS X Finder turds
.DS_Store
# Patch results
*.orig
*.rej

View file

@ -205,15 +205,16 @@ failGlobalsInit:
}
/* ArenaCreateV -- create the arena and call initializers */
/* ArenaCreate -- create the arena and call initializers */
Res ArenaCreateV(Arena *arenaReturn, ArenaClass class, va_list args)
Res ArenaCreate(Arena *arenaReturn, ArenaClass class, ArgList args)
{
Arena arena;
Res res;
AVER(arenaReturn != NULL);
AVERT(ArenaClass, class);
AVER(ArgListCheck(args));
/* We must initialise the event subsystem very early, because event logging
will start as soon as anything interesting happens and expect to write

View file

@ -186,8 +186,7 @@ static void ClientChunkFinish(Chunk chunk)
* .arena.init: Once the arena has been allocated, we call ArenaInit
* to do the generic part of init.
*/
static Res ClientArenaInit(Arena *arenaReturn, ArenaClass class,
va_list args)
static Res ClientArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args)
{
Arena arena;
ClientArena clientArena;
@ -196,11 +195,32 @@ static Res ClientArenaInit(Arena *arenaReturn, ArenaClass class,
Addr base, limit, chunkBase;
Res res;
Chunk chunk;
size = va_arg(args, Size);
base = va_arg(args, Addr);
mps_arg_s arg;
AVER(arenaReturn != NULL);
AVER((ArenaClass)mps_arena_class_cl() == class);
AVER(ArgListCheck(args));
if (ArgPick(&arg, args, MPS_KEY_ARENA_SIZE)) {
size = arg.val.size;
if (ArgPick(&arg, args, MPS_KEY_ARENA_CL_ADDR))
base = arg.val.addr;
else {
res = ResPARAM;
goto failParam;
}
} else if (ArgPick(&arg, args, MPS_KEY_VARARGS)) {
if (ArgPick(&arg, args, MPS_KEY_ARENA_CL_ADDR)) {
res = ResPARAM;
goto failParam;
}
size = va_arg(arg.val.varargs, Size);
base = va_arg(arg.val.varargs, Addr);
} else {
res = ResPARAM;
goto failParam;
}
AVER(base != (Addr)0);
clArenaSize = SizeAlignUp(sizeof(ClientArenaStruct), MPS_PF_ALIGN);
@ -243,6 +263,7 @@ static Res ClientArenaInit(Arena *arenaReturn, ArenaClass class,
failChunkCreate:
ArenaFinish(arena);
failParam:
return res;
}

View file

@ -340,7 +340,7 @@ static void testPageTable(ArenaClass class, ...)
va_list args;
va_start(args, class);
die(ArenaCreateV(&arena, class, args), "ArenaCreate");
die(ArenaCreate(&arena, class, args), "ArenaCreate");
va_end(args);
die(PoolCreate(&pool, arena, PoolClassMV(),

View file

@ -445,7 +445,7 @@ static void VMChunkFinish(Chunk chunk)
* .arena.init: Once the arena has been allocated, we call ArenaInit
* to do the generic part of init.
*/
static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, va_list args)
static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, ArgList args)
{
Size userSize; /* size requested by user */
Size chunkSize; /* size actually created */
@ -456,15 +456,26 @@ static Res VMArenaInit(Arena *arenaReturn, ArenaClass class, va_list args)
Index gen;
VM arenaVM;
Chunk chunk;
userSize = va_arg(args, Size);
mps_arg_s arg;
AVER(arenaReturn != NULL);
AVER(class == VMArenaClassGet() || class == VMNZArenaClassGet());
AVER(ArgListCheck(args));
if (ArgPick(&arg, args, MPS_KEY_ARENA_SIZE))
userSize = arg.val.size;
else if (ArgPick(&arg, args, MPS_KEY_VARARGS))
userSize = va_arg(arg.val.varargs, Size);
else {
res = ResPARAM;
goto failVMCreate;
}
AVER(userSize > 0);
/* Create a VM to hold the arena and map it. */
vmArenaSize = SizeAlignUp(sizeof(VMArenaStruct), MPS_PF_ALIGN);
res = VMCreate(&arenaVM, vmArenaSize);
res = VMCreate(&arenaVM, vmArenaSize, args);
if (res != ResOK)
goto failVMCreate;
res = VMMap(arenaVM, VMBase(arenaVM), VMLimit(arenaVM));

126
mps/code/arg.c Normal file
View file

@ -0,0 +1,126 @@
/* arg.c: ARGUMENT LISTS
*
* $Id: //info.ravenbrook.com/project/mps/custom/cet/main/code/bt.c#1 $
* Copyright (c) 2013 Ravenbrook Limited. See end of file for license.
*/
#include "config.h"
#include "check.h"
#include "mpm.h"
SRCID(arg, "$Id$");
#define KeySig ((Sig)0x519CE333) /* SIGnature KEYyy */
typedef struct mps_key_s {
Sig sig;
const char *name;
Bool (*check)(Arg arg);
} KeyStruct;
static Bool ArgCheckCant(Arg arg) {
UNUSED(arg);
return TRUE;
}
const KeyStruct _mps_key_varargs = {KeySig, "VARARGS", ArgCheckCant};
/* KeyCheck -- check the validity of an argument key */
Bool KeyCheck(Key key)
{
CHECKS(Key, key);
CHECKL(key->name != NULL);
CHECKL(FUNCHECK(key->check));
return TRUE;
}
Bool ArgCheck(Arg arg)
{
CHECKL(arg != NULL);
CHECKD(Key, arg->key);
CHECKL(arg->key->check(arg));
return TRUE;
}
/* ArgCheck -- check the validity of an argument list */
Bool ArgListCheck(ArgList args)
{
Index i;
CHECKL(args != NULL);
/* FIXME: Maximum plausible length? */
for (i = 0; args[i].key != MPS_KEY_ARGS_END; ++i)
CHECKL(ArgCheck(&args[i]));
return TRUE;
}
Bool ArgPick(mps_arg_s *argOut, mps_arg_s args[], Key key) {
Index i;
AVER(argOut != NULL);
AVERT(Arg, args);
AVERT(Key, key);
for (i = 0; args[i].key != MPS_KEY_ARGS_END; ++i)
if (args[i].key == key)
goto found;
return FALSE;
found:
*argOut = args[i];
for(;;) {
args[i] = args[i + 1];
if (args[i].key == MPS_KEY_ARGS_END)
break;
++i;
}
return TRUE;
}
/* C. COPYRIGHT AND LICENSE
*
* Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>.
* All rights reserved. This is an open source license. Contact
* Ravenbrook for commercial licensing options.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Redistributions in any form must be accompanied by information on how
* to obtain complete source code for this software and any accompanying
* software that uses this software. The source code must either be
* included in the distribution or be available for no more than the cost
* of distribution plus a nominal fee, and must be freely redistributable
* under reasonable conditions. For an executable file, complete source
* code means the source code for all modules it contains. It does not
* include source code for modules or files that typically accompany the
* major components of the operating system on which the executable file
* runs.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

View file

@ -130,6 +130,14 @@ extern int (AddrComp)(Addr a, Addr b, Size size);
extern Bool ResIsAllocFailure(Res res);
/* Argument Lists */
extern Bool KeyCheck(Key key);
extern Bool ArgCheck(Arg arg);
extern Bool ArgListCheck(ArgList args);
extern Bool ArgPick(ArgStruct *argOut, ArgList args, Key key);
/* Logs and Powers
*
* SizeIsP2 returns TRUE if and only if size is a non-negative integer
@ -485,7 +493,7 @@ extern AbstractArenaClass AbstractArenaClassGet(void);
extern Bool ArenaClassCheck(ArenaClass class);
extern Bool ArenaCheck(Arena arena);
extern Res ArenaCreateV(Arena *arenaReturn, ArenaClass class, va_list args);
extern Res ArenaCreate(Arena *arenaReturn, ArenaClass class, mps_arg_s args[]);
extern void ArenaDestroy(Arena arena);
extern Res ArenaInit(Arena arena, ArenaClass class);
extern void ArenaFinish(Arena arena);
@ -966,7 +974,7 @@ extern Res RootsIterate(Globals arena, RootIterateFn f, void *p);
extern Align VMAlign(VM vm);
extern Bool VMCheck(VM vm);
extern Res VMCreate(VM *VMReturn, Size size);
extern Res VMCreate(VM *VMReturn, Size size, mps_arg_s args[]);
extern void VMDestroy(VM vm);
extern Addr VMBase(VM vm);
extern Addr VMLimit(VM vm);

View file

@ -44,6 +44,11 @@ typedef void *Pointer; /* <design/type/#pointer> */
typedef Word Clock; /* processor time */
typedef MPS_T_ULONGEST ULongest; /* <design/type/#ulongest> */
typedef mps_arg_s ArgStruct;
typedef mps_arg_s *Arg;
typedef mps_arg_s *ArgList;
typedef mps_key_t Key;
typedef Word RefSet; /* design.mps.refset */
typedef Word ZoneSet; /* design.mps.refset */
typedef unsigned Rank;
@ -109,7 +114,7 @@ typedef struct StackContextStruct *StackContext;
/* Arena*Method -- see <code/mpmst.h#ArenaClassStruct> */
typedef Res (*ArenaInitMethod)(Arena *arenaReturn,
ArenaClass class, va_list args);
ArenaClass class, mps_arg_s args[]);
typedef void (*ArenaFinishMethod)(Arena arena);
typedef Size (*ArenaReservedMethod)(Arena arena);
typedef void (*ArenaSpareCommitExceededMethod)(Arena arena);

View file

@ -70,6 +70,7 @@
#include "ss.c"
#include "version.c"
#include "table.c"
#include "arg.c"
/* Additional pool classes */

View file

@ -62,6 +62,7 @@ typedef struct mps_alloc_pattern_s
*mps_alloc_pattern_t; /* allocation patterns */
typedef struct mps_frame_s
*mps_frame_t; /* allocation frames */
typedef const struct mps_key_s *mps_key_t; /* argument key */
/* Concrete Types */
@ -91,6 +92,36 @@ enum {
MPS_RES_PARAM /* illegal user parameter value */
};
/* Keyword argument lists */
typedef struct mps_arg_s {
mps_key_t key;
union {
mps_bool_t b;
char c;
const char *string;
int i;
unsigned u;
long l;
unsigned long ul;
size_t size;
va_list varargs;
mps_addr_t addr;
} val;
} mps_arg_s;
#define MPS_KEY_ARGS_END NULL
/* 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_varargs;
#define MPS_KEY_VARARGS (&_mps_key_varargs)
extern const struct mps_key_s _mps_key_arena_size;
#define MPS_KEY_ARENA_SIZE (&_mps_key_arena_size)
/* <a id="message.types"> Keep in sync with
* <code/mpmtypes.h#message.types> */
/* Not meant to be used by clients, they should use the macros below. */
@ -272,6 +303,8 @@ extern mps_bool_t mps_arena_step(mps_arena_t, double, double);
extern mps_res_t mps_arena_create(mps_arena_t *, mps_arena_class_t, ...);
extern mps_res_t mps_arena_create_v(mps_arena_t *, mps_arena_class_t, va_list);
extern mps_res_t mps_arena_create_args(mps_arena_t *, mps_arena_class_t,
mps_arg_s []);
extern void mps_arena_destroy(mps_arena_t);
extern size_t mps_arena_reserved(mps_arena_t);

View file

@ -182,6 +182,7 @@
3124CAFB156BE82000753214 /* testlib.c in Sources */ = {isa = PBXBuildFile; fileRef = 31EEAC9E156AB73400714D05 /* testlib.c */; };
3124CAFC156BE82900753214 /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; };
3150AE53156ABA2500A6E22A /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; };
317B3C2B1731830100F9A469 /* arg.c in Sources */ = {isa = PBXBuildFile; fileRef = 317B3C2A1731830100F9A469 /* arg.c */; };
31A47BA4156C1E130039B1C2 /* mps.c in Sources */ = {isa = PBXBuildFile; fileRef = 31A47BA3156C1E130039B1C2 /* mps.c */; };
31D60007156D3C6200337B26 /* segsmss.c in Sources */ = {isa = PBXBuildFile; fileRef = 31D60006156D3C5F00337B26 /* segsmss.c */; };
31D60008156D3C7400337B26 /* libmps.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 31EEABFB156AAF9D00714D05 /* libmps.a */; };
@ -1049,6 +1050,7 @@
3124CAE4156BE6D500753214 /* fmthe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fmthe.c; sourceTree = "<group>"; };
3124CAEB156BE7F300753214 /* amcss */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = amcss; sourceTree = BUILT_PRODUCTS_DIR; };
3124CAF5156BE81100753214 /* amcss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = amcss.c; sourceTree = "<group>"; };
317B3C2A1731830100F9A469 /* arg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = arg.c; sourceTree = "<group>"; };
31A47BA3156C1E130039B1C2 /* mps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mps.c; sourceTree = "<group>"; };
31A47BA5156C1E5E0039B1C2 /* ssixi3.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ssixi3.c; sourceTree = "<group>"; };
31D60006156D3C5F00337B26 /* segsmss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = segsmss.c; sourceTree = "<group>"; };
@ -1568,6 +1570,7 @@
31EEAC05156AB27B00714D05 /* arena.c */,
31EEAC06156AB27B00714D05 /* arenacl.c */,
31EEAC03156AB23A00714D05 /* arenavm.c */,
317B3C2A1731830100F9A469 /* arg.c */,
31EEAC3F156AB32500714D05 /* boot.c */,
31EEAC27156AB2F200714D05 /* bt.c */,
31EEAC19156AB2B200714D05 /* buffer.c */,
@ -2690,6 +2693,7 @@
buildActionMask = 2147483647;
files = (
31A47BA4156C1E130039B1C2 /* mps.c in Sources */,
317B3C2B1731830100F9A469 /* arg.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View file

@ -9,6 +9,9 @@
#include "mps.h"
/* Client arena base address argument */
extern const struct mps_key_s _mps_key_arena_cl_addr;
#define MPS_KEY_ARENA_CL_ADDR (&_mps_key_arena_cl_addr)
extern mps_arena_class_t mps_arena_class_cl(void);

View file

@ -52,6 +52,10 @@
#include "sac.h"
#include "chain.h"
#include <stdarg.h>
#include <string.h>
SRCID(mpsi, "$Id$");
@ -311,11 +315,14 @@ mps_res_t mps_arena_create(mps_arena_t *mps_arena_o,
mps_arena_class_t mps_arena_class, ...)
{
mps_res_t res;
va_list args;
mps_arg_s args[2];
args[0].key = MPS_KEY_VARARGS;
va_start(args[0].val.varargs, mps_arena_class);
args[1].key = MPS_KEY_ARGS_END;
res = mps_arena_create_args(mps_arena_o, mps_arena_class, args);
va_end(args[0].val.varargs);
va_start(args, mps_arena_class);
res = mps_arena_create_v(mps_arena_o, mps_arena_class, args);
va_end(args);
return res;
}
@ -323,7 +330,25 @@ mps_res_t mps_arena_create(mps_arena_t *mps_arena_o,
/* mps_arena_create_v -- create an arena object */
mps_res_t mps_arena_create_v(mps_arena_t *mps_arena_o,
mps_arena_class_t arena_class, va_list args)
mps_arena_class_t arena_class,
va_list varargs)
{
mps_arg_s args[2];
args[0].key = MPS_KEY_VARARGS;
/* FIXME: va_copy not available in C89 */
memcpy(&args[0].val.varargs, &varargs, sizeof(va_list));
args[1].key = MPS_KEY_ARGS_END;
return mps_arena_create_args(mps_arena_o, arena_class, args);
}
/* mps_arena_create_arg -- create an arena object */
mps_res_t mps_arena_create_args(mps_arena_t *mps_arena_o,
mps_arena_class_t arena_class,
mps_arg_s mps_args[])
{
Arena arena;
Res res;
@ -334,15 +359,21 @@ mps_res_t mps_arena_create_v(mps_arena_t *mps_arena_o,
AVER(mps_arena_o != NULL);
res = ArenaCreateV(&arena, arena_class, args);
res = ArenaCreate(&arena, arena_class, mps_args);
if (res != ResOK)
return res;
/* FIXME: Consider doing this
if (args[0].key != MPS_KEY_ARGS_END)
return MPS_RES_PARAM;
*/
ArenaLeave(arena);
*mps_arena_o = (mps_arena_t)arena;
return MPS_RES_OK;
}
/* mps_arena_destroy -- destroy an arena object */
void mps_arena_destroy(mps_arena_t arena)

View file

@ -98,9 +98,12 @@ Bool VMCheck(VM vm)
}
Res VM
/* VMCreate -- reserve some virtual address space, and create a VM structure */
Res VMCreate(VM *vmReturn, Size size)
Res VMCreate(VM *vmReturn, Size size, mps_arg_s args[])
{
Align align;
VM vm;
@ -109,6 +112,8 @@ Res VMCreate(VM *vmReturn, Size size)
Res res;
AVER(vmReturn != NULL);
AVERT(Arg, args);
UNUSED(args);
/* Find out the page size from the OS */
pagesize = getpagesize();