Skip to content

Instantly share code, notes, and snippets.

@zhuomingliang
Forked from gerdr/parrot.h
Created February 6, 2012 16:12
Show Gist options
  • Save zhuomingliang/1752965 to your computer and use it in GitHub Desktop.
Save zhuomingliang/1752965 to your computer and use it in GitHub Desktop.
Parrot object model refactor proposal
#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