Fix for bug 510673 (Add a quickstub for document.write). r/sr=jst.

--HG--
extra : rebase_source : 10b08ef2c45a0db19122851cd105a7580e499d0a
This commit is contained in:
Peter Van der Beken 2009-08-14 19:55:43 +02:00
parent 796e8d2758
commit 3fbf50e20c
8 changed files with 73 additions and 128 deletions

View File

@ -2194,77 +2194,6 @@ nsHTMLDocument::Writeln(const nsAString& aText)
return WriteCommon(aText, PR_TRUE);
}
nsresult
nsHTMLDocument::ScriptWriteCommon(PRBool aNewlineTerminate)
{
nsAXPCNativeCallContext *ncc = nsnull;
nsresult rv = nsContentUtils::XPConnect()->
GetCurrentNativeCallContext(&ncc);
NS_ENSURE_SUCCESS(rv, rv);
if (ncc) {
// We're called from JS, concatenate the extra arguments into
// string_buffer
PRUint32 i, argc;
ncc->GetArgc(&argc);
JSContext *cx = nsnull;
rv = ncc->GetJSContext(&cx);
NS_ENSURE_SUCCESS(rv, rv);
jsval *argv = nsnull;
ncc->GetArgvPtr(&argv);
NS_ENSURE_TRUE(argv, NS_ERROR_UNEXPECTED);
if (argc == 1) {
JSAutoRequest ar(cx);
JSString *jsstr = JS_ValueToString(cx, argv[0]);
NS_ENSURE_TRUE(jsstr, NS_ERROR_OUT_OF_MEMORY);
nsDependentString str(reinterpret_cast<const PRUnichar *>
(::JS_GetStringChars(jsstr)),
::JS_GetStringLength(jsstr));
return WriteCommon(str, aNewlineTerminate);
}
if (argc > 1) {
nsAutoString string_buffer;
for (i = 0; i < argc; ++i) {
JSAutoRequest ar(cx);
JSString *str = JS_ValueToString(cx, argv[i]);
NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY);
string_buffer.Append(reinterpret_cast<const PRUnichar *>
(::JS_GetStringChars(str)),
::JS_GetStringLength(str));
}
return WriteCommon(string_buffer, aNewlineTerminate);
}
}
// No arguments...
return WriteCommon(EmptyString(), aNewlineTerminate);
}
NS_IMETHODIMP
nsHTMLDocument::Write()
{
return ScriptWriteCommon(PR_FALSE);
}
NS_IMETHODIMP
nsHTMLDocument::Writeln()
{
return ScriptWriteCommon(PR_TRUE);
}
NS_IMETHODIMP
nsHTMLDocument::ImportNode(nsIDOMNode* aImportedNode,
PRBool aDeep,

View File

@ -246,7 +246,6 @@ protected:
nsresult WriteCommon(const nsAString& aText,
PRBool aNewlineTerminate);
nsresult ScriptWriteCommon(PRBool aNewlineTerminate);
nsresult OpenCommon(const nsACString& aContentType, PRBool aReplace);
nsresult CreateAndAddWyciwygChannel(void);

View File

@ -73,12 +73,8 @@ interface nsIDOMHTMLDocument : nsIDOMDocument
[noscript] void open();
void close();
// The methods write() and writeln() must be callable from JS with
// no arguments for backwards compatibility, thus they are marked
// [noscript] here. The JS versions of these methods are defined in
// nsIDOMNSHTMLDocument.
[noscript] void write(in DOMString text);
[noscript] void writeln(in DOMString text);
void write([optional] in DOMString text);
void writeln([optional] in DOMString text);
nsIDOMNodeList getElementsByName(in DOMString elementName);
};

View File

