Bug 1438502 - Add error reports to CacheEntry internal methods. r=anba
☠☠ backed out by 5626666b65bb ☠ ☠
authorNicolas B. Pierron <nicolas.b.pierron@gmail.com>
Thu, 15 Feb 2018 13:43:47 +0000
changeset 403959 cfd98003fc0f68673f6053d2800e3d0fa99868a8
parent 403958 a8aa7e2af130f28442a965188abdf80c30a737aa
child 403960 7cff9cca3774c19713e6092a63e8bbeb8a623462
push id99904
push usernpierron@mozilla.com
push dateThu, 15 Feb 2018 16:03:04 +0000
treeherdermozilla-inbound@cfd98003fc0f [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,22 @@
+// 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) {
+    assertEq(e.message.includes("CacheEntry"), 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)) {