Mercurial > hgrepos > Python2 > PyMuPDF
diff mupdf-source/thirdparty/mujs/jsobject.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mupdf-source/thirdparty/mujs/jsobject.c Mon Sep 15 11:43:07 2025 +0200 @@ -0,0 +1,560 @@ +#include "jsi.h" + +static void jsB_new_Object(js_State *J) +{ + if (js_isundefined(J, 1) || js_isnull(J, 1)) + js_newobject(J); + else + js_pushobject(J, js_toobject(J, 1)); +} + +static void jsB_Object(js_State *J) +{ + if (js_isundefined(J, 1) || js_isnull(J, 1)) + js_newobject(J); + else + js_pushobject(J, js_toobject(J, 1)); +} + +static void Op_toString(js_State *J) +{ + if (js_isundefined(J, 0)) + js_pushliteral(J, "[object Undefined]"); + else if (js_isnull(J, 0)) + js_pushliteral(J, "[object Null]"); + else { + js_Object *self = js_toobject(J, 0); + switch (self->type) { + case JS_COBJECT: js_pushliteral(J, "[object Object]"); break; + case JS_CARRAY: js_pushliteral(J, "[object Array]"); break; + case JS_CFUNCTION: js_pushliteral(J, "[object Function]"); break; + case JS_CSCRIPT: js_pushliteral(J, "[object Function]"); break; + case JS_CCFUNCTION: js_pushliteral(J, "[object Function]"); break; + case JS_CERROR: js_pushliteral(J, "[object Error]"); break; + case JS_CBOOLEAN: js_pushliteral(J, "[object Boolean]"); break; + case JS_CNUMBER: js_pushliteral(J, "[object Number]"); break; + case JS_CSTRING: js_pushliteral(J, "[object String]"); break; + case JS_CREGEXP: js_pushliteral(J, "[object RegExp]"); break; + case JS_CDATE: js_pushliteral(J, "[object Date]"); break; + case JS_CMATH: js_pushliteral(J, "[object Math]"); break; + case JS_CJSON: js_pushliteral(J, "[object JSON]"); break; + case JS_CARGUMENTS: js_pushliteral(J, "[object Arguments]"); break; + case JS_CITERATOR: js_pushliteral(J, "[object Iterator]"); break; + case JS_CUSERDATA: + js_pushliteral(J, "[object "); + js_pushliteral(J, self->u.user.tag); + js_concat(J); + js_pushliteral(J, "]"); + js_concat(J); + break; + } + } +} + +static void Op_valueOf(js_State *J) +{ + js_copy(J, 0); +} + +static void Op_hasOwnProperty(js_State *J) +{ + js_Object *self = js_toobject(J, 0); + const char *name = js_tostring(J, 1); + js_Property *ref; + int k; + + if (self->type == JS_CSTRING) { + if (js_isarrayindex(J, name, &k) && k >= 0 && k < self->u.s.length) { + js_pushboolean(J, 1); + return; + } + } + + if (self->type == JS_CARRAY && self->u.a.simple) { + if (js_isarrayindex(J, name, &k) && k >= 0 && k < self->u.a.flat_length) { + js_pushboolean(J, 1); + return; + } + } + + ref = jsV_getownproperty(J, self, name); + js_pushboolean(J, ref != NULL); +} + +static void Op_isPrototypeOf(js_State *J) +{ + js_Object *self = js_toobject(J, 0); + if (js_isobject(J, 1)) { + js_Object *V = js_toobject(J, 1); + do { + V = V->prototype; + if (V == self) { + js_pushboolean(J, 1); + return; + } + } while (V); + } + js_pushboolean(J, 0); +} + +static void Op_propertyIsEnumerable(js_State *J) +{ + js_Object *self = js_toobject(J, 0); + const char *name = js_tostring(J, 1); + js_Property *ref = jsV_getownproperty(J, self, name); + js_pushboolean(J, ref && !(ref->atts & JS_DONTENUM)); +} + +static void O_getPrototypeOf(js_State *J) +{ + js_Object *obj; + if (!js_isobject(J, 1)) + js_typeerror(J, "not an object"); + obj = js_toobject(J, 1); + if (obj->prototype) + js_pushobject(J, obj->prototype); + else + js_pushnull(J); +} + +static void O_getOwnPropertyDescriptor(js_State *J) +{ + js_Object *obj; + js_Property *ref; + if (!js_isobject(J, 1)) + js_typeerror(J, "not an object"); + obj = js_toobject(J, 1); + ref = jsV_getproperty(J, obj, js_tostring(J, 2)); + if (!ref) { + // TODO: builtin properties (string and array index and length, regexp flags, etc) + js_pushundefined(J); + } else { + js_newobject(J); + if (!ref->getter && !ref->setter) { + js_pushvalue(J, ref->value); + js_defproperty(J, -2, "value", 0); + js_pushboolean(J, !(ref->atts & JS_READONLY)); + js_defproperty(J, -2, "writable", 0); + } else { + if (ref->getter) + js_pushobject(J, ref->getter); + else + js_pushundefined(J); + js_defproperty(J, -2, "get", 0); + if (ref->setter) + js_pushobject(J, ref->setter); + else + js_pushundefined(J); + js_defproperty(J, -2, "set", 0); + } + js_pushboolean(J, !(ref->atts & JS_DONTENUM)); + js_defproperty(J, -2, "enumerable", 0); + js_pushboolean(J, !(ref->atts & JS_DONTCONF)); + js_defproperty(J, -2, "configurable", 0); + } +} + +static int O_getOwnPropertyNames_walk(js_State *J, js_Property *ref, int i) +{ + if (ref->left->level) + i = O_getOwnPropertyNames_walk(J, ref->left, i); + js_pushstring(J, ref->name); + js_setindex(J, -2, i++); + if (ref->right->level) + i = O_getOwnPropertyNames_walk(J, ref->right, i); + return i; +} + +static void O_getOwnPropertyNames(js_State *J) +{ + js_Object *obj; + char name[32]; + int k; + int i; + + if (!js_isobject(J, 1)) + js_typeerror(J, "not an object"); + obj = js_toobject(J, 1); + + js_newarray(J); + + if (obj->properties->level) + i = O_getOwnPropertyNames_walk(J, obj->properties, 0); + else + i = 0; + + if (obj->type == JS_CARRAY) { + js_pushliteral(J, "length"); + js_setindex(J, -2, i++); + if (obj->u.a.simple) { + for (k = 0; k < obj->u.a.flat_length; ++k) { + js_itoa(name, k); + js_pushstring(J, name); + js_setindex(J, -2, i++); + } + } + } + + if (obj->type == JS_CSTRING) { + js_pushliteral(J, "length"); + js_setindex(J, -2, i++); + for (k = 0; k < obj->u.s.length; ++k) { + js_itoa(name, k); + js_pushstring(J, name); + js_setindex(J, -2, i++); + } + } + + if (obj->type == JS_CREGEXP) { + js_pushliteral(J, "source"); + js_setindex(J, -2, i++); + js_pushliteral(J, "global"); + js_setindex(J, -2, i++); + js_pushliteral(J, "ignoreCase"); + js_setindex(J, -2, i++); + js_pushliteral(J, "multiline"); + js_setindex(J, -2, i++); + js_pushliteral(J, "lastIndex"); + js_setindex(J, -2, i++); + } +} + +static void ToPropertyDescriptor(js_State *J, js_Object *obj, const char *name, js_Object *desc) +{ + int haswritable = 0; + int hasvalue = 0; + int enumerable = 0; + int configurable = 0; + int writable = 0; + int atts = 0; + + js_pushobject(J, obj); + js_pushobject(J, desc); + + if (js_hasproperty(J, -1, "writable")) { + haswritable = 1; + writable = js_toboolean(J, -1); + js_pop(J, 1); + } + if (js_hasproperty(J, -1, "enumerable")) { + enumerable = js_toboolean(J, -1); + js_pop(J, 1); + } + if (js_hasproperty(J, -1, "configurable")) { + configurable = js_toboolean(J, -1); + js_pop(J, 1); + } + if (js_hasproperty(J, -1, "value")) { + hasvalue = 1; + js_defproperty(J, -3, name, 0); + } + + if (!writable) atts |= JS_READONLY; + if (!enumerable) atts |= JS_DONTENUM; + if (!configurable) atts |= JS_DONTCONF; + + if (js_hasproperty(J, -1, "get")) { + if (haswritable || hasvalue) + js_typeerror(J, "value/writable and get/set attributes are exclusive"); + } else { + js_pushundefined(J); + } + + if (js_hasproperty(J, -2, "set")) { + if (haswritable || hasvalue) + js_typeerror(J, "value/writable and get/set attributes are exclusive"); + } else { + js_pushundefined(J); + } + + js_defaccessor(J, -4, name, atts); + + js_pop(J, 2); +} + +static void O_defineProperty(js_State *J) +{ + if (!js_isobject(J, 1)) js_typeerror(J, "not an object"); + if (!js_isobject(J, 3)) js_typeerror(J, "not an object"); + ToPropertyDescriptor(J, js_toobject(J, 1), js_tostring(J, 2), js_toobject(J, 3)); + js_copy(J, 1); +} + +static void O_defineProperties_walk(js_State *J, js_Property *ref) +{ + if (ref->left->level) + O_defineProperties_walk(J, ref->left); + if (!(ref->atts & JS_DONTENUM)) { + js_pushvalue(J, ref->value); + ToPropertyDescriptor(J, js_toobject(J, 1), ref->name, js_toobject(J, -1)); + js_pop(J, 1); + } + if (ref->right->level) + O_defineProperties_walk(J, ref->right); +} + +static void O_defineProperties(js_State *J) +{ + js_Object *props; + + if (!js_isobject(J, 1)) js_typeerror(J, "not an object"); + if (!js_isobject(J, 2)) js_typeerror(J, "not an object"); + + props = js_toobject(J, 2); + if (props->properties->level) + O_defineProperties_walk(J, props->properties); + + js_copy(J, 1); +} + +static void O_create_walk(js_State *J, js_Object *obj, js_Property *ref) +{ + if (ref->left->level) + O_create_walk(J, obj, ref->left); + if (!(ref->atts & JS_DONTENUM)) { + if (ref->value.t.type != JS_TOBJECT) + js_typeerror(J, "not an object"); + ToPropertyDescriptor(J, obj, ref->name, ref->value.u.object); + } + if (ref->right->level) + O_create_walk(J, obj, ref->right); +} + +static void O_create(js_State *J) +{ + js_Object *obj; + js_Object *proto; + js_Object *props; + + if (js_isobject(J, 1)) + proto = js_toobject(J, 1); + else if (js_isnull(J, 1)) + proto = NULL; + else + js_typeerror(J, "not an object or null"); + + obj = jsV_newobject(J, JS_COBJECT, proto); + js_pushobject(J, obj); + + if (js_isdefined(J, 2)) { + if (!js_isobject(J, 2)) + js_typeerror(J, "not an object"); + props = js_toobject(J, 2); + if (props->properties->level) + O_create_walk(J, obj, props->properties); + } +} + +static int O_keys_walk(js_State *J, js_Property *ref, int i) +{ + if (ref->left->level) + i = O_keys_walk(J, ref->left, i); + if (!(ref->atts & JS_DONTENUM)) { + js_pushstring(J, ref->name); + js_setindex(J, -2, i++); + } + if (ref->right->level) + i = O_keys_walk(J, ref->right, i); + return i; +} + +static void O_keys(js_State *J) +{ + js_Object *obj; + char name[32]; + int i, k; + + if (!js_isobject(J, 1)) + js_typeerror(J, "not an object"); + obj = js_toobject(J, 1); + + js_newarray(J); + + if (obj->properties->level) + i = O_keys_walk(J, obj->properties, 0); + else + i = 0; + + if (obj->type == JS_CSTRING) { + for (k = 0; k < obj->u.s.length; ++k) { + js_itoa(name, k); + js_pushstring(J, name); + js_setindex(J, -2, i++); + } + } + + if (obj->type == JS_CARRAY && obj->u.a.simple) { + for (k = 0; k < obj->u.a.flat_length; ++k) { + js_itoa(name, k); + js_pushstring(J, name); + js_setindex(J, -2, i++); + } + } +} + +static void O_preventExtensions(js_State *J) +{ + js_Object *obj; + if (!js_isobject(J, 1)) + js_typeerror(J, "not an object"); + obj = js_toobject(J, 1); + jsR_unflattenarray(J, obj); + obj->extensible = 0; + js_copy(J, 1); +} + +static void O_isExtensible(js_State *J) +{ + if (!js_isobject(J, 1)) + js_typeerror(J, "not an object"); + js_pushboolean(J, js_toobject(J, 1)->extensible); +} + +static void O_seal_walk(js_State *J, js_Property *ref) +{ + if (ref->left->level) + O_seal_walk(J, ref->left); + ref->atts |= JS_DONTCONF; + if (ref->right->level) + O_seal_walk(J, ref->right); +} + +static void O_seal(js_State *J) +{ + js_Object *obj; + + if (!js_isobject(J, 1)) + js_typeerror(J, "not an object"); + + obj = js_toobject(J, 1); + jsR_unflattenarray(J, obj); + obj->extensible = 0; + + if (obj->properties->level) + O_seal_walk(J, obj->properties); + + js_copy(J, 1); +} + +static int O_isSealed_walk(js_State *J, js_Property *ref) +{ + if (ref->left->level) + if (!O_isSealed_walk(J, ref->left)) + return 0; + if (!(ref->atts & JS_DONTCONF)) + return 0; + if (ref->right->level) + if (!O_isSealed_walk(J, ref->right)) + return 0; + return 1; +} + +static void O_isSealed(js_State *J) +{ + js_Object *obj; + + if (!js_isobject(J, 1)) + js_typeerror(J, "not an object"); + + obj = js_toobject(J, 1); + if (obj->extensible) { + js_pushboolean(J, 0); + return; + } + + if (obj->properties->level) + js_pushboolean(J, O_isSealed_walk(J, obj->properties)); + else + js_pushboolean(J, 1); +} + +static void O_freeze_walk(js_State *J, js_Property *ref) +{ + if (ref->left->level) + O_freeze_walk(J, ref->left); + ref->atts |= JS_READONLY | JS_DONTCONF; + if (ref->right->level) + O_freeze_walk(J, ref->right); +} + +static void O_freeze(js_State *J) +{ + js_Object *obj; + + if (!js_isobject(J, 1)) + js_typeerror(J, "not an object"); + + obj = js_toobject(J, 1); + jsR_unflattenarray(J, obj); + obj->extensible = 0; + + if (obj->properties->level) + O_freeze_walk(J, obj->properties); + + js_copy(J, 1); +} + +static int O_isFrozen_walk(js_State *J, js_Property *ref) +{ + if (ref->left->level) + if (!O_isFrozen_walk(J, ref->left)) + return 0; + if (!(ref->atts & JS_READONLY)) + return 0; + if (!(ref->atts & JS_DONTCONF)) + return 0; + if (ref->right->level) + if (!O_isFrozen_walk(J, ref->right)) + return 0; + return 1; +} + +static void O_isFrozen(js_State *J) +{ + js_Object *obj; + + if (!js_isobject(J, 1)) + js_typeerror(J, "not an object"); + + obj = js_toobject(J, 1); + + if (obj->properties->level) { + if (!O_isFrozen_walk(J, obj->properties)) { + js_pushboolean(J, 0); + return; + } + } + + js_pushboolean(J, !obj->extensible); +} + +void jsB_initobject(js_State *J) +{ + js_pushobject(J, J->Object_prototype); + { + jsB_propf(J, "Object.prototype.toString", Op_toString, 0); + jsB_propf(J, "Object.prototype.toLocaleString", Op_toString, 0); + jsB_propf(J, "Object.prototype.valueOf", Op_valueOf, 0); + jsB_propf(J, "Object.prototype.hasOwnProperty", Op_hasOwnProperty, 1); + jsB_propf(J, "Object.prototype.isPrototypeOf", Op_isPrototypeOf, 1); + jsB_propf(J, "Object.prototype.propertyIsEnumerable", Op_propertyIsEnumerable, 1); + } + js_newcconstructor(J, jsB_Object, jsB_new_Object, "Object", 1); + { + /* ES5 */ + jsB_propf(J, "Object.getPrototypeOf", O_getPrototypeOf, 1); + jsB_propf(J, "Object.getOwnPropertyDescriptor", O_getOwnPropertyDescriptor, 2); + jsB_propf(J, "Object.getOwnPropertyNames", O_getOwnPropertyNames, 1); + jsB_propf(J, "Object.create", O_create, 2); + jsB_propf(J, "Object.defineProperty", O_defineProperty, 3); + jsB_propf(J, "Object.defineProperties", O_defineProperties, 2); + jsB_propf(J, "Object.seal", O_seal, 1); + jsB_propf(J, "Object.freeze", O_freeze, 1); + jsB_propf(J, "Object.preventExtensions", O_preventExtensions, 1); + jsB_propf(J, "Object.isSealed", O_isSealed, 1); + jsB_propf(J, "Object.isFrozen", O_isFrozen, 1); + jsB_propf(J, "Object.isExtensible", O_isExtensible, 1); + jsB_propf(J, "Object.keys", O_keys, 1); + } + js_defglobal(J, "Object", JS_DONTENUM); +}
