2017-04-17 06:17:10 -06:00

547 lines
23 KiB
C++
Executable File

/* Value.h - metaclass system MAXScript values
*
* All MAXScript-specific C++ objects are subclasses of a single root class, Value,
* and allocated & automatically freed in a specially maintained heap. There is also
* a metaclass system to provide a runtime type calculus for the scripter. Value subclasses
* are divided into those that are scripter-visible, (ie, may wind up as objects that the
* scripter may pass around or store in variables, etc.), and those that are entirely
* internal to the scripter operation (such as thunks, etc.). The scripter-visible
* classes (the majority) are represented in the metasystem by instances of separate
* metaclasses. The metaclasses are all subclasses of ValueMetaClass, the metaclass of
* a class X is named XClass and its sole instance is X_class. The class instances are
* made visible in globals (usually) named X.
*
* Each Value instance has a tag word that either contains a pointer to the instance's
* class instance (in the case of scripter-visible classes) or the reserved value INTERNAL_CLASS_TAG.
* This value is used in performing runtimne type tests and for yielding results to classOf
* methods.
*
* The metaclass, its instance and some of the class calculus methods are usually defined via
* a bunch of macros defined here (see visible_class, visible_class_instance, etc.)
*
* Some of the classes are can be instanced directly as literals in a script, such as strings,
* Point3s, arrays, etc. Some others are instantiable directly by applying the class value
* to a set of initializing parameters, ie, using the class as a function in a function call,
* for example, ray, quat, interval, etc. These are defined via a variant macro: applyable_class().
* A special case of this is provided in the MAXWrapper subsytem for creatable MAX objects, such as
* boxes, lights, camera, etc.. These are represnted by instances of the class MAXClass, and again, thses
* instances are exposed in globals to be applied to creation paramters. These instances
* contain a lot of property metadata and are defined in MAX_classes.cpp. See MAXObject.h for more
* info.
*
* Copyright (c) John Wainwright, 1996
*
*/
#ifndef _H_VALUE
#define _H_VALUE
#include "Colctble.h"
#include "Max.h"
#include "STDMAT.H"
#include "Surf_api.h"
#include "Collect.h"
class Name;
#include "defextfn.h"
# include "corename.h"
// forward declarations...
class PathName;
class Undefined;
class UserProp;
class UserGeneric;
class CallContext;
extern ScripterExport Undefined undefined;
extern ScripterExport bool dontThrowAccessorError;
class ValueMetaClass;
typedef struct node_map node_map;
// the root MAXScript class
class Value : public Collectable
{
private:
ScripterExport static Matrix3 s_error_matrix;
ScripterExport static Box2 s_error_box2;
public:
ValueMetaClass* tag; // runtime type tag; filled in by subclasses
ScripterExport virtual BOOL is_kind_of(ValueMetaClass* c);
ScripterExport virtual ValueMetaClass* local_base_class(); // local base class in this class's plug-in
virtual Value* eval() { check_interrupts(); return this; }
virtual Value* eval_no_wrapper() { check_interrupts(); return this; }
ScripterExport virtual Value* apply(Value** arglist, int count, CallContext* cc=NULL);
virtual void export_to_scripter() { }
virtual Value* map(node_map& m) { unimplemented(_T("map"), this) ; return this; }
virtual Value* map_path(PathName* path, node_map& m) { unimplemented(_T("map_path"), this) ; return this; }
virtual Value* find_first(BOOL (*test_fn)(INode* node, int level, void* arg), void* test_arg) { unimplemented(_T("find_first"), this) ; return this; }
virtual Value* get_path(PathName* path) { unimplemented(_T("get"), this) ; return this; }
ScripterExport virtual void sprin1(CharStream* stream);
ScripterExport virtual void sprint(CharStream* stream);
virtual void prin1() { sprin1(thread_local(current_stdout)); }
virtual void print() { sprint(thread_local(current_stdout)); }
/* include all the protocol declarations */
#include "defabsfn.h"
# include "mathpro.h"
# include "vectpro.h"
# include "matpro.h"
# include "quatpro.h"
# include "arraypro.h"
# include "streampr.h"
# include "strngpro.h"
# include "timepro.h"
# include "colorpro.h"
# include "nodepro.h"
# include "ctrlrpro.h"
# include "prims.h"
# include "biprops.h"
# include "bitmapro.h"
# include "texmapro.h"
# include "atmspro.h"
# include "nurbspro.h"
# include "ctbmapro.h"
// MXSAgni specific -- START --
# include "bmatpro.h"
# include "boxpro.h"
# include "phyblpro.h"
# include "phymcpro.h"
# include "bipedpro.h"
# include "notespro.h"
# include "xrefspro.h"
// MXSAgni specific -- END --
ScripterExport virtual Class_ID get_max_class_id() { return Class_ID(0, 0); }
ScripterExport virtual Value* delete_vf(Value** arglist, int arg_count) { ABSTRACT_FUNCTION(_T("delete"), this, Value*); }
ScripterExport virtual Value* clearSelection_vf(Value** arglist, int arg_count) { ABSTRACT_FUNCTION(_T("clearSelection"), this, Value*); }
#undef def_generic
#define def_generic(fn, name) ScripterExport virtual Value* fn##_vf(Value** arglist, int arg_count);
# include "kernlpro.h"
virtual float to_float() { ABSTRACT_CONVERTER(float, Float); }
virtual TCHAR* to_string() { ABSTRACT_CONVERTER(TCHAR*, String); }
virtual TSTR to_filename() { ABSTRACT_CONVERTER(TCHAR*, FileName); }
virtual int to_int() { ABSTRACT_CONVERTER(int, Integer); }
virtual BOOL to_bool() { ABSTRACT_CONVERTER(BOOL, Boolean); }
virtual BitArray& to_bitarray() { throw ConversionError (this, _T("BitArray")); return *(BitArray*)NULL; }
virtual Point4 to_point4() { ABSTRACT_CONVERTER(Point4, Point4); }
virtual Point3 to_point3() { ABSTRACT_CONVERTER(Point3, Point3); }
virtual Point2 to_point2() { ABSTRACT_CONVERTER(Point2, Point2); }
virtual AColor to_acolor() { throw ConversionError (this, _T("Color")); return AColor(0,0,0); }
virtual COLORREF to_colorref() { throw ConversionError (this, _T("Color")); return RGB(0,0,0); }
virtual INode* to_node() { ABSTRACT_CONVERTER(INode*, <node>); }
virtual Ray to_ray() { throw ConversionError (this, _T("Ray")); return Ray(); }
virtual Interval to_interval() { throw ConversionError (this, _T("Interval")); return Interval(); }
virtual Quat to_quat() { throw ConversionError (this, _T("Quaternion")); return Quat(); }
virtual AngAxis to_angaxis() { throw ConversionError (this, _T("AngleAxis")); return AngAxis(); }
virtual Matrix3& to_matrix3() { throw ConversionError (this, _T("Matrix")); return s_error_matrix; }
virtual float* to_eulerangles() { ABSTRACT_CONVERTER(float*, Float); }
virtual Mtl* to_mtl() { ABSTRACT_CONVERTER(Mtl*, Material); }
virtual Texmap* to_texmap() { ABSTRACT_CONVERTER(Texmap*, TextureMap); }
virtual MtlBase* to_mtlbase() { ABSTRACT_CONVERTER(MtlBase*, MtlBase); }
virtual Modifier* to_modifier() { ABSTRACT_CONVERTER(Modifier*, Modifier); }
virtual TimeValue to_timevalue() { ABSTRACT_CONVERTER(TimeValue, Time); }
virtual Control* to_controller() { ABSTRACT_CONVERTER(Control*, Controller); }
virtual Atmospheric* to_atmospheric() { ABSTRACT_CONVERTER(Atmospheric*, Atmospheric); }
virtual Effect* to_effect() { ABSTRACT_CONVERTER(Effect*, Effect); } // RK: Added this
virtual IMultiPassCameraEffect* to_mpassCamEffect() { ABSTRACT_CONVERTER(IMultiPassCameraEffect*, Effect); } // LAM: Added this
virtual ShadowType* to_shadowtype() { ABSTRACT_CONVERTER(ShadowType*, ShadowType); } // RK: Added this
virtual FilterKernel* to_filter() { ABSTRACT_CONVERTER(FilterKernel*, FilterKernel); } // RK: Added this
virtual INode* to_rootnode() { ABSTRACT_CONVERTER(INode*, <root>); } // RK: Added this
virtual ITrackViewNode* to_trackviewnode() { ABSTRACT_CONVERTER(ITrackViewNode*, TrackViewNode); }
virtual NURBSIndependentPoint* to_nurbsindependentpoint() { throw ConversionError (this, _T("NURBSIndependentPoint")); return (NURBSIndependentPoint*)0; }
virtual NURBSPoint* to_nurbspoint() { throw ConversionError (this, _T("NURBSPoint")); return (NURBSPoint*)0; }
virtual NURBSObject* to_nurbsobject() { throw ConversionError (this, _T("NURBSObject")); return (NURBSObject*)0; }
virtual NURBSControlVertex* to_nurbscontrolvertex() { throw ConversionError (this, _T("NURBSControlVertex")); return (NURBSControlVertex*)0; }
virtual NURBSCurve* to_nurbscurve() { throw ConversionError (this, _T("NURBSCurve")); return (NURBSCurve*)0; }
virtual NURBSCVCurve* to_nurbscvcurve() { throw ConversionError (this, _T("NURBSCVCurve")); return (NURBSCVCurve*)0; }
virtual NURBSSurface* to_nurbssurface() { throw ConversionError (this, _T("NURBSSurface")); return (NURBSSurface*)0; }
virtual NURBSTexturePoint* to_nurbstexturepoint() { throw ConversionError (this, _T("NURBSTexturePoint")); return (NURBSTexturePoint*)0; }
virtual NURBSSet* to_nurbsset() { throw ConversionError (this, _T("NURBSSet")); return (NURBSSet*)0; }
virtual ReferenceTarget* to_reftarg() { ABSTRACT_CONVERTER(ReferenceTarget*, MaxObject); }
virtual Mesh* to_mesh() { ABSTRACT_CONVERTER(Mesh*, Mesh); }
virtual Thunk* to_thunk() { ABSTRACT_CONVERTER(Thunk*, &-reference); }
virtual void to_fpvalue(FPValue& v) { throw ConversionError (this, _T("FPValue")); }
virtual Renderer* to_renderer() { ABSTRACT_CONVERTER(Renderer*, Renderer); } // LAM: Added this 9/15/01
// MXSAgni specific -- START --
virtual Box2& to_box2() { throw ConversionError (this, _T("Box2")); return s_error_box2; }
// MXSAgni specific -- END --
virtual NURBSTextureSurface* to_nurbstexturesurface() { throw ConversionError (this, _T("NURBSTextureSurface")); return (NURBSTextureSurface*)0; }
virtual NURBSDisplay* to_nurbsdisplay() { throw ConversionError (this, _T("NURBSDisplay")); return (NURBSDisplay*)0; }
virtual TessApprox* to_tessapprox() { throw ConversionError (this, _T("TessApprox")); return (TessApprox*)0; }
virtual Value* widen_to(Value* arg, Value** arg_list) { ABSTRACT_WIDENER(arg); }
virtual BOOL comparable(Value* arg) { return (tag == arg->tag); }
virtual BOOL is_const() { return FALSE; }
// LAM - 7/8/03 - defect 504956 - following identifies classes that derive from MAXWrapper. Only other implementation is in MAXWrapper
// used by garbage collector to prevent collection of MAXWrapper-derived values while doing light collection
virtual BOOL derives_from_MAXWrapper() { return FALSE; }
ScripterExport virtual Value* get_property(Value** arg_list, int count);
ScripterExport virtual Value* set_property(Value** arg_list, int count);
ScripterExport Value* _get_property(Value* prop);
ScripterExport virtual Value* _set_property(Value* prop, Value* val);
virtual Value* get_container_property(Value* prop, Value* cur_prop) { if (!dontThrowAccessorError) throw AccessorError (cur_prop, prop); return NULL; }
// Win64 Cleanup: Shuler
virtual Value* set_container_property(Value* prop, Value* val, Value* cur_prop) { throw AccessorError (cur_prop, prop); return NULL;}
// Win64 Cleanup: Shuler
#ifdef USE_PROPERTY_PATH_THUNKS
virtual Value* get_property_path(Value** arg_list, int count);
virtual Value* set_property_path(Value** arg_list, int count);
#endif
// polymorphic default type predicates - abstracted over by is_x(v) macros as needed
virtual BOOL _is_collection() { return FALSE; }
virtual BOOL _is_charstream() { return FALSE; }
virtual BOOL _is_rolloutcontrol() { return FALSE; }
virtual BOOL _is_rolloutthunk() { return FALSE; }
virtual BOOL _is_function() { return FALSE; }
virtual BOOL _is_selection() { return FALSE; }
virtual BOOL _is_thunk() { return FALSE; }
virtual BOOL _is_indirect_thunk() { return FALSE; }
// yield selection set iterator if you can
virtual SelectionIterator* selection_iterator() { throw RuntimeError (_T("Operation requires a selection (Array or BitArray)")); return NULL; }
// scene persistence functions
ScripterExport virtual IOResult Save(ISave* isave);
// the Load fn is a static method on loadbale classes, see SceneIO.cpp & .h and each loadable class
// called during MAX exit to have all MAXScript-side refs dropped (main implementation in MAXWrapper)
virtual void drop_MAX_refs() { }
// access ID'd FPInterface if supported
virtual BaseInterface* GetInterface(Interface_ID id) { return NULL; }
// stack allocation routines
ScripterExport Value* make_heap_permanent();
ScripterExport Value* make_heap_static() { Value* v = make_heap_permanent(); v->flags |= GC_STATIC; return v; }
ScripterExport Value* get_heap_ptr() { if (!has_heap_copy()) return migrate_to_heap(); return is_on_stack() ? get_stack_heap_ptr() : this; }
ScripterExport Value* get_stack_heap_ptr() { return (Value*)next; }
ScripterExport Value* migrate_to_heap();
ScripterExport Value* get_live_ptr() { return is_on_stack() && has_heap_copy() ? get_stack_heap_ptr() : this; }
};
inline Value* heap_ptr(Value* v) { return v ? v->get_heap_ptr() : NULL; } // ensure v is in heap, migrate if not, return heap pointer
inline Value* live_ptr(Value* v) { return v->get_live_ptr(); } // get live pointer, if on stack & migrated, heap copy is live
/* ---------- the base class for all metaclasses ---------- */
class MetaClassClass;
extern MetaClassClass value_metaclass; // the metaclass class
class ValueMetaClass : public Value
{
public:
TCHAR* name;
UserProp* user_props; // additional, user defined property accessors
short uprop_count;
UserGeneric* user_gens; // " " " generic fns
short ugen_count;
Tab<FPInterfaceDesc*> prop_interfaces; // static interfaces who methods appear as properties on instances of the class
ValueMetaClass() { }
ScripterExport ValueMetaClass(TCHAR* iname);
ScripterExport BOOL is_kind_of(ValueMetaClass* c);
# define is_valueclass(o) ((o)->tag == (ValueMetaClass*)&value_metaclass)
ScripterExport void sprin1(CharStream* s);
ScripterExport void export_to_scripter();
ScripterExport void add_user_prop(TCHAR* prop, value_cf getter, value_cf setter);
ScripterExport void add_user_generic(TCHAR* name, value_cf fn);
ScripterExport UserGeneric* find_user_gen(Value* name);
ScripterExport UserProp* find_user_prop(Value* prop);
// static property interfaces
ScripterExport void add_prop_interface(FPInterfaceDesc* fpd) { prop_interfaces.Append(1, &fpd); }
ScripterExport int num_prop_interfaces() { return prop_interfaces.Count(); }
ScripterExport FPInterfaceDesc* get_prop_interface(int i) { return prop_interfaces[i]; }
/* #include "defimpfn.h"
// subclass & instance virtual array accessors
def_prop_getter(subclasses);
def_prop_getter(instances);
*/
};
#define classof_methods(_cls, _super) \
Value* classOf_vf(Value** arg_list, int count) \
{ \
check_arg_count(classOf, 1, count + 1); \
return &_cls##_class; \
} \
Value* superClassOf_vf(Value** arg_list, int count) \
{ \
check_arg_count(superClassOf, 1, count + 1); \
return &_super##_class; \
} \
Value* isKindOf_vf(Value** arg_list, int count) \
{ \
check_arg_count(isKindOf, 2, count + 1); \
return (arg_list[0] == &_cls##_class) ? \
&true_value : \
_super::isKindOf_vf(arg_list, count); \
} \
BOOL is_kind_of(ValueMetaClass* c) \
{ \
return (c == &_cls##_class) ? 1 \
: _super::is_kind_of(c); \
}
#define visible_class(_cls) \
class _cls##Class : public ValueMetaClass \
{ \
public: \
_cls##Class(TCHAR* name) : ValueMetaClass (name) { } \
void collect() { delete this; } \
}; \
extern ScripterExport _cls##Class _cls##_class;
#define visible_class_s(_cls, _super) \
class _cls##Class : public ValueMetaClass \
{ \
public: \
_cls##Class(TCHAR* name) : ValueMetaClass (name) { } \
void collect() { delete this; } \
Value* classOf_vf(Value** arg_list, int count) \
{ \
check_arg_count(classOf, 1, count + 1); \
return &_super##_class; \
} \
Value* superClassOf_vf(Value** arg_list, int count) \
{ \
return _super##_class.classOf_vf(NULL, 0); \
} \
}; \
extern ScripterExport _cls##Class _cls##_class;
#define applyable_class(_cls) \
class _cls##Class : public ValueMetaClass \
{ \
public: \
_cls##Class(TCHAR* name) : ValueMetaClass (name) { }\
void collect() { delete this; } \
ScripterExport Value* apply(Value** arglist, int count, CallContext* cc=NULL); \
}; \
extern ScripterExport _cls##Class _cls##_class;
#define applyable_class_s(_cls, _super) \
class _cls##Class : public ValueMetaClass \
{ \
public: \
_cls##Class(TCHAR* name) : ValueMetaClass (name) { }\
Value* classOf_vf(Value** arg_list, int count) \
{ \
check_arg_count(classOf, 1, count + 1); \
return &_super##_class; \
} \
Value* superClassOf_vf(Value** arg_list, int count) \
{ \
return _super##_class.classOf_vf(NULL, 0); \
} \
void collect() { delete this; } \
ScripterExport Value* apply(Value** arglist, int count, CallContext* cc=NULL); \
}; \
extern ScripterExport _cls##Class _cls##_class;
#define visible_class_instance(_cls, _name) \
ScripterExport _cls##Class _cls##_class (_T(_name));
#define class_tag(_cls) &_cls##_class
#define INTERNAL_CLASS_TAG ((ValueMetaClass*)0L)
#define INTERNAL_INDEX_THUNK_TAG ((ValueMetaClass*)1L)
#define INTERNAL_PROP_THUNK_TAG ((ValueMetaClass*)2L)
#define INTERNAL_LOCAL_THUNK_TAG ((ValueMetaClass*)3L)
#define INTERNAL_FREE_THUNK_TAG ((ValueMetaClass*)4L)
#define INTERNAL_RO_LOCAL_THUNK_TAG ((ValueMetaClass*)5L)
#define INTERNAL_CODE_TAG ((ValueMetaClass*)6L)
#define INTERNAL_SOURCEWRAPPER_TAG ((ValueMetaClass*)7L)
#define INTERNAL_PIPE_TAG ((ValueMetaClass*)8L)
#define INTERNAL_TOOL_LOCAL_THUNK_TAG ((ValueMetaClass*)9L)
#define INTERNAL_GLOBAL_THUNK_TAG ((ValueMetaClass*)10L)
#define INTERNAL_CONST_GLOBAL_THUNK_TAG ((ValueMetaClass*)11L)
#define INTERNAL_SYS_GLOBAL_THUNK_TAG ((ValueMetaClass*)12L)
#define INTERNAL_PLUGIN_LOCAL_THUNK_TAG ((ValueMetaClass*)13L)
#define INTERNAL_PLUGIN_PARAM_THUNK_TAG ((ValueMetaClass*)14L)
#define INTERNAL_RCMENU_LOCAL_THUNK_TAG ((ValueMetaClass*)15L)
#define INTERNAL_STRUCT_MEM_THUNK_TAG ((ValueMetaClass*)16L)
#define INTERNAL_MSPLUGIN_TAG ((ValueMetaClass*)17L)
#define INTERNAL_STRUCT_TAG ((ValueMetaClass*)18L)
#define INTERNAL_MAKER_TAG ((ValueMetaClass*)19L)
#define INTERNAL_CODEBLOCK_LOCAL_TAG ((ValueMetaClass*)20L)
#define INTERNAL_CODEBLOCK_TAG ((ValueMetaClass*)21L)
#define INTERNAL_THUNK_REF_TAG ((ValueMetaClass*)22L)
#define INTERNAL_THUNK_DEREF_TAG ((ValueMetaClass*)23L)
#define INTERNAL_STRUCT_METHOD_TAG ((ValueMetaClass*)24L) // LAM - defect 307069
#define INTERNAL_MSPLUGIN_METHOD_TAG ((ValueMetaClass*)25L) // LAM - 9/6/02 - defect 291499
#define INTERNAL_TAGS ((ValueMetaClass*)100L) // must be higher than all internal tags
visible_class (Value)
/* ---------- the distinguished value subclasses ---------- */
visible_class (Boolean)
class Boolean;
class ValueLoader;
extern ScripterExport Boolean true_value;
extern ScripterExport Boolean false_value;
class Boolean : public Value
{
public:
Boolean() { tag = &Boolean_class; }
classof_methods (Boolean, Value);
void collect() { delete this; }
void sprin1(CharStream* s);
# define is_bool(o) ((o)->tag == &Boolean_class)
Value* not_vf(Value**arg_list, int count);
BOOL to_bool() { return this == &true_value; }
void to_fpvalue(FPValue& v) { v.i = (this == &true_value) ? 1 : 0; v.type = (ParamType2)TYPE_BOOL; }
// scene I/O
IOResult Save(ISave* isave);
static Value* Load(ILoad* iload, USHORT chunkID, ValueLoader* vload);
};
/* ----- */
visible_class (Undefined)
class Undefined : public Value
{
public:
Undefined() { tag = &Undefined_class; }
classof_methods (Undefined, Value);
void collect() { delete this; }
ScripterExport void sprin1(CharStream* s);
Value* copy_vf(Value** arg_list, int count) { return this; }
// scene I/O
IOResult Save(ISave* isave);
static Value* Load(ILoad* iload, USHORT chunkID, ValueLoader* vload);
Mtl* to_mtl() { return NULL; } // undefined is a NULL material
};
extern ScripterExport Undefined undefined;
extern ScripterExport Undefined dontCollect;
extern ScripterExport Undefined loopExit;
/* ----- */
visible_class (Ok)
class Ok : public Value
{
public:
Ok() { tag = &Ok_class; }
classof_methods (Ok, Value);
void collect() { delete this; }
ScripterExport void sprin1(CharStream* s);
// scene I/O
IOResult Save(ISave* isave);
static Value* Load(ILoad* iload, USHORT chunkID, ValueLoader* vload);
};
extern ScripterExport Ok ok;
/* ----- */
visible_class (Empty)
class Empty : public Value
{
public:
Empty() { tag = &Empty_class; }
classof_methods (Empty, Value);
void collect() { delete this; }
ScripterExport void sprin1(CharStream* s);
};
extern ScripterExport Empty empty;
/* ----- */
visible_class (Unsupplied)
class Unsupplied : public Value
{
public:
Unsupplied() { tag = &Unsupplied_class; }
classof_methods (Unsupplied, Value);
void collect() { delete this; }
ScripterExport void sprin1(CharStream* s);
// scene I/O
IOResult Save(ISave* isave);
static Value* Load(ILoad* iload, USHORT chunkID, ValueLoader* vload);
};
extern ScripterExport Unsupplied unsupplied;
/* ---------- subclass and instance virtual arrays ----------
visible_class (SubclassArray)
class SubclassArray : Value
{
public:
ValueMetaClass* theClass; // whose subclasses we represent
SubclassArray(ValueMetaClass* cls);
classof_methods (SubclassArray, Value);
BOOL _is_collection() { return 1; }
void collect() { delete this; }
void sprin1(CharStream* s) { s->printf(_T("<Subclasses of %s>"), theClass->name); }
// operations
Value* map(node_map& m);
Value* get_vf(Value** arg_list, int count);
// built-in property accessors
def_property ( count );
};
visible_class (InstanceArray)
class InstanceArray : Value
{
public:
ValueMetaClass* theClass; // whose instances we represent
InstanceArray(ValueMetaClass* cls);
classof_methods (InstanceArray, Value);
BOOL _is_collection() { return 1; }
void collect() { delete this; }
void sprin1(CharStream* s) { s->printf(_T("<Instances of %s>"), theClass->name); }
// operations
Value* map(node_map& m);
Value* get_vf(Value** arg_list, int count);
// built-in property accessors
def_property ( count );
};
*/
#endif