diff options
Diffstat (limited to 'source4/lib/appweb/ejs-2.0/ejs/ejsVar.h')
-rw-r--r-- | source4/lib/appweb/ejs-2.0/ejs/ejsVar.h | 1091 |
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 + */ |