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