1
0
mirror of https://github.com/samba-team/samba.git synced 2025-12-13 16:23:50 +03:00
Files
samba-mirror/source/lib/appweb/ejs-2.0/ejs/ejsVar.h

1092 lines
34 KiB
C

/*
* 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
*/