@ -39,7 +39,7 @@
#include "domstubs.idl"
[scriptable, uuid(79beb289-3644-4b54-9432-9fb993945629)]
[scriptable, uuid(43ac2f64-8a1e-488a-9468-01a2155caf63)]
interface nsIDOMNSHTMLDocument : nsISupports
{
readonly attribute long width;
@ -65,9 +65,7 @@ interface nsIDOMNSHTMLDocument : nsISupports
nsIDOMDocument open(in ACString aContentType,
in boolean aReplace);
// Scriptable versions of write(), writeln(), clear().
void write();
void writeln();
// Scriptable version of clear().
void clear();
/**

View File

@ -332,6 +332,8 @@ members = [
'nsIDOMHTMLDocument.forms',
'nsIDOMHTMLDocument.cookie',
'nsIDOMHTMLDocument.images',
'nsIDOMHTMLDocument.write',
'nsIDOMHTMLDocument.writeln',
'nsIDOMHTMLElement.className',
'nsIDOMHTMLElement.id',
'nsIDOMHTMLElement.title',
@ -428,8 +430,6 @@ members = [
'nsIDOMNSHTMLDocument.domain',
'nsIDOMNSHTMLDocument.getSelection',
'nsIDOMNSHTMLDocument.designMode',
#'nsIDOMNSHTMLDocument.write', # uses GetCurrentNativeCallContext
#'nsIDOMNSHTMLDocument.writeln', # uses GetCurrentNativeCallContext
'nsIDOMNSHTMLElement.contentEditable',
'nsIDOMNSHTMLElement.offsetParent',
'nsIDOMNSHTMLElement.innerHTML',
@ -529,8 +529,20 @@ customIncludes = [
nsIDOMNode_GetChildNodes_customMethodCallCode = """
nsIDOMNodeList* result = self->GetChildNodesList();
if (!result)
return xpc_qsThrowGetterSetterFailed(cx, NS_ERROR_OUT_OF_MEMORY, JSVAL_TO_OBJECT(*vp), id);
rv = result ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
"""
nsIDOMHTMLDocument_Write_customMethodCallCode = """
nsAString &str = arg0;
for (uintN i = 1; i < argc; ++i) {
xpc_qsDOMString next_arg(cx, argv[i], &argv[i]);
if (!next_arg.IsValid())
return JS_FALSE;
str.Append(next_arg);
}
rv = self->%s(arg0);
"""
customMethodCalls = {
@ -544,7 +556,8 @@ customMethodCalls = {
},
'nsIDOMNode_GetChildNodes': {
'thisType': 'nsINode',
'code': nsIDOMNode_GetChildNodes_customMethodCallCode
'code': nsIDOMNode_GetChildNodes_customMethodCallCode,
'canFail': True
},
'nsIDOMNode_GetPreviousSibling': {
'thisType': 'nsINode',
@ -565,5 +578,13 @@ customMethodCalls = {
'nsIDOMNodeList_Item': {
'thisType': 'nsINodeList',
'code': ' nsINode* result = self->GetNodeAt(arg0);'
},
'nsIDOMHTMLDocument_Write': {
'code': nsIDOMHTMLDocument_Write_customMethodCallCode % 'Write',
'canFail': True
},
'nsIDOMHTMLDocument_Writeln': {
'code': nsIDOMHTMLDocument_Write_customMethodCallCode % 'Writeln',
'canFail': True
}
}

View File

@ -221,14 +221,21 @@ def addStubMember(memberId, member, traceable):
% (member.kind.capitalize(), memberId,
attrname))
if member.kind == 'method':
if len(member.params) <= 3:
mayTrace = True
for param in member.params:
for attrname, value in vars(param).items():
if value is True and attrname not in ('optional',):
if value is True:
# Let the tracer call the regular fastnative method if there
# are optional arguments.
if attrname == 'optional':
mayTrace = False
continue
raise UserError("Method %s, parameter %s: "
"unrecognized property %r"
% (memberId, param.name, attrname))
if len(member.params) <= 3:
mayTrace = True
member.traceable = traceable and mayTrace
@ -387,27 +394,27 @@ argumentUnboxingTemplates = {
" JS_ValueToBoolean(cx, ${argVal}, &${name});\n",
'[astring]':
" xpc_qsAString ${name}(cx, ${argPtr});\n"
" xpc_qsAString ${name}(cx, ${argVal}, ${argPtr});\n"
" if (!${name}.IsValid())\n"
" return JS_FALSE;\n",
'[domstring]':
" xpc_qsDOMString ${name}(cx, ${argPtr});\n"
" xpc_qsDOMString ${name}(cx, ${argVal}, ${argPtr});\n"
" if (!${name}.IsValid())\n"
" return JS_FALSE;\n",
'string':
" char *${name};\n"
" if (!xpc_qsJsvalToCharStr(cx, ${argPtr}, &${name}))\n"
" if (!xpc_qsJsvalToCharStr(cx, ${argVal}, ${argPtr}, &${name}))\n"
" return JS_FALSE;\n",
'wstring':
" PRUnichar *${name};\n"
" if (!xpc_qsJsvalToWcharStr(cx, ${argPtr}, &${name}))\n"
" if (!xpc_qsJsvalToWcharStr(cx, ${argVal}, ${argPtr}, &${name}))\n"
" return JS_FALSE;\n",
'[cstring]':
" xpc_qsACString ${name}(cx, ${argPtr});\n"
" xpc_qsACString ${name}(cx, ${argVal}, ${argPtr});\n"
" if (!${name}.IsValid())\n"
" return JS_FALSE;\n"
}
@ -434,8 +441,8 @@ def writeArgumentUnboxing(f, i, name, type, haveCcx, optional, rvdeclared):
argPtr = "vp"
argVal = "*vp"
elif optional:
argPtr = '! /* TODO - optional parameter of this type not supported */'
argVal = "(%d < argc ? argv[%d] : JSVAL_NULL)" % (i, i)
argPtr = "(%d < argc ? &argv[%d] : NULL)" % (i, i)
else:
argVal = "argv[%d]" % i
argPtr = "&" + argVal
@ -450,9 +457,6 @@ def writeArgumentUnboxing(f, i, name, type, haveCcx, optional, rvdeclared):
if typeName is not None:
template = argumentUnboxingTemplates.get(typeName)
if template is not None:
if optional and ("${argPtr}" in template):
warn("Optional parameters of type %s are not supported."
% type.name)
f.write(substitute(template, params))
return rvdeclared
# else fall through; the type isn't supported yet.
@ -740,6 +744,11 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
haveCcx=False, optional=False,
rvdeclared=rvdeclared)
canFail = customMethodCall is None or customMethodCall.get('canFail', False)
if canFail and not rvdeclared:
f.write(" nsresult rv;\n")
rvdeclared = True
if customMethodCall is not None:
f.write("%s\n" % customMethodCall['code'])
f.write("#ifdef DEBUG\n")
@ -748,9 +757,6 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
% member.iface.name);
prefix = 'debug_'
else:
if not rvdeclared:
f.write(" nsresult rv;\n")
rvdeclared = True
prefix = ''
resultname = prefix + 'result'
@ -777,7 +783,18 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
f.write(" %s = %s->%s(%s);\n" % (nsresultname, selfname, comName, args))
if customMethodCall is None:
if customMethodCall is not None:
if isMethod or isGetter:
checkSuccess = "NS_SUCCEEDED(debug_rv)"
if canFail:
checkSuccess += " == NS_SUCCEEDED(rv)"
f.write(" NS_ASSERTION(%s && "
"xpc_qsSameResult(debug_result, result),\n"
" \"Got the wrong answer from the custom "
"method call!\");\n" % checkSuccess)
f.write("#endif\n")
if canFail:
# Check for errors.
f.write(" if (NS_FAILED(rv))\n")
if isMethod:
@ -794,13 +811,6 @@ def writeQuickStub(f, customMethodCalls, member, stubName, isSetter=False):
thisval = '*tvr.addr()'
f.write(" return xpc_qsThrowGetterSetterFailed(cx, rv, " +
"JSVAL_TO_OBJECT(%s), id);\n" % thisval)
else:
if isMethod or isGetter:
f.write(" NS_ASSERTION(NS_SUCCEEDED(debug_rv) && "
"xpc_qsSameResult(debug_result, result),\n"
" \"Got the wrong answer from the custom "
"method call!\");\n")
f.write("#endif\n")
# Convert the return value.
if isMethod or isGetter:

View File

@ -679,16 +679,14 @@ xpc_qsThrowBadSetterValue(JSContext *cx, nsresult rv,
ThrowBadArg(cx, rv, ifaceName, memberName, 0);
}
xpc_qsDOMString::xpc_qsDOMString(JSContext *cx, jsval *pval)
xpc_qsDOMString::xpc_qsDOMString(JSContext *cx, jsval v, jsval *pval)
{
// From the T_DOMSTRING case in XPCConvert::JSData2Native.
typedef implementation_type::char_traits traits;
jsval v;
JSString *s;
const PRUnichar *chars;
size_t len;
v = *pval;
if(JSVAL_IS_STRING(v))
{
s = JSVAL_TO_STRING(v);
@ -718,16 +716,14 @@ xpc_qsDOMString::xpc_qsDOMString(JSContext *cx, jsval *pval)
mValid = JS_TRUE;
}
xpc_qsAString::xpc_qsAString(JSContext *cx, jsval *pval)
xpc_qsAString::xpc_qsAString(JSContext *cx, jsval v, jsval *pval)
{
// From the T_ASTRING case in XPCConvert::JSData2Native.
typedef implementation_type::char_traits traits;
jsval v;
JSString *s;
const PRUnichar *chars;
size_t len;
v = *pval;
if(JSVAL_IS_STRING(v))
{
s = JSVAL_TO_STRING(v);
@ -757,13 +753,11 @@ xpc_qsAString::xpc_qsAString(JSContext *cx, jsval *pval)
mValid = JS_TRUE;
}
xpc_qsACString::xpc_qsACString(JSContext *cx, jsval *pval)
xpc_qsACString::xpc_qsACString(JSContext *cx, jsval v, jsval *pval)
{
// From the T_CSTRING case in XPCConvert::JSData2Native.
jsval v;
JSString *s;
v = *pval;
if(JSVAL_IS_STRING(v))
{
s = JSVAL_TO_STRING(v);
@ -1004,9 +998,8 @@ xpc_qsUnwrapArgImpl(JSContext *cx,
}
JSBool
xpc_qsJsvalToCharStr(JSContext *cx, jsval *pval, char **pstr)
xpc_qsJsvalToCharStr(JSContext *cx, jsval v, jsval *pval, char **pstr)
{
jsval v = *pval;
JSString *str;
if(JSVAL_IS_STRING(v))
@ -1030,9 +1023,8 @@ xpc_qsJsvalToCharStr(JSContext *cx, jsval *pval, char **pstr)
}
JSBool
xpc_qsJsvalToWcharStr(JSContext *cx, jsval *pval, PRUnichar **pstr)
xpc_qsJsvalToWcharStr(JSContext *cx, jsval v, jsval *pval, PRUnichar **pstr)
{
jsval v = *pval;
JSString *str;
if(JSVAL_IS_STRING(v))

View File

@ -257,7 +257,7 @@ protected:
class xpc_qsDOMString : public xpc_qsBasicString<nsAString, nsDependentString>
{
public:
xpc_qsDOMString(JSContext *cx, jsval *pval);
xpc_qsDOMString(JSContext *cx, jsval v, jsval *pval);
};
/**
@ -267,7 +267,7 @@ public:
class xpc_qsAString : public xpc_qsBasicString<nsAString, nsDependentString>
{
public:
xpc_qsAString(JSContext *cx, jsval *pval);
xpc_qsAString(JSContext *cx, jsval v, jsval *pval);
};
/**
@ -277,7 +277,7 @@ public:
class xpc_qsACString : public xpc_qsBasicString<nsACString, nsCString>
{
public:
xpc_qsACString(JSContext *cx, jsval *pval);
xpc_qsACString(JSContext *cx, jsval v, jsval *pval);
};
struct xpc_qsSelfRef
@ -314,10 +314,10 @@ struct xpc_qsArgValArray
* null or undefined. Unicode data is garbled as with JS_GetStringBytes.
*/
JSBool
xpc_qsJsvalToCharStr(JSContext *cx, jsval *pval, char **pstr);
xpc_qsJsvalToCharStr(JSContext *cx, jsval v, jsval *pval, char **pstr);
JSBool
xpc_qsJsvalToWcharStr(JSContext *cx, jsval *pval, PRUnichar **pstr);
xpc_qsJsvalToWcharStr(JSContext *cx, jsval v, jsval *pval, PRUnichar **pstr);
/** Convert an nsAString to jsval, returning JS_TRUE on success. */