Advertisement
Guest User

Untitled

a guest
Sep 5th, 2018
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.30 KB | None | 0 0
  1. --- jsfriendapi.cpp
  2. +++ jsfriendapi.cpp
  3. @@ -803,72 +804,44 @@ JS_FRIEND_API(bool)
  4. js::DumpScript(JSContext* cx, JSScript* scriptArg)
  5. {
  6. return DumpScript(cx, scriptArg, stdout);
  7. }
  8.  
  9. #endif
  10.  
  11. static const char*
  12. -FormatValue(JSContext* cx, const Value& vArg, UniqueChars& bytes)
  13. +FormatValue(JSContext* cx, HandleValue v, UniqueChars& bytes)
  14. {
  15. - RootedValue v(cx, vArg);
  16. -
  17. if (v.isMagic(JS_OPTIMIZED_OUT))
  18. return "[unavailable]";
  19.  
  20. - /*
  21. - * We could use Maybe<AutoRealm> here, but G++ can't quite follow
  22. - * that, and warns about uninitialized members being used in the
  23. - * destructor.
  24. - */
  25. - RootedString str(cx);
  26. - if (v.isObject()) {
  27. - if (IsCrossCompartmentWrapper(&v.toObject()))
  28. - return "[cross-compartment wrapper]";
  29. - AutoRealm ar(cx, &v.toObject());
  30. + if (IsCallable(v))
  31. + return "[function]";
  32. +
  33. + if (v.isObject() && IsCrossCompartmentWrapper(&v.toObject()))
  34. + return "[cross-compartment wrapper]";
  35. +
  36. + JSString* str;
  37. + {
  38. + mozilla::Maybe<AutoRealm> ar;
  39. + if (v.isObject())
  40. + ar.emplace(cx, &v.toObject());
  41. +
  42. str = ToString<CanGC>(cx, v);
  43. - } else {
  44. - str = ToString<CanGC>(cx, v);
  45. + if (!str)
  46. + return nullptr;
  47. }
  48.  
  49. - if (!str)
  50. - return nullptr;
  51. bytes = JS_EncodeStringToLatin1(cx, str);
  52. - if (!bytes)
  53. - return nullptr;
  54. - const char* buf = bytes.get();
  55. - const char* found = strstr(buf, "function ");
  56. - if (found && (found - buf <= 2))
  57. - return "[function]";
  58. - return buf;
  59. + return bytes.get();
  60. }
  61.  
  62. -// Wrapper for JS_sprintf_append() that reports allocation failure to the
  63. -// context.
  64. -static JS::UniqueChars
  65. -MOZ_FORMAT_PRINTF(3, 4)
  66. -sprintf_append(JSContext* cx, JS::UniqueChars&& buf, const char* fmt, ...)
  67. -{
  68. - va_list ap;
  69. -
  70. - va_start(ap, fmt);
  71. - JS::UniqueChars result = JS_vsprintf_append(std::move(buf), fmt, ap);
  72. - va_end(ap);
  73. -
  74. - if (!result) {
  75. - ReportOutOfMemory(cx);
  76. - return nullptr;
  77. - }
  78. -
  79. - return result;
  80. -}
  81. -
  82. -static JS::UniqueChars
  83. -FormatFrame(JSContext* cx, const FrameIter& iter, JS::UniqueChars&& inBuf, int num,
  84. +static bool
  85. +FormatFrame(JSContext* cx, const FrameIter& iter, Sprinter& sp, int num,
  86. bool showArgs, bool showLocals, bool showThisProps)
  87. {
  88. MOZ_ASSERT(!cx->isExceptionPending());
  89. RootedScript script(cx, iter.script());
  90. jsbytecode* pc = iter.pc();
  91.  
  92. RootedObject envChain(cx, iter.environmentChain(cx));
  93. JSAutoRealm ar(cx, envChain);
  94. @@ -882,33 +855,33 @@ FormatFrame(JSContext* cx, const FrameIt
  95.  
  96. RootedValue thisVal(cx);
  97. if (iter.hasUsableAbstractFramePtr() &&
  98. iter.isFunctionFrame() &&
  99. fun && !fun->isArrow() && !fun->isDerivedClassConstructor() &&
  100. !(fun->isBoundFunction() && iter.isConstructing()))
  101. {
  102. if (!GetFunctionThis(cx, iter.abstractFramePtr(), &thisVal))
  103. - return nullptr;
  104. + return false;
  105. }
  106.  
  107. // print the frame number and function name
  108. - JS::UniqueChars buf(std::move(inBuf));
  109. if (funname) {
  110. UniqueChars funbytes = JS_EncodeStringToLatin1(cx, funname);
  111. if (!funbytes)
  112. - return nullptr;
  113. - buf = sprintf_append(cx, std::move(buf), "%d %s(", num, funbytes.get());
  114. + return false;
  115. + if (!sp.printf("%d %s(", num, funbytes.get()))
  116. + return false;
  117. } else if (fun) {
  118. - buf = sprintf_append(cx, std::move(buf), "%d anonymous(", num);
  119. + if (!sp.printf("%d anonymous(", num))
  120. + return false;
  121. } else {
  122. - buf = sprintf_append(cx, std::move(buf), "%d <TOP LEVEL>", num);
  123. + if (!sp.printf("%d <TOP LEVEL>", num))
  124. + return false;
  125. }
  126. - if (!buf)
  127. - return nullptr;
  128.  
  129. if (showArgs && iter.hasArgs()) {
  130. PositionalFormalParameterIter fi(script);
  131. bool first = true;
  132. for (unsigned i = 0; i < iter.numActualArgs(); i++) {
  133. RootedValue arg(cx);
  134. if (i < iter.numFormalArgs() && fi.closedOver()) {
  135. arg = iter.callObj(cx).aliasedBinding(fi);
  136. @@ -924,203 +897,200 @@ FormatFrame(JSContext* cx, const FrameIt
  137. } else {
  138. arg = MagicValue(JS_OPTIMIZED_OUT);
  139. }
  140.  
  141. UniqueChars valueBytes;
  142. const char* value = FormatValue(cx, arg, valueBytes);
  143. if (!value) {
  144. if (cx->isThrowingOutOfMemory())
  145. - return nullptr;
  146. + return false;
  147. cx->clearPendingException();
  148. }
  149.  
  150. UniqueChars nameBytes;
  151. const char* name = nullptr;
  152.  
  153. if (i < iter.numFormalArgs()) {
  154. MOZ_ASSERT(fi.argumentSlot() == i);
  155. if (!fi.isDestructured()) {
  156. nameBytes = JS_EncodeStringToLatin1(cx, fi.name());
  157. name = nameBytes.get();
  158. if (!name)
  159. - return nullptr;
  160. + return false;
  161. } else {
  162. name = "(destructured parameter)";
  163. }
  164. fi++;
  165. }
  166.  
  167. if (value) {
  168. - buf = sprintf_append(cx, std::move(buf), "%s%s%s%s%s%s",
  169. - !first ? ", " : "",
  170. - name ? name :"",
  171. - name ? " = " : "",
  172. - arg.isString() ? "\"" : "",
  173. - value,
  174. - arg.isString() ? "\"" : "");
  175. - if (!buf)
  176. - return nullptr;
  177. + if (!sp.printf("%s%s%s%s%s%s",
  178. + !first ? ", " : "",
  179. + name ? name :"",
  180. + name ? " = " : "",
  181. + arg.isString() ? "\"" : "",
  182. + value,
  183. + arg.isString() ? "\"" : ""))
  184. + {
  185. + return false;
  186. + }
  187.  
  188. first = false;
  189. } else {
  190. - buf = sprintf_append(cx, std::move(buf),
  191. - " <Failed to get argument while inspecting stack frame>\n");
  192. - if (!buf)
  193. - return nullptr;
  194. + if (!sp.put(" <Failed to get argument while inspecting stack frame>\n"))
  195. + return false;
  196.  
  197. }
  198. }
  199. }
  200.  
  201. // print filename and line number
  202. - buf = sprintf_append(cx, std::move(buf), "%s [\"%s\":%d]\n",
  203. - fun ? ")" : "",
  204. - filename ? filename : "<unknown>",
  205. - lineno);
  206. - if (!buf)
  207. - return nullptr;
  208. -
  209. + if (!sp.printf("%s [\"%s\":%d]\n",
  210. + fun ? ")" : "",
  211. + filename ? filename : "<unknown>",
  212. + lineno))
  213. + {
  214. + return false;
  215. + }
  216.  
  217. // Note: Right now we don't dump the local variables anymore, because
  218. // that is hard to support across all the JITs etc.
  219.  
  220. // print the value of 'this'
  221. if (showLocals) {
  222. if (!thisVal.isUndefined()) {
  223. - UniqueChars thisValBytes;
  224. RootedString thisValStr(cx, ToString<CanGC>(cx, thisVal));
  225. if (!thisValStr) {
  226. if (cx->isThrowingOutOfMemory())
  227. - return nullptr;
  228. + return false;
  229. cx->clearPendingException();
  230. }
  231. if (thisValStr) {
  232. - thisValBytes = JS_EncodeStringToLatin1(cx, thisValStr);
  233. + UniqueChars thisValBytes = JS_EncodeStringToLatin1(cx, thisValStr);
  234. if (!thisValBytes)
  235. - return nullptr;
  236. - buf = sprintf_append(cx, std::move(buf), " this = %s\n", thisValBytes.get());
  237. + return false;
  238. + if (!sp.printf(" this = %s\n", thisValBytes.get()))
  239. + return false;
  240. } else {
  241. - buf = sprintf_append(cx, std::move(buf), " <failed to get 'this' value>\n");
  242. + if (!sp.put(" <failed to get 'this' value>\n"))
  243. + return false;
  244. }
  245. - if (!buf)
  246. - return nullptr;
  247. }
  248. }
  249.  
  250. if (showThisProps && thisVal.isObject()) {
  251. RootedObject obj(cx, &thisVal.toObject());
  252.  
  253. AutoIdVector keys(cx);
  254. if (!GetPropertyKeys(cx, obj, JSITER_OWNONLY, &keys)) {
  255. if (cx->isThrowingOutOfMemory())
  256. - return nullptr;
  257. + return false;
  258. cx->clearPendingException();
  259. }
  260.  
  261. - RootedId id(cx);
  262. for (size_t i = 0; i < keys.length(); i++) {
  263. RootedId id(cx, keys[i]);
  264. RootedValue key(cx, IdToValue(id));
  265. RootedValue v(cx);
  266.  
  267. if (!GetProperty(cx, obj, obj, id, &v)) {
  268. if (cx->isThrowingOutOfMemory())
  269. - return nullptr;
  270. + return false;
  271. cx->clearPendingException();
  272. - buf = sprintf_append(cx, std::move(buf),
  273. - " <Failed to fetch property while inspecting stack frame>\n");
  274. - if (!buf)
  275. - return nullptr;
  276. + if (!sp.put(" <Failed to fetch property while inspecting stack frame>\n"))
  277. + return false;
  278. continue;
  279. }
  280.  
  281. UniqueChars nameBytes;
  282. const char* name = FormatValue(cx, key, nameBytes);
  283. if (!name) {
  284. if (cx->isThrowingOutOfMemory())
  285. - return nullptr;
  286. + return false;
  287. cx->clearPendingException();
  288. }
  289.  
  290. UniqueChars valueBytes;
  291. const char* value = FormatValue(cx, v, valueBytes);
  292. if (!value) {
  293. if (cx->isThrowingOutOfMemory())
  294. - return nullptr;
  295. + return false;
  296. cx->clearPendingException();
  297. }
  298.  
  299. if (name && value) {
  300. - buf = sprintf_append(cx, std::move(buf), " this.%s = %s%s%s\n",
  301. - name,
  302. - v.isString() ? "\"" : "",
  303. - value,
  304. - v.isString() ? "\"" : "");
  305. + if (!sp.printf(" this.%s = %s%s%s\n",
  306. + name,
  307. + v.isString() ? "\"" : "",
  308. + value,
  309. + v.isString() ? "\"" : ""))
  310. + {
  311. + return false;
  312. + }
  313. } else {
  314. - buf = sprintf_append(cx, std::move(buf),
  315. - " <Failed to format values while inspecting stack frame>\n");
  316. + if (!sp.put(" <Failed to format values while inspecting stack frame>\n"))
  317. + return false;
  318. }
  319. - if (!buf)
  320. - return nullptr;
  321. }
  322. }
  323.  
  324. MOZ_ASSERT(!cx->isExceptionPending());
  325. - return buf;
  326. + return true;
  327. }
  328.  
  329. -static JS::UniqueChars
  330. -FormatWasmFrame(JSContext* cx, const FrameIter& iter, JS::UniqueChars&& inBuf, int num)
  331. +static bool
  332. +FormatWasmFrame(JSContext* cx, const FrameIter& iter, Sprinter& sp, int num)
  333. {
  334. UniqueChars nameStr;
  335. if (JSAtom* functionDisplayAtom = iter.maybeFunctionDisplayAtom()) {
  336. nameStr = StringToNewUTF8CharsZ(cx, *functionDisplayAtom);
  337. if (!nameStr)
  338. - return nullptr;
  339. + return false;
  340. }
  341.  
  342. - JS::UniqueChars buf = sprintf_append(cx, std::move(inBuf), "%d %s()",
  343. - num,
  344. - nameStr ? nameStr.get() : "<wasm-function>");
  345. - if (!buf)
  346. - return nullptr;
  347. + if (!sp.printf("%d %s()", num, nameStr ? nameStr.get() : "<wasm-function>"))
  348. + return false;
  349.  
  350. - buf = sprintf_append(cx, std::move(buf), " [\"%s\":wasm-function[%d]:0x%x]\n",
  351. - iter.filename() ? iter.filename() : "<unknown>",
  352. - iter.wasmFuncIndex(),
  353. - iter.wasmBytecodeOffset());
  354. - if (!buf)
  355. - return nullptr;
  356. + if (!sp.printf(" [\"%s\":wasm-function[%d]:0x%x]\n",
  357. + iter.filename() ? iter.filename() : "<unknown>",
  358. + iter.wasmFuncIndex(),
  359. + iter.wasmBytecodeOffset()))
  360. + {
  361. + return false;
  362. + }
  363.  
  364. MOZ_ASSERT(!cx->isExceptionPending());
  365. - return buf;
  366. + return true;
  367. }
  368.  
  369. JS_FRIEND_API(JS::UniqueChars)
  370. -JS::FormatStackDump(JSContext* cx, JS::UniqueChars&& inBuf, bool showArgs, bool showLocals,
  371. - bool showThisProps)
  372. +JS::FormatStackDump(JSContext* cx, bool showArgs, bool showLocals, bool showThisProps)
  373. {
  374. int num = 0;
  375.  
  376. - JS::UniqueChars buf(std::move(inBuf));
  377. + Sprinter sp(cx);
  378. + if (!sp.init())
  379. + return nullptr;
  380. +
  381. for (AllFramesIter i(cx); !i.done(); ++i) {
  382. - if (i.hasScript())
  383. - buf = FormatFrame(cx, i, std::move(buf), num, showArgs, showLocals, showThisProps);
  384. - else
  385. - buf = FormatWasmFrame(cx, i, std::move(buf), num);
  386. - if (!buf)
  387. + bool ok = i.hasScript()
  388. + ? FormatFrame(cx, i, sp, num, showArgs, showLocals, showThisProps)
  389. + : FormatWasmFrame(cx, i, sp, num);
  390. + if (!ok)
  391. return nullptr;
  392. num++;
  393. }
  394.  
  395. - if (!num)
  396. - buf = JS_sprintf_append(std::move(buf), "JavaScript stack is empty\n");
  397. + if (num == 0) {
  398. + if (!sp.put("JavaScript stack is empty\n"))
  399. + return nullptr;
  400. + }
  401.  
  402. - return buf;
  403. + return sp.release();
  404. }
  405.  
  406. extern JS_FRIEND_API(bool)
  407. JS::ForceLexicalInitialization(JSContext *cx, HandleObject obj)
  408. {
  409. AssertHeapIsIdle();
  410. CHECK_THREAD(cx);
  411. cx->check(obj);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement