5 static void jsB_new_Object(js_State *J)
7 if (js_gettop(J) == 1 || js_isundefined(J, 1) || js_isnull(J, 1))
10 js_pushobject(J, js_toobject(J, 1));
13 static void jsB_Object(js_State *J)
15 if (js_gettop(J) == 1 || js_isundefined(J, 1) || js_isnull(J, 1))
18 js_pushobject(J, js_toobject(J, 1));
21 static void Op_toString(js_State *J)
23 js_Object *self = js_toobject(J, 0);
25 case JS_COBJECT: js_pushliteral(J, "[object Object]"); break;
26 case JS_CARRAY: js_pushliteral(J, "[object Array]"); break;
27 case JS_CFUNCTION: js_pushliteral(J, "[object Function]"); break;
28 case JS_CSCRIPT: js_pushliteral(J, "[object Function]"); break;
29 case JS_CCFUNCTION: js_pushliteral(J, "[object Function]"); break;
30 case JS_CERROR: js_pushliteral(J, "[object Error]"); break;
31 case JS_CBOOLEAN: js_pushliteral(J, "[object Boolean]"); break;
32 case JS_CNUMBER: js_pushliteral(J, "[object Number]"); break;
33 case JS_CSTRING: js_pushliteral(J, "[object String]"); break;
34 case JS_CREGEXP: js_pushliteral(J, "[object RegExp]"); break;
35 case JS_CDATE: js_pushliteral(J, "[object Date]"); break;
36 case JS_CMATH: js_pushliteral(J, "[object Math]"); break;
37 case JS_CJSON: js_pushliteral(J, "[object JSON]"); break;
38 case JS_CITERATOR: js_pushliteral(J, "[Iterator]"); break;
40 js_pushliteral(J, "[object ");
41 js_pushliteral(J, self->u.user.tag);
43 js_pushliteral(J, "]");
49 static void Op_valueOf(js_State *J)
54 static void Op_hasOwnProperty(js_State *J)
56 js_Object *self = js_toobject(J, 0);
57 const char *name = js_tostring(J, 1);
58 js_Property *ref = jsV_getownproperty(J, self, name);
59 js_pushboolean(J, ref != NULL);
62 static void Op_isPrototypeOf(js_State *J)
64 js_Object *self = js_toobject(J, 0);
65 if (js_isobject(J, 1)) {
66 js_Object *V = js_toobject(J, 1);
78 static void Op_propertyIsEnumerable(js_State *J)
80 js_Object *self = js_toobject(J, 0);
81 const char *name = js_tostring(J, 1);
82 js_Property *ref = jsV_getownproperty(J, self, name);
83 js_pushboolean(J, ref && !(ref->atts & JS_DONTENUM));
86 static void O_getPrototypeOf(js_State *J)
89 if (!js_isobject(J, 1))
90 js_typeerror(J, "not an object");
91 obj = js_toobject(J, 1);
93 js_pushobject(J, obj->prototype);
98 static void O_getOwnPropertyDescriptor(js_State *J)
102 if (!js_isobject(J, 1))
103 js_typeerror(J, "not an object");
104 obj = js_toobject(J, 1);
105 ref = jsV_getproperty(J, obj, js_tostring(J, 2));
110 if (!ref->getter && !ref->setter) {
111 js_pushvalue(J, ref->value);
112 js_setproperty(J, -2, "value");
113 js_pushboolean(J, !(ref->atts & JS_READONLY));
114 js_setproperty(J, -2, "writable");
117 js_pushobject(J, ref->getter);
120 js_setproperty(J, -2, "get");
122 js_pushobject(J, ref->setter);
125 js_setproperty(J, -2, "set");
127 js_pushboolean(J, !(ref->atts & JS_DONTENUM));
128 js_setproperty(J, -2, "enumerable");
129 js_pushboolean(J, !(ref->atts & JS_DONTCONF));
130 js_setproperty(J, -2, "configurable");
134 static void O_getOwnPropertyNames(js_State *J)
141 if (!js_isobject(J, 1))
142 js_typeerror(J, "not an object");
143 obj = js_toobject(J, 1);
148 for (ref = obj->head; ref; ref = ref->next) {
149 js_pushliteral(J, ref->name);
150 js_setindex(J, -2, i++);
153 if (obj->type == JS_CARRAY) {
154 js_pushliteral(J, "length");
155 js_setindex(J, -2, i++);
158 if (obj->type == JS_CSTRING) {
159 js_pushliteral(J, "length");
160 js_setindex(J, -2, i++);
161 for (k = 0; k < obj->u.s.length; ++k) {
163 js_setindex(J, -2, i++);
167 if (obj->type == JS_CREGEXP) {
168 js_pushliteral(J, "source");
169 js_setindex(J, -2, i++);
170 js_pushliteral(J, "global");
171 js_setindex(J, -2, i++);
172 js_pushliteral(J, "ignoreCase");
173 js_setindex(J, -2, i++);
174 js_pushliteral(J, "multiline");
175 js_setindex(J, -2, i++);
176 js_pushliteral(J, "lastIndex");
177 js_setindex(J, -2, i++);
181 static void ToPropertyDescriptor(js_State *J, js_Object *obj, const char *name, js_Object *desc)
186 int configurable = 0;
190 js_pushobject(J, obj);
191 js_pushobject(J, desc);
193 if (js_hasproperty(J, -1, "writable")) {
195 writable = js_toboolean(J, -1);
198 if (js_hasproperty(J, -1, "enumerable")) {
199 enumerable = js_toboolean(J, -1);
202 if (js_hasproperty(J, -1, "configurable")) {
203 configurable = js_toboolean(J, -1);
206 if (js_hasproperty(J, -1, "value")) {
208 js_setproperty(J, -3, name);
211 if (!writable) atts |= JS_READONLY;
212 if (!enumerable) atts |= JS_DONTENUM;
213 if (!configurable) atts |= JS_DONTCONF;
215 if (js_hasproperty(J, -1, "get")) {
216 if (haswritable || hasvalue)
217 js_typeerror(J, "value/writable and get/set attributes are exclusive");
222 if (js_hasproperty(J, -2, "set")) {
223 if (haswritable || hasvalue)
224 js_typeerror(J, "value/writable and get/set attributes are exclusive");
229 js_defaccessor(J, -4, name, atts);
234 static void O_defineProperty(js_State *J)
236 if (!js_isobject(J, 1)) js_typeerror(J, "not an object");
237 if (!js_isobject(J, 3)) js_typeerror(J, "not an object");
238 ToPropertyDescriptor(J, js_toobject(J, 1), js_tostring(J, 2), js_toobject(J, 3));
242 static void O_defineProperties(js_State *J)
247 if (!js_isobject(J, 1)) js_typeerror(J, "not an object");
248 if (!js_isobject(J, 2)) js_typeerror(J, "not an object");
250 props = js_toobject(J, 2);
251 for (ref = props->head; ref; ref = ref->next) {
252 if (!(ref->atts & JS_DONTENUM)) {
253 js_pushvalue(J, ref->value);
254 ToPropertyDescriptor(J, js_toobject(J, 1), ref->name, js_toobject(J, -1));
262 static void O_create(js_State *J)
269 if (js_isobject(J, 1))
270 proto = js_toobject(J, 1);
271 else if (js_isnull(J, 1))
274 js_typeerror(J, "not an object or null");
276 obj = jsV_newobject(J, JS_COBJECT, proto);
277 js_pushobject(J, obj);
279 if (js_isdefined(J, 2)) {
280 if (!js_isobject(J, 2)) js_typeerror(J, "not an object");
281 props = js_toobject(J, 2);
282 for (ref = props->head; ref; ref = ref->next) {
283 if (!(ref->atts & JS_DONTENUM)) {
284 if (ref->value.type != JS_TOBJECT) js_typeerror(J, "not an object");
285 ToPropertyDescriptor(J, obj, ref->name, ref->value.u.object);
291 static void O_keys(js_State *J)
298 if (!js_isobject(J, 1))
299 js_typeerror(J, "not an object");
300 obj = js_toobject(J, 1);
305 for (ref = obj->head; ref; ref = ref->next) {
306 if (!(ref->atts & JS_DONTENUM)) {
307 js_pushliteral(J, ref->name);
308 js_setindex(J, -2, i++);
312 if (obj->type == JS_CSTRING) {
313 for (k = 0; k < obj->u.s.length; ++k) {
315 js_setindex(J, -2, i++);
320 static void O_preventExtensions(js_State *J)
322 if (!js_isobject(J, 1))
323 js_typeerror(J, "not an object");
324 js_toobject(J, 1)->extensible = 0;
328 static void O_isExtensible(js_State *J)
330 if (!js_isobject(J, 1))
331 js_typeerror(J, "not an object");
332 js_pushboolean(J, js_toobject(J, 1)->extensible);
335 static void O_seal(js_State *J)
340 if (!js_isobject(J, 1))
341 js_typeerror(J, "not an object");
343 obj = js_toobject(J, 1);
346 for (ref = obj->head; ref; ref = ref->next)
347 ref->atts |= JS_DONTCONF;
352 static void O_isSealed(js_State *J)
357 if (!js_isobject(J, 1))
358 js_typeerror(J, "not an object");
360 obj = js_toobject(J, 1);
361 if (obj->extensible) {
362 js_pushboolean(J, 0);
366 for (ref = obj->head; ref; ref = ref->next) {
367 if (!(ref->atts & JS_DONTCONF)) {
368 js_pushboolean(J, 0);
373 js_pushboolean(J, 1);
376 static void O_freeze(js_State *J)
381 if (!js_isobject(J, 1))
382 js_typeerror(J, "not an object");
384 obj = js_toobject(J, 1);
387 for (ref = obj->head; ref; ref = ref->next)
388 ref->atts |= JS_READONLY | JS_DONTCONF;
393 static void O_isFrozen(js_State *J)
398 if (!js_isobject(J, 1))
399 js_typeerror(J, "not an object");
401 obj = js_toobject(J, 1);
402 if (obj->extensible) {
403 js_pushboolean(J, 0);
407 for (ref = obj->head; ref; ref = ref->next) {
408 if (!(ref->atts & (JS_READONLY | JS_DONTCONF))) {
409 js_pushboolean(J, 0);
414 js_pushboolean(J, 1);
417 void jsB_initobject(js_State *J)
419 js_pushobject(J, J->Object_prototype);
421 jsB_propf(J, "toString", Op_toString, 0);
422 jsB_propf(J, "toLocaleString", Op_toString, 0);
423 jsB_propf(J, "valueOf", Op_valueOf, 0);
424 jsB_propf(J, "hasOwnProperty", Op_hasOwnProperty, 1);
425 jsB_propf(J, "isPrototypeOf", Op_isPrototypeOf, 1);
426 jsB_propf(J, "propertyIsEnumerable", Op_propertyIsEnumerable, 1);
428 js_newcconstructor(J, jsB_Object, jsB_new_Object, "Object", 1);
431 jsB_propf(J, "getPrototypeOf", O_getPrototypeOf, 1);
432 jsB_propf(J, "getOwnPropertyDescriptor", O_getOwnPropertyDescriptor, 2);
433 jsB_propf(J, "getOwnPropertyNames", O_getOwnPropertyNames, 1);
434 jsB_propf(J, "create", O_create, 2);
435 jsB_propf(J, "defineProperty", O_defineProperty, 3);
436 jsB_propf(J, "defineProperties", O_defineProperties, 2);
437 jsB_propf(J, "seal", O_seal, 1);
438 jsB_propf(J, "freeze", O_freeze, 1);
439 jsB_propf(J, "preventExtensions", O_preventExtensions, 1);
440 jsB_propf(J, "isSealed", O_isSealed, 1);
441 jsB_propf(J, "isFrozen", O_isFrozen, 1);
442 jsB_propf(J, "isExtensible", O_isExtensible, 1);
443 jsB_propf(J, "keys", O_keys, 1);
445 js_defglobal(J, "Object", JS_DONTENUM);