/* * Convert to string. * * This method only uses JavaScript-modifiable properties name, message. It * is left to the host to check for private data and report filename and line * number information along with this message. */ static JSBool exn_toString(JSContext *cx, uintN argc, Value *vp) { jsval v; JSString *name, *message, *result; jschar *chars, *cp; size_t name_length, message_length, length; JSObject *obj = ToObject(cx, &vp[1]); if (!obj) return JS_FALSE; if (!obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), Valueify(&v))) return JS_FALSE; name = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString; vp->setString(name); if (!JS_GetProperty(cx, obj, js_message_str, &v)) return JS_FALSE; message = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString; if (message->length() != 0) { name_length = name->length(); message_length = message->length(); length = (name_length ? name_length + 2 : 0) + message_length; cp = chars = (jschar *) cx->malloc_((length + 1) * sizeof(jschar)); if (!chars) return JS_FALSE; if (name_length) { const jschar *name_chars = name->getChars(cx); if (!name_chars) return JS_FALSE; js_strncpy(cp, name_chars, name_length); cp += name_length; *cp++ = ':'; *cp++ = ' '; } const jschar *message_chars = message->getChars(cx); if (!message_chars) return JS_FALSE; js_strncpy(cp, message_chars, message_length); cp += message_length; *cp = 0; result = js_NewString(cx, chars, length); if (!result) { cx->free_(chars); return JS_FALSE; } } else { result = name; } vp->setString(result); return JS_TRUE; }
static JSBool IteratorNextImpl(JSContext *cx, JSObject *obj, jsval *rval) { JSObject *iterable; jsval state; uintN flags; JSBool foreach, ok; jsid id; JS_ASSERT(obj->getClass() == &js_IteratorClass); iterable = obj->getParent(); JS_ASSERT(iterable); state = obj->getSlot(JSSLOT_ITER_STATE); if (JSVAL_IS_NULL(state)) goto stop; flags = JSVAL_TO_INT(obj->getSlot(JSSLOT_ITER_FLAGS)); JS_ASSERT(!(flags & JSITER_ENUMERATE)); foreach = (flags & JSITER_FOREACH) != 0; ok = #if JS_HAS_XML_SUPPORT (foreach && OBJECT_IS_XML(cx, iterable)) ? js_EnumerateXMLValues(cx, iterable, JSENUMERATE_NEXT, &state, &id, rval) : #endif iterable->enumerate(cx, JSENUMERATE_NEXT, &state, &id); if (!ok) return JS_FALSE; obj->setSlot(JSSLOT_ITER_STATE, state); if (JSVAL_IS_NULL(state)) goto stop; if (foreach) { #if JS_HAS_XML_SUPPORT if (!OBJECT_IS_XML(cx, iterable) && !iterable->getProperty(cx, id, rval)) { return JS_FALSE; } #endif if (!NewKeyValuePair(cx, id, *rval, rval)) return JS_FALSE; } else { *rval = ID_TO_VALUE(id); } return JS_TRUE; stop: JS_ASSERT(obj->getSlot(JSSLOT_ITER_STATE) == JSVAL_NULL); *rval = JSVAL_HOLE; return JS_TRUE; }
static JSBool JA(JSContext *cx, Value *vp, StringifyContext *scx) { JSObject *obj = &vp->toObject(); CycleDetector detect(scx, obj); if (!detect.init(cx)) return JS_FALSE; if (!scx->sb.append('[')) return JS_FALSE; jsuint length; if (!js_GetLengthProperty(cx, obj, &length)) return JS_FALSE; if (length != 0 && !WriteIndent(cx, scx, scx->depth)) return JS_FALSE; AutoValueRooter outputValue(cx); jsid id; jsuint i; for (i = 0; i < length; i++) { id = INT_TO_JSID(i); if (!obj->getProperty(cx, id, outputValue.addr())) return JS_FALSE; if (!Str(cx, id, obj, scx, outputValue.addr())) return JS_FALSE; if (outputValue.value().isUndefined()) { if (!scx->sb.append("null")) return JS_FALSE; } if (i < length - 1) { if (!scx->sb.append(',')) return JS_FALSE; if (!WriteIndent(cx, scx, scx->depth)) return JS_FALSE; } } if (length != 0 && !WriteIndent(cx, scx, scx->depth - 1)) return JS_FALSE; return scx->sb.append(']'); }
/* * Convert to string. * * This method only uses JavaScript-modifiable properties name, message. It * is left to the host to check for private data and report filename and line * number information along with this message. */ static JSBool exn_toString(JSContext *cx, uintN argc, jsval *vp) { JSObject *obj; jsval v; JSString *name, *message, *result; jschar *chars, *cp; size_t name_length, message_length, length; obj = JS_THIS_OBJECT(cx, vp); if (!obj || !obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), &v)) return JS_FALSE; name = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString; *vp = STRING_TO_JSVAL(name); if (!JS_GetProperty(cx, obj, js_message_str, &v)) return JS_FALSE; message = JSVAL_IS_STRING(v) ? JSVAL_TO_STRING(v) : cx->runtime->emptyString; if (message->length() != 0) { name_length = name->length(); message_length = message->length(); length = (name_length ? name_length + 2 : 0) + message_length; cp = chars = (jschar *) cx->malloc((length + 1) * sizeof(jschar)); if (!chars) return JS_FALSE; if (name_length) { js_strncpy(cp, name->chars(), name_length); cp += name_length; *cp++ = ':'; *cp++ = ' '; } js_strncpy(cp, message->chars(), message_length); cp += message_length; *cp = 0; result = js_NewString(cx, chars, length); if (!result) { cx->free(chars); return JS_FALSE; } } else { result = name; } *vp = STRING_TO_JSVAL(result); return JS_TRUE; }
static JSBool JA(JSContext *cx, jsval *vp, StringifyContext *scx) { JSObject *obj = JSVAL_TO_OBJECT(*vp); if (!scx->cb.append('[')) return JS_FALSE; jsuint length; if (!js_GetLengthProperty(cx, obj, &length)) return JS_FALSE; jsval outputValue = JSVAL_NULL; JSAutoTempValueRooter tvr(cx, 1, &outputValue); jsid id; jsuint i; for (i = 0; i < length; i++) { id = INT_TO_JSID(i); if (!obj->getProperty(cx, id, &outputValue)) return JS_FALSE; if (!Str(cx, id, obj, scx, &outputValue)) return JS_FALSE; if (outputValue == JSVAL_VOID) { if (!js_AppendLiteral(scx->cb, "null")) return JS_FALSE; } if (i < length - 1) { if (!scx->cb.append(',')) return JS_FALSE; if (!WriteIndent(cx, scx, scx->depth)) return JS_FALSE; } } if (length != 0 && !WriteIndent(cx, scx, scx->depth - 1)) return JS_FALSE; return scx->cb.append(']'); }
/* * Return a string that may eval to something similar to the original object. */ static JSBool exn_toSource(JSContext *cx, uintN argc, Value *vp) { JSString *name, *message, *filename, *lineno_as_str, *result; jsval localroots[3] = {JSVAL_NULL, JSVAL_NULL, JSVAL_NULL}; size_t lineno_length, name_length, message_length, filename_length, length; jschar *chars, *cp; JSObject *obj = ToObject(cx, &vp[1]); if (!obj) return false; if (!obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), vp)) return false; name = js_ValueToString(cx, *vp); if (!name) return false; vp->setString(name); { AutoArrayRooter tvr(cx, JS_ARRAY_LENGTH(localroots), Valueify(localroots)); #ifdef __GNUC__ message = filename = NULL; #endif if (!JS_GetProperty(cx, obj, js_message_str, &localroots[0]) || !(message = js_ValueToSource(cx, Valueify(localroots[0])))) { return false; } localroots[0] = STRING_TO_JSVAL(message); if (!JS_GetProperty(cx, obj, js_fileName_str, &localroots[1]) || !(filename = js_ValueToSource(cx, Valueify(localroots[1])))) { return false; } localroots[1] = STRING_TO_JSVAL(filename); if (!JS_GetProperty(cx, obj, js_lineNumber_str, &localroots[2])) return false; uint32_t lineno; if (!ValueToECMAUint32(cx, Valueify(localroots[2]), &lineno)) return false; if (lineno != 0) { lineno_as_str = js_ValueToString(cx, Valueify(localroots[2])); if (!lineno_as_str) return false; lineno_length = lineno_as_str->length(); } else { lineno_as_str = NULL; lineno_length = 0; } /* Magic 8, for the characters in ``(new ())''. */ name_length = name->length(); message_length = message->length(); length = 8 + name_length + message_length; filename_length = filename->length(); if (filename_length != 0) { /* append filename as ``, {filename}'' */ length += 2 + filename_length; if (lineno_as_str) { /* append lineno as ``, {lineno_as_str}'' */ length += 2 + lineno_length; } } else { if (lineno_as_str) { /* * no filename, but have line number, * need to append ``, "", {lineno_as_str}'' */ length += 6 + lineno_length; } } cp = chars = (jschar *) cx->malloc_((length + 1) * sizeof(jschar)); if (!chars) return false; *cp++ = '('; *cp++ = 'n'; *cp++ = 'e'; *cp++ = 'w'; *cp++ = ' '; const jschar *name_chars = name->getChars(cx); if (!name_chars) return false; js_strncpy(cp, name_chars, name_length); cp += name_length; *cp++ = '('; const jschar *message_chars = message->getChars(cx); if (!message_chars) return false; if (message_length != 0) { js_strncpy(cp, message_chars, message_length); cp += message_length; } if (filename_length != 0) { /* append filename as ``, {filename}'' */ *cp++ = ','; *cp++ = ' '; const jschar *filename_chars = filename->getChars(cx); if (!filename_chars) return false; js_strncpy(cp, filename_chars, filename_length); cp += filename_length; } else { if (lineno_as_str) { /* * no filename, but have line number, * need to append ``, "", {lineno_as_str}'' */ *cp++ = ','; *cp++ = ' '; *cp++ = '"'; *cp++ = '"'; } } if (lineno_as_str) { /* append lineno as ``, {lineno_as_str}'' */ *cp++ = ','; *cp++ = ' '; const jschar *lineno_chars = lineno_as_str->getChars(cx); if (!lineno_chars) return false; js_strncpy(cp, lineno_chars, lineno_length); cp += lineno_length; } *cp++ = ')'; *cp++ = ')'; *cp = 0; result = js_NewString(cx, chars, length); if (!result) { cx->free_(chars); return false; } vp->setString(result); return true; } }
/* * Return a string that may eval to something similar to the original object. */ static JSBool exn_toSource(JSContext *cx, uintN argc, jsval *vp) { JSObject *obj; JSString *name, *message, *filename, *lineno_as_str, *result; jsval localroots[3] = {JSVAL_NULL, JSVAL_NULL, JSVAL_NULL}; JSTempValueRooter tvr; JSBool ok; uint32 lineno; size_t lineno_length, name_length, message_length, filename_length, length; jschar *chars, *cp; obj = JS_THIS_OBJECT(cx, vp); if (!obj || !obj->getProperty(cx, ATOM_TO_JSID(cx->runtime->atomState.nameAtom), vp)) return JS_FALSE; name = js_ValueToString(cx, *vp); if (!name) return JS_FALSE; *vp = STRING_TO_JSVAL(name); MUST_FLOW_THROUGH("out"); JS_PUSH_TEMP_ROOT(cx, 3, localroots, &tvr); #ifdef __GNUC__ message = filename = NULL; #endif ok = JS_GetProperty(cx, obj, js_message_str, &localroots[0]) && (message = js_ValueToSource(cx, localroots[0])); if (!ok) goto out; localroots[0] = STRING_TO_JSVAL(message); ok = JS_GetProperty(cx, obj, js_fileName_str, &localroots[1]) && (filename = js_ValueToSource(cx, localroots[1])); if (!ok) goto out; localroots[1] = STRING_TO_JSVAL(filename); ok = JS_GetProperty(cx, obj, js_lineNumber_str, &localroots[2]); if (!ok) goto out; lineno = js_ValueToECMAUint32 (cx, &localroots[2]); ok = !JSVAL_IS_NULL(localroots[2]); if (!ok) goto out; if (lineno != 0) { lineno_as_str = js_ValueToString(cx, localroots[2]); if (!lineno_as_str) { ok = JS_FALSE; goto out; } lineno_length = lineno_as_str->length(); } else { lineno_as_str = NULL; lineno_length = 0; } /* Magic 8, for the characters in ``(new ())''. */ name_length = name->length(); message_length = message->length(); length = 8 + name_length + message_length; filename_length = filename->length(); if (filename_length != 0) { /* append filename as ``, {filename}'' */ length += 2 + filename_length; if (lineno_as_str) { /* append lineno as ``, {lineno_as_str}'' */ length += 2 + lineno_length; } } else { if (lineno_as_str) { /* * no filename, but have line number, * need to append ``, "", {lineno_as_str}'' */ length += 6 + lineno_length; } } cp = chars = (jschar *) cx->malloc((length + 1) * sizeof(jschar)); if (!chars) { ok = JS_FALSE; goto out; } *cp++ = '('; *cp++ = 'n'; *cp++ = 'e'; *cp++ = 'w'; *cp++ = ' '; js_strncpy(cp, name->chars(), name_length); cp += name_length; *cp++ = '('; if (message_length != 0) { js_strncpy(cp, message->chars(), message_length); cp += message_length; } if (filename_length != 0) { /* append filename as ``, {filename}'' */ *cp++ = ','; *cp++ = ' '; js_strncpy(cp, filename->chars(), filename_length); cp += filename_length; } else { if (lineno_as_str) { /* * no filename, but have line number, * need to append ``, "", {lineno_as_str}'' */ *cp++ = ','; *cp++ = ' '; *cp++ = '"'; *cp++ = '"'; } } if (lineno_as_str) { /* append lineno as ``, {lineno_as_str}'' */ *cp++ = ','; *cp++ = ' '; js_strncpy(cp, lineno_as_str->chars(), lineno_length); cp += lineno_length; } *cp++ = ')'; *cp++ = ')'; *cp = 0; result = js_NewString(cx, chars, length); if (!result) { cx->free(chars); ok = JS_FALSE; goto out; } *vp = STRING_TO_JSVAL(result); ok = JS_TRUE; out: JS_POP_TEMP_ROOT(cx, &tvr); return ok; }