static JSBool js_conio_cprintf(JSContext *cx, uintN argc, jsval *arglist) { JSObject *obj=JS_THIS_OBJECT(cx, arglist); jsval *argv=JS_ARGV(cx, arglist); }
## ===== instance function implementation template bool ${signature_name}(JSContext *cx, uint32_t argc, jsval *vp) { #if len($arguments) > 0 jsval *argv = JS_ARGV(cx, vp); bool ok = true; #end if #if not $is_constructor JSObject *obj = JS_THIS_OBJECT(cx, vp); js_proxy_t *proxy = jsb_get_js_proxy(obj); ${namespaced_class_name}* cobj = (${namespaced_class_name} *)(proxy ? proxy->ptr : NULL); JSB_PRECONDITION2( cobj, cx, false, "${signature_name} : Invalid Native Object"); #end if #if len($arguments) >= $min_args #set arg_count = len($arguments) #set arg_idx = $min_args #while $arg_idx <= $arg_count if (argc == ${arg_idx}) { #set $count = 0 #while $count < $arg_idx #set $arg = $arguments[$count] ${arg.to_string($generator)} arg${count}; #set $count = $count + 1 #end while #set $count = 0 #set arg_list = "" #set arg_array = [] #while $count < $arg_idx #set $arg = $arguments[$count] ${arg.to_native({"generator": $generator, "in_value": "argv[" + str(count) + "]",
/* * 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; }
JSBool Library::Declare(JSContext* cx, uintN argc, jsval* vp) { JSObject* obj = JS_THIS_OBJECT(cx, vp); if (!obj || !IsLibrary(cx, obj)) { JS_ReportError(cx, "not a library"); return JS_FALSE; } PRLibrary* library = GetLibrary(cx, obj); if (!library) { JS_ReportError(cx, "library not open"); return JS_FALSE; } // We allow two API variants: // 1) library.declare(name, abi, returnType, argType1, ...) // declares a function with the given properties, and resolves the symbol // address in the library. // 2) library.declare(name, type) // declares a symbol of 'type', and resolves it. The object that comes // back will be of type 'type', and will point into the symbol data. // This data will be both readable and writable via the usual CData // accessors. If 'type' is a PointerType to a FunctionType, the result will // be a function pointer, as with 1). if (argc < 2) { JS_ReportError(cx, "declare requires at least two arguments"); return JS_FALSE; } jsval* argv = JS_ARGV(cx, vp); if (!JSVAL_IS_STRING(argv[0])) { JS_ReportError(cx, "first argument must be a string"); return JS_FALSE; } JSObject* fnObj = NULL; JSObject* typeObj; js::AutoObjectRooter root(cx); bool isFunction = argc > 2; if (isFunction) { // Case 1). // Create a FunctionType representing the function. fnObj = FunctionType::CreateInternal(cx, argv[1], argv[2], &argv[3], argc - 3); if (!fnObj) return JS_FALSE; root.setObject(fnObj); // Make a function pointer type. typeObj = PointerType::CreateInternal(cx, fnObj); if (!typeObj) return JS_FALSE; root.setObject(typeObj); } else { // Case 2). if (JSVAL_IS_PRIMITIVE(argv[1]) || !CType::IsCType(cx, JSVAL_TO_OBJECT(argv[1])) || !CType::IsSizeDefined(cx, JSVAL_TO_OBJECT(argv[1]))) { JS_ReportError(cx, "second argument must be a type of defined size"); return JS_FALSE; } typeObj = JSVAL_TO_OBJECT(argv[1]); if (CType::GetTypeCode(cx, typeObj) == TYPE_pointer) { fnObj = PointerType::GetBaseType(cx, typeObj); isFunction = fnObj && CType::GetTypeCode(cx, fnObj) == TYPE_function; } } void* data; PRFuncPtr fnptr; JSString* nameStr = JSVAL_TO_STRING(argv[0]); AutoCString symbol; if (isFunction) { // Build the symbol, with mangling if necessary. FunctionType::BuildSymbolName(cx, nameStr, fnObj, symbol); AppendString(symbol, "\0"); // Look up the function symbol. fnptr = PR_FindFunctionSymbol(library, symbol.begin()); if (!fnptr) { JS_ReportError(cx, "couldn't find function symbol in library"); return JS_FALSE; } data = &fnptr; } else { // 'typeObj' is another data type. Look up the data symbol. AppendString(symbol, nameStr); AppendString(symbol, "\0"); data = PR_FindSymbol(library, symbol.begin()); if (!data) { JS_ReportError(cx, "couldn't find symbol in library"); return JS_FALSE; } } JSObject* result = CData::Create(cx, typeObj, obj, data, isFunction); if (!result) return JS_FALSE; JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(result)); // Seal the CData object, to prevent modification of the function pointer. // This permanently associates this object with the library, and avoids // having to do things like reset SLOT_REFERENT when someone tries to // change the pointer value. // XXX This will need to change when bug 541212 is fixed -- CData::ValueSetter // could be called on a sealed object. if (isFunction && !JS_FreezeObject(cx, result)) return JS_FALSE; return JS_TRUE; }
JSBool gjs_console_interact(JSContext *context, unsigned argc, jsval *vp) { JSObject *object = JS_THIS_OBJECT(context, vp); gboolean eof = FALSE; jsval result; JSString *str; GString *buffer = NULL; char *temp_buf = NULL; int lineno; int startline; FILE *file = stdin; JS_SetErrorReporter(context, gjs_console_error_reporter); /* It's an interactive filehandle; drop into read-eval-print loop. */ lineno = 1; do { /* * Accumulate lines until we get a 'compilable unit' - one that either * generates an error (before running out of source) or that compiles * cleanly. This should be whenever we get a complete statement that * coincides with the end of a line. */ startline = lineno; buffer = g_string_new(""); do { if (!gjs_console_readline(context, &temp_buf, file, startline == lineno ? "cjs> " : ".... ")) { eof = JS_TRUE; break; } g_string_append(buffer, temp_buf); g_free(temp_buf); lineno++; } while (!JS_BufferIsCompilableUnit(context, object, buffer->str, buffer->len)); JS::CompileOptions options(context); options.setUTF8(true) .setFileAndLine("typein", startline); js::RootedObject rootedObj(context, object); JS::Evaluate(context, rootedObj, options, buffer->str, buffer->len, &result); gjs_schedule_gc_if_needed(context); if (JS_GetPendingException(context, &result)) { str = JS_ValueToString(context, result); JS_ClearPendingException(context); } else if (JSVAL_IS_VOID(result)) { goto next; } else { str = JS_ValueToString(context, result); } if (str) { char *display_str; display_str = gjs_value_debug_string(context, result); if (display_str != NULL) { g_fprintf(stdout, "%s\n", display_str); g_free(display_str); } } next: g_string_free(buffer, TRUE); } while (!eof); g_fprintf(stdout, "\n"); if (file != stdin) fclose(file); return JS_TRUE; }
JSBool js_cocos2dx_CCBReader_createSceneWithNodeGraphFromFile(JSContext *cx, uint32_t argc, jsval *vp) { jsval *argv = JS_ARGV(cx, vp); JSBool ok = JS_TRUE; JSObject *obj; cocos2d::extension::CCBReader* cobj; obj = JS_THIS_OBJECT(cx, vp); js_proxy_t *proxy = jsb_get_js_proxy(obj); cobj = (cocos2d::extension::CCBReader *)(proxy ? proxy->ptr : NULL); TEST_NATIVE_OBJECT(cx, cobj) if (argc == 2) { const char* arg0; std::string arg0_tmp; ok &= jsval_to_std_string(cx, argv[0], &arg0_tmp); arg0 = arg0_tmp.c_str(); cocos2d::CCObject* arg1; do { js_proxy_t *proxy; JSObject *tmpObj = JSVAL_TO_OBJECT(argv[1]); proxy = jsb_get_js_proxy(tmpObj); arg1 = (cocos2d::CCObject*)(proxy ? proxy->ptr : NULL); TEST_NATIVE_OBJECT(cx, arg1) } while (0); JSB_PRECONDITION2(ok, cx, JS_FALSE, "Error processing arguments"); cocos2d::CCScene* ret = cobj->createSceneWithNodeGraphFromFile(arg0, arg1); jsval jsret; do { if (ret) { js_proxy_t *proxy = js_get_or_create_proxy<cocos2d::CCScene>(cx, ret); jsret = OBJECT_TO_JSVAL(proxy->obj); } else { jsret = JSVAL_NULL; } } while (0); JS_SET_RVAL(cx, vp, jsret); return JS_TRUE; } if (argc == 1) { const char* arg0; std::string arg0_tmp; ok &= jsval_to_std_string(cx, argv[0], &arg0_tmp); arg0 = arg0_tmp.c_str(); JSB_PRECONDITION2(ok, cx, JS_FALSE, "Error processing arguments"); cocos2d::CCScene* ret = cobj->createSceneWithNodeGraphFromFile(arg0); jsval jsret; do { if (ret) { js_proxy_t *proxy = js_get_or_create_proxy<cocos2d::CCScene>(cx, ret); jsret = OBJECT_TO_JSVAL(proxy->obj); } else { jsret = JSVAL_NULL; } } while (0); JS_SET_RVAL(cx, vp, jsret); return JS_TRUE; } if (argc == 3) { const char* arg0; std::string arg0_tmp; ok &= jsval_to_std_string(cx, argv[0], &arg0_tmp); arg0 = arg0_tmp.c_str(); cocos2d::CCObject* arg1; do { js_proxy_t *proxy; JSObject *tmpObj = JSVAL_TO_OBJECT(argv[1]); proxy = jsb_get_js_proxy(tmpObj); arg1 = (cocos2d::CCObject*)(proxy ? proxy->ptr : NULL); TEST_NATIVE_OBJECT(cx, arg1) } while (0); cocos2d::CCSize arg2; ok &= jsval_to_ccsize(cx, argv[2], &arg2); JSB_PRECONDITION2(ok, cx, JS_FALSE, "Error processing arguments"); cocos2d::CCScene* ret = cobj->createSceneWithNodeGraphFromFile(arg0, arg1, arg2); jsval jsret; do { if (ret) { js_proxy_t *proxy = js_get_or_create_proxy<cocos2d::CCScene>(cx, ret); jsret = OBJECT_TO_JSVAL(proxy->obj); } else { jsret = JSVAL_NULL; } } while (0); JS_SET_RVAL(cx, vp, jsret); return JS_TRUE; } return JS_FALSE; }
bool Library::Declare(JSContext* cx, unsigned argc, Value* vp) { CallArgs args = CallArgsFromVp(argc, vp); RootedObject obj(cx, JS_THIS_OBJECT(cx, vp)); if (!obj) return false; if (!IsLibrary(obj)) { JS_ReportError(cx, "not a library"); return false; } PRLibrary* library = GetLibrary(obj); if (!library) { JS_ReportError(cx, "library not open"); return false; } // We allow two API variants: // 1) library.declare(name, abi, returnType, argType1, ...) // declares a function with the given properties, and resolves the symbol // address in the library. // 2) library.declare(name, type) // declares a symbol of 'type', and resolves it. The object that comes // back will be of type 'type', and will point into the symbol data. // This data will be both readable and writable via the usual CData // accessors. If 'type' is a PointerType to a FunctionType, the result will // be a function pointer, as with 1). if (args.length() < 2) { JS_ReportError(cx, "declare requires at least two arguments"); return false; } if (!args[0].isString()) { JS_ReportError(cx, "first argument must be a string"); return false; } RootedObject fnObj(cx, nullptr); RootedObject typeObj(cx); bool isFunction = args.length() > 2; if (isFunction) { // Case 1). // Create a FunctionType representing the function. fnObj = FunctionType::CreateInternal(cx, args[1], args[2], HandleValueArray::subarray(args, 3, args.length() - 3)); if (!fnObj) return false; // Make a function pointer type. typeObj = PointerType::CreateInternal(cx, fnObj); if (!typeObj) return false; } else { // Case 2). if (args[1].isPrimitive() || !CType::IsCType(args[1].toObjectOrNull()) || !CType::IsSizeDefined(args[1].toObjectOrNull())) { JS_ReportError(cx, "second argument must be a type of defined size"); return false; } typeObj = args[1].toObjectOrNull(); if (CType::GetTypeCode(typeObj) == TYPE_pointer) { fnObj = PointerType::GetBaseType(typeObj); isFunction = fnObj && CType::GetTypeCode(fnObj) == TYPE_function; } } void* data; PRFuncPtr fnptr; RootedString nameStr(cx, args[0].toString()); AutoCString symbol; if (isFunction) { // Build the symbol, with mangling if necessary. FunctionType::BuildSymbolName(nameStr, fnObj, symbol); AppendString(symbol, "\0"); // Look up the function symbol. fnptr = PR_FindFunctionSymbol(library, symbol.begin()); if (!fnptr) { JS_ReportError(cx, "couldn't find function symbol in library"); return false; } data = &fnptr; } else { // 'typeObj' is another data type. Look up the data symbol. AppendString(symbol, nameStr); AppendString(symbol, "\0"); data = PR_FindSymbol(library, symbol.begin()); if (!data) { JS_ReportError(cx, "couldn't find symbol in library"); return false; } } RootedObject result(cx, CData::Create(cx, typeObj, obj, data, isFunction)); if (!result) return false; if (isFunction) JS_SetReservedSlot(result, SLOT_FUNNAME, StringValue(nameStr)); args.rval().setObject(*result); // Seal the CData object, to prevent modification of the function pointer. // This permanently associates this object with the library, and avoids // having to do things like reset SLOT_REFERENT when someone tries to // change the pointer value. // XXX This will need to change when bug 541212 is fixed -- CData::ValueSetter // could be called on a sealed object. if (isFunction && !JS_FreezeObject(cx, result)) return false; return true; }
static JSBool CVE_2012_0478_firefox4_0_1_nsIDOMWebGLRenderingContext_TexImage2D(JSContext *cx, uintN argc, jsval *vp) { XPC_QS_ASSERT_CONTEXT_OK(cx); JSObject *obj = JS_THIS_OBJECT(cx, vp); if (!obj) return JS_FALSE; nsresult rv; nsIDOMWebGLRenderingContext *self; xpc_qsSelfRef selfref; js::AutoValueRooter tvr(cx); if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull)) return JS_FALSE; if (argc < 6 || argc == 7 || argc == 8) return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS); jsval *argv = JS_ARGV(cx, vp); // arguments common to all cases GET_UINT32_ARG(argv0, 0); GET_INT32_ARG(argv1, 1); if (argc > 5 && !JSVAL_IS_PRIMITIVE(argv[5])) { // implement the variants taking a DOMElement as argv[5] GET_UINT32_ARG(argv2, 2); GET_UINT32_ARG(argv3, 3); GET_UINT32_ARG(argv4, 4); nsIDOMElement *elt; xpc_qsSelfRef eltRef; rv = xpc_qsUnwrapArg<nsIDOMElement>(cx, argv[5], &elt, &eltRef.ptr, &argv[5]); if (NS_FAILED(rv)) return JS_FALSE; rv = self->TexImage2D_dom(argv0, argv1, argv2, argv3, argv4, elt); if (NS_FAILED(rv)) { // failed to interprete argv[5] as a DOMElement, now try to interprete it as ImageData JSObject *argv5 = JSVAL_TO_OBJECT(argv[5]); jsval js_width, js_height, js_data; JS_GetProperty(cx, argv5, "width", &js_width); JS_GetProperty(cx, argv5, "height", &js_height); JS_GetProperty(cx, argv5, "data", &js_data); if (js_width == JSVAL_VOID || js_height == JSVAL_VOID || js_data == JSVAL_VOID) { xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 5); return JS_FALSE; } int32 int_width, int_height; JSObject *obj_data = JSVAL_TO_OBJECT(js_data); if (!JS_ValueToECMAInt32(cx, js_width, &int_width) || !JS_ValueToECMAInt32(cx, js_height, &int_height)) { return JS_FALSE; } if (!js_IsTypedArray(obj_data)) { xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 5); return JS_FALSE; } rv = self->TexImage2D_imageData(argv0, argv1, argv2, int_width, int_height, 0, argv3, argv4, js::TypedArray::fromJSObject(obj_data)); } } else if (argc > 8 && JSVAL_IS_OBJECT(argv[8])) // here, we allow null ! { // implement the variants taking a buffer/array as argv[8] GET_UINT32_ARG(argv2, 2); GET_INT32_ARG(argv3, 3); GET_INT32_ARG(argv4, 4); GET_INT32_ARG(argv5, 5); GET_UINT32_ARG(argv6, 6); GET_UINT32_ARG(argv7, 7); JSObject *argv8 = JSVAL_TO_OBJECT(argv[8]); // then try to grab either a js::ArrayBuffer, js::TypedArray, or null if (argv8 == nsnull) { rv = self->TexImage2D_buf(argv0, argv1, argv2, argv3, argv4, argv5, argv6, argv7, nsnull); } else if (js_IsArrayBuffer(argv8)) { rv = self->TexImage2D_buf(argv0, argv1, argv2, argv3, argv4, argv5, argv6, argv7, js::ArrayBuffer::fromJSObject(argv8)); } else if (js_IsTypedArray(argv8)) { rv = self->TexImage2D_array(argv0, argv1, argv2, argv3, argv4, argv5, argv6, argv7, js::TypedArray::fromJSObject(argv8)); } else { xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 8); return JS_FALSE; } } else { xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS); return JS_FALSE; } if (NS_FAILED(rv)) return xpc_qsThrowMethodFailed(cx, rv, vp); *vp = JSVAL_VOID; return JS_TRUE; }
static JSBool setDash_func(JSContext *context, unsigned argc, jsval *vp) { jsval *argv = JS_ARGV(context, vp); JSObject *obj = JS_THIS_OBJECT(context, vp); guint i; cairo_t *cr; JSObject *dashes; double offset; JSBool retval = JS_FALSE; guint len; GArray *dashes_c = NULL; if (!gjs_parse_args(context, "setDash", "of", argc, argv, "dashes", &dashes, "offset", &offset)) return JS_FALSE; JS_AddObjectRoot(context, &dashes); if (!JS_IsArrayObject(context, dashes)) { gjs_throw(context, "dashes must be an array"); goto out; } if (!JS_GetArrayLength(context, dashes, &len)) { gjs_throw(context, "Can't get length of dashes"); goto out; } dashes_c = g_array_sized_new (FALSE, FALSE, sizeof(double), len); for (i = 0; i < len; ++i) { jsval elem; double b; elem = JSVAL_VOID; if (!JS_GetElement(context, dashes, i, &elem)) { goto out; } if (JSVAL_IS_VOID(elem)) continue; if (!JS_ValueToNumber(context, elem, &b)) goto out; if (b <= 0) { gjs_throw(context, "Dash value must be positive"); goto out; } g_array_append_val(dashes_c, b); } cr = gjs_cairo_context_get_context(context, obj); cairo_set_dash(cr, (double*)dashes_c->data, dashes_c->len, offset); JS_SET_RVAL(context, vp, JSVAL_VOID); retval = JS_TRUE; out: if (dashes_c != NULL) g_array_free (dashes_c, TRUE); JS_RemoveObjectRoot(context, &dashes); return retval; }
/* * 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_GET_PROPERTY(cx, obj, 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); /* After this, control must flow through label out: to exit. */ JS_PUSH_TEMP_ROOT(cx, 3, localroots, &tvr); 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 = JSSTRING_LENGTH(lineno_as_str); } else { lineno_as_str = NULL; lineno_length = 0; } /* Magic 8, for the characters in ``(new ())''. */ name_length = JSSTRING_LENGTH(name); message_length = JSSTRING_LENGTH(message); length = 8 + name_length + message_length; filename_length = JSSTRING_LENGTH(filename); 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 *) JS_malloc(cx, (length + 1) * sizeof(jschar)); if (!chars) { ok = JS_FALSE; goto out; } *cp++ = '('; *cp++ = 'n'; *cp++ = 'e'; *cp++ = 'w'; *cp++ = ' '; js_strncpy(cp, JSSTRING_CHARS(name), name_length); cp += name_length; *cp++ = '('; if (message_length != 0) { js_strncpy(cp, JSSTRING_CHARS(message), message_length); cp += message_length; } if (filename_length != 0) { /* append filename as ``, {filename}'' */ *cp++ = ','; *cp++ = ' '; js_strncpy(cp, JSSTRING_CHARS(filename), 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, JSSTRING_CHARS(lineno_as_str), lineno_length); cp += lineno_length; } *cp++ = ')'; *cp++ = ')'; *cp = 0; result = js_NewString(cx, chars, length); if (!result) { JS_free(cx, chars); ok = JS_FALSE; goto out; } *vp = STRING_TO_JSVAL(result); ok = JS_TRUE; out: JS_POP_TEMP_ROOT(cx, &tvr); return ok; }