summaryrefslogtreecommitdiff
path: root/source4/lib/appweb/ejs-2.0/ejs/ejsVar.h
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/appweb/ejs-2.0/ejs/ejsVar.h')
-rw-r--r--source4/lib/appweb/ejs-2.0/ejs/ejsVar.h1091
1 files changed, 1091 insertions, 0 deletions
diff --git a/source4/lib/appweb/ejs-2.0/ejs/ejsVar.h b/source4/lib/appweb/ejs-2.0/ejs/ejsVar.h
new file mode 100644
index 0000000000..071665e00b
--- /dev/null
+++ b/source4/lib/appweb/ejs-2.0/ejs/ejsVar.h
@@ -0,0 +1,1091 @@
+/*
+ * ejsVar.h -- EJS Universal Variable Type
+ */
+
+/*
+ * @copy default
+ *
+ * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
+ * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
+ *
+ * This software is distributed under commercial and open source licenses.
+ * You may use the GPL open source license described below or you may acquire
+ * a commercial license from Mbedthis Software. You agree to be fully bound
+ * by the terms of either license. Consult the LICENSE.TXT distributed with
+ * this software for full details.
+ *
+ * This software is open source; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See the GNU General Public License for more
+ * details at: http://www.mbedthis.com/downloads/gplLicense.html
+ *
+ * This program is distributed WITHOUT ANY WARRANTY; without even the
+ * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * This GPL license does NOT permit incorporating this software into
+ * proprietary programs. If you are unable to comply with the GPL, you must
+ * acquire a commercial license to use this software. Commercial licenses
+ * for this software and support services are available from Mbedthis
+ * Software at http://www.mbedthis.com
+ *
+ * @end
+ */
+
+/*
+ * Variables can efficiently store primitive types and can hold references to
+ * objects. Objects can store properties which are themselves variables.
+ * Properties can be primitive data types, other objects or methods.
+ * Properties are indexed by a character name. A variable may store one of
+ * the following types:
+ *
+ * string, integer, integer-64bit, C method, C method with string args,
+ * Javascript method, Floating point number, boolean value, Undefined
+ * value and the Null value.
+ *
+ * Variables have names while objects may be referenced by multiple variables.
+ * Objects use reference counting for garbage collection.
+ *
+ * This module is not thread safe for performance and compactness. It relies
+ * on upper modules to provide thread synchronization as required. The API
+ * provides primitives to get variable/object references or to get copies of
+ * variables which will help minimize required lock times.
+ */
+
+#ifndef _h_EJS_VAR
+#define _h_EJS_VAR 1
+
+/********************************* Includes ***********************************/
+
+#include "mpr.h"
+
+/********************************** Defines ***********************************/
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Defined in ejs.h
+ */
+typedef struct Ejs Ejs;
+
+/*
+ * Constants
+ */
+#if BLD_FEATURE_SQUEEZE
+ /**
+ * Maximum property or variable name size
+ */
+ #define EJS_MAX_ID 64
+
+ /*
+ * EJS_VAR_HASH_SIZE must be less than the size of the bit field
+ * propertyIndex in EjsProperty.
+ */
+ #define EJS_OBJ_HASH_SIZE 13
+
+ /**
+ * Maximum number of arguments per function call
+ */
+ #define EJS_MAX_ARGS 32
+ #define EJS_INC_ARGS 8 /* Frame stack increment */
+
+#else
+ #define EJS_MAX_ID 256
+ #define EJS_OBJ_HASH_SIZE 29
+ #define EJS_MAX_ARGS 64
+ #define EJS_INC_ARGS 8
+#endif
+
+#define EJS_VAR_MAX_RECURSE 5 /* Max object loops */
+
+#if !DOXYGEN
+/*
+ * Forward declare types
+ */
+struct Ejs;
+struct EjsObj;
+struct EjsProperty;
+struct EjsVar;
+#endif
+
+/**
+ * @overview EJ primitive variable type
+ * @description EJ primitive variable values are stored in EjsVar structures.
+ * The type of the primitive data is described by an EjsType field.
+ * EjsVar variable types.
+ * @stability Prototype.
+ * @library libejs.
+ * @see EJS_TYPE_UNDEFINED, EJS_TYPE_NULL, EJS_TYPE_BOOL, EJS_TYPE_CMETHOD,
+ * EJS_TYPE_FLOAT, EJS_TYPE_INT, EJS_TYPE_INT64, EJS_TYPE_OBJECT,
+ * EJS_TYPE_METHOD, EJS_TYPE_STRING, EJS_TYPE_STRING_CMETHOD, EJS_TYPE_PTR,
+ */
+typedef uint EjsType;
+#define EJS_TYPE_UNDEFINED 0 /**< Undefined. No value has been set */
+#define EJS_TYPE_NULL 1 /**< Value defined to be null. */
+#define EJS_TYPE_BOOL 2 /**< Boolean type. */
+#define EJS_TYPE_CMETHOD 3 /**< C method */
+#define EJS_TYPE_FLOAT 4 /**< Floating point number */
+#define EJS_TYPE_INT 5 /**< Integer number */
+#define EJS_TYPE_INT64 6 /**< 64-bit Integer number */
+#define EJS_TYPE_OBJECT 7 /**< Object reference */
+#define EJS_TYPE_METHOD 8 /**< JavaScript method */
+#define EJS_TYPE_STRING 9 /**< String (immutable) */
+#define EJS_TYPE_STRING_CMETHOD 10 /**< C method with string args */
+#define EJS_TYPE_PTR 11 /**< Opaque pointer */
+
+/*
+ * Create a type for the default number type
+ * Config.h will define the default number type. For example:
+ *
+ * BLD_FEATURE_NUM_TYPE=int
+ * BLD_FEATURE_NUM_TYPE_ID=EJS_TYPE_INT
+ */
+
+/**
+ * Set to the type used for EJS numeric variables. Will equate to int, int64
+ * or double.
+ */
+typedef BLD_FEATURE_NUM_TYPE EjsNum;
+
+/**
+ * Set to the EJS_TYPE used for EJS numeric variables. Will equate to
+ * EJS_TYPE_INT, EJS_TYPE_INT64 or EJS_TYPE_FLOAT.
+ */
+#define EJS_NUM_VAR BLD_FEATURE_NUM_TYPE_ID
+#define EJS_TYPE_NUM BLD_FEATURE_NUM_TYPE_ID
+
+/*
+ * Return TRUE if a variable is a method type
+ */
+#define ejsVarIsMethod(vp) \
+ ((vp)->type == EJS_TYPE_METHOD || (vp)->type == EJS_TYPE_STRING_CMETHOD || \
+ (vp)->type == EJS_TYPE_CMETHOD)
+
+/*
+ * Return TRUE if a variable is a numeric type
+ */
+#define ejsVarIsNumber(vp) \
+ ((vp)->type == EJS_TYPE_INT || (vp)->type == EJS_TYPE_INT64 || \
+ (vp)->type == EJS_TYPE_FLOAT)
+
+/*
+ * Return TRUE if a variable is a boolean
+ */
+#define ejsVarIsBoolean(vp) \
+ ((vp)->type == EJS_TYPE_BOOL)
+
+/*
+ * Return TRUE if a variable is an integer type
+ */
+#define ejsVarIsInteger(vp) ((vp)->type == EJS_TYPE_INT)
+
+/*
+ * Return TRUE if a variable is a string
+ */
+#define ejsVarIsString(vp) \
+ ((vp)->type == EJS_TYPE_STRING)
+
+/*
+ * Return TRUE if a variable is an object
+ */
+#define ejsVarIsObject(vp) \
+ ((vp)->type == EJS_TYPE_OBJECT)
+
+/*
+ * Return TRUE if a variable is a floating number
+ */
+#define ejsVarIsFloating(vp) \
+ ((vp)->type == EJS_TYPE_FLOAT)
+
+/*
+ * Return TRUE if a variable is undefined
+ */
+#define ejsVarIsUndefined(var) \
+ ((var)->type == EJS_TYPE_UNDEFINED)
+
+/*
+ * Return TRUE if a variable is null
+ */
+#define ejsVarIsNull(var) \
+ ((var)->type == EJS_TYPE_NULL)
+
+/*
+ * Return TRUE if a variable is a valid type (not null or undefined)
+ */
+#define ejsVarIsValid(var) \
+ (((var)->type != EJS_TYPE_NULL) && ((var)->type != EJS_TYPE_UNDEFINED))
+
+/*
+ * Return TRUE if a variable is a ptr type
+ */
+#define ejsVarIsPtr(vp) \
+ ((vp)->type == EJS_TYPE_PTR)
+
+/* MOB -- convert all ep to ejs */
+/**
+ * @overview C Method signature
+ * @description This is the calling signature for C Methods.
+ * @param ejs Ejs reference returned from ejsCreateInterp
+ * @param thisObj Reference to the "this" object. (The object containing the
+ * method).
+ * @param argc Number of arguments.
+ * @param argv Array of arguments. Each argument is held in an EjsVar type.
+ * @stability Prototype.
+ * @library libejs.
+ * @see ejsCreateCMethodVar
+ */
+typedef int (*EjsCMethod)(struct Ejs *ejs, struct EjsVar *thisObj,
+ int argc, struct EjsVar **argv);
+
+/**
+ * C Method with string arguments signature
+ * @overview C Method with string arguments signature
+ * @description This is the calling signature for C Methods.
+ * @param ejs Ejs reference returned from ejsCreateInterp
+ * @param thisObj Reference to the "this" object (object containing the
+ * method.
+ * @param argc Number of arguments.
+ * @param argv Array of arguments. Each argument is held in an C string
+ * pointer.
+ * @stability Prototype.
+ * @library libejs.
+ * @see ejsCreateStringCMethodVar
+ */
+typedef int (*EjsStringCMethod)(struct Ejs *ep, struct EjsVar *thisObj,
+ int argc, char **argv);
+
+/**
+ * Flags for types: EJS_TYPE_CMETHOD, EJS_TYPE_STRING_CMETHOD
+ * NOTE: flags == 0 means to use the EJS handle on method callbacks
+ */
+/* Use the primary handle on method callbacks */
+#define EJS_PRIMARY_HANDLE 0x1
+
+/* Use the alternate handle on method callbacks */
+#define EJS_ALT_HANDLE 0x2
+
+/** Method should not create a new local variable block */
+#define EJS_NO_LOCAL 0x4
+
+/* Method is a get accessor */
+#define EJS_GET_ACCESSOR 0x8
+
+/* Method is a set accessor */
+#define EJS_SET_ACCESSOR 0x10
+
+/*
+ * Flags for E4X (Xml type)
+ */
+/* Node is a text node */
+#define EJS_XML_FLAGS_TEXT 0x1
+
+/* Node is a processing instruction */
+#define EJS_XML_FLAGS_PI 0x2
+
+/* Node is a comment */
+#define EJS_XML_FLAGS_COMMENT 0x4
+
+/* Node is an attribute */
+#define EJS_XML_FLAGS_ATTRIBUTE 0x8
+
+/* Node is an element */
+#define EJS_XML_FLAGS_ELEMENT 0x10
+
+/**
+ * Copy depth
+ * @overview Specifies how an object should be copied
+ * @description The EjsCopyDepth type specifies how an object's properties
+ * should be copied. Several routines take EjsCopyDepth parameters to
+ * control how the properties of an object should be copied. It provides
+ * three copy options:
+ * @see ejsWriteVar
+ */
+typedef enum EjsCopyDepth {
+ /**
+ * During an object copy, object property references will be copied so
+ * that the original object and the copy will share the same reference to
+ * a property object. Properties containing primitive types including
+ * strings will have their values copied and will not share references.
+ */
+ EJS_SHALLOW_COPY, /** Copy strings. Copy object references. */
+ /*
+ * During an object copy, object properties will be replicated so that
+ * the original object and the copy will not share references to the same
+ * object properties. If the original object's properties are themselves
+ * objects, their properties will not be copied. Only their references
+ * will be copied. i.e. the deep copy is one level deep.
+ */
+ EJS_DEEP_COPY, /** Copy strings and copy object contents. */
+ /*
+ * During an object copy, all object properties will be replicated so that
+ * the original object and the copy will not share references to the same
+ * object properties. If the original object's properties are themselves
+ * objects, their properties will be copied. i.e. the copy is of infinite
+ * depth.
+ */
+ EJS_RECURSIVE_DEEP_COPY /** Copy strings and copy object contents
+ recursively (complete copy). */
+} EjsCopyDepth;
+
+
+/*
+ * Enumeration flags
+ */
+/** Enumerate data properties */
+#define EJS_ENUM_DATA 0x0
+
+/** Enumerate sub classes */
+#define EJS_ENUM_CLASSES 0x1
+
+/** Enumerate non-enumerable properties */
+#define EJS_ENUM_HIDDEN 0x2
+
+/** Enumerate all properties */
+#define EJS_ENUM_ALL (0x3)
+
+/** Magic number when allocated */
+#define EJS_MAGIC 0xe801e2ec
+#define EJS_MAGIC_FREE 0xe701e3ea
+
+
+/*
+ * Garbage Collection Linkage. Free list only uses the next pointers.
+ */
+typedef struct EjsGCLink {
+#if BLD_DEBUG
+ uint magic; /* Magic number */
+#endif
+#if BLD_FEATURE_ALLOC_LEAK_TRACK
+ const char *allocatedBy; /* Who allocated this */
+#endif
+ struct EjsGCLink *next; /* Next property */
+} EjsGCLink;
+
+
+/**
+ * @overview EJS Variable Type
+ * @description The EJ language supports an extensive set of primitive types.
+ * These variable types can efficiently store primitive data types such as
+ * integers, strings, binary string, booleans, floating point numbers,
+ * pointer references, and objects. EjsVars are the universal type used by
+ * EJ to hold objects, classes and properties.
+ * \n\n
+ * An EjsVar may store one of the following types:
+ * @li Boolean
+ * @li Floating point (if supported in this build)
+ * @li Integer
+ * @li 64 bit integer (if supported in this build)
+ * @li String
+ * @li Binary string
+ * @li C function or C++ method
+ * @li C function with string args
+ * @li Javascript method
+ * @li Object
+ * @li Null value.
+ * @li Undefined value
+ * \n\n
+ * Objects can hold object properties which are themselves EJS variables.
+ * Properties are hash indexed by the property name and are stored in
+ * an ordered sequence. i.e. Order of properties is maintained. Objects may
+ * be referenced by multiple variables and they use garbage collection to
+ * reclaim memory no longer in use by objects and properties.
+ *
+ * @warning This module is @e not thread safe for performance and
+ * compactness. It relies on upper modules to provide thread
+ * synchronization as required. The API provides primitives to get
+ * variable/object references or to get copies of variables which should
+ * help minimize required lock times.
+ * @stability Prototype.
+ * @library libejs
+ * @see Ejs, EjsProperty, ejsCreateStringVar, ejsFreeVar
+ */
+
+typedef struct EjsVar { /* Size 12 bytes */
+ /*
+ * GC must be first
+ */
+#if BLD_DEBUG || BLD_FEATURE_ALLOC_LEAK_TRACK
+ EjsGCLink gc; /* Garbage collection links */
+#endif
+
+#if BLD_DEBUG
+ const char *propertyName; /* Ptr to property name */
+#endif
+
+ /*
+ * Union of primitive types. When debugging on Linux, don't use unions
+ * as the gdb debugger can't display them.
+ */
+#if (!BLD_DEBUG && !VXWORKS) || WIN || BREW_SIMULATOR
+ union {
+#endif
+ /*
+ * For debugging, we order the common types first
+ */
+ struct EjsObj *objectState; /* Object state information */
+ int integer;
+ bool boolean;
+
+#if BLD_FEATURE_FLOATING_POINT
+ double floating;
+#endif
+#if BLD_FEATURE_INT64
+ int64 integer64;
+#endif
+
+ struct {
+ int length; /* String length (sans null) */
+ /*
+ * All strings always have a trailing null allocated
+ */
+ union {
+ char *string; /* String */
+ uchar *ustring; /* Binary string */
+ };
+ };
+
+ struct { /* Javascript methods */
+ MprArray *args; /* Null terminated */
+ char *body;
+ } method;
+
+ struct { /* Method with EjsVar args */
+ EjsCMethod fn; /* Method pointer */
+ void *userData; /* User data for method */
+ } cMethod;
+
+ struct { /* Method with string args */
+ EjsStringCMethod fn; /* Method pointer */
+ void *userData; /* User data for method */
+ } cMethodWithStrings;
+
+ struct {
+ void *userPtr; /* Opaque pointer */
+ int (*destructor)(Ejs *ejs, struct EjsVar *vp);
+ } ptr;
+
+#if (!BLD_DEBUG && !VXWORKS) || WIN || BREW_SIMULATOR
+ };
+#endif
+
+ /*
+ * Packed bit field (32 bits)
+ */
+ uint flags : 8; /* Type specific flags */
+ EjsType type : 4; /* Selector into union */
+ uint stringLen : 4; /* Length of string if inline */
+ uint allocatedData : 1; /* Node needs freeing */
+ uint isArray : 1; /* Var is an array */
+ uint isArrayLength : 1; /* Var is array.length */
+ uint callsSuper : 1; /* Method calls super() */
+ uint isProperty : 1; /* Part of a property */
+ uint reserved : 11; /* Unused */
+
+} EjsVar;
+
+
+/*
+ * Linkage for the ordered list of properties
+ */
+typedef struct EjsPropLink {
+ struct EjsPropLink *next; /* Next property */
+ struct EjsPropLink *prev; /* Previous property */
+
+ /*
+ * To make debugging easier
+ */
+#if BLD_DEBUG
+ const char *propertyName; /* Pointer to name */
+ struct EjsProperty *property; /* Pointer to property */
+ struct EjsPropLink *head; /* Dummy head of list */
+#endif
+} EjsPropLink;
+
+
+/**
+ * @overview Object Property Type
+ * @description The EjsProperty type is used to store all object properties.
+ * It contains the property name, property linkage, propery attributes
+ * such as public/private, enumerable and readonly settings. It also
+ * contains an EjsVar to store the property data value.
+ * @stability Prototype.
+ * @library libejs
+ * @see Ejs, EjsVar
+ */
+typedef struct EjsProperty { /* Size 96 bytes in squeeze */
+ /*
+ * EjsVar must be first. We often take the address of "var" and take
+ * advantage of if an EjsProperty is null, then &prop->var will be null
+ * also. Be WARNED. External users should use ejsGetVarPtr and
+ * ejsGetPropertyPtr to convert between the two.
+ */
+ EjsVar var; /* Property value */
+
+ /* OPT change this to a pointer to the base class property */
+ char name[EJS_MAX_ID]; /* Name */
+
+ uint visited : 1; /* Has been traversed */
+ uint isPrivate : 1; /* Property is private */
+ uint isProtected : 1; /* Property is protected */
+ uint dontEnumerate : 1; /* Not enumerable */
+ uint dontDelete : 1; /* Prevent delete */
+ uint readonly : 1; /* Unmodifiable */
+ uint allowNonUnique : 1; /* Multiple of same name ok */
+ uint delayedDelete : 1;
+ uint reserved : 24;
+
+ EjsPropLink link; /* Ordered linked list */
+ struct EjsProperty *hashNext; /* Hash table linkage */
+
+ /* MOB -- is this really required */
+ struct EjsObj *parentObj; /* Pointer to parent object */
+
+} EjsProperty;
+
+
+#define EJS_OP_DOT 0x1
+#define EJS_OP_INDEX 0x2
+#define EJS_OP_PLUS 0x3
+#define EJS_OP_MINUS 0x4
+#define EJS_OP_MULTIPLY 0x5
+#define EJS_OP_DIVIDE 0x6
+#define EJS_OP_CALL 0x7
+
+typedef struct EjsOp {
+ int opType;
+
+} EjsOp;
+
+/*
+ * Propety Access Methods. Used per class.
+ * MOB -- rename EjsHelpers
+ */
+typedef struct EjsMethods {
+#if FUTURE
+ int (*create)(Ejs *ep, EjsVar *thisObj);
+ int (*deleteProperty)(Ejs *ep, EjsVar *thisObj, const char *prop);
+ EjsVar *(*getProperty)(Ejs *ep, EjsVar *thisObj, const char *prop);
+ EjsVar *(*setProperty)(Ejs *ep, EjsVar *thisObj, const char *prop);
+ int (*hasProperty)(Ejs *ep, EjsVar *thisObj, const char *prop);
+ int (*hasInstance)(Ejs *ep, EjsVar *thisObj, const char *prop);
+ int (*operate)(Ejs *ep, EjsVar *thisObj, EjsOp op, EjsVar *result,
+ EjsVar *lhs, EjsVar *rhs, int *code);
+#else
+
+ EjsVar *(*createProperty)(Ejs *ep, EjsVar *obj, const char *property);
+ int (*deleteProperty)(Ejs *ep, EjsVar *obj, const char *property);
+ EjsVar *(*getProperty)(Ejs *ep, EjsVar *obj, const char *property);
+ EjsVar *(*setProperty)(Ejs *ep, EjsVar *obj, const char *property,
+ const EjsVar *value);
+ /*
+ * Other implemented internal properties in ECMA-262 are:
+ *
+ * [[Construct]] implemented via EjsVar methods
+ * [[Prototype]] implemented via EjsObj->baseClass
+ * [[Class]] implemented via EjsObj->baseClass->name
+ * [[Value]] Implemented via EjsProperty + EjsVar + EjsObj
+ */
+
+ /*
+ * FUTURE -- not implemented
+ */
+ int (*canPut)(Ejs *ep, EjsVar *obj, const char *property);
+ int (*defaultValue)(Ejs *ep, EjsVar *obj, const char *property,
+ const char *hint);
+ int (*hasProperty)(Ejs *ep, EjsVar *obj, const char *property);
+ EjsVar *(*call)(Ejs *ep, EjsVar *obj, const char *property,
+ EjsVar *args);
+ int (*hasInstance)(Ejs *ep, EjsVar *obj, const char *property);
+ int (*scope)(Ejs *ep, EjsVar *obj, const char *property);
+ int (*match)(Ejs *ep, EjsVar *obj, const char *property,
+ const char *string, int index);
+#endif
+} EjsMethods;
+
+
+/*
+ * Ejs Object Type
+ */
+typedef struct EjsObj {
+ /*
+ * GC must be first
+ */
+ EjsGCLink gc; /* Garbage collection links */
+
+ union {
+ char *objName; /* Object name */
+ char *className; /* Class name */
+ };
+
+ struct EjsVar *baseClass; /* Pointer to base class object */
+
+ EjsPropLink link; /* Ordered list of properties */
+
+ /* OPT -- dynamically allocate this only if required */
+ EjsProperty *propertyHash[EJS_OBJ_HASH_SIZE]; /* Hash chains */
+
+ /* OPT -- could save this and store off baseClass only */
+ EjsMethods *methods; /* Property access methods */
+ void *nativeData; /* Native object data */
+
+ int (*destructor)(Ejs *ejs, struct EjsVar *vp);
+
+ uint numProperties : 16; /* Total count of items */
+ uint visited : 1; /* Has been traversed */
+ uint gcMarked : 1; /* Node marked in-use by GC */
+ uint permanent : 1; /* Permanent object, dont GC */
+ uint alive : 1; /* Only GC if alive */
+ uint noConstructor : 1; /* Object has no constructor */
+ uint dirty : 1; /* Object has been modified */
+ uint hasErrors : 1; /* Update error */
+ uint preventDeleteProp : 1; /* Don't allow prop deletion */
+ uint delayedDeleteProp : 1; /* Delayed delete of props */
+ uint reserved : 7; /* Unused */
+
+ Ejs *ejs; /* Owning interp */
+
+#if BLD_FEATURE_MULTITHREAD
+ MprLock *mutex; /* Advisory mutex lock */
+#endif
+} EjsObj;
+
+
+/*
+ * Define a field macro so code an use numbers in a "generic" fashion.
+ */
+#if EJS_NUM_VAR == EJS_TYPE_INT || DOXYGEN
+/*
+ * Default numeric type
+ */
+#define ejsNumber integer
+#endif
+#if EJS_NUM_VAR == EJS_TYPE_INT64
+/* Default numeric type */
+#define ejsNumber integer64
+#endif
+#if EJS_NUM_VAR == EJS_TYPE_FLOAT
+/* Default numeric type */
+#define ejsNumber floating
+#endif
+
+typedef BLD_FEATURE_NUM_TYPE EjsNumber;
+
+/*
+ * Memory allocation slabs
+ */
+#define EJS_SLAB_OBJ 0
+#define EJS_SLAB_PROPERTY 1
+#define EJS_SLAB_VAR 2
+#define EJS_SLAB_MAX 3
+
+/**
+ * Object and pointer property destructory type
+ */
+typedef int (*EjsDestructor)(Ejs *ejs, EjsVar *vp);
+
+#if BLD_FEATURE_ALLOC_LEAK_TRACK || DOXYGEN
+/*
+ * Line number information args and declarations for ejsAlloc.
+ * Use EJS_LOC_ARGS in normal user code.
+ * Use EJS_LOC_DEC in declarations.
+ * Use EJS_LOC_PASS in layered APIs to pass original line info down.
+ */
+#define EJS_LOC_ARGS(ejs) ejs, MPR_LOC
+#define EJS_LOC_DEC(ejs, loc) Ejs *ejs, const char *loc
+#define EJS_LOC_PASS(ejs, loc) ejs, loc
+#else
+#define EJS_LOC_ARGS(ejs) ejs
+#define EJS_LOC_DEC(ejs, loc) Ejs *ejs
+#define EJS_LOC_PASS(ejs, loc) ejs
+#endif
+
+/******************************* Internal Prototypes **************************/
+
+#define ejsInitVar(vp, varType) \
+ if (1) { \
+ (vp)->type = varType; \
+ (vp)->isArray = 0; \
+ (vp)->flags = 0; \
+ } else
+extern void ejsClearVar(Ejs *ep, EjsVar *vp);
+
+extern int ejsDestroyObj(Ejs *ep, EjsObj *obj);
+extern EjsVar *ejsCreatePropertyMethod(Ejs *ep, EjsVar *obj,
+ const char *name);
+extern EjsVar *ejsSetPropertyMethod(Ejs *ep, EjsVar *obj, const char *name,
+ const EjsVar *value);
+extern EjsVar *ejsGetPropertyMethod(Ejs *ep, EjsVar *obj, const char *name);
+extern int ejsDeletePropertyMethod(Ejs *ep, EjsVar *obj,
+ const char *name);
+extern void ejsSetArrayLength(Ejs *ep, EjsVar *obj, const char *creating,
+ const char *deleting, const EjsVar *setLength);
+
+/*
+ * At the moment, these are the same routine
+ */
+extern void ejsSetClassName(Ejs *ep, EjsVar *obj, const char *name);
+#define ejsSetObjName ejsSetObjName
+
+extern bool ejsIsObjDirty(EjsVar *vp);
+extern void ejsResetObjDirtyBit(EjsVar *vp);
+
+extern int ejsObjHasErrors(EjsVar *vp);
+extern void ejsClearObjErrors(EjsVar *vp);
+
+extern EjsVar *ejsClearProperty(Ejs *ep, EjsVar *obj, const char *prop);
+
+typedef int (*EjsSortFn)(Ejs *ep, EjsProperty *p1, EjsProperty *p2,
+ const char *propertyName, int order);
+extern void ejsSortProperties(Ejs *ep, EjsVar *obj, EjsSortFn fn,
+ const char *propertyName, int order);
+
+#if BLD_DEBUG
+#define ejsSetVarName(ep, vp, varName) \
+ if (1) { \
+ (vp)->propertyName = varName; \
+ if ((vp)->type == EJS_TYPE_OBJECT && \
+ (vp)->objectState && \
+ ((vp)->objectState->objName == 0)) { \
+ (vp)->objectState->objName = \
+ mprStrdup(ep, varName); \
+ } \
+ } else
+#else
+#define ejsSetVarName(ep, vp, varName)
+#endif
+
+EjsVar *ejsFindProperty(Ejs *ep, EjsVar **obj, char **property,
+ EjsVar *global, EjsVar *local, const char *fullName,
+ int create);
+
+extern EjsVar *ejsCopyProperties(Ejs *ep, EjsVar *dest,
+ const EjsVar *src, EjsCopyDepth copyDepth);
+
+#define EJS_LINK_OFFSET ((uint) (&((EjsProperty*) 0)->link))
+#define ejsGetPropertyFromLink(lp) \
+ ((EjsProperty*) ((char*) lp - EJS_LINK_OFFSET))
+
+#define ejsGetObjPtr(vp) ((EjsObj*) vp->objectState)
+
+extern void ejsMakePropertyPrivate(EjsProperty *pp, int isPrivate);
+extern void ejsMakePropertyReadOnly(EjsProperty *pp, int readonly);
+extern void ejsMakePropertyUndeleteable(EjsProperty *pp, int deletable);
+extern int ejsMakeObjLive(EjsVar *vp, bool alive);
+extern void ejsMakeClassNoConstructor(EjsVar *vp);
+
+extern bool ejsBlockInUseInt(EjsVar *vp);
+#if BLD_DEBUG
+ #define ejsBlockInUse(vp) ejsBlockInUseInt(vp)
+#else
+ #define ejsBlockInUse(vp)
+#endif
+
+/********************************* Prototypes *********************************/
+
+/*
+ * Variable constructors and destructors
+ */
+extern EjsVar *ejsCreateBinaryStringVar(Ejs *ep, const uchar *value,
+ int len);
+extern EjsVar *ejsCreateBoolVar(Ejs *ep, int value);
+extern EjsVar *ejsCreateCMethodVar(Ejs *ep, EjsCMethod fn,
+ void *userData, int flags);
+#if BLD_FEATURE_FLOATING_POINT
+extern EjsVar *ejsCreateFloatVar(Ejs *ep, double value);
+#endif
+extern EjsVar *ejsCreateIntegerVar(Ejs *ep, int value);
+#if BLD_FEATURE_INT64
+extern EjsVar *ejsCreateInteger64Var(Ejs *ep, int64 value);
+#endif
+
+extern EjsVar *ejsCreateMethodVar(Ejs *ep, const char *body,
+ MprArray *args, int flags);
+extern EjsVar *ejsCreateNullVar(Ejs *ep);
+extern EjsVar *ejsCreateNumberVar(Ejs *ep, EjsNumber value);
+
+#define ejsCreateObjVar(ep) \
+ ejsCreateObjVarInternal(EJS_LOC_ARGS(ep))
+extern EjsVar *ejsCreateObjVarInternal(EJS_LOC_DEC(ep, loc));
+
+extern EjsVar *ejsCreatePtrVar(Ejs *ep, void *ptr, EjsDestructor dest);
+
+extern EjsVar *ejsCreateStringCMethodVar(Ejs *ep, EjsStringCMethod fn,
+ void *userData, int flags);
+
+#define ejsCreateStringVar(ep, value) \
+ ejsCreateStringVarInternal(EJS_LOC_ARGS(ep), value)
+extern EjsVar *ejsCreateStringVarInternal(EJS_LOC_DEC(ep, loc),
+ const char *value);
+
+extern EjsVar *ejsCreateUndefinedVar(Ejs *ep);
+
+/* MOB -- naming. Should be Create/Destroy */
+extern void ejsFreeVar(Ejs *ep, EjsVar *vp);
+
+/*
+ * Var support routines
+ */
+extern int ejsGetVarFlags(EjsVar *vp);
+extern void ejsSetVarFlags(EjsVar *obj, int flags);
+
+extern EjsType ejsGetVarType(EjsVar *vp);
+extern const char *ejsGetVarTypeAsString(EjsVar *vp);
+
+extern void *ejsGetCMethodUserData(EjsVar *obj);
+extern void ejsSetCMethodUserData(EjsVar *obj, void *userData);
+
+extern void *ejsGetVarUserPtr(EjsVar *vp);
+extern void ejsSetVarUserPtr(EjsVar *vp, void *data);
+
+
+/*
+ * Variable access and manipulation. These work on standalone objects.
+ */
+#define ejsDupVar(ep, src, copyDepth) \
+ ejsDupVarInternal(EJS_LOC_ARGS(ep), src, copyDepth)
+extern EjsVar *ejsDupVarInternal(EJS_LOC_DEC(ep, loc), EjsVar *src,
+ EjsCopyDepth copyDepth);
+#define ejsWriteVar(ep, dest, src, copyDepth) \
+ ejsWriteVarInternal(EJS_LOC_ARGS(ep), dest, src, copyDepth)
+extern EjsVar *ejsWriteVarInternal(EJS_LOC_DEC(ep, loc), EjsVar *dest,
+ const EjsVar *src, EjsCopyDepth copyDepth);
+extern EjsVar *ejsWriteVarAsBinaryString(Ejs *ep, EjsVar *dest,
+ const uchar *value, int len);
+extern EjsVar *ejsWriteVarAsBoolean(Ejs *ep, EjsVar *dest, bool value);
+extern EjsVar *ejsWriteVarAsCMethod(Ejs *ep, EjsVar *dest, EjsCMethod fn,
+ void *userData, int flags);
+#if BLD_FEATURE_FLOATING_POINT
+extern EjsVar *ejsWriteVarAsFloat(Ejs *ep, EjsVar *dest, double value);
+#endif
+extern EjsVar *ejsWriteVarAsInteger(Ejs *ep, EjsVar *dest, int value);
+#if BLD_FEATURE_INT64
+extern EjsVar *ejsWriteVarAsInteger64(Ejs *ep, EjsVar *dest, int64 value);
+#endif
+extern EjsVar *ejsWriteVarAsMethod(Ejs *ep, EjsVar *dest,
+ const char *body, MprArray *args);
+extern EjsVar *ejsWriteVarAsNull(Ejs *ep, EjsVar *dest);
+extern EjsVar *ejsWriteVarAsNumber(Ejs *ep, EjsVar *dest, EjsNum value);
+#define ejsWriteVarAsString(ep, dest, value) \
+ ejsWriteVarAsStringInternal(EJS_LOC_ARGS(ep), dest, value)
+extern EjsVar *ejsWriteVarAsStringInternal(EJS_LOC_DEC(ep, loc),
+ EjsVar *dest, const char *value);
+extern EjsVar *ejsWriteVarAsStringCMethod(Ejs *ep, EjsVar *dest,
+ EjsStringCMethod fn, void *userData, int flags);
+extern EjsVar *ejsWriteVarAsUndefined(Ejs *ep, EjsVar *dest);
+
+/*
+ * These routines do not convert types
+ */
+/* MOB -- make this a fn and pass back the length as an arg */
+#define ejsReadVarAsBinaryString(vp) ((const uchar*) (vp->ustring));
+#define ejsReadVarAsBoolean(vp) (vp->boolean);
+#define ejsReadVarAsCMethod(vp) (vp->cMethod);
+#if BLD_FEATURE_FLOATING_POINT
+#define ejsReadVarAsFloat(vp) (vp->floating);
+#endif
+#define ejsReadVarAsInteger(vp) (vp->integer);
+#if BLD_FEATURE_INT64
+#define ejsReadVarAsInteger64(vp) (vp->int64);
+#endif
+#define ejsReadVarAsString(vp) ((const char*) (vp->string));
+#define ejsReadVarAsStringCMethod(vp) (vp->cMethodWithStrings);
+/* MOB -- remove this fn */
+#define ejsReadVarStringLength(vp) (vp->length);
+
+/*
+ * Object property creation routines
+ */
+extern EjsProperty *ejsCreateProperty(Ejs *ep, EjsVar *obj, const char *prop);
+extern EjsProperty *ejsCreateSimpleProperty(Ejs *ep, EjsVar *obj,
+ const char *prop);
+extern EjsProperty *ejsCreateSimpleNonUniqueProperty(Ejs *ep, EjsVar *obj,
+ const char *prop);
+/* MOB -- should be destroy */
+extern int ejsDeleteProperty(Ejs *ep, EjsVar *obj, const char *prop);
+
+
+/*
+ * Get property routines
+ */
+extern EjsProperty *ejsGetProperty(Ejs *ep, EjsVar *obj, const char *prop);
+extern EjsProperty *ejsGetSimpleProperty(Ejs *ep, EjsVar *obj,
+ const char *prop);
+
+extern EjsVar *ejsGetPropertyAsVar(Ejs *ep, EjsVar *obj,
+ const char *prop);
+extern int ejsGetPropertyCount(EjsVar *obj);
+
+extern const uchar *ejsGetPropertyAsBinaryString(Ejs *ep, EjsVar *obj,
+ const char *prop, int *length);
+extern bool ejsGetPropertyAsBoolean(Ejs *ep, EjsVar *obj,
+ const char *prop);
+extern int ejsGetPropertyAsInteger(Ejs *ep, EjsVar *obj,
+ const char *prop);
+extern int64 ejsGetPropertyAsInteger64(Ejs *ep, EjsVar *obj,
+ const char *prop);
+extern EjsNum ejsGetPropertyAsNumber(Ejs *ep, EjsVar *obj,
+ const char *prop);
+extern void *ejsGetPropertyAsPtr(Ejs *ep, EjsVar *obj,
+ const char *prop);
+extern const char *ejsGetPropertyAsString(Ejs *ep, EjsVar *obj,
+ const char *prop);
+
+/*
+ * Object property update routines
+ */
+extern EjsProperty *ejsSetBaseProperty(Ejs *ep, EjsVar *obj, const char *prop,
+ const EjsVar *value);
+extern EjsProperty *ejsSetProperty(Ejs *ep, EjsVar *obj, const char *prop,
+ const EjsVar *value);
+extern EjsProperty *ejsSetPropertyAndFree(Ejs *ep, EjsVar *obj,
+ const char *prop, EjsVar *value);
+extern EjsProperty *ejsSetPropertyToBinaryString(Ejs *ep, EjsVar *obj,
+ const char *prop, const uchar *value, int len);
+extern EjsProperty *ejsSetPropertyToBoolean(Ejs *ep, EjsVar *obj,
+ const char *prop, bool value);
+extern EjsProperty *ejsSetPropertyToCMethod(Ejs *ep, EjsVar *obj,
+ const char *prop, EjsCMethod fn, void *userData,
+ int flags);
+#if BLD_FEATURE_FLOATING_POINT
+extern EjsProperty *ejsSetPropertyToFloat(Ejs *ep, EjsVar *obj,
+ const char *prop, double value);
+#endif
+extern EjsProperty *ejsSetPropertyToInteger(Ejs *ep, EjsVar *obj,
+ const char *prop, int value);
+#if BLD_FEATURE_INT64
+extern EjsProperty *ejsSetPropertyToInteger64(Ejs *ep, EjsVar *obj,
+ const char *prop, int64 value);
+#endif
+extern EjsProperty *ejsSetPropertyToMethod(Ejs *ep, EjsVar *obj,
+ const char *prop, const char *body, MprArray *args,
+ int flags);
+extern EjsProperty *ejsSetPropertyToNewObj(Ejs *ep, EjsVar *obj,
+ const char *prop, const char *className,
+ MprArray *args);
+extern EjsProperty *ejsSetPropertyToNull(Ejs *ep, EjsVar *obj,
+ const char *prop);
+extern EjsProperty *ejsSetPropertyToNumber(Ejs *ep, EjsVar *obj,
+ const char *prop, EjsNum value);
+extern EjsProperty *ejsSetPropertyToObj(Ejs *ep, EjsVar *obj,
+ const char *prop);
+extern EjsProperty *ejsSetPropertyToPtr(Ejs *ep, EjsVar *obj,
+ const char *prop, void *ptr, EjsDestructor destructor);
+
+extern EjsProperty *ejsSetPropertyToStringCMethod(Ejs *ep, EjsVar *obj,
+ const char *prop, EjsStringCMethod fn,
+ void *userData, int flags);
+extern EjsProperty *ejsSetPropertyToString(Ejs *ep, EjsVar *obj,
+ const char *prop, const char *value);
+extern EjsProperty *ejsSetPropertyToUndefined(Ejs *ep, EjsVar *obj,
+ const char *prop);
+
+
+/* Convenience function */
+extern EjsVar *ejsSetPropertyToObjAsVar(Ejs *ep, EjsVar *obj,
+ const char *prop);
+extern void ejsSetObjDestructor(Ejs *ep, EjsVar *obj,
+ EjsDestructor destructor);
+extern void ejsClearObjDestructor(Ejs *ep, EjsVar *obj);
+
+/*
+ * Enumeration of properties
+ * MOB -- should these take an ejs parameter to be consistent
+ */
+extern EjsProperty *ejsGetFirstProperty(const EjsVar *obj, int flags);
+extern EjsProperty *ejsGetNextProperty(EjsProperty *last, int flags);
+
+/*
+ * Method definition and control.
+ */
+extern EjsProperty *ejsDefineMethod(Ejs *ep, EjsVar *obj, const char *prop,
+ const char *body, MprArray *args);
+extern EjsProperty *ejsDefineCMethod(Ejs *ep, EjsVar *obj, const char *prop,
+ EjsCMethod fn, int flags);
+
+extern EjsProperty *ejsDefineStringCMethod(Ejs *ep, EjsVar *obj,
+ const char *prop, EjsStringCMethod fn, int flags);
+
+extern EjsProperty *ejsDefineAccessors(Ejs *ep, EjsVar *obj,
+ const char *prop, const char *getBody,
+ const char *setBody);
+extern EjsProperty *ejsDefineCAccessors(Ejs *ep, EjsVar *obj,
+ const char *prop, EjsCMethod getFn, EjsCMethod setFn,
+ int flags);
+
+/*
+ * Macro to get the variable value portion of a property
+ */
+#define ejsGetVarPtr(pp) (&((pp)->var))
+#define ejsGetPropertyPtr(vp) ((EjsProperty*) vp)
+
+/* MOB -- take ejs to be consistent */
+extern int ejsMakePropertyEnumerable(EjsProperty *pp, bool enumerable);
+extern int ejsMakeObjPermanent(EjsVar *vp, bool permanent);
+
+
+/*
+ * Var conversion routines
+ * MOB -- should these take an Ejs as first arg for consistency
+ */
+extern bool ejsVarToBoolean(EjsVar *vp);
+#if BLD_FEATURE_FLOATING_POINT
+extern double ejsVarToFloat(EjsVar *vp);
+#endif
+extern int ejsVarToInteger(EjsVar *vp);
+#if BLD_FEATURE_INT64
+extern int64 ejsVarToInteger64(EjsVar *vp);
+#endif
+extern EjsNum ejsVarToNumber(EjsVar *vp);
+extern char *ejsVarToString(Ejs *ep, EjsVar *vp);
+extern char *ejsVarToStringEx(Ejs *ep, EjsVar *vp, bool *alloc);
+extern char *ejsFormatVar(Ejs *ep, const char *fmt, EjsVar *vp);
+
+#if BLD_FEATURE_FLOATING_POINT
+extern double ejsParseFloat(const char *str);
+#endif
+/*
+ * Parsing and type range checking routines
+ */
+extern bool ejsParseBoolean(const char *str);
+extern int ejsParseInteger(const char *str);
+#if BLD_FEATURE_INT64
+extern int64 ejsParseInteger64(const char *str);
+#endif
+extern EjsNum ejsParseNumber(const char *str);
+extern EjsVar *ejsParseVar(Ejs *ep, const char *str, EjsType prefType);
+
+#if BLD_FEATURE_FLOATING_POINT
+extern bool ejsIsInfinite(double f);
+extern bool ejsIsNan(double f);
+#endif
+
+/*
+ * Advisory locking support
+ */
+#if BLD_FEATURE_MULTITHREAD
+extern void ejsLockObj(EjsVar *vp);
+extern void ejsUnlockObj(EjsVar *vp);
+#endif
+
+/*
+ * Just for debugging
+ */
+extern bool ejsObjIsCollectable(EjsVar *vp);
+
+#ifdef __cplusplus
+}
+#endif
+
+/*****************************************************************************/
+#endif /* _h_EJS_VAR */
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim:tw=78
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
+ */