1 /* Copyright (c) 2003, David Leonard. All rights reserved. */ 2 3 #ifndef _SEE_h_object_ 4 #define _SEE_h_object_ 5 6 struct SEE_value; 7 struct SEE_object; 8 struct SEE_string; 9 struct SEE_scope; 10 struct SEE_enum; 11 struct SEE_interpreter; 12 13 /* 14 * Class method types. Even though ECMAScript uses a prototype 15 * inheritance model, objects still have to carry something like 16 * a vtbl. 17 */ 18 typedef void (*SEE_get_fn_t)(struct SEE_interpreter *i, 19 struct SEE_object *obj, struct SEE_string *prop, 20 struct SEE_value *res); 21 typedef void (*SEE_put_fn_t)(struct SEE_interpreter *i, 22 struct SEE_object *obj, struct SEE_string *prop, 23 struct SEE_value *res, int flags); 24 typedef int (*SEE_boolean_fn_t)(struct SEE_interpreter *i, 25 struct SEE_object *obj, struct SEE_string *prop); 26 typedef int (*SEE_hasinstance_fn_t)(struct SEE_interpreter *i, 27 struct SEE_object *obj, struct SEE_value *instance); 28 typedef void (*SEE_default_fn_t)(struct SEE_interpreter *i, 29 struct SEE_object *obj, struct SEE_value *hint, 30 struct SEE_value *res); 31 typedef void (*SEE_call_fn_t)(struct SEE_interpreter *i, 32 struct SEE_object *obj, struct SEE_object *thisobj, 33 int argc, struct SEE_value **argv, 34 struct SEE_value *res); 35 typedef struct SEE_enum *(*SEE_enumerator_fn_t)(struct SEE_interpreter *i, 36 struct SEE_object *obj); 37 typedef void * (*SEE_get_sec_domain_fn_t)(struct SEE_interpreter *i, 38 struct SEE_object *obj); 39 40 /* 41 * Object classes: an object insatnce appears as a container of named 42 * properties accessible through methods provided by its object class. 43 * Object classes are a SEE implementation feature and not directly visible 44 * to ECMAScript programs. 45 * 46 * All object classes must implement: Prototype, Class, Get, Put, CanPut, 47 * HasProperty, Delete and DefaultValue. (DefaultValue may simply 48 * throw a TypeError, and Proptype may be NULL) 49 * Optionally, object classes can implement the enumerator, Construct, Call 50 * or HasInstance. Unimplemented optional methods are indicated as NULL. 51 */ 52 struct SEE_objectclass { 53 const char * Class; /* [[Class]] */ 54 SEE_get_fn_t Get; /* [[Get]] */ 55 SEE_put_fn_t Put; /* [[Put]] */ 56 SEE_boolean_fn_t CanPut; /* [[CanPut]] */ 57 SEE_boolean_fn_t HasProperty; /* [[HasProperty]] */ 58 SEE_boolean_fn_t Delete; /* [[Delete]] */ 59 SEE_default_fn_t DefaultValue; /* [[DefaultValue]] */ 60 SEE_enumerator_fn_t enumerator; /* enumerator */ 61 SEE_call_fn_t Construct; /* [[Construct]] */ 62 SEE_call_fn_t Call; /* [[Call]] */ 63 SEE_hasinstance_fn_t HasInstance; /* [[HasInstance]] */ 64 SEE_get_sec_domain_fn_t get_sec_domain; /* get_sec_domain */ 65 }; 66 67 /* 68 * Base object structure. This structure is not generally useful 69 * unless extended (see struct SEE_native in <see/native.h>). 70 */ 71 struct SEE_object { 72 struct SEE_objectclass *objectclass; 73 struct SEE_object *Prototype; /* [[Prototype]] */ 74 void *host_data; 75 }; 76 77 #ifndef NDEBUG 78 # define _SEE_INTERN_ASSERT(i,s) _SEE_intern_assert(i, s) 79 struct SEE_string *_SEE_intern_assert(struct SEE_interpreter *i, 80 struct SEE_string *s); 81 #else 82 # define _SEE_INTERN_ASSERT(i,s) (s) 83 #endif 84 85 86 #define SEE_OBJECT_GET(interp, obj, name, res) \ 87 (*(obj)->objectclass->Get)(interp, obj, \ 88 _SEE_INTERN_ASSERT(interp, name), res) 89 #define SEE_OBJECT_PUT(interp, obj, name, val, attrs) \ 90 (*(obj)->objectclass->Put)(interp, obj, \ 91 _SEE_INTERN_ASSERT(interp, name), val, attrs) 92 #define SEE_OBJECT_CANPUT(interp, obj, name) \ 93 (*(obj)->objectclass->CanPut)(interp, obj, \ 94 _SEE_INTERN_ASSERT(interp, name)) 95 #define SEE_OBJECT_HASPROPERTY(interp, obj, name) \ 96 (*(obj)->objectclass->HasProperty)(interp, obj, \ 97 _SEE_INTERN_ASSERT(interp, name)) 98 #define SEE_OBJECT_DELETE(interp, obj, name) \ 99 (*(obj)->objectclass->Delete)(interp, obj, \ 100 _SEE_INTERN_ASSERT(interp, name)) 101 #define SEE_OBJECT_DEFAULTVALUE(interp, obj, hint, res) \ 102 (*(obj)->objectclass->DefaultValue)(interp, obj, hint, res) 103 #define SEE_OBJECT_CONSTRUCT(interp, obj, thisobj, argc, argv, res) \ 104 SEE_object_construct(interp, obj, thisobj, argc, argv, res) 105 #define _SEE_OBJECT_CONSTRUCT(interp, obj, thisobj, argc, argv, res) \ 106 (*(obj)->objectclass->Construct)(interp, obj, thisobj, argc, argv, res) 107 #define SEE_OBJECT_CALL(interp, obj, thisobj, argc, argv, res) \ 108 SEE_object_call(interp, obj, thisobj, argc, argv, res) 109 #define _SEE_OBJECT_CALL(interp, obj, thisobj, argc, argv, res) \ 110 (*(obj)->objectclass->Call)(interp, obj, thisobj, argc, argv, res) 111 #define SEE_OBJECT_HASINSTANCE(interp, obj, instance) \ 112 (*(obj)->objectclass->HasInstance)(interp, obj, instance) 113 #define SEE_OBJECT_ENUMERATOR(interp, obj) \ 114 (*(obj)->objectclass->enumerator)(interp, obj) 115 #define SEE_OBJECT_GET_SEC_DOMAIN(interp, obj) \ 116 (*(obj)->objectclass->get_sec_domain)(interp, obj) 117 118 /* Convenience macros that use ASCII C strings for names */ 119 struct SEE_string *SEE_intern_ascii(struct SEE_interpreter *, const char *); 120 #define SEE_OBJECT_GETA(interp, obj, name, res) \ 121 SEE_OBJECT_GET(interp, obj, SEE_intern_ascii(interp, name), res) 122 #define SEE_OBJECT_PUTA(interp, obj, name, val, attrs) \ 123 SEE_OBJECT_PUT(interp, obj, SEE_intern_ascii(interp, name), val, attrs) 124 #define SEE_OBJECT_CANPUTA(interp, obj, name) \ 125 SEE_OBJECT_CANPUT(interp, obj, SEE_intern_ascii(interp, name)) 126 #define SEE_OBJECT_HASPROPERTYA(interp, obj, name) \ 127 SEE_OBJECT_HASPROPERTY(interp, obj, SEE_intern_ascii(interp, name)) 128 #define SEE_OBJECT_DELETEA(interp, obj, name) \ 129 SEE_OBJECT_DELETE(interp, obj, SEE_intern_ascii(interp, name)) 130 131 #define SEE_OBJECT_HAS_CALL(obj) ((obj)->objectclass->Call) 132 #define SEE_OBJECT_HAS_CONSTRUCT(obj) ((obj)->objectclass->Construct) 133 #define SEE_OBJECT_HAS_HASINSTANCE(obj) ((obj)->objectclass->HasInstance) 134 #define SEE_OBJECT_HAS_ENUMERATOR(obj) ((obj)->objectclass->enumerator) 135 #define SEE_OBJECT_HAS_GET_SEC_DOMAIN(obj) ((obj)->objectclass->get_sec_domain) 136 137 /* [[Put]] attributes */ 138 #define SEE_ATTR_READONLY 0x01 139 #define SEE_ATTR_DONTENUM 0x02 140 #define SEE_ATTR_DONTDELETE 0x04 141 #define SEE_ATTR_INTERNAL 0x08 142 143 /* Enumerator class. */ 144 struct SEE_enumclass { 145 void *unused; /* deprecated */ 146 struct SEE_string *(*next)(struct SEE_interpreter *i, 147 struct SEE_enum *e, int *flags_return); 148 }; 149 150 /* 151 * Enumerator instance. This structure is generally subclassed to 152 * hold enumeration state. 153 */ 154 struct SEE_enum { 155 struct SEE_enumclass *enumclass; 156 }; 157 158 #define SEE_ENUM_NEXT(i,e,dep) \ 159 _SEE_INTERN_ASSERT(i, ((e)->enumclass->next)(i,e,dep)) 160 161 /* 162 * This macro tests to see if two objects are "joined", i.e. a change to one 163 * is reflected in the other. This is only useful with function 164 * objects that share a common function implementation. 165 */ 166 #define SEE_OBJECT_JOINED(a,b) \ 167 ((a) == (b) || \ 168 ((a)->objectclass == (b)->objectclass && \ 169 SEE_function_is_joined(a,b))) 170 int SEE_function_is_joined(struct SEE_object *a, struct SEE_object *b); 171 172 /* A convenience function equivalent to "new Object()" */ 173 struct SEE_object *SEE_Object_new(struct SEE_interpreter *); 174 175 /* 176 * Wrappers around [[Call]] and [[Construct]] that check for 177 * recursion limits being reached and to keep track of the security 178 * domains. 179 */ 180 void SEE_object_call(struct SEE_interpreter *, struct SEE_object *, 181 struct SEE_object *, int, struct SEE_value **, struct SEE_value *); 182 void SEE_object_construct(struct SEE_interpreter *, struct SEE_object *, 183 struct SEE_object *, int, struct SEE_value **, struct SEE_value *); 184 185 /* val instanceof obj */ 186 int SEE_object_instanceof(struct SEE_interpreter *interp, 187 struct SEE_value *val, struct SEE_object *obj); 188 189 #endif /* _SEE_h_object_ */ 190