Bug 1438502 - Add error reports to CacheEntry internal methods. r=anba
authorNicolas B. Pierron <nicolas.b.pierron@gmail.com>
Thu, 15 Feb 2018 13:43:47 +0000
changeset 404100 e48b1c8130b99041eb384d1043cd998bfe6612a7
parent 404099 3ed4ca56120b74ffc0c5745c83e773692241bb0e
child 404101 24f191972279a7fcac58aaa55d6f85a08a4ef115
push id33451
push usernbeleuzu@mozilla.com
push dateFri, 16 Feb 2018 09:51:13 +0000
treeherdermozilla-central@9eaebbcc33fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersanba
bugs1438502
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1438502 - Add error reports to CacheEntry internal methods. r=anba
js/src/jit-test/tests/self-test/cacheEntry.js
js/src/shell/js.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/self-test/cacheEntry.js
@@ -0,0 +1,23 @@
+// These tests are checking that CacheEntry_getBytecode properly set an error
+// when there is no bytecode registered.
+var caught = 0;
+var code = cacheEntry("");
+try {
+    offThreadDecodeScript(code);
+}
+catch (e) {
+    // offThreadDecodeScript does not work with the --no-thread command line option.
+    assertEq(e.message.includes("CacheEntry") || e.message.includes("offThreadDecodeScript"), true);
+    caught++;
+}
+
+code = cacheEntry("");
+try {
+    evaluate(code, {loadBytecode: true});
+}
+catch (e) {
+    assertEq(e.message.includes("CacheEntry"), true);
+    caught++;
+}
+
+assertEq(caught, 2);
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -1546,33 +1546,37 @@ CacheEntry(JSContext* cx, unsigned argc,
 
 static bool
 CacheEntry_isCacheEntry(JSObject* cache)
 {
     return JS_GetClass(cache) == &CacheEntry_class;
 }
 
 static JSString*
-CacheEntry_getSource(HandleObject cache)
+CacheEntry_getSource(JSContext* cx, HandleObject cache)
 {
     MOZ_ASSERT(CacheEntry_isCacheEntry(cache));
     Value v = JS_GetReservedSlot(cache, CacheEntry_SOURCE);
-    if (!v.isString())
+    if (!v.isString()) {
+        JS_ReportErrorASCII(cx, "CacheEntry_getSource: Unexpected type of source reserved slot.");
         return nullptr;
+    }
 
     return v.toString();
 }
 
 static uint8_t*
-CacheEntry_getBytecode(HandleObject cache, uint32_t* length)
+CacheEntry_getBytecode(JSContext* cx, HandleObject cache, uint32_t* length)
 {
     MOZ_ASSERT(CacheEntry_isCacheEntry(cache));
     Value v = JS_GetReservedSlot(cache, CacheEntry_BYTECODE);
-    if (!v.isObject() || !v.toObject().is<ArrayBufferObject>())
+    if (!v.isObject() || !v.toObject().is<ArrayBufferObject>()) {
+        JS_ReportErrorASCII(cx, "CacheEntry_getBytecode: Unexpected type of bytecode reserved slot.");
         return nullptr;
+    }
 
     ArrayBufferObject* arrayBuffer = &v.toObject().as<ArrayBufferObject>();
     *length = arrayBuffer->byteLength();
     return arrayBuffer->dataPointer();
 }
 
 static bool
 CacheEntry_setBytecode(JSContext* cx, HandleObject cache, uint8_t* buffer, uint32_t length)
@@ -1649,17 +1653,19 @@ Evaluate(JSContext* cx, unsigned argc, V
     }
 
     RootedString code(cx, nullptr);
     RootedObject cacheEntry(cx, nullptr);
     if (args[0].isString()) {
         code = args[0].toString();
     } else if (args[0].isObject() && CacheEntry_isCacheEntry(&args[0].toObject())) {
         cacheEntry = &args[0].toObject();
-        code = CacheEntry_getSource(cacheEntry);
+        code = CacheEntry_getSource(cx, cacheEntry);
+        if (!code)
+            return false;
     }
 
     if (!code || (args.length() == 2 && args[1].isPrimitive())) {
         JS_ReportErrorNumberASCII(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "evaluate");
         return false;
     }
 
     CompileOptions options(cx);
@@ -1832,17 +1838,17 @@ Evaluate(JSContext* cx, unsigned argc, V
         return false;
 
     JS::TranscodeBuffer loadBuffer;
     JS::TranscodeBuffer saveBuffer;
 
     if (loadBytecode) {
         uint32_t loadLength = 0;
         uint8_t* loadData = nullptr;
-        loadData = CacheEntry_getBytecode(cacheEntry, &loadLength);
+        loadData = CacheEntry_getBytecode(cx, cacheEntry, &loadLength);
         if (!loadData)
             return false;
         if (!loadBuffer.append(loadData, loadLength)) {
             JS_ReportOutOfMemory(cx);
             return false;
         }
     }
 
@@ -4910,17 +4916,17 @@ OffThreadDecodeScript(JSContext* cx, uns
 
     // We assume the caller wants caching if at all possible, ignoring
     // heuristics that make sense for a real browser.
     options.forceAsync = true;
 
     JS::TranscodeBuffer loadBuffer;
     uint32_t loadLength = 0;
     uint8_t* loadData = nullptr;
-    loadData = CacheEntry_getBytecode(cacheEntry, &loadLength);
+    loadData = CacheEntry_getBytecode(cx, cacheEntry, &loadLength);
     if (!loadData)
         return false;
     if (!loadBuffer.append(loadData, loadLength)) {
         JS_ReportOutOfMemory(cx);
         return false;
     }
 
     if (!JS::CanDecodeOffThread(cx, options, loadLength)) {