-
-
Save zhuomingliang/1752965 to your computer and use it in GitHub Desktop.
Parrot object model refactor proposal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef PARROT_H_ | |
#define PARROT_H_ | |
#include <stddef.h> | |
// short names so we don't have to type Parrot_ everywhere | |
#define PInt Parrot_Int | |
#define PNum Parrot_Num | |
// ... | |
// dynamic type id | |
enum parrot_value_type_ | |
{ | |
PARROT_FAIL_VALUE, | |
PARROT_VOID_VALUE, | |
PARROT_INT_VALUE, | |
PARROT_NUM_VALUE, | |
PARROT_STRING_VALUE, | |
PARROT_OBJECT_VALUE | |
}; | |
typedef enum parrot_value_type_ PValueType; | |
// configured types | |
typedef long long PInt; | |
typedef double PNum; | |
// a dynamically typed value | |
// used for cross-language calls and generic data structures | |
typedef union parrot_value_ PValue; | |
// a 6model object | |
typedef struct parrot_object_ PObject; | |
// internal 6model objects with known structure | |
typedef struct parrot_interp_ PInterp; | |
typedef struct parrot_string_ PString; | |
typedef struct parrot_stable_ PSTable; | |
typedef struct parrot_hash_ PArray; | |
typedef struct parrot_hash_ PHash; | |
typedef struct parrot_hash_ PObjectHash; | |
// ... | |
// the 6model representation | |
typedef struct parrot_repr_ PRepr; | |
// parrot-level objects implemented in C use vtables for performance reasons | |
// the existing monolithic vtable is split into separate interfaces | |
// aggregate of vtable pointers | |
typedef struct parrot_vtable_ PVTable; | |
// handles conversion to language-specific calling conventions | |
// methods callable from other languages need to provide this vtable | |
typedef struct parrot_vt_method_ PVTMethod; | |
// this replaces the 6model ContainerSpec | |
// needs some thinking to get the vtable<->6model interaction right | |
typedef struct parrot_vt_container_ PVTContainer; | |
// ... | |
// vtables are opt-in - if a member is NULL, fall back to duck-typing: | |
// ask the meta-object for a method object and go through its invoke vtable | |
struct parrot_vtable_ | |
{ | |
PVTMethod *method; | |
PVTContainer *container; | |
// ... | |
}; | |
struct parrot_repr_ | |
{ | |
// a repr needs no numeric id, so we got rid of it | |
PString *name; | |
// the various repr functions, including gc-specifics... | |
PObject *(*allocate)(PInterp *interp, PSTable *st); | |
void (*initialize)(PInterp *interp, PSTable *st, void *data); | |
// ... | |
// the SixModel_REPROps_* tables get flattened into this as well: | |
// the additional indirection is unnecessary | |
}; | |
// every object starts with a PObject member | |
struct parrot_object_ | |
{ | |
PSTable *stable; | |
// ... | |
// things like the serialization context or flags go here | |
}; | |
struct parrot_interp_ | |
{ | |
PObject header; | |
PObjectHash *repr_registry; | |
// ... | |
}; | |
// the exact meaning of the args object is language-specific | |
// interoperable methods must accept a PArray argument | |
struct parrot_vt_method_ | |
{ | |
PValue (*invoke)(PInterp *interp, PObject *obj, PObject *args); | |
}; | |
// example code: | |
/* PInterp *interp = ...; | |
PObject *obj = ...; | |
PObject *method = Parrot_find_method(...); | |
assert(method); | |
PVTMethod vt = method->vtable.method; | |
assert(vt); | |
PValue storage[2]; | |
storage[0].type = PARROT_INT_VALUE; | |
storage[0].as_int.value = 42; | |
storage[1].type = PARROT_INT_VALUE; | |
storage[1].as_int.value = 666; | |
PArray args = PARROT_STACK_ARRAY; // uses a repr with correct gc methods | |
Parrot_array_set_storage(&args, storage, 2); | |
PValue rv = vt->invoke(interp, obj, &args); | |
switch(rv.type) | |
{ | |
case PARROT_FAIL_VALUE: | |
... | |
} | |
*/ | |
union parrot_value_ | |
{ | |
PValueType type; | |
struct { PValueType type; PInt value; } as_int; | |
struct { PValueType type; PNum value; } as_num; | |
struct { PValueType type; PString *value; } as_string; | |
struct { PValueType type; PObject *value; } as_object; | |
}; | |
struct parrot_stable_ | |
{ | |
PObject header; | |
PRepr *repr; | |
PVTable vtable; | |
PObject *meta_object; | |
PObject *type_object; | |
PObject *method_cache; | |
PObject **static_method_cache; | |
size_t static_method_cache_size; | |
PObject **type_check_cache; | |
size_t type_check_cache_size; | |
// ... | |
}; | |
// meta-object methods need not be virtual | |
extern PObject *Parrot_find_method( | |
PInterp *interp, PObject *obj, PString *name, PInt hint); | |
extern PInt Parrot_type_check(PInterp *interp, PObject *obj, PObject *checkee); | |
// hide short names in parrot-specific source files | |
#ifndef PARROT_SOURCE | |
#undef PInt | |
#undef PNum | |
//... | |
#endif | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment