2 * ejsVar.h -- EJS Universal Variable Type
8 * Copyright (c) Mbedthis Software LLC, 2003-2006. All Rights Reserved.
9 * Copyright (c) Michael O'Brien, 1994-1995. All Rights Reserved.
11 * This software is distributed under commercial and open source licenses.
12 * You may use the GPL open source license described below or you may acquire
13 * a commercial license from Mbedthis Software. You agree to be fully bound
14 * by the terms of either license. Consult the LICENSE.TXT distributed with
15 * this software for full details.
17 * This software is open source; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License as published by the
19 * Free Software Foundation; either version 2 of the License, or (at your
20 * option) any later version. See the GNU General Public License for more
21 * details at: http://www.mbedthis.com/downloads/gplLicense.html
23 * This program is distributed WITHOUT ANY WARRANTY; without even the
24 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
26 * This GPL license does NOT permit incorporating this software into
27 * proprietary programs. If you are unable to comply with the GPL, you must
28 * acquire a commercial license to use this software. Commercial licenses
29 * for this software and support services are available from Mbedthis
30 * Software at http://www.mbedthis.com
36 * Variables can efficiently store primitive types and can hold references to
37 * objects. Objects can store properties which are themselves variables.
38 * Properties can be primitive data types, other objects or methods.
39 * Properties are indexed by a character name. A variable may store one of
40 * the following types:
42 * string, integer, integer-64bit, C method, C method with string args,
43 * Javascript method, Floating point number, boolean value, Undefined
44 * value and the Null value.
46 * Variables have names while objects may be referenced by multiple variables.
47 * Objects use reference counting for garbage collection.
49 * This module is not thread safe for performance and compactness. It relies
50 * on upper modules to provide thread synchronization as required. The API
51 * provides primitives to get variable/object references or to get copies of
52 * variables which will help minimize required lock times.
58 /********************************* Includes ***********************************/
62 /********************************** Defines ***********************************/
70 typedef struct Ejs Ejs;
75 #if BLD_FEATURE_SQUEEZE
77 * Maximum property or variable name size
82 * EJS_VAR_HASH_SIZE must be less than the size of the bit field
83 * propertyIndex in EjsProperty.
85 #define EJS_OBJ_HASH_SIZE 13
88 * Maximum number of arguments per function call
90 #define EJS_MAX_ARGS 32
91 #define EJS_INC_ARGS 8 /* Frame stack increment */
94 #define EJS_MAX_ID 256
95 #define EJS_OBJ_HASH_SIZE 29
96 #define EJS_MAX_ARGS 64
97 #define EJS_INC_ARGS 8
100 #define EJS_VAR_MAX_RECURSE 5 /* Max object loops */
104 * Forward declare types
113 * @overview EJ primitive variable type
114 * @description EJ primitive variable values are stored in EjsVar structures.
115 * The type of the primitive data is described by an EjsType field.
116 * EjsVar variable types.
117 * @stability Prototype.
119 * @see EJS_TYPE_UNDEFINED, EJS_TYPE_NULL, EJS_TYPE_BOOL, EJS_TYPE_CMETHOD,
120 * EJS_TYPE_FLOAT, EJS_TYPE_INT, EJS_TYPE_INT64, EJS_TYPE_OBJECT,
121 * EJS_TYPE_METHOD, EJS_TYPE_STRING, EJS_TYPE_STRING_CMETHOD, EJS_TYPE_PTR,
123 typedef uint EjsType;
124 #define EJS_TYPE_UNDEFINED 0 /**< Undefined. No value has been set */
125 #define EJS_TYPE_NULL 1 /**< Value defined to be null. */
126 #define EJS_TYPE_BOOL 2 /**< Boolean type. */
127 #define EJS_TYPE_CMETHOD 3 /**< C method */
128 #define EJS_TYPE_FLOAT 4 /**< Floating point number */
129 #define EJS_TYPE_INT 5 /**< Integer number */
130 #define EJS_TYPE_INT64 6 /**< 64-bit Integer number */
131 #define EJS_TYPE_OBJECT 7 /**< Object reference */
132 #define EJS_TYPE_METHOD 8 /**< JavaScript method */
133 #define EJS_TYPE_STRING 9 /**< String (immutable) */
134 #define EJS_TYPE_STRING_CMETHOD 10 /**< C method with string args */
135 #define EJS_TYPE_PTR 11 /**< Opaque pointer */
138 * Create a type for the default number type
139 * Config.h will define the default number type. For example:
141 * BLD_FEATURE_NUM_TYPE=int
142 * BLD_FEATURE_NUM_TYPE_ID=EJS_TYPE_INT
146 * Set to the type used for EJS numeric variables. Will equate to int, int64
149 typedef BLD_FEATURE_NUM_TYPE EjsNum;
152 * Set to the EJS_TYPE used for EJS numeric variables. Will equate to
153 * EJS_TYPE_INT, EJS_TYPE_INT64 or EJS_TYPE_FLOAT.
155 #define EJS_NUM_VAR BLD_FEATURE_NUM_TYPE_ID
156 #define EJS_TYPE_NUM BLD_FEATURE_NUM_TYPE_ID
159 * Return TRUE if a variable is a method type
161 #define ejsVarIsMethod(vp) \
162 ((vp)->type == EJS_TYPE_METHOD || (vp)->type == EJS_TYPE_STRING_CMETHOD || \
163 (vp)->type == EJS_TYPE_CMETHOD)
166 * Return TRUE if a variable is a numeric type
168 #define ejsVarIsNumber(vp) \
169 ((vp)->type == EJS_TYPE_INT || (vp)->type == EJS_TYPE_INT64 || \
170 (vp)->type == EJS_TYPE_FLOAT)
173 * Return TRUE if a variable is a boolean
175 #define ejsVarIsBoolean(vp) \
176 ((vp)->type == EJS_TYPE_BOOL)
179 * Return TRUE if a variable is an integer type
181 #define ejsVarIsInteger(vp) ((vp)->type == EJS_TYPE_INT)
184 * Return TRUE if a variable is a string
186 #define ejsVarIsString(vp) \
187 ((vp)->type == EJS_TYPE_STRING)
190 * Return TRUE if a variable is an object
192 #define ejsVarIsObject(vp) \
193 ((vp)->type == EJS_TYPE_OBJECT)
196 * Return TRUE if a variable is a floating number
198 #define ejsVarIsFloating(vp) \
199 ((vp)->type == EJS_TYPE_FLOAT)
202 * Return TRUE if a variable is undefined
204 #define ejsVarIsUndefined(var) \
205 ((var)->type == EJS_TYPE_UNDEFINED)
208 * Return TRUE if a variable is null
210 #define ejsVarIsNull(var) \
211 ((var)->type == EJS_TYPE_NULL)
214 * Return TRUE if a variable is a valid type (not null or undefined)
216 #define ejsVarIsValid(var) \
217 (((var)->type != EJS_TYPE_NULL) && ((var)->type != EJS_TYPE_UNDEFINED))
220 * Return TRUE if a variable is a ptr type
222 #define ejsVarIsPtr(vp) \
223 ((vp)->type == EJS_TYPE_PTR)
225 /* MOB -- convert all ep to ejs */
227 * @overview C Method signature
228 * @description This is the calling signature for C Methods.
229 * @param ejs Ejs reference returned from ejsCreateInterp
230 * @param thisObj Reference to the "this" object. (The object containing the
232 * @param argc Number of arguments.
233 * @param argv Array of arguments. Each argument is held in an EjsVar type.
234 * @stability Prototype.
236 * @see ejsCreateCMethodVar
238 typedef int (*EjsCMethod)(struct Ejs *ejs, struct EjsVar *thisObj,
239 int argc, struct EjsVar **argv);
242 * C Method with string arguments signature
243 * @overview C Method with string arguments signature
244 * @description This is the calling signature for C Methods.
245 * @param ejs Ejs reference returned from ejsCreateInterp
246 * @param thisObj Reference to the "this" object (object containing the
248 * @param argc Number of arguments.
249 * @param argv Array of arguments. Each argument is held in an C string
251 * @stability Prototype.
253 * @see ejsCreateStringCMethodVar
255 typedef int (*EjsStringCMethod)(struct Ejs *ep, struct EjsVar *thisObj,
256 int argc, char **argv);
259 * Flags for types: EJS_TYPE_CMETHOD, EJS_TYPE_STRING_CMETHOD
260 * NOTE: flags == 0 means to use the EJS handle on method callbacks
262 /* Use the primary handle on method callbacks */
263 #define EJS_PRIMARY_HANDLE 0x1
265 /* Use the alternate handle on method callbacks */
266 #define EJS_ALT_HANDLE 0x2
268 /** Method should not create a new local variable block */
269 #define EJS_NO_LOCAL 0x4
271 /* Method is a get accessor */
272 #define EJS_GET_ACCESSOR 0x8
274 /* Method is a set accessor */
275 #define EJS_SET_ACCESSOR 0x10
278 * Flags for E4X (Xml type)
280 /* Node is a text node */
281 #define EJS_XML_FLAGS_TEXT 0x1
283 /* Node is a processing instruction */
284 #define EJS_XML_FLAGS_PI 0x2
286 /* Node is a comment */
287 #define EJS_XML_FLAGS_COMMENT 0x4
289 /* Node is an attribute */
290 #define EJS_XML_FLAGS_ATTRIBUTE 0x8
292 /* Node is an element */
293 #define EJS_XML_FLAGS_ELEMENT 0x10
297 * @overview Specifies how an object should be copied
298 * @description The EjsCopyDepth type specifies how an object's properties
299 * should be copied. Several routines take EjsCopyDepth parameters to
300 * control how the properties of an object should be copied. It provides
301 * three copy options:
304 typedef enum EjsCopyDepth {
306 * During an object copy, object property references will be copied so
307 * that the original object and the copy will share the same reference to
308 * a property object. Properties containing primitive types including
309 * strings will have their values copied and will not share references.
311 EJS_SHALLOW_COPY, /** Copy strings. Copy object references. */
313 * During an object copy, object properties will be replicated so that
314 * the original object and the copy will not share references to the same
315 * object properties. If the original object's properties are themselves
316 * objects, their properties will not be copied. Only their references
317 * will be copied. i.e. the deep copy is one level deep.
319 EJS_DEEP_COPY, /** Copy strings and copy object contents. */
321 * During an object copy, all object properties will be replicated so that
322 * the original object and the copy will not share references to the same
323 * object properties. If the original object's properties are themselves
324 * objects, their properties will be copied. i.e. the copy is of infinite
327 EJS_RECURSIVE_DEEP_COPY /** Copy strings and copy object contents
328 recursively (complete copy). */
335 /** Enumerate data properties */
336 #define EJS_ENUM_DATA 0x0
338 /** Enumerate sub classes */
339 #define EJS_ENUM_CLASSES 0x1
341 /** Enumerate non-enumerable properties */
342 #define EJS_ENUM_HIDDEN 0x2
344 /** Enumerate all properties */
345 #define EJS_ENUM_ALL (0x3)
347 /** Magic number when allocated */
348 #define EJS_MAGIC 0xe801e2ec
349 #define EJS_MAGIC_FREE 0xe701e3ea
353 * Garbage Collection Linkage. Free list only uses the next pointers.
355 typedef struct EjsGCLink {
357 uint magic; /* Magic number */
359 #if BLD_FEATURE_ALLOC_LEAK_TRACK
360 const char *allocatedBy; /* Who allocated this */
362 struct EjsGCLink *next; /* Next property */
367 * @overview EJS Variable Type
368 * @description The EJ language supports an extensive set of primitive types.
369 * These variable types can efficiently store primitive data types such as
370 * integers, strings, binary string, booleans, floating point numbers,
371 * pointer references, and objects. EjsVars are the universal type used by
372 * EJ to hold objects, classes and properties.
374 * An EjsVar may store one of the following types:
376 * @li Floating point (if supported in this build)
378 * @li 64 bit integer (if supported in this build)
381 * @li C function or C++ method
382 * @li C function with string args
383 * @li Javascript method
386 * @li Undefined value
388 * Objects can hold object properties which are themselves EJS variables.
389 * Properties are hash indexed by the property name and are stored in
390 * an ordered sequence. i.e. Order of properties is maintained. Objects may
391 * be referenced by multiple variables and they use garbage collection to
392 * reclaim memory no longer in use by objects and properties.
394 * @warning This module is @e not thread safe for performance and
395 * compactness. It relies on upper modules to provide thread
396 * synchronization as required. The API provides primitives to get
397 * variable/object references or to get copies of variables which should
398 * help minimize required lock times.
399 * @stability Prototype.
401 * @see Ejs, EjsProperty, ejsCreateStringVar, ejsFreeVar
404 typedef struct EjsVar { /* Size 12 bytes */
408 #if BLD_DEBUG || BLD_FEATURE_ALLOC_LEAK_TRACK
409 EjsGCLink gc; /* Garbage collection links */
413 const char *propertyName; /* Ptr to property name */
417 * Union of primitive types. When debugging on Linux, don't use unions
418 * as the gdb debugger can't display them.
420 #if (!BLD_DEBUG && !VXWORKS) || WIN || BREW_SIMULATOR
424 * For debugging, we order the common types first
426 struct EjsObj *objectState; /* Object state information */
430 #if BLD_FEATURE_FLOATING_POINT
433 #if BLD_FEATURE_INT64
438 int length; /* String length (sans null) */
440 * All strings always have a trailing null allocated
443 char *string; /* String */
444 uchar *ustring; /* Binary string */
448 struct { /* Javascript methods */
449 MprArray *args; /* Null terminated */
453 struct { /* Method with EjsVar args */
454 EjsCMethod fn; /* Method pointer */
455 void *userData; /* User data for method */
458 struct { /* Method with string args */
459 EjsStringCMethod fn; /* Method pointer */
460 void *userData; /* User data for method */
461 } cMethodWithStrings;
464 void *userPtr; /* Opaque pointer */
465 int (*destructor)(Ejs *ejs, struct EjsVar *vp);
468 #if (!BLD_DEBUG && !VXWORKS) || WIN || BREW_SIMULATOR
473 * Packed bit field (32 bits)
475 uint flags : 8; /* Type specific flags */
476 EjsType type : 4; /* Selector into union */
477 uint stringLen : 4; /* Length of string if inline */
478 uint allocatedData : 1; /* Node needs freeing */
479 uint isArray : 1; /* Var is an array */
480 uint isArrayLength : 1; /* Var is array.length */
481 uint callsSuper : 1; /* Method calls super() */
482 uint isProperty : 1; /* Part of a property */
483 uint reserved : 11; /* Unused */
489 * Linkage for the ordered list of properties
491 typedef struct EjsPropLink {
492 struct EjsPropLink *next; /* Next property */
493 struct EjsPropLink *prev; /* Previous property */
496 * To make debugging easier
499 const char *propertyName; /* Pointer to name */
500 struct EjsProperty *property; /* Pointer to property */
501 struct EjsPropLink *head; /* Dummy head of list */
507 * @overview Object Property Type
508 * @description The EjsProperty type is used to store all object properties.
509 * It contains the property name, property linkage, propery attributes
510 * such as public/private, enumerable and readonly settings. It also
511 * contains an EjsVar to store the property data value.
512 * @stability Prototype.
516 typedef struct EjsProperty { /* Size 96 bytes in squeeze */
518 * EjsVar must be first. We often take the address of "var" and take
519 * advantage of if an EjsProperty is null, then &prop->var will be null
520 * also. Be WARNED. External users should use ejsGetVarPtr and
521 * ejsGetPropertyPtr to convert between the two.
523 EjsVar var; /* Property value */
525 /* OPT change this to a pointer to the base class property */
526 char name[EJS_MAX_ID]; /* Name */
528 uint visited : 1; /* Has been traversed */
529 uint isPrivate : 1; /* Property is private */
530 uint isProtected : 1; /* Property is protected */
531 uint dontEnumerate : 1; /* Not enumerable */
532 uint dontDelete : 1; /* Prevent delete */
533 uint readonly : 1; /* Unmodifiable */
534 uint allowNonUnique : 1; /* Multiple of same name ok */
535 uint delayedDelete : 1;
538 EjsPropLink link; /* Ordered linked list */
539 struct EjsProperty *hashNext; /* Hash table linkage */
541 /* MOB -- is this really required */
542 struct EjsObj *parentObj; /* Pointer to parent object */
547 #define EJS_OP_DOT 0x1
548 #define EJS_OP_INDEX 0x2
549 #define EJS_OP_PLUS 0x3
550 #define EJS_OP_MINUS 0x4
551 #define EJS_OP_MULTIPLY 0x5
552 #define EJS_OP_DIVIDE 0x6
553 #define EJS_OP_CALL 0x7
555 typedef struct EjsOp {
561 * Propety Access Methods. Used per class.
562 * MOB -- rename EjsHelpers
564 typedef struct EjsMethods {
566 int (*create)(Ejs *ep, EjsVar *thisObj);
567 int (*deleteProperty)(Ejs *ep, EjsVar *thisObj, const char *prop);
568 EjsVar *(*getProperty)(Ejs *ep, EjsVar *thisObj, const char *prop);
569 EjsVar *(*setProperty)(Ejs *ep, EjsVar *thisObj, const char *prop);
570 int (*hasProperty)(Ejs *ep, EjsVar *thisObj, const char *prop);
571 int (*hasInstance)(Ejs *ep, EjsVar *thisObj, const char *prop);
572 int (*operate)(Ejs *ep, EjsVar *thisObj, EjsOp op, EjsVar *result,
573 EjsVar *lhs, EjsVar *rhs, int *code);
576 EjsVar *(*createProperty)(Ejs *ep, EjsVar *obj, const char *property);
577 int (*deleteProperty)(Ejs *ep, EjsVar *obj, const char *property);
578 EjsVar *(*getProperty)(Ejs *ep, EjsVar *obj, const char *property);
579 EjsVar *(*setProperty)(Ejs *ep, EjsVar *obj, const char *property,
580 const EjsVar *value);
582 * Other implemented internal properties in ECMA-262 are:
584 * [[Construct]] implemented via EjsVar methods
585 * [[Prototype]] implemented via EjsObj->baseClass
586 * [[Class]] implemented via EjsObj->baseClass->name
587 * [[Value]] Implemented via EjsProperty + EjsVar + EjsObj
591 * FUTURE -- not implemented
593 int (*canPut)(Ejs *ep, EjsVar *obj, const char *property);
594 int (*defaultValue)(Ejs *ep, EjsVar *obj, const char *property,
596 int (*hasProperty)(Ejs *ep, EjsVar *obj, const char *property);
597 EjsVar *(*call)(Ejs *ep, EjsVar *obj, const char *property,
599 int (*hasInstance)(Ejs *ep, EjsVar *obj, const char *property);
600 int (*scope)(Ejs *ep, EjsVar *obj, const char *property);
601 int (*match)(Ejs *ep, EjsVar *obj, const char *property,
602 const char *string, int index);
610 typedef struct EjsObj {
614 EjsGCLink gc; /* Garbage collection links */
617 char *objName; /* Object name */
618 char *className; /* Class name */
621 struct EjsVar *baseClass; /* Pointer to base class object */
623 EjsPropLink link; /* Ordered list of properties */
625 /* OPT -- dynamically allocate this only if required */
626 EjsProperty *propertyHash[EJS_OBJ_HASH_SIZE]; /* Hash chains */
628 /* OPT -- could save this and store off baseClass only */
629 EjsMethods *methods; /* Property access methods */
630 void *nativeData; /* Native object data */
632 int (*destructor)(Ejs *ejs, struct EjsVar *vp);
634 uint numProperties : 16; /* Total count of items */
635 uint visited : 1; /* Has been traversed */
636 uint gcMarked : 1; /* Node marked in-use by GC */
637 uint permanent : 1; /* Permanent object, dont GC */
638 uint alive : 1; /* Only GC if alive */
639 uint noConstructor : 1; /* Object has no constructor */
640 uint dirty : 1; /* Object has been modified */
641 uint hasErrors : 1; /* Update error */
642 uint preventDeleteProp : 1; /* Don't allow prop deletion */
643 uint delayedDeleteProp : 1; /* Delayed delete of props */
644 uint reserved : 7; /* Unused */
646 Ejs *ejs; /* Owning interp */
648 #if BLD_FEATURE_MULTITHREAD
649 MprLock *mutex; /* Advisory mutex lock */
655 * Define a field macro so code an use numbers in a "generic" fashion.
657 #if EJS_NUM_VAR == EJS_TYPE_INT || DOXYGEN
659 * Default numeric type
661 #define ejsNumber integer
663 #if EJS_NUM_VAR == EJS_TYPE_INT64
664 /* Default numeric type */
665 #define ejsNumber integer64
667 #if EJS_NUM_VAR == EJS_TYPE_FLOAT
668 /* Default numeric type */
669 #define ejsNumber floating
672 typedef BLD_FEATURE_NUM_TYPE EjsNumber;
675 * Memory allocation slabs
677 #define EJS_SLAB_OBJ 0
678 #define EJS_SLAB_PROPERTY 1
679 #define EJS_SLAB_VAR 2
680 #define EJS_SLAB_MAX 3
683 * Object and pointer property destructory type
685 typedef int (*EjsDestructor)(Ejs *ejs, EjsVar *vp);
687 #if BLD_FEATURE_ALLOC_LEAK_TRACK || DOXYGEN
689 * Line number information args and declarations for ejsAlloc.
690 * Use EJS_LOC_ARGS in normal user code.
691 * Use EJS_LOC_DEC in declarations.
692 * Use EJS_LOC_PASS in layered APIs to pass original line info down.
694 #define EJS_LOC_ARGS(ejs) ejs, MPR_LOC
695 #define EJS_LOC_DEC(ejs, loc) Ejs *ejs, const char *loc
696 #define EJS_LOC_PASS(ejs, loc) ejs, loc
698 #define EJS_LOC_ARGS(ejs) ejs
699 #define EJS_LOC_DEC(ejs, loc) Ejs *ejs
700 #define EJS_LOC_PASS(ejs, loc) ejs
703 /******************************* Internal Prototypes **************************/
705 #define ejsInitVar(vp, varType) \
707 (vp)->type = varType; \
711 extern void ejsClearVar(Ejs *ep, EjsVar *vp);
713 extern int ejsDestroyObj(Ejs *ep, EjsObj *obj);
714 extern EjsVar *ejsCreatePropertyMethod(Ejs *ep, EjsVar *obj,
716 extern EjsVar *ejsSetPropertyMethod(Ejs *ep, EjsVar *obj, const char *name,
717 const EjsVar *value);
718 extern EjsVar *ejsGetPropertyMethod(Ejs *ep, EjsVar *obj, const char *name);
719 extern int ejsDeletePropertyMethod(Ejs *ep, EjsVar *obj,
721 extern void ejsSetArrayLength(Ejs *ep, EjsVar *obj, const char *creating,
722 const char *deleting, const EjsVar *setLength);
725 * At the moment, these are the same routine
727 extern void ejsSetClassName(Ejs *ep, EjsVar *obj, const char *name);
728 #define ejsSetObjName ejsSetObjName
730 extern bool ejsIsObjDirty(EjsVar *vp);
731 extern void ejsResetObjDirtyBit(EjsVar *vp);
733 extern int ejsObjHasErrors(EjsVar *vp);
734 extern void ejsClearObjErrors(EjsVar *vp);
736 extern EjsVar *ejsClearProperty(Ejs *ep, EjsVar *obj, const char *prop);
738 typedef int (*EjsSortFn)(Ejs *ep, EjsProperty *p1, EjsProperty *p2,
739 const char *propertyName, int order);
740 extern void ejsSortProperties(Ejs *ep, EjsVar *obj, EjsSortFn fn,
741 const char *propertyName, int order);
744 #define ejsSetVarName(ep, vp, varName) \
746 (vp)->propertyName = varName; \
747 if ((vp)->type == EJS_TYPE_OBJECT && \
748 (vp)->objectState && \
749 ((vp)->objectState->objName == 0)) { \
750 (vp)->objectState->objName = \
751 mprStrdup(ep, varName); \
755 #define ejsSetVarName(ep, vp, varName)
758 EjsVar *ejsFindProperty(Ejs *ep, EjsVar **obj, char **property,
759 EjsVar *global, EjsVar *local, const char *fullName,
762 extern EjsVar *ejsCopyProperties(Ejs *ep, EjsVar *dest,
763 const EjsVar *src, EjsCopyDepth copyDepth);
765 #define EJS_LINK_OFFSET ((uint) (&((EjsProperty*) 0)->link))
766 #define ejsGetPropertyFromLink(lp) \
767 ((EjsProperty*) ((char*) lp - EJS_LINK_OFFSET))
769 #define ejsGetObjPtr(vp) ((EjsObj*) vp->objectState)
771 extern void ejsMakePropertyPrivate(EjsProperty *pp, int isPrivate);
772 extern void ejsMakePropertyReadOnly(EjsProperty *pp, int readonly);
773 extern void ejsMakePropertyUndeleteable(EjsProperty *pp, int deletable);
774 extern int ejsMakeObjLive(EjsVar *vp, bool alive);
775 extern void ejsMakeClassNoConstructor(EjsVar *vp);
777 extern bool ejsBlockInUseInt(EjsVar *vp);
779 #define ejsBlockInUse(vp) ejsBlockInUseInt(vp)
781 #define ejsBlockInUse(vp)
784 /********************************* Prototypes *********************************/
787 * Variable constructors and destructors
789 extern EjsVar *ejsCreateBinaryStringVar(Ejs *ep, const uchar *value,
791 extern EjsVar *ejsCreateBoolVar(Ejs *ep, int value);
792 extern EjsVar *ejsCreateCMethodVar(Ejs *ep, EjsCMethod fn,
793 void *userData, int flags);
794 #if BLD_FEATURE_FLOATING_POINT
795 extern EjsVar *ejsCreateFloatVar(Ejs *ep, double value);
797 extern EjsVar *ejsCreateIntegerVar(Ejs *ep, int value);
798 #if BLD_FEATURE_INT64
799 extern EjsVar *ejsCreateInteger64Var(Ejs *ep, int64 value);
802 extern EjsVar *ejsCreateMethodVar(Ejs *ep, const char *body,
803 MprArray *args, int flags);
804 extern EjsVar *ejsCreateNullVar(Ejs *ep);
805 extern EjsVar *ejsCreateNumberVar(Ejs *ep, EjsNumber value);
807 #define ejsCreateObjVar(ep) \
808 ejsCreateObjVarInternal(EJS_LOC_ARGS(ep))
809 extern EjsVar *ejsCreateObjVarInternal(EJS_LOC_DEC(ep, loc));
811 extern EjsVar *ejsCreatePtrVar(Ejs *ep, void *ptr, EjsDestructor dest);
813 extern EjsVar *ejsCreateStringCMethodVar(Ejs *ep, EjsStringCMethod fn,
814 void *userData, int flags);
816 #define ejsCreateStringVar(ep, value) \
817 ejsCreateStringVarInternal(EJS_LOC_ARGS(ep), value)
818 extern EjsVar *ejsCreateStringVarInternal(EJS_LOC_DEC(ep, loc),
821 extern EjsVar *ejsCreateUndefinedVar(Ejs *ep);
823 /* MOB -- naming. Should be Create/Destroy */
824 extern void ejsFreeVar(Ejs *ep, EjsVar *vp);
827 * Var support routines
829 extern int ejsGetVarFlags(EjsVar *vp);
830 extern void ejsSetVarFlags(EjsVar *obj, int flags);
832 extern EjsType ejsGetVarType(EjsVar *vp);
833 extern const char *ejsGetVarTypeAsString(EjsVar *vp);
835 extern void *ejsGetCMethodUserData(EjsVar *obj);
836 extern void ejsSetCMethodUserData(EjsVar *obj, void *userData);
838 extern void *ejsGetVarUserPtr(EjsVar *vp);
839 extern void ejsSetVarUserPtr(EjsVar *vp, void *data);
843 * Variable access and manipulation. These work on standalone objects.
845 #define ejsDupVar(ep, src, copyDepth) \
846 ejsDupVarInternal(EJS_LOC_ARGS(ep), src, copyDepth)
847 extern EjsVar *ejsDupVarInternal(EJS_LOC_DEC(ep, loc), EjsVar *src,
848 EjsCopyDepth copyDepth);
849 #define ejsWriteVar(ep, dest, src, copyDepth) \
850 ejsWriteVarInternal(EJS_LOC_ARGS(ep), dest, src, copyDepth)
851 extern EjsVar *ejsWriteVarInternal(EJS_LOC_DEC(ep, loc), EjsVar *dest,
852 const EjsVar *src, EjsCopyDepth copyDepth);
853 extern EjsVar *ejsWriteVarAsBinaryString(Ejs *ep, EjsVar *dest,
854 const uchar *value, int len);
855 extern EjsVar *ejsWriteVarAsBoolean(Ejs *ep, EjsVar *dest, bool value);
856 extern EjsVar *ejsWriteVarAsCMethod(Ejs *ep, EjsVar *dest, EjsCMethod fn,
857 void *userData, int flags);
858 #if BLD_FEATURE_FLOATING_POINT
859 extern EjsVar *ejsWriteVarAsFloat(Ejs *ep, EjsVar *dest, double value);
861 extern EjsVar *ejsWriteVarAsInteger(Ejs *ep, EjsVar *dest, int value);
862 #if BLD_FEATURE_INT64
863 extern EjsVar *ejsWriteVarAsInteger64(Ejs *ep, EjsVar *dest, int64 value);
865 extern EjsVar *ejsWriteVarAsMethod(Ejs *ep, EjsVar *dest,
866 const char *body, MprArray *args);
867 extern EjsVar *ejsWriteVarAsNull(Ejs *ep, EjsVar *dest);
868 extern EjsVar *ejsWriteVarAsNumber(Ejs *ep, EjsVar *dest, EjsNum value);
869 #define ejsWriteVarAsString(ep, dest, value) \
870 ejsWriteVarAsStringInternal(EJS_LOC_ARGS(ep), dest, value)
871 extern EjsVar *ejsWriteVarAsStringInternal(EJS_LOC_DEC(ep, loc),
872 EjsVar *dest, const char *value);
873 extern EjsVar *ejsWriteVarAsStringCMethod(Ejs *ep, EjsVar *dest,
874 EjsStringCMethod fn, void *userData, int flags);
875 extern EjsVar *ejsWriteVarAsUndefined(Ejs *ep, EjsVar *dest);
878 * These routines do not convert types
880 /* MOB -- make this a fn and pass back the length as an arg */
881 #define ejsReadVarAsBinaryString(vp) ((const uchar*) (vp->ustring));
882 #define ejsReadVarAsBoolean(vp) (vp->boolean);
883 #define ejsReadVarAsCMethod(vp) (vp->cMethod);
884 #if BLD_FEATURE_FLOATING_POINT
885 #define ejsReadVarAsFloat(vp) (vp->floating);
887 #define ejsReadVarAsInteger(vp) (vp->integer);
888 #if BLD_FEATURE_INT64
889 #define ejsReadVarAsInteger64(vp) (vp->int64);
891 #define ejsReadVarAsString(vp) ((const char*) (vp->string));
892 #define ejsReadVarAsStringCMethod(vp) (vp->cMethodWithStrings);
893 /* MOB -- remove this fn */
894 #define ejsReadVarStringLength(vp) (vp->length);
897 * Object property creation routines
899 extern EjsProperty *ejsCreateProperty(Ejs *ep, EjsVar *obj, const char *prop);
900 extern EjsProperty *ejsCreateSimpleProperty(Ejs *ep, EjsVar *obj,
902 extern EjsProperty *ejsCreateSimpleNonUniqueProperty(Ejs *ep, EjsVar *obj,
904 /* MOB -- should be destroy */
905 extern int ejsDeleteProperty(Ejs *ep, EjsVar *obj, const char *prop);
909 * Get property routines
911 extern EjsProperty *ejsGetProperty(Ejs *ep, EjsVar *obj, const char *prop);
912 extern EjsProperty *ejsGetSimpleProperty(Ejs *ep, EjsVar *obj,
915 extern EjsVar *ejsGetPropertyAsVar(Ejs *ep, EjsVar *obj,
917 extern int ejsGetPropertyCount(EjsVar *obj);
919 extern const uchar *ejsGetPropertyAsBinaryString(Ejs *ep, EjsVar *obj,
920 const char *prop, int *length);
921 extern bool ejsGetPropertyAsBoolean(Ejs *ep, EjsVar *obj,
923 extern int ejsGetPropertyAsInteger(Ejs *ep, EjsVar *obj,
925 extern int64 ejsGetPropertyAsInteger64(Ejs *ep, EjsVar *obj,
927 extern EjsNum ejsGetPropertyAsNumber(Ejs *ep, EjsVar *obj,
929 extern void *ejsGetPropertyAsPtr(Ejs *ep, EjsVar *obj,
931 extern const char *ejsGetPropertyAsString(Ejs *ep, EjsVar *obj,
935 * Object property update routines
937 extern EjsProperty *ejsSetBaseProperty(Ejs *ep, EjsVar *obj, const char *prop,
938 const EjsVar *value);
939 extern EjsProperty *ejsSetProperty(Ejs *ep, EjsVar *obj, const char *prop,
940 const EjsVar *value);
941 extern EjsProperty *ejsSetPropertyAndFree(Ejs *ep, EjsVar *obj,
942 const char *prop, EjsVar *value);
943 extern EjsProperty *ejsSetPropertyToBinaryString(Ejs *ep, EjsVar *obj,
944 const char *prop, const uchar *value, int len);
945 extern EjsProperty *ejsSetPropertyToBoolean(Ejs *ep, EjsVar *obj,
946 const char *prop, bool value);
947 extern EjsProperty *ejsSetPropertyToCMethod(Ejs *ep, EjsVar *obj,
948 const char *prop, EjsCMethod fn, void *userData,
950 #if BLD_FEATURE_FLOATING_POINT
951 extern EjsProperty *ejsSetPropertyToFloat(Ejs *ep, EjsVar *obj,
952 const char *prop, double value);
954 extern EjsProperty *ejsSetPropertyToInteger(Ejs *ep, EjsVar *obj,
955 const char *prop, int value);
956 #if BLD_FEATURE_INT64
957 extern EjsProperty *ejsSetPropertyToInteger64(Ejs *ep, EjsVar *obj,
958 const char *prop, int64 value);
960 extern EjsProperty *ejsSetPropertyToMethod(Ejs *ep, EjsVar *obj,
961 const char *prop, const char *body, MprArray *args,
963 extern EjsProperty *ejsSetPropertyToNewObj(Ejs *ep, EjsVar *obj,
964 const char *prop, const char *className,
966 extern EjsProperty *ejsSetPropertyToNull(Ejs *ep, EjsVar *obj,
968 extern EjsProperty *ejsSetPropertyToNumber(Ejs *ep, EjsVar *obj,
969 const char *prop, EjsNum value);
970 extern EjsProperty *ejsSetPropertyToObj(Ejs *ep, EjsVar *obj,
972 extern EjsProperty *ejsSetPropertyToPtr(Ejs *ep, EjsVar *obj,
973 const char *prop, void *ptr, EjsDestructor destructor);
975 extern EjsProperty *ejsSetPropertyToStringCMethod(Ejs *ep, EjsVar *obj,
976 const char *prop, EjsStringCMethod fn,
977 void *userData, int flags);
978 extern EjsProperty *ejsSetPropertyToString(Ejs *ep, EjsVar *obj,
979 const char *prop, const char *value);
980 extern EjsProperty *ejsSetPropertyToUndefined(Ejs *ep, EjsVar *obj,
984 /* Convenience function */
985 extern EjsVar *ejsSetPropertyToObjAsVar(Ejs *ep, EjsVar *obj,
987 extern void ejsSetObjDestructor(Ejs *ep, EjsVar *obj,
988 EjsDestructor destructor);
989 extern void ejsClearObjDestructor(Ejs *ep, EjsVar *obj);
992 * Enumeration of properties
993 * MOB -- should these take an ejs parameter to be consistent
995 extern EjsProperty *ejsGetFirstProperty(const EjsVar *obj, int flags);
996 extern EjsProperty *ejsGetNextProperty(EjsProperty *last, int flags);
999 * Method definition and control.
1001 extern EjsProperty *ejsDefineMethod(Ejs *ep, EjsVar *obj, const char *prop,
1002 const char *body, MprArray *args);
1003 extern EjsProperty *ejsDefineCMethod(Ejs *ep, EjsVar *obj, const char *prop,
1004 EjsCMethod fn, int flags);
1006 extern EjsProperty *ejsDefineStringCMethod(Ejs *ep, EjsVar *obj,
1007 const char *prop, EjsStringCMethod fn, int flags);
1009 extern EjsProperty *ejsDefineAccessors(Ejs *ep, EjsVar *obj,
1010 const char *prop, const char *getBody,
1011 const char *setBody);
1012 extern EjsProperty *ejsDefineCAccessors(Ejs *ep, EjsVar *obj,
1013 const char *prop, EjsCMethod getFn, EjsCMethod setFn,
1017 * Macro to get the variable value portion of a property
1019 #define ejsGetVarPtr(pp) (&((pp)->var))
1020 #define ejsGetPropertyPtr(vp) ((EjsProperty*) vp)
1022 /* MOB -- take ejs to be consistent */
1023 extern int ejsMakePropertyEnumerable(EjsProperty *pp, bool enumerable);
1024 extern int ejsMakeObjPermanent(EjsVar *vp, bool permanent);
1028 * Var conversion routines
1029 * MOB -- should these take an Ejs as first arg for consistency
1031 extern bool ejsVarToBoolean(EjsVar *vp);
1032 #if BLD_FEATURE_FLOATING_POINT
1033 extern double ejsVarToFloat(EjsVar *vp);
1035 extern int ejsVarToInteger(EjsVar *vp);
1036 #if BLD_FEATURE_INT64
1037 extern int64 ejsVarToInteger64(EjsVar *vp);
1039 extern EjsNum ejsVarToNumber(EjsVar *vp);
1040 extern char *ejsVarToString(Ejs *ep, EjsVar *vp);
1041 extern char *ejsVarToStringEx(Ejs *ep, EjsVar *vp, bool *alloc);
1042 extern char *ejsFormatVar(Ejs *ep, const char *fmt, EjsVar *vp);
1044 #if BLD_FEATURE_FLOATING_POINT
1045 extern double ejsParseFloat(const char *str);
1048 * Parsing and type range checking routines
1050 extern bool ejsParseBoolean(const char *str);
1051 extern int ejsParseInteger(const char *str);
1052 #if BLD_FEATURE_INT64
1053 extern int64 ejsParseInteger64(const char *str);
1055 extern EjsNum ejsParseNumber(const char *str);
1056 extern EjsVar *ejsParseVar(Ejs *ep, const char *str, EjsType prefType);
1058 #if BLD_FEATURE_FLOATING_POINT
1059 extern bool ejsIsInfinite(double f);
1060 extern bool ejsIsNan(double f);
1064 * Advisory locking support
1066 #if BLD_FEATURE_MULTITHREAD
1067 extern void ejsLockObj(EjsVar *vp);
1068 extern void ejsUnlockObj(EjsVar *vp);
1072 * Just for debugging
1074 extern bool ejsObjIsCollectable(EjsVar *vp);
1080 /*****************************************************************************/
1081 #endif /* _h_EJS_VAR */
1089 * vim600: sw=4 ts=4 fdm=marker
1090 * vim<600: sw=4 ts=4