Merge inbound to mozilla-central. a=merge
authorOana Pop Rus <opoprus@mozilla.com>
Thu, 28 Feb 2019 23:47:12 +0200
changeset 519630 98d4803bb2de
parent 519613 db533ea3d561 (current diff)
parent 519629 664a5bdd8ab1 (diff)
child 519681 ca1739a4ed1d
child 519750 08157bb630a6
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone67.0a1
first release with
nightly linux32
98d4803bb2de / 67.0a1 / 20190228214753 / files
nightly linux64
98d4803bb2de / 67.0a1 / 20190228214753 / files
nightly mac
98d4803bb2de / 67.0a1 / 20190228214753 / files
nightly win32
98d4803bb2de / 67.0a1 / 20190228214753 / files
nightly win64
98d4803bb2de / 67.0a1 / 20190228214753 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central. a=merge
--- a/browser/base/content/test/pageinfo/browser_pageinfo_firstPartyIsolation.js
+++ b/browser/base/content/test/pageinfo/browser_pageinfo_firstPartyIsolation.js
@@ -1,15 +1,10 @@
 const Cm = Components.manager;
 
-function waitForEvent(elem, event) {
-  return new Promise(resolve => {
-    elem.addEventListener(event, resolve, {capture: true, once: true});
-  });
-}
 
 function testFirstPartyDomain(pageInfo) {
   return new Promise(resolve => {
     const EXPECTED_DOMAIN = "example.com";
     info("pageInfo load");
     pageInfo.onFinished.push(async function() {
       info("pageInfo onfinished");
       let tree = pageInfo.document.getElementById("imagetree");
@@ -27,19 +22,19 @@ function testFirstPartyDomain(pageInfo) 
         let preview = pageInfo.document.getElementById("thepreviewimage");
         info("preview.src=" + preview.src);
 
         // For <img>, we will query imgIRequest.imagePrincipal later, so we wait
         // for loadend event. For <audio> and <video>, so far we only can get
         // the triggeringprincipal attribute on the node, so we simply wait for
         // loadstart.
         if (i == 0) {
-          await waitForEvent(preview, "loadend");
+          await BrowserTestUtils.waitForEvent(preview, "loadend");
         } else {
-          await waitForEvent(preview, "loadstart");
+          await BrowserTestUtils.waitForEvent(preview, "loadstart");
         }
 
         info("preview load " + i);
 
         // Originally thepreviewimage is loaded with SystemPrincipal, therefore
         // it won't have origin attributes, now we've changed to loadingPrincipal
         // to the content in bug 1376971, it should have firstPartyDomain set.
         if (i == 0) {
@@ -76,17 +71,17 @@ async function test() {
   BrowserTestUtils.loadURI(gBrowser.selectedBrowser, url);
   await loadPromise;
 
   // Pass a dummy imageElement, if there isn't an imageElement, pageInfo.js
   // will do a preview, however this sometimes will cause intermittent failures,
   // see bug 1403365.
   let pageInfo = BrowserPageInfo(url, "mediaTab", {});
   info("waitForEvent pageInfo");
-  await waitForEvent(pageInfo, "load");
+  await BrowserTestUtils.waitForEvent(pageInfo, "load");
 
   info("calling testFirstPartyDomain");
   await testFirstPartyDomain(pageInfo);
 
   pageInfo.close();
   gBrowser.removeCurrentTab();
   finish();
 }
--- a/devtools/client/inspector/rules/models/text-property.js
+++ b/devtools/client/inspector/rules/models/text-property.js
@@ -136,17 +136,17 @@ class TextProperty {
     if (changed) {
       this.updateEditor();
     }
   }
 
   setValue(value, priority, force = false) {
     const store = this.rule.elementStyle.store;
 
-    if (this.editor && value !== this.editor.committed.value || force) {
+    if (value !== this.value || force) {
       store.userProperties.setProperty(this.rule.domRule, this.name, value);
     }
 
     return this.rule.setPropertyValue(this, value, priority)
       .then(() => this.updateEditor());
   }
 
   /**
@@ -159,20 +159,19 @@ class TextProperty {
   updateValue(value) {
     if (value !== this.value) {
       this.value = value;
       this.updateEditor();
     }
   }
 
   async setName(name) {
-    if (name !== this.name && this.editor) {
+    if (name !== this.name) {
       const store = this.rule.elementStyle.store;
-      store.userProperties.setProperty(this.rule.domRule, name,
-                                       this.editor.committed.value);
+      store.userProperties.setProperty(this.rule.domRule, name, this.value);
     }
 
     await this.rule.setPropertyName(this, name);
     this.updateEditor();
   }
 
   setEnabled(value) {
     this.rule.setPropertyEnabled(this, value);
@@ -183,18 +182,23 @@ class TextProperty {
     this.rule.removeProperty(this);
   }
 
   /**
    * Return a string representation of the rule property.
    */
   stringifyProperty() {
     // Get the displayed property value
-    let declaration = this.name + ": " + this.editor.valueSpan.textContent +
-      ";";
+    let declaration = this.name + ": " + this.value;
+
+    if (this.priority) {
+      declaration += " !" + this.priority;
+    }
+
+    declaration += ";";
 
     // Comment out property declarations that are not enabled
     if (!this.enabled) {
       declaration = "/* " + escapeCSSComment(declaration) + " */";
     }
 
     return declaration;
   }
--- a/intl/unicharutil/util/ICUUtils.cpp
+++ b/intl/unicharutil/util/ICUUtils.cpp
@@ -1,26 +1,40 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifdef MOZILLA_INTERNAL_API
 
+#include "mozilla/Assertions.h"
+#include "mozilla/UniquePtr.h"
+
 #  include "ICUUtils.h"
 #  include "mozilla/Preferences.h"
 #  include "mozilla/intl/LocaleService.h"
 #  include "nsIContent.h"
 #  include "mozilla/dom/Document.h"
 #  include "nsString.h"
 #  include "unicode/uloc.h"
 #  include "unicode/unum.h"
 
 using namespace mozilla;
 using mozilla::intl::LocaleService;
 
+class NumberFormatDeleter {
+ public:
+  void operator()(UNumberFormat* aPtr) {
+    MOZ_ASSERT(aPtr != nullptr,
+               "UniquePtr deleter shouldn't be called for nullptr");
+    unum_close(aPtr);
+  }
+};
+
+using UniqueUNumberFormat = UniquePtr<UNumberFormat, NumberFormatDeleter>;
+
 /**
  * This pref just controls whether we format the number with grouping separator
  * characters when the internal value is set or updated. It does not stop the
  * user from typing in a number and using grouping separators.
  */
 static bool gLocaleNumberGroupingEnabled;
 static const char LOCALE_NUMBER_GROUPING_PREF_STR[] =
     "dom.forms.number.grouping";
@@ -86,32 +100,32 @@ void ICUUtils::LanguageTagIterForContent
   static const int32_t kBufferSize = 256;
 
   UChar buffer[kBufferSize];
 
   nsAutoCString langTag;
   aLangTags.GetNext(langTag);
   while (!langTag.IsEmpty()) {
     UErrorCode status = U_ZERO_ERROR;
-    AutoCloseUNumberFormat format(
+    UniqueUNumberFormat format(
         unum_open(UNUM_DECIMAL, nullptr, 0, langTag.get(), nullptr, &status));
     // Since unum_setAttribute have no UErrorCode parameter, we have to
     // check error status.
     if (U_FAILURE(status)) {
       aLangTags.GetNext(langTag);
       continue;
     }
-    unum_setAttribute(format, UNUM_GROUPING_USED,
+    unum_setAttribute(format.get(), UNUM_GROUPING_USED,
                       LocaleNumberGroupingIsEnabled());
     // ICU default is a maximum of 3 significant fractional digits. We don't
     // want that limit, so we set it to the maximum that a double can represent
     // (14-16 decimal fractional digits).
-    unum_setAttribute(format, UNUM_MAX_FRACTION_DIGITS, 16);
-    int32_t length = unum_formatDouble(format, aValue, buffer, kBufferSize,
-                                       nullptr, &status);
+    unum_setAttribute(format.get(), UNUM_MAX_FRACTION_DIGITS, 16);
+    int32_t length = unum_formatDouble(format.get(), aValue, buffer,
+                                       kBufferSize, nullptr, &status);
     NS_ASSERTION(length < kBufferSize && status != U_BUFFER_OVERFLOW_ERROR &&
                      status != U_STRING_NOT_TERMINATED_WARNING,
                  "Need a bigger buffer?!");
     if (U_SUCCESS(status)) {
       ICUUtils::AssignUCharArrayToString(buffer, length, aLocalizedValue);
       return true;
     }
     aLangTags.GetNext(langTag);
@@ -128,26 +142,27 @@ void ICUUtils::LanguageTagIterForContent
   }
 
   uint32_t length = aValue.Length();
 
   nsAutoCString langTag;
   aLangTags.GetNext(langTag);
   while (!langTag.IsEmpty()) {
     UErrorCode status = U_ZERO_ERROR;
-    AutoCloseUNumberFormat format(
+    UniqueUNumberFormat format(
         unum_open(UNUM_DECIMAL, nullptr, 0, langTag.get(), nullptr, &status));
     if (!LocaleNumberGroupingIsEnabled()) {
-      unum_setAttribute(format.rwget(), UNUM_GROUPING_USED, UBool(0));
+      unum_setAttribute(format.get(), UNUM_GROUPING_USED, UBool(0));
     }
     int32_t parsePos = 0;
     static_assert(sizeof(UChar) == 2 && sizeof(nsAString::char_type) == 2,
                   "Unexpected character size - the following cast is unsafe");
     double val =
-        unum_parseDouble(format, (const UChar*)PromiseFlatString(aValue).get(),
+        unum_parseDouble(format.get(),
+                         (const UChar*)PromiseFlatString(aValue).get(),
                          length, &parsePos, &status);
     if (U_SUCCESS(status) && parsePos == (int32_t)length) {
       return val;
     }
     aLangTags.GetNext(langTag);
   }
   return std::numeric_limits<float>::quiet_NaN();
 }
--- a/intl/unicharutil/util/ICUUtils.h
+++ b/intl/unicharutil/util/ICUUtils.h
@@ -5,31 +5,21 @@
 
 #ifndef mozilla_ICUUtils_h__
 #define mozilla_ICUUtils_h__
 
 // The ICU utils implementation needs internal things like XPCOM strings and
 // nsGkAtom, so we only build when included into internal libs:
 #ifdef MOZILLA_INTERNAL_API
 
-#  include "mozilla/Scoped.h"
 #  include "nsString.h"
 #  include "unicode/unum.h"  // for UNumberFormat
 
 class nsIContent;
 
-struct ScopedUNumberFormatTraits {
-  typedef UNumberFormat* type;
-  static type empty() { return nullptr; }
-  static void release(type handle) {
-    if (handle) unum_close(handle);
-  }
-};
-typedef mozilla::Scoped<ScopedUNumberFormatTraits> AutoCloseUNumberFormat;
-
 class ICUUtils {
  public:
   /**
    * This class is used to encapsulate an nsIContent object to allow lazy
    * iteration over its primary and fallback BCP 47 language tags.
    */
   class LanguageTagIterForContent {
    public:
--- a/js/public/GCVariant.h
+++ b/js/public/GCVariant.h
@@ -42,19 +42,17 @@ template <typename... Ts>
 struct GCVariantImplementation;
 
 // The base case.
 template <typename T>
 struct GCVariantImplementation<T> {
   template <typename ConcreteVariant>
   static void trace(JSTracer* trc, ConcreteVariant* v, const char* name) {
     T& thing = v->template as<T>();
-    if (!mozilla::IsPointer<T>::value || thing) {
-      GCPolicy<T>::trace(trc, &thing, name);
-    }
+    GCPolicy<T>::trace(trc, &thing, name);
   }
 
   template <typename Matcher, typename ConcreteVariant>
   static typename Matcher::ReturnType match(Matcher& matcher,
                                             Handle<ConcreteVariant> v) {
     const T& thing = v.get().template as<T>();
     return matcher.match(Handle<T>::fromMarkedLocation(&thing));
   }
@@ -71,19 +69,17 @@ struct GCVariantImplementation<T> {
 template <typename T, typename... Ts>
 struct GCVariantImplementation<T, Ts...> {
   using Next = GCVariantImplementation<Ts...>;
 
   template <typename ConcreteVariant>
   static void trace(JSTracer* trc, ConcreteVariant* v, const char* name) {
     if (v->template is<T>()) {
       T& thing = v->template as<T>();
-      if (!mozilla::IsPointer<T>::value || thing) {
-        GCPolicy<T>::trace(trc, &thing, name);
-      }
+      GCPolicy<T>::trace(trc, &thing, name);
     } else {
       Next::trace(trc, v, name);
     }
   }
 
   template <typename Matcher, typename ConcreteVariant>
   static typename Matcher::ReturnType match(Matcher& matcher,
                                             Handle<ConcreteVariant> v) {
--- a/js/public/UbiNodeCensus.h
+++ b/js/public/UbiNodeCensus.h
@@ -175,49 +175,38 @@ class CountBase {
 
   size_t total_;
 
   // The smallest JS::ubi::Node::identifier() passed to this instance's
   // count() method. This provides a stable way to sort sets.
   Node::Id smallestNodeIdCounted_;
 };
 
-class RootedCount : JS::CustomAutoRooter {
-  CountBasePtr count;
-
-  void trace(JSTracer* trc) override { count->trace(trc); }
-
- public:
-  RootedCount(JSContext* cx, CountBasePtr&& count)
-      : CustomAutoRooter(cx), count(std::move(count)) {}
-  CountBase* operator->() const { return count.get(); }
-  explicit operator bool() const { return count.get(); }
-  operator CountBasePtr&() { return count; }
-};
+using RootedCount = JS::Rooted<CountBasePtr>;
 
 // Common data for a census traversal, shared across all CountType nodes.
 struct Census {
   JSContext* const cx;
   // If the targetZones set is non-empty, then only consider nodes whose zone
   // is an element of the set. If the targetZones set is empty, then nodes in
   // all zones are considered.
   JS::ZoneSet targetZones;
 
   explicit Census(JSContext* cx) : cx(cx) {}
 };
 
 // A BreadthFirst handler type that conducts a census, using a CountBase to
 // categorize and count each node.
 class CensusHandler {
   Census& census;
-  CountBasePtr& rootCount;
+  JS::Handle<CountBasePtr> rootCount;
   mozilla::MallocSizeOf mallocSizeOf;
 
  public:
-  CensusHandler(Census& census, CountBasePtr& rootCount,
+  CensusHandler(Census& census, JS::Handle<CountBasePtr> rootCount,
                 mozilla::MallocSizeOf mallocSizeOf)
       : census(census), rootCount(rootCount), mallocSizeOf(mallocSizeOf) {}
 
   MOZ_MUST_USE bool report(JSContext* cx, MutableHandleValue report) {
     return rootCount->report(cx, report);
   }
 
   // This class needs to retain no per-node data.
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -77,17 +77,17 @@ static HashNumber HashValue(const Value&
 
   if (v.isString()) {
     return v.toString()->asAtom().hash();
   }
   if (v.isSymbol()) {
     return v.toSymbol()->hash();
   }
   if (v.isBigInt()) {
-    return v.toBigInt()->hash();
+    return MaybeForwarded(v.toBigInt())->hash();
   }
   if (v.isObject()) {
     return hcs.scramble(v.asRawBits());
   }
 
   MOZ_ASSERT(!v.isGCThing(), "do not reveal pointers via hash codes");
   return mozilla::HashGeneric(v.asRawBits());
 }
@@ -418,18 +418,19 @@ const JSFunctionSpec MapObject::methods[
 const JSPropertySpec MapObject::staticProperties[] = {
     JS_SELF_HOSTED_SYM_GET(species, "MapSpecies", 0), JS_PS_END};
 
 template <class Range>
 static void TraceKey(Range& r, const HashableValue& key, JSTracer* trc) {
   HashableValue newKey = key.trace(trc);
 
   if (newKey.get() != key.get()) {
-    // The hash function only uses the bits of the Value, so it is safe to
-    // rekey even when the object or string has been modified by the GC.
+    // The hash function must take account of the fact that the thing being
+    // hashed may have been moved by GC. This is only an issue for BigInt as for
+    // other types the hash function only uses the bits of the Value.
     r.rekeyFront(newKey);
   }
 }
 
 void MapObject::trace(JSTracer* trc, JSObject* obj) {
   if (ValueMap* map = obj->as<MapObject>().getData()) {
     for (ValueMap::Range r = map->all(); !r.empty(); r.popFront()) {
       TraceKey(r, r.front().key, trc);
--- a/js/src/builtin/intl/CommonFunctions.js
+++ b/js/src/builtin/intl/CommonFunctions.js
@@ -1329,30 +1329,19 @@ function SupportedLocales(availableLocal
         if (matcher !== undefined) {
             matcher = ToString(matcher);
             if (matcher !== "lookup" && matcher !== "best fit")
                 ThrowRangeError(JSMSG_INVALID_LOCALE_MATCHER, matcher);
         }
     }
 
     // Steps 2-5.
-    var subset = (matcher === undefined || matcher === "best fit")
-                 ? BestFitSupportedLocales(availableLocales, requestedLocales)
-                 : LookupSupportedLocales(availableLocales, requestedLocales);
-
-    // Steps 6-7.
-    for (var i = 0; i < subset.length; i++) {
-        _DefineDataProperty(subset, i, subset[i],
-                            ATTR_ENUMERABLE | ATTR_NONCONFIGURABLE | ATTR_NONWRITABLE);
-    }
-    _DefineDataProperty(subset, "length", subset.length,
-                        ATTR_NONENUMERABLE | ATTR_NONCONFIGURABLE | ATTR_NONWRITABLE);
-
-    // Step 8.
-    return subset;
+    return (matcher === undefined || matcher === "best fit")
+           ? BestFitSupportedLocales(availableLocales, requestedLocales)
+           : LookupSupportedLocales(availableLocales, requestedLocales);
 }
 
 /**
  * Extracts a property value from the provided options object, converts it to
  * the required type, checks whether it is one of a list of allowed values,
  * and fills in a fallback value if necessary.
  *
  * Spec: ECMAScript Internationalization API Specification, 9.2.10.
--- a/js/src/gc/GC.cpp
+++ b/js/src/gc/GC.cpp
@@ -6267,16 +6267,19 @@ class SweepActionSequence final : public
 
   ActionVector actions;
   typename Iter::State iterState;
 
  public:
   bool init(UniquePtr<Action>* acts, size_t count) {
     for (size_t i = 0; i < count; i++) {
       auto& action = acts[i];
+      if (!action) {
+        return false;
+      }
       if (action->shouldSkip()) {
         continue;
       }
       if (!actions.emplaceBack(std::move(action))) {
         return false;
       }
     }
     return true;
--- a/js/src/gc/WeakMap.h
+++ b/js/src/gc/WeakMap.h
@@ -136,50 +136,73 @@ class WeakMapBase : public mozilla::Link
   // Whether this object has been marked during garbage collection and which
   // color it was marked.
   bool marked;
   gc::MarkColor markColor;
 };
 
 template <class Key, class Value>
 class WeakMap
-    : public HashMap<Key, Value, MovableCellHasher<Key>, ZoneAllocPolicy>,
+    : private HashMap<Key, Value, MovableCellHasher<Key>, ZoneAllocPolicy>,
       public WeakMapBase {
  public:
-  typedef HashMap<Key, Value, MovableCellHasher<Key>, ZoneAllocPolicy> Base;
-  typedef typename Base::Enum Enum;
-  typedef typename Base::Lookup Lookup;
-  typedef typename Base::Entry Entry;
-  typedef typename Base::Range Range;
-  typedef typename Base::Ptr Ptr;
-  typedef typename Base::AddPtr AddPtr;
+  using Base = HashMap<Key, Value, MovableCellHasher<Key>, ZoneAllocPolicy>;
+
+  using Lookup = typename Base::Lookup;
+  using Entry = typename Base::Entry;
+  using Range = typename Base::Range;
+  using Ptr = typename Base::Ptr;
+  using AddPtr = typename Base::AddPtr;
+
+  struct Enum : public Base::Enum {
+    explicit Enum(WeakMap& map) : Base::Enum(static_cast<Base&>(map)) {}
+  };
+
+  using Base::all;
+  using Base::has;
+  using Base::clear;
+  using Base::shallowSizeOfExcludingThis;
+
+  // Resolve ambiguity with LinkedListElement<>::remove.
+  using Base::remove;
 
   explicit WeakMap(JSContext* cx, JSObject* memOf = nullptr);
 
-  // Overwritten to add a read barrier to prevent an incorrectly gray value
-  // from escaping the weak map. See the UnmarkGrayTracer::onChild comment in
-  // gc/Marking.cpp.
+  // Add a read barrier to prevent an incorrectly gray value from escaping the
+  // weak map. See the UnmarkGrayTracer::onChild comment in gc/Marking.cpp.
   Ptr lookup(const Lookup& l) const {
     Ptr p = Base::lookup(l);
     if (p) {
       exposeGCThingToActiveJS(p->value());
     }
     return p;
   }
 
   AddPtr lookupForAdd(const Lookup& l) {
     AddPtr p = Base::lookupForAdd(l);
     if (p) {
       exposeGCThingToActiveJS(p->value());
     }
     return p;
   }
 
-  // Resolve ambiguity with LinkedListElement<>::remove.
-  using Base::remove;
+  template <typename KeyInput, typename ValueInput>
+  MOZ_MUST_USE bool put(KeyInput&& key, ValueInput&& value) {
+    MOZ_ASSERT(key);
+    return Base::put(std::forward<KeyInput>(key),
+                     std::forward<ValueInput>(value));
+  }
+
+  template <typename KeyInput, typename ValueInput>
+  MOZ_MUST_USE bool relookupOrAdd(AddPtr& ptr, KeyInput&& key,
+                                  ValueInput&& value) {
+    MOZ_ASSERT(key);
+    return Base::relookupOrAdd(ptr, std::forward<KeyInput>(key),
+                               std::forward<ValueInput>(value));
+  }
 
   void markEntry(GCMarker* marker, gc::Cell* markedCell,
                  JS::GCCellPtr origKey) override;
 
   void trace(JSTracer* trc) override;
 
  protected:
   static void addWeakEntry(GCMarker* marker, JS::GCCellPtr key,
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1530643.js
@@ -0,0 +1,3 @@
+// |jit-test| skip-if: !('oomAtAllocation' in this) || helperThreadCount() === 0
+oomAtAllocation(11, 11);
+evalInWorker("");
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/gc/bug-1531018.js
@@ -0,0 +1,3 @@
+gczeal(14,1);
+const one = BigInt(1);
+new Map([[one, 42]]).has(one);
--- a/js/src/jit-test/tests/wasm/basic.js
+++ b/js/src/jit-test/tests/wasm/basic.js
@@ -73,17 +73,17 @@ var f = wasmEvalText('(module (func (par
 assertErrorMessage(f, TypeError, /i64/);
 
 var f = wasmEvalText('(module (import $imp "a" "b" (param i64) (result i32)) (func $f (result i32) (call $imp (i64.const 0))) (export "" $f))', {a:{b:()=>{}}}).exports[""];
 assertErrorMessage(f, TypeError, /i64/);
 var f = wasmEvalText('(module (import $imp "a" "b" (result i64)) (func $f (result i64) (call $imp)) (export "" $f))', {a:{b:()=>{}}}).exports[""];
 assertErrorMessage(f, TypeError, /i64/);
 
 wasmFullPassI64('(module (func $run (result i64) (i64.const 123)))', 123);
-wasmFullPassI64('(module (func $run (param i64) (result i64) (get_local 0)))',
+wasmFullPassI64('(module (func $run (param i64) (result i64) (local.get 0)))',
                 '0x123400007fffffff',
                 {},
                 '(i64.const 0x123400007fffffff)');
 wasmFullPassI64('(module (func $run (param i64) (result i64) (i64.add (get_local 0) (i64.const 1))))',
                 '0x1234000100000000',
                 {},
                 '(i64.const 0x12340000ffffffff)');
 
@@ -175,30 +175,30 @@ assertEq(new Uint8Array(buf)[65535], 'c'
 // ----------------------------------------------------------------------------
 // locals
 
 assertEq(wasmEvalText('(module (func (param i32) (result i32) (get_local 0)) (export "" 0))').exports[""](), 0);
 assertEq(wasmEvalText('(module (func (param i32) (result i32) (get_local 0)) (export "" 0))').exports[""](42), 42);
 assertEq(wasmEvalText('(module (func (param i32) (param i32) (result i32) (get_local 0)) (export "" 0))').exports[""](42, 43), 42);
 assertEq(wasmEvalText('(module (func (param i32) (param i32) (result i32) (get_local 1)) (export "" 0))').exports[""](42, 43), 43);
 
-wasmFailValidateText('(module (func (get_local 0)))', /get_local index out of range/);
+wasmFailValidateText('(module (func (get_local 0)))', /local.get index out of range/);
 wasmFailValidateText('(module (func (result f32) (local i32) (get_local 0)))', mismatchError("i32", "f32"));
 wasmFailValidateText('(module (func (result i32) (local f32) (get_local 0)))', mismatchError("f32", "i32"));
 wasmFailValidateText('(module (func (result f32) (param i32) (local f32) (get_local 0)))', mismatchError("i32", "f32"));
 wasmFailValidateText('(module (func (result i32) (param i32) (local f32) (get_local 1)))', mismatchError("f32", "i32"));
 
 wasmValidateText('(module (func (local i32)))');
 wasmValidateText('(module (func (local i32) (local f32)))');
 
 wasmFullPass('(module (func (result i32) (local i32) (get_local 0)) (export "run" 0))', 0);
 wasmFullPass('(module (func (result i32) (param i32) (local f32) (get_local 0)) (export "run" 0))', 0);
 wasmFullPass('(module (func (result f32) (param i32) (local f32) (get_local 1)) (export "run" 0))', 0);
 
-wasmFailValidateText('(module (func (set_local 0 (i32.const 0))))', /set_local index out of range/);
+wasmFailValidateText('(module (func (local.set 0 (i32.const 0))))', /local.set index out of range/);
 wasmFailValidateText('(module (func (local f32) (set_local 0 (i32.const 0))))', mismatchError("i32", "f32"));
 wasmFailValidateText('(module (func (local f32) (set_local 0 (nop))))', emptyStackError);
 wasmFailValidateText('(module (func (local i32) (local f32) (set_local 0 (get_local 1))))', mismatchError("f32", "i32"));
 wasmFailValidateText('(module (func (local i32) (local f32) (set_local 1 (get_local 0))))', mismatchError("i32", "f32"));
 
 wasmValidateText('(module (func (local i32) (set_local 0 (i32.const 0))))');
 wasmValidateText('(module (func (local i32) (local f32) (set_local 0 (get_local 0))))');
 wasmValidateText('(module (func (local i32) (local f32) (set_local 1 (get_local 1))))');
@@ -306,17 +306,17 @@ var {v2i, i2i, i2v} = wasmEvalText(`(mod
     (type (func (param i32) (result i32)))
     (type (func (param i32)))
     (func (type 0) (i32.const 13))
     (func (type 0) (i32.const 42))
     (func (type 1) (i32.add (get_local 0) (i32.const 1)))
     (func (type 1) (i32.add (get_local 0) (i32.const 2)))
     (func (type 1) (i32.add (get_local 0) (i32.const 3)))
     (func (type 1) (i32.add (get_local 0) (i32.const 4)))
-    (table anyfunc (elem 0 1 2 3 4 5))
+    (table funcref (elem 0 1 2 3 4 5))
     (func (param i32) (result i32) (call_indirect 0 (get_local 0)))
     (func (param i32) (param i32) (result i32) (call_indirect 1 (get_local 1) (get_local 0)))
     (func (param i32) (call_indirect 2 (i32.const 0) (get_local 0)))
     (export "v2i" 6)
     (export "i2i" 7)
     (export "i2v" 8)
 )`).exports;
 
@@ -348,17 +348,17 @@ assertErrorMessage(() => i2v(5), Error, 
 
     var stack;
     wasmFullPass(
         `(module
             (type $v2v (func))
             (import $foo "" "f")
             (func $a (call $foo))
             (func $b (result i32) (i32.const 0))
-            (table anyfunc (elem $a $b))
+            (table funcref (elem $a $b))
             (func $bar (call_indirect $v2v (i32.const 0)))
             (export "run" $bar)
         )`,
         undefined,
         {"":{f:() => { stack = new Error().stack }}}
     );
 
     disableGeckoProfiling();
--- a/js/src/jit-test/tests/wasm/builtin.js
+++ b/js/src/jit-test/tests/wasm/builtin.js
@@ -11,17 +11,17 @@ function unary(name) {
 
     let f32 = x => Math.fround(Math[name](Math.fround(x)));
     let f64 = Math[name];
 
     let i = wasmEvalText(`(module
         (import $f32 "math" "func" (param f32) (result f32))
         (import $f64 "math" "func" (param f64) (result f64))
 
-        (table $t 10 anyfunc)
+        (table $t 10 funcref)
         (type $f_f (func (param f32) (result f32)))
         (type $d_d (func (param f64) (result f64)))
         (elem (i32.const 0) $f32 $f64)
 
         (func (export "f32") (param f32) (result f32)
             get_local 0
             call $f32
         )
@@ -60,17 +60,17 @@ function binary(name) {
 
     let f32 = (x, y) => Math.fround(Math[name](Math.fround(x), Math.fround(y)));
     let f64 = Math[name];
 
     let i = wasmEvalText(`(module
         (import $f32 "math" "func" (param f32) (param f32) (result f32))
         (import $f64 "math" "func" (param f64) (param f64) (result f64))
 
-        (table $t 10 anyfunc)
+        (table $t 10 funcref)
         (type $ff_f (func (param f32) (param f32) (result f32)))
         (type $dd_d (func (param f64) (param f64) (result f64)))
         (elem (i32.const 0) $f32 $f64)
 
         (func (export "f32") (param f32) (param f32) (result f32)
             get_local 0
             get_local 1
             call $f32
--- a/js/src/jit-test/tests/wasm/caching.js
+++ b/js/src/jit-test/tests/wasm/caching.js
@@ -61,17 +61,17 @@ testCached(
 
 testCached(
     `(module
        (type $T (func (result i32)))
        (func $t1 (import "" "t1") (type $T))
        (func $t2 (import "" "t2") (type $T))
        (func $t3 (type $T) (i32.const 30))
        (func $t4 (type $T) (i32.const 40))
-       (table anyfunc (elem $t1 $t2 $t3 $t4))
+       (table funcref (elem $t1 $t2 $t3 $t4))
        (func (export "run") (param i32) (result i32)
          (call_indirect $T (get_local 0))))`,
     {'':{ t1() { return 10 }, t2() { return 20 } }},
     i => {
         assertEq(i.exports.run(0), 10);
         assertEq(i.exports.run(1), 20);
         assertEq(i.exports.run(2), 30);
         assertEq(i.exports.run(3), 40);
--- a/js/src/jit-test/tests/wasm/errors.js
+++ b/js/src/jit-test/tests/wasm/errors.js
@@ -101,19 +101,19 @@ test(I64TruncUF64Code, '(module (func (d
 test(I32TruncSF32Code, '(module (func (drop (i32.trunc_s/f32 (f32.const nan)))) (start 0))', RuntimeError, /invalid conversion to integer/);
 test(I32TruncSF64Code, '(module (func (drop (i32.trunc_s/f64 (f64.const nan)))) (start 0))', RuntimeError, /invalid conversion to integer/);
 test(I32TruncUF32Code, '(module (func (drop (i32.trunc_u/f32 (f32.const nan)))) (start 0))', RuntimeError, /invalid conversion to integer/);
 test(I32TruncUF64Code, '(module (func (drop (i32.trunc_u/f64 (f64.const nan)))) (start 0))', RuntimeError, /invalid conversion to integer/);
 test(I64TruncSF32Code, '(module (func (drop (i64.trunc_s/f32 (f32.const nan)))) (start 0))', RuntimeError, /invalid conversion to integer/);
 test(I64TruncSF64Code, '(module (func (drop (i64.trunc_s/f64 (f64.const nan)))) (start 0))', RuntimeError, /invalid conversion to integer/);
 test(I64TruncUF32Code, '(module (func (drop (i64.trunc_u/f32 (f32.const nan)))) (start 0))', RuntimeError, /invalid conversion to integer/);
 test(I64TruncUF64Code, '(module (func (drop (i64.trunc_u/f64 (f64.const nan)))) (start 0))', RuntimeError, /invalid conversion to integer/);
-test(CallIndirectCode, '(module (table 1 anyfunc) (func (call_indirect 0 (i32.const 0))) (start 0))', RuntimeError, /indirect call to null/);
-test(CallIndirectCode, '(module (table 1 anyfunc) (func (call_indirect 0 (i32.const 1))) (start 0))', RuntimeError, /index out of bounds/);
-test(CallIndirectCode, '(module (table anyfunc (elem $blah)) (func (call_indirect 0 (i32.const 0))) (func $blah (param i32)) (start 0))', RuntimeError, /indirect call signature mismatch/);
+test(CallIndirectCode, '(module (table 1 funcref) (func (call_indirect 0 (i32.const 0))) (start 0))', RuntimeError, /indirect call to null/);
+test(CallIndirectCode, '(module (table 1 funcref) (func (call_indirect 0 (i32.const 1))) (start 0))', RuntimeError, /index out of bounds/);
+test(CallIndirectCode, '(module (table funcref (elem $blah)) (func (call_indirect 0 (i32.const 0))) (func $blah (param i32)) (start 0))', RuntimeError, /indirect call signature mismatch/);
 testLoad(I32Load8S, 'i32.load8_s', 1, RuntimeError, /index out of bounds/);
 testLoad(I32Load8U, 'i32.load8_u', 1, RuntimeError, /index out of bounds/);
 testLoad(I32Load16S, 'i32.load16_s', 2, RuntimeError, /index out of bounds/);
 testLoad(I32Load16U, 'i32.load16_u', 2, RuntimeError, /index out of bounds/);
 testLoad(I64Load8S, 'i64.load8_s', 1, RuntimeError, /index out of bounds/);
 testLoad(I64Load8U, 'i64.load8_u', 1, RuntimeError, /index out of bounds/);
 testLoad(I64Load16S, 'i64.load16_s', 2, RuntimeError, /index out of bounds/);
 testLoad(I64Load16U, 'i64.load16_u', 2, RuntimeError, /index out of bounds/);
@@ -140,17 +140,17 @@ testStore(F64Store, 'f64.store', 'f64', 
 test(4 /* = num locals */, '(module (func (local i32 i64 f32 f64) (call 0)) (start 0))', InternalError, /too much recursion/);
 
 // Test whole callstack.
 var {stack, binary} = test(UnreachableCode, `(module
     (type $v2v (func))
     (func $a unreachable)
     (func $b call $a)
     (func $c call $b)
-    (table anyfunc (elem $c))
+    (table funcref (elem $c))
     (func $d (call_indirect $v2v (i32.const 0)))
     (func $e call $d)
     (start $e)
 )`, RuntimeError, /unreachable executed/);
 const N = 5;
 assertEq(stack.length > N, true);
 assertEq(getWasmFunctionIndex(stack[0].line), 0);
 var lastLine = stack[0].line;
--- a/js/src/jit-test/tests/wasm/full-cycle.js
+++ b/js/src/jit-test/tests/wasm/full-cycle.js
@@ -66,33 +66,33 @@ wasmFullPass(`(module
         i32.const 1
         i32.load offset=2
     )
     (export "mem" memory)
 )`, 0x050403, {"": {memory}});
 
 // Tables.
 wasmFullPass(`(module
-    (table (export "table") 3 anyfunc)
+    (table (export "table") 3 funcref)
     (type $t (func (result i32)))
     (func $foo (result i32) (i32.const 1))
     (func $bar (result i32) (i32.const 2))
     (func $baz (result i32) (i32.const 3))
     (elem (i32.const 0) $baz $bar)
     (elem (i32.const 2) $foo)
     (func (export "run") (param i32) (result i32)
         get_local 0
         call_indirect $t
     )
 )`, 3, {}, 0);
 
-let table = new WebAssembly.Table({ element: 'anyfunc', initial: 3, maximum: 3 });
+let table = new WebAssembly.Table({ element: 'funcref', initial: 3, maximum: 3 });
 
 wasmFullPass(`(module
-    (table (import "" "table") 3 4 anyfunc)
+    (table (import "" "table") 3 4 funcref)
     (type $t (func (result i32)))
     (func $foo (result i32) (i32.const 1))
     (func $bar (result i32) (i32.const 2))
     (func $baz (result i32) (i32.const 3))
     (elem (i32.const 0) $baz $bar)
     (elem (i32.const 2) $foo)
     (func (export "run") (param i32) (result i32)
         get_local 0
--- a/js/src/jit-test/tests/wasm/gc/anyref.js
+++ b/js/src/jit-test/tests/wasm/gc/anyref.js
@@ -345,17 +345,17 @@ exports = wasmEvalText(`(module
         get_global $count_g
         i32.add
         set_global $count_g
 
         get_local $param
         call $mirror
     )
 
-    (table (export "table") 10 anyfunc)
+    (table (export "table") 10 funcref)
     (elem (i32.const 0) $f $g $mirror $augment)
     (type $table_type (func (param anyref) (result anyref)))
 
     (func (export "call_indirect") (param $i i32) (param $ref anyref) (result anyref)
         get_local $ref
         get_local $i
         call_indirect $table_type
     )
--- a/js/src/jit-test/tests/wasm/gc/ion-and-baseline.js
+++ b/js/src/jit-test/tests/wasm/gc/ion-and-baseline.js
@@ -17,17 +17,17 @@
 // without the caller knowing this or having to declare it.  All such calls
 // should fail in an orderly manner with a type mismatch, at the point of the
 // call.
 
 var refmod = new WebAssembly.Module(wasmTextToBinary(
     `(module
       (gc_feature_opt_in 3)
 
-      (import $tbl "" "tbl" (table 4 anyfunc))
+      (import $tbl "" "tbl" (table 4 funcref))
       (import $print "" "print" (func (param i32)))
 
       (type $htype (func (param anyref)))
       (type $itype (func (result anyref)))
 
       (elem (i32.const 0) $f $g)
 
       (func $f (param anyref)
@@ -42,17 +42,17 @@ var refmod = new WebAssembly.Module(wasm
 
       (func (export "test_i")
        (drop (call_indirect $itype (i32.const 3))))
 
      )`));
 
 var nonrefmod = new WebAssembly.Module(wasmTextToBinary(
     `(module
-      (import $tbl "" "tbl" (table 4 anyfunc))
+      (import $tbl "" "tbl" (table 4 funcref))
       (import $print "" "print" (func (param i32)))
 
       (type $ftype (func (param i32)))
       (type $gtype (func (result i32)))
 
       (elem (i32.const 2) $h $i)
 
       ;; Should fail because of the signature mismatch: parameter
@@ -66,17 +66,17 @@ var nonrefmod = new WebAssembly.Module(w
       (func $h (param i32)
        (call $print (i32.const 2)))
 
       (func $i (result i32)
        (call $print (i32.const 3))
        (i32.const 37))
      )`));
 
-var tbl = new WebAssembly.Table({initial:4, element:"anyfunc"});
+var tbl = new WebAssembly.Table({initial:4, element:"funcref"});
 var refins = new WebAssembly.Instance(refmod, {"":{print, tbl}}).exports;
 var nonrefins = new WebAssembly.Instance(nonrefmod, {"":{print, tbl}}).exports;
 
 assertErrorMessage(() => nonrefins.test_f(),
                    WebAssembly.RuntimeError,
                    /indirect call signature mismatch/);
 
 assertErrorMessage(() => nonrefins.test_g(),
--- a/js/src/jit-test/tests/wasm/gc/ref-restrict.js
+++ b/js/src/jit-test/tests/wasm/gc/ref-restrict.js
@@ -172,178 +172,178 @@ assertEq(typeof wasmCompile(
          "object");
 
 // Exported table cannot reference functions that are exposed for Ref, but anyref is OK.
 
 assertErrorMessage(() => wasmCompile(
     `(module
       (gc_feature_opt_in 3)
       (type $box (struct (field $val i32)))
-      (table (export "tbl") 1 anyfunc)
+      (table (export "tbl") 1 funcref)
       (elem (i32.const 0) $f1)
       (func $f1 (param (ref $box)) (unreachable)))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertErrorMessage(() => wasmCompile(
     `(module
       (gc_feature_opt_in 3)
       (type $box (struct (field $val i32)))
-      (table (export "tbl") 1 anyfunc)
+      (table (export "tbl") 1 funcref)
       (elem (i32.const 0) $f1)
       (func $f1 (result (ref $box)) (ref.null)))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertEq(typeof wasmCompile(
     `(module
       (gc_feature_opt_in 3)
-      (table (export "tbl") 1 anyfunc)
+      (table (export "tbl") 1 funcref)
       (elem (i32.const 0) $f1)
       (func $f1 (param anyref) (unreachable)))`),
          "object");
 
 assertEq(typeof wasmCompile(
     `(module
       (gc_feature_opt_in 3)
-      (table (export "tbl") 1 anyfunc)
+      (table (export "tbl") 1 funcref)
       (elem (i32.const 0) $f1)
       (func $f1 (result anyref) (ref.null)))`),
          "object");
 
 // Imported table cannot reference functions that are exposed for Ref, though anyref is OK.
 
 assertErrorMessage(() => wasmCompile(
     `(module
       (gc_feature_opt_in 3)
       (type $box (struct (field $val i32)))
-      (import "m" "tbl" (table 1 anyfunc))
+      (import "m" "tbl" (table 1 funcref))
       (elem (i32.const 0) $f1)
       (func $f1 (param (ref $box)) (unreachable)))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertErrorMessage(() => wasmCompile(
     `(module
       (gc_feature_opt_in 3)
       (type $box (struct (field $val i32)))
-      (import "m" "tbl" (table 1 anyfunc))
+      (import "m" "tbl" (table 1 funcref))
       (elem (i32.const 0) $f1)
       (func $f1 (result (ref $box)) (ref.null)))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertEq(typeof wasmCompile(
     `(module
       (gc_feature_opt_in 3)
-      (import "m" "tbl" (table 1 anyfunc))
+      (import "m" "tbl" (table 1 funcref))
       (elem (i32.const 0) $f1)
       (func $f1 (param anyref) (unreachable)))`),
          "object");
 
 assertEq(typeof wasmCompile(
     `(module
       (gc_feature_opt_in 3)
-      (import "m" "tbl" (table 1 anyfunc))
+      (import "m" "tbl" (table 1 funcref))
       (elem (i32.const 0) $f1)
       (func $f1 (result anyref) (ref.null)))`),
          "object");
 
 // Can't call via exported table with type that is exposed for Ref, though anyref is OK.
 
 assertErrorMessage(() => wasmCompile(
     `(module
       (gc_feature_opt_in 3)
       (type $box (struct (field $val i32)))
       (type $fn (func (param (ref $box))))
-      (table (export "tbl") 1 anyfunc)
+      (table (export "tbl") 1 funcref)
       (func (param i32)
        (call_indirect $fn (ref.null) (get_local 0))))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertErrorMessage(() => wasmCompile(
     `(module
       (gc_feature_opt_in 3)
       (type $box (struct (field $val i32)))
       (type $fn (func (result (ref $box))))
-      (table (export "tbl") 1 anyfunc)
+      (table (export "tbl") 1 funcref)
       (func (param i32) (result (ref $box))
        (call_indirect $fn (get_local 0))))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertEq(typeof wasmCompile(
     `(module
       (gc_feature_opt_in 3)
       (type $fn (func (param anyref)))
-      (table (export "tbl") 1 anyfunc)
+      (table (export "tbl") 1 funcref)
       (func (param i32)
        (call_indirect $fn (ref.null) (get_local 0))))`),
          "object");
 
 assertEq(typeof wasmCompile(
     `(module
       (gc_feature_opt_in 3)
       (type $fn (func (result anyref)))
-      (table (export "tbl") 1 anyfunc)
+      (table (export "tbl") 1 funcref)
       (func (param i32) (result anyref)
        (call_indirect $fn (get_local 0))))`),
          "object");
 
 // Can't call via imported table with type that is exposed for Ref, though anyref is OK.
 
 assertErrorMessage(() => wasmCompile(
     `(module
       (gc_feature_opt_in 3)
       (type $box (struct (field $val i32)))
       (type $fn (func (param (ref $box))))
-      (import "m" "tbl" (table 1 anyfunc))
+      (import "m" "tbl" (table 1 funcref))
       (func (param i32)
        (call_indirect $fn (ref.null) (get_local 0))))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertErrorMessage(() => wasmCompile(
     `(module
       (gc_feature_opt_in 3)
       (type $box (struct (field $val i32)))
       (type $fn (func (result (ref $box))))
-      (import "m" "tbl" (table 1 anyfunc))
+      (import "m" "tbl" (table 1 funcref))
       (func (param i32) (result (ref $box))
        (call_indirect $fn (get_local 0))))`),
                    WebAssembly.CompileError,
                    /cannot expose reference type/);
 
 assertEq(typeof wasmCompile(
     `(module
       (gc_feature_opt_in 3)
       (type $fn (func (param anyref)))
-      (import "m" "tbl" (table 1 anyfunc))
+      (import "m" "tbl" (table 1 funcref))
       (func (param i32)
        (call_indirect $fn (ref.null) (get_local 0))))`),
          "object");
 
 assertEq(typeof wasmCompile(
     `(module
       (gc_feature_opt_in 3)
       (type $fn (func (result anyref)))
-      (import "m" "tbl" (table 1 anyfunc))
+      (import "m" "tbl" (table 1 funcref))
       (func (param i32) (result anyref)
        (call_indirect $fn (get_local 0))))`),
          "object");
 
 // We can call via a private table with a type that is exposed for Ref.
 
 {
     let m = wasmCompile(
         `(module
           (gc_feature_opt_in 3)
           (type $box (struct (field $val i32)))
           (type $fn (func (param (ref $box)) (result i32)))
-          (table 1 anyfunc)
+          (table 1 funcref)
           (elem (i32.const 0) $f1)
           (func $f1 (param (ref $box)) (result i32) (i32.const 37))
           (func (export "f") (param i32) (result i32)
            (call_indirect $fn (ref.null) (get_local 0))))`);
     let i = new WebAssembly.Instance(m).exports;
     assertEq(i.f(0), 37);
 }
--- a/js/src/jit-test/tests/wasm/gc/stackmaps1.js
+++ b/js/src/jit-test/tests/wasm/gc/stackmaps1.js
@@ -17,17 +17,17 @@ const {Module,Instance} = WebAssembly;
 
 let t =
   `(module
      (gc_feature_opt_in 3)
      (import $check3 "" "check3" (func (param anyref) (param anyref) (param anyref)))
      (type $typeOfFn0
            (func (result i32) (param i32) (param anyref) (param i32)
                               (param anyref) (param anyref) (param i32)))
-     (table 1 1 anyfunc)
+     (table 1 1 funcref)
      (elem (i32.const 0) $fn0)
 
      (import $alloc "" "alloc" (func (result anyref)))
 
      ;; -- fn 0
      (func $fn0 (export "fn0")
                 (result i32) (param $arg1 i32) (param $arg2 anyref) (param $arg3 i32)
                              (param $arg4 anyref) (param $arg5 anyref) (param $arg6 i32)
--- a/js/src/jit-test/tests/wasm/gc/stackmaps2.js
+++ b/js/src/jit-test/tests/wasm/gc/stackmaps2.js
@@ -27,17 +27,17 @@ const {Module,Instance} = WebAssembly;
 const DEBUG = false;
 
 let t =
   `(module
      (gc_feature_opt_in 3)
      (type $typeOfFn0
            (func (result i32) (param i32) (param anyref) (param i32)
                               (param anyref) (param anyref) (param i32)))
-     (table 1 1 anyfunc)
+     (table 1 1 funcref)
      (elem (i32.const 0) $fn0)
 
      (import $alloc "" "alloc" (func (result anyref)))
      (import $quitp "" "quitp" (func (result i32)))
      (import $check3 "" "check3" (func (param anyref) (param anyref) (param anyref)))
 
      ;; -- fn 0
      (func $fn0 (export "fn0")
--- a/js/src/jit-test/tests/wasm/gc/structs.js
+++ b/js/src/jit-test/tests/wasm/gc/structs.js
@@ -1,17 +1,17 @@
 // |jit-test| skip-if: !wasmGcEnabled() || wasmCompileMode() != 'baseline'
 
 var conf = getBuildConfiguration();
 
 var bin = wasmTextToBinary(
     `(module
       (gc_feature_opt_in 3)
 
-      (table 2 anyfunc)
+      (table 2 funcref)
       (elem (i32.const 0) $doit $doitagain)
 
       ;; Type array has a mix of types
 
       (type $f1 (func (param i32) (result i32)))
 
       (type $point (struct
                     (field $point_x i32)
--- a/js/src/jit-test/tests/wasm/gc/tables-generalized-disabled.js
+++ b/js/src/jit-test/tests/wasm/gc/tables-generalized-disabled.js
@@ -1,6 +1,6 @@
 // |jit-test| skip-if: wasmGeneralizedTables()
 
 assertErrorMessage(() => new WebAssembly.Table({element:"anyref", initial:10}),
                    TypeError,
-                   /"element" property of table descriptor must be "anyfunc"/);
+                   /"element" property of table descriptor must be "funcref"/);
 
--- a/js/src/jit-test/tests/wasm/gc/tables-generalized.js
+++ b/js/src/jit-test/tests/wasm/gc/tables-generalized.js
@@ -87,53 +87,53 @@ new WebAssembly.Instance(new WebAssembly
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
        (gc_feature_opt_in 3)
        (func $f1 (result i32) (i32.const 0))
        (table 10 anyref)
        (elem (i32.const 0) $f1))`)),
                    WebAssembly.CompileError,
-                   /only tables of 'anyfunc' may have element segments/);
+                   /only tables of 'funcref' may have element segments/);
 
 // Wasm: table.init on table-of-anyref is forbidden
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
        (gc_feature_opt_in 3)
        (func $f1 (result i32) (i32.const 0))
        (table 10 anyref)
        (elem passive $f1)
        (func
          (table.init 0 (i32.const 0) (i32.const 0) (i32.const 0))))`)),
                    WebAssembly.CompileError,
-                   /only tables of 'anyfunc' may have element segments/);
+                   /only tables of 'funcref' may have element segments/);
 
 // Wasm: table types must match at link time
 
 assertErrorMessage(
     () => new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(
     `(module
        (gc_feature_opt_in 3)
        (import "m" "t" (table 10 anyref)))`)),
-                                   {m:{t: new WebAssembly.Table({element:"anyfunc", initial:10})}}),
+                                   {m:{t: new WebAssembly.Table({element:"funcref", initial:10})}}),
     WebAssembly.LinkError,
     /imported table type mismatch/);
 
 // call_indirect cannot reference table-of-anyref
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
        (gc_feature_opt_in 3)
        (table 10 anyref)
        (type $t (func (param i32) (result i32)))
        (func (result i32)
          (call_indirect $t (i32.const 37))))`)),
                    WebAssembly.CompileError,
-                   /indirect calls must go through a table of 'anyfunc'/);
+                   /indirect calls must go through a table of 'funcref'/);
 
 ///////////////////////////////////////////////////////////////////////////
 //
 // additional js api tests
 
 {
     let tbl = new WebAssembly.Table({element:"anyref", initial:10});
 
@@ -188,31 +188,31 @@ assertErrorMessage(() => new WebAssembly
     `(module
        (gc_feature_opt_in 3)
        (table 10 anyref)
        (func (export "f") (param f64) (result anyref)
          (table.get (get_local 0))))`)),
                    WebAssembly.CompileError,
                    /type mismatch/);
 
-// table.get on table of anyfunc - fails validation because anyfunc is not expressible
+// table.get on table of funcref - fails validation because funcref is not expressible
 // Both with and without anyref support
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
-       (table 10 anyfunc)
+       (table 10 funcref)
        (func (export "f") (param i32)
          (drop (table.get (get_local 0)))))`)),
                    WebAssembly.CompileError,
                    /table.get only on tables of anyref/);
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
        (gc_feature_opt_in 3)
-       (table 10 anyfunc)
+       (table 10 funcref)
        (func (export "f") (param i32)
          (drop (table.get (get_local 0)))))`)),
                    WebAssembly.CompileError,
                    /table.get only on tables of anyref/);
 
 // table.get when there are no tables - fails validation
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
@@ -262,24 +262,24 @@ assertErrorMessage(() => new WebAssembly
     `(module
        (gc_feature_opt_in 3)
        (table 10 anyref)
        (func (export "f") (param f64)
          (table.set (i32.const 0) (get_local 0))))`)),
                    WebAssembly.CompileError,
                    /type mismatch/);
 
-// table.set on table of anyfunc - fails validation
+// table.set on table of funcref - fails validation
 // We need the gc_feature_opt_in here because of the anyref parameter; if we change
 // that to some other type, it's the validation of that type that fails us.
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
     `(module
       (gc_feature_opt_in 3)
-      (table 10 anyfunc)
+      (table 10 funcref)
       (func (export "f") (param anyref)
        (table.set (i32.const 0) (get_local 0))))`)),
                    WebAssembly.CompileError,
                    /table.set only on tables of anyref/);
 
 // table.set when there are no tables - fails validation
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
@@ -332,22 +332,22 @@ assertEq(ins.exports.t.length, 20)
           (func (export "grow") (param i32) (result i32)
            (table.grow (get_local 0) (ref.null))))`);
     assertEq(ins.exports.grow(0), 10);
     assertEq(ins.exports.grow(1), 10);
     assertEq(ins.exports.grow(9), 11);
     assertEq(ins.exports.grow(0), 20);
 }
 
-// Can't grow table of anyfunc yet
+// Can't grow table of funcref yet
 
 assertErrorMessage(() => wasmEvalText(
     `(module
       (gc_feature_opt_in 3)     ;; Required because of the 'anyref' null value below
-      (table $t 2 anyfunc)
+      (table $t 2 funcref)
       (func $f
        (drop (table.grow (i32.const 1) (ref.null)))))`),
                    WebAssembly.CompileError,
                    /table.grow only on tables of anyref/);
 
 // table.grow with non-i32 argument - fails validation
 
 assertErrorMessage(() => new WebAssembly.Module(wasmTextToBinary(
@@ -389,22 +389,22 @@ for (let visibility of ['', '(export "t"
     assertEq(ins.exports.grow(1), 10);
     assertEq(ins.exports.size(), 11);
     assertEq(ins.exports.grow(9), 11);
     assertEq(ins.exports.size(), 20);
     assertEq(ins.exports.grow(0), 20);
     assertEq(ins.exports.size(), 20);
 }
 
-// table.size on table of anyfunc
+// table.size on table of funcref
 
 {
     let ins = wasmEvalText(
         `(module
-          (table (export "t") 2 anyfunc)
+          (table (export "t") 2 funcref)
           (func (export "f") (result i32)
            (table.size)))`);
     assertEq(ins.exports.f(), 2);
     ins.exports.t.grow(1);
     assertEq(ins.exports.f(), 3);
 }
 
 // JS API for growing the table can take a fill argument, defaulting to null
@@ -431,17 +431,17 @@ let VALUES = [null,
         assertEq(t.get(t.length-3), prev);
         assertEq(t.get(t.length-2), v);
         assertEq(t.get(t.length-1), v);
         prev = v;
     }
 }
 
 {
-    let t = new WebAssembly.Table({element:"anyfunc", initial:0});
+    let t = new WebAssembly.Table({element:"funcref", initial:0});
     let ins = wasmEvalText(
         `(module
            (func (export "f") (param i32) (result i32)
              (get_local 0)))`);
     t.grow(1);
     assertEq(t.get(t.length-1), null);
     t.grow(2, ins.exports.f);
     assertEq(t.get(t.length-3), null);
--- a/js/src/jit-test/tests/wasm/gc/tables-multiple.js
+++ b/js/src/jit-test/tests/wasm/gc/tables-multiple.js
@@ -9,18 +9,18 @@
 
 // - multiple local tables of misc type: syntax, validation, instantiation
 // - element segments can point to a table
 // - call-indirect can specify a table and will use it
 // - be sure to test table stuff w/o gc_feature_opt_in so that we get ion coverage too
 
 var ins = wasmEvalText(
     `(module
-      (table $t1 2 anyfunc)
-      (table $t2 2 anyfunc)
+      (table $t1 2 funcref)
+      (table $t2 2 funcref)
       (type $ftype (func (param i32) (result i32)))
       (elem $t1 (i32.const 0) $f1 $f2)
       (elem $t2 (i32.const 0) $f3 $f4)
       (func $f1 (param $n i32) (result i32)
        (i32.add (get_local $n) (i32.const 1)))
       (func $f2 (param $n i32) (result i32)
        (i32.add (get_local $n) (i32.const 2)))
       (func $f3 (param $n i32) (result i32)
@@ -39,46 +39,46 @@ assertEq(ins.g(1, 10), 14);
 
 // - export multiple tables.
 //   note the first and third tables make the export list not start at zero,
 //   and make it sparse
 
 var ins = wasmEvalText(
     `(module
       (gc_feature_opt_in 3)
-      (table $t0 (import "m" "t") 2 anyfunc)
-      (table $t1 (export "t1") 2 anyfunc)
+      (table $t0 (import "m" "t") 2 funcref)
+      (table $t1 (export "t1") 2 funcref)
       (table 1 anyref)
-      (table $t2 (export "t2") 3 anyfunc))`,
-    {m:{t: new WebAssembly.Table({element:"anyfunc", initial:2})}}).exports;
+      (table $t2 (export "t2") 3 funcref))`,
+    {m:{t: new WebAssembly.Table({element:"funcref", initial:2})}}).exports;
 
 assertEq(ins.t1 instanceof WebAssembly.Table, true);
 assertEq(ins.t1.length, 2);
 assertEq(ins.t2 instanceof WebAssembly.Table, true);
 assertEq(ins.t2.length, 3);
 
 // - multiple imported tables of misc type
 // - table.get and table.set can point to a table
 
-var exp = {m:{t0: new WebAssembly.Table({element:"anyfunc", initial:2}),
+var exp = {m:{t0: new WebAssembly.Table({element:"funcref", initial:2}),
               t1: new WebAssembly.Table({element:"anyref", initial:3}),
-              t2: new WebAssembly.Table({element:"anyfunc", initial:4}),
+              t2: new WebAssembly.Table({element:"funcref", initial:4}),
               t3: new WebAssembly.Table({element:"anyref", initial:5})}};
 var ins = wasmEvalText(
     `(module
       (gc_feature_opt_in 3)
 
-      (table $t0 (import "m" "t0") 2 anyfunc)
+      (table $t0 (import "m" "t0") 2 funcref)
       (type $id_i32_t (func (param i32) (result i32)))
       (func $id_i32 (param i32) (result i32) (get_local 0))
       (elem $t0 (i32.const 1) $id_i32)
 
       (table $t1 (import "m" "t1") 3 anyref)
 
-      (table $t2 (import "m" "t2") 4 anyfunc)
+      (table $t2 (import "m" "t2") 4 funcref)
       (type $id_f64_t (func (param f64) (result f64)))
       (func $id_f64 (param f64) (result f64) (get_local 0))
       (elem $t2 (i32.const 3) $id_f64)
 
       (table $t3 (import "m" "t3") 5 anyref)
 
       (func (export "f0") (param i32) (result i32)
        (call_indirect $t0 $id_i32_t (get_local 0) (i32.const 1)))
@@ -180,37 +180,37 @@ assertEq(ins.exports.get(1), values[1]);
 // in effect forces a representation for the function in the local table that
 // captures the function's instance, at the latest at the time the copy is
 // executed.
 //
 // In the case where the function is imported, it comes from a different module.
 //
 // Also tests:
 // - local tables can be exported and re-imported in another module
-// - table.copy between tables of anyfunc is possible without gc_feature_opt_in
+// - table.copy between tables of funcref is possible without gc_feature_opt_in
 
 var arg = 4;
 for (let [x,y,result,init] of [['(export "t")', '', arg*13, true],
                                ['', '(export "t")', arg*13, true],
                                ['(import "m" "t")', '', arg*13, true],
                                ['', '(import "m" "t")', arg-11, false]])
 {
     var otherins = wasmEvalText(
         `(module
-          (table $t (export "t") 2 anyfunc)
+          (table $t (export "t") 2 funcref)
           (type $fn1 (func (param i32) (result i32)))
           (func $f1 (param $n i32) (result i32)
            (i32.sub (get_local $n) (i32.const 11)))
           (elem $t (i32.const 1) $f1))`);
 
     let text =
         `(module
-          (table $t0 ${x} 2 anyfunc)
+          (table $t0 ${x} 2 funcref)
 
-          (table $t1 ${y} 2 anyfunc)
+          (table $t1 ${y} 2 funcref)
           (type $fn1 (func (param i32) (result i32)))
           (func $f1 (param $n i32) (result i32)
            (i32.mul (get_local $n) (i32.const 13)))
           ${init ? "(elem $t1 (i32.const 1) $f1)" : ""}
 
           (func (export "f") (param $n i32) (result i32)
            (table.copy $t0 (i32.const 0) $t1 (i32.const 0) (i32.const 2))
            (call_indirect $t0 $fn1 (get_local $n) (i32.const 1))))`;
@@ -227,17 +227,17 @@ for (let [x,y,result,init] of [['(export
 var tbl = new WebAssembly.Table({element:"anyref", initial:1});
 var exp = {m: {t0: tbl, t1:tbl}};
 
 var ins = wasmEvalText(
     `(module
       (gc_feature_opt_in 3)
       (import $t0 "m" "t0" (table 1 anyref))
       (import $t1 "m" "t1" (table 1 anyref))
-      (table $t2 (export "t2") 1 anyfunc)
+      (table $t2 (export "t2") 1 funcref)
       (func (export "f") (result i32)
        (table.grow $t0 (i32.const 1) (ref.null)))
       (func (export "g") (result i32)
        (table.grow $t1 (i32.const 1) (ref.null)))
       (func (export "size") (result i32)
        (table.size $t2)))`,
     exp);
 
@@ -245,65 +245,65 @@ assertEq(ins.exports.f(), 1);
 assertEq(ins.exports.g(), 2);
 assertEq(ins.exports.f(), 3);
 assertEq(ins.exports.g(), 4);
 assertEq(tbl.length, 5);
 ins.exports.t2.grow(3);
 assertEq(ins.exports.size(), 4);
 
 // - table.init on tables other than table 0
-// - gc_feature_opt_in not required for table.init on table(anyfunc) even with multiple tables
+// - gc_feature_opt_in not required for table.init on table(funcref) even with multiple tables
 
 var ins = wasmEvalText(
     `(module
-      (table $t0 2 anyfunc)
-      (table $t1 2 anyfunc)
+      (table $t0 2 funcref)
+      (table $t1 2 funcref)
       (elem passive $f0 $f1) ;; 0
       (type $ftype (func (param i32) (result i32)))
       (func $f0 (param i32) (result i32)
        (i32.mul (get_local 0) (i32.const 13)))
       (func $f1 (param i32) (result i32)
        (i32.sub (get_local 0) (i32.const 11)))
       (func (export "call") (param i32) (param i32) (result i32)
        (call_indirect $t1 $ftype (get_local 1) (get_local 0)))
       (func (export "init")
        (table.init $t1 0 (i32.const 0) (i32.const 0) (i32.const 2))))`);
 
 ins.exports.init();
 assertEq(ins.exports.call(0, 10), 130);
 assertEq(ins.exports.call(1, 10), -1);
 
-// - [white-box] if a multi-imported table of anyfunc is grown and the grown
+// - [white-box] if a multi-imported table of funcref is grown and the grown
 //   part is properly initialized with functions then calls through both tables
 //   in the grown area should succeed, ie, bounds checks should pass.  this is
 //   an interesting case because we cache the table bounds for the benefit of
 //   call_indirect, so here we're testing that the caches are updated properly
 //   even when a table is observed multiple times (also by multiple modules).
-//   there's some extra hair here because a table of anyfunc can be grown only
+//   there's some extra hair here because a table of funcref can be grown only
 //   from JS at the moment.
 // - also test that bounds checking continues to catch OOB calls
 
-var tbl = new WebAssembly.Table({element:"anyfunc", initial:2});
+var tbl = new WebAssembly.Table({element:"funcref", initial:2});
 var exp = {m:{t0: tbl, t1: tbl}};
 var ins = wasmEvalText(
     `(module
-      (import "m" "t0" (table $t0 2 anyfunc))
-      (import "m" "t1" (table $t1 2 anyfunc))
+      (import "m" "t0" (table $t0 2 funcref))
+      (import "m" "t1" (table $t1 2 funcref))
       (type $ftype (func (param f64) (result f64)))
       (func (export "f") (param $n f64) (result f64)
        (f64.mul (get_local $n) (f64.const 3.25)))
       (func (export "do0") (param $i i32) (param $n f64) (result f64)
        (call_indirect $t0 $ftype (get_local $n) (get_local $i)))
       (func (export "do1") (param $i i32) (param $n f64) (result f64)
        (call_indirect $t1 $ftype (get_local $n) (get_local $i))))`,
     exp);
 var ins2 = wasmEvalText(
     `(module
-      (import "m" "t0" (table $t0 2 anyfunc))
-      (import "m" "t1" (table $t1 2 anyfunc))
+      (import "m" "t0" (table $t0 2 funcref))
+      (import "m" "t1" (table $t1 2 funcref))
       (type $ftype (func (param f64) (result f64)))
       (func (export "do0") (param $i i32) (param $n f64) (result f64)
        (call_indirect $t0 $ftype (get_local $n) (get_local $i)))
       (func (export "do1") (param $i i32) (param $n f64) (result f64)
        (call_indirect $t1 $ftype (get_local $n) (get_local $i))))`,
     exp);
 
 assertEq(tbl.grow(10), 2);
@@ -388,67 +388,67 @@ assertErrorMessage(() => wasmEvalText(
       (table $t1 2 anyref)
       (func $f (result i32)
        (table.grow 2 (i32.const 1) (ref.null))))`),
                    WebAssembly.CompileError,
                    /table index out of range for table.grow/);
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (table $t0 2 anyfunc)
+      (table $t0 2 funcref)
       (elem passive) ;; 0
       (func $f (result i32)
        (table.init 2 0 (i32.const 0) (i32.const 0) (i32.const 0))))`),
                    WebAssembly.CompileError,
                    /table index out of range for table.init/);
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (table $t0 2 anyfunc)
+      (table $t0 2 funcref)
       (elem 2 (i32.const 0)))`),
                    WebAssembly.CompileError,
                    /table index out of range for element segment/);
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (table $t0 2 anyfunc)
+      (table $t0 2 funcref)
       (type $ft (func (param f64) (result i32)))
       (func $f (result i32)
        (call_indirect 2 $ft (f64.const 3.14) (i32.const 0))))`),
                    WebAssembly.CompileError,
                    /table index out of range for call_indirect/);
 
 // Syntax errors when parsing text
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (table $t0 2 anyfunc)
+      (table $t0 2 funcref)
       (elem 0 passive (i32.const 0)))`),
                    SyntaxError,
                    /passive segment must not have a table/);
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (table $t0 2 anyfunc)
+      (table $t0 2 funcref)
       (elem passive) ;; 0
       (func $f (result i32)
        (table.init $t0 (i32.const 0) (i32.const 0) (i32.const 0))))`), // no segment
                    SyntaxError,
                    /expected element segment reference/);
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (table $t0 2 anyfunc)
-      (table $t1 2 anyfunc)
+      (table $t0 2 funcref)
+      (table $t1 2 funcref)
       (func $f
        (table.copy 0 (i32.const 0) (i32.const 0) (i32.const 2))))`), // target without source
                    SyntaxError,
                    /source is required if target is specified/);
 
 assertErrorMessage(() => wasmEvalText(
     `(module
-      (table $t0 2 anyfunc)
-      (table $t1 2 anyfunc)
+      (table $t0 2 funcref)
+      (table $t1 2 funcref)
       (func $f
        (table.copy (i32.const 0) 0 (i32.const 0) (i32.const 2))))`), // source without target
                    SyntaxError,
                    /parsing wasm text/);
 
--- a/js/src/jit-test/tests/wasm/gc/tables-stress.js
+++ b/js/src/jit-test/tests/wasm/gc/tables-stress.js
@@ -1,11 +1,11 @@
 // |jit-test| skip-if: !wasmGeneralizedTables()
 
-for ( let prefix of ['', '(table $prefix 0 32 anyfunc)']) {
+for ( let prefix of ['', '(table $prefix 0 32 funcref)']) {
     let mod = new WebAssembly.Module(wasmTextToBinary(
     `(module
        (gc_feature_opt_in 3)
        ${prefix}
        (table $tbl 0 anyref)
        (import $item "m" "item" (func (result anyref)))
        (func (export "run") (param $numiters i32)
          (local $i i32)
--- a/js/src/jit-test/tests/wasm/globals.js
+++ b/js/src/jit-test/tests/wasm/globals.js
@@ -5,28 +5,28 @@ assertErrorMessage(() => wasmEvalText(`(
 assertErrorMessage(() => wasmEvalText(`(module (global i32))`), SyntaxError, /parsing/);
 assertErrorMessage(() => wasmEvalText(`(module (global (mut i32)))`), SyntaxError, /parsing/);
 
 // Initializer expressions.
 wasmFailValidateText(`(module (global i32 (f32.const 13.37)))`, /type mismatch/);
 wasmFailValidateText(`(module (global f64 (f32.const 13.37)))`, /type mismatch/);
 wasmFailValidateText(`(module (global i32 (i32.add (i32.const 13) (i32.const 37))))`, /failed to read end/);
 
-wasmFailValidateText(`(module (global i32 (get_global 0)))`, /out of range/);
+wasmFailValidateText(`(module (global i32 (global.get 0)))`, /out of range/);
 wasmFailValidateText(`(module (global i32 (get_global 1)) (global i32 (i32.const 1)))`, /out of range/);
 
 // Test a well-defined global section.
 function testInner(type, initialValue, nextValue, coercion)
 {
     var module = wasmEvalText(`(module
         (global (mut ${type}) (${type}.const ${initialValue}))
         (global ${type} (${type}.const ${initialValue}))
 
         (func $get (result ${type}) (get_global 0))
-        (func $set (param ${type}) (set_global 0 (get_local 0)))
+        (func $set (param ${type}) (global.set 0 (get_local 0)))
 
         (func $get_cst (result ${type}) (get_global 1))
 
         (export "get" $get)
         (export "get_cst" $get_cst)
 
         (export "set" $set)
     )`).exports;
@@ -86,21 +86,21 @@ for (let i = 0; i < 5; i++) {
             continue;
         assertEq(module[`get${j}`](), values[j]);
     }
     assertEq(module[`set${i}`](values[i]), undefined);
     assertEq(module[`get${i}`](), values[i]);
 }
 
 // Initializer expressions can also be used in elem section initializers.
-wasmFailValidateText(`(module (import "globals" "a" (global f32)) (table 4 anyfunc) (elem (get_global 0) $f) (func $f))`, /type mismatch/);
+wasmFailValidateText(`(module (import "globals" "a" (global f32)) (table 4 funcref) (elem (get_global 0) $f) (func $f))`, /type mismatch/);
 
 module = wasmEvalText(`(module
     (import "globals" "a" (global i32))
-    (table (export "tbl") 4 anyfunc)
+    (table (export "tbl") 4 funcref)
     (elem (get_global 0) $f)
     (func $f)
     (export "f" $f)
 )`, {
     globals: {
         a: 1
     }
 }).exports;
--- a/js/src/jit-test/tests/wasm/import-export-sigs.js
+++ b/js/src/jit-test/tests/wasm/import-export-sigs.js
@@ -27,17 +27,17 @@ var module = new WebAssembly.Module(wasm
   (export "v_Ififd" $vIfifd)
 
   (import $iv "env" "i_v" (result i32))
   (export "i_v" $iv)
 
   (import $Ii "env" "I_i" (result i64) (param i32))
   (export "I_i" $Ii)
 
-  (import $table "env" "table" (table 0 anyfunc))
+  (import $table "env" "table" (table 0 funcref))
   (export "table" (table $table))
 
   (import $fd "env" "f_d" (result f32) (param f64))
   (export "f_d" $fd)
 
   (import $dffd "env" "d_ffd" (result f64) (param f32) (param f32) (param f64))
   (export "d_ffd" $dffd)
 )`));
--- a/js/src/jit-test/tests/wasm/import-export.js
+++ b/js/src/jit-test/tests/wasm/import-export.js
@@ -9,41 +9,41 @@ const mem1PageMax1 = new Memory({initial
 const mem2Page = new Memory({initial:2});
 const mem2PageMax2 = new Memory({initial:2, maximum: 2});
 const mem2PageMax3 = new Memory({initial:2, maximum: 3});
 const mem2PageMax4 = new Memory({initial:2, maximum: 4});
 const mem3Page = new Memory({initial:3});
 const mem3PageMax3 = new Memory({initial:3, maximum: 3});
 const mem4Page = new Memory({initial:4});
 const mem4PageMax4 = new Memory({initial:4, maximum: 4});
-const tab1Elem = new Table({initial:1, element:"anyfunc"});
-const tab2Elem = new Table({initial:2, element:"anyfunc"});
-const tab3Elem = new Table({initial:3, element:"anyfunc"});
-const tab4Elem = new Table({initial:4, element:"anyfunc"});
+const tab1Elem = new Table({initial:1, element:"funcref"});
+const tab2Elem = new Table({initial:2, element:"funcref"});
+const tab3Elem = new Table({initial:3, element:"funcref"});
+const tab4Elem = new Table({initial:4, element:"funcref"});
 
 // Memory size consistency and internal limits.
 assertErrorMessage(() => new Memory({initial:2, maximum:1}), RangeError, /bad Memory maximum size/);
 
 try {
     new Memory({initial:16384});
 } catch(e) {
     assertEq(String(e).indexOf("out of memory") !== -1, true);
 }
 
 assertErrorMessage(() => new Memory({initial: 16385}), RangeError, /bad Memory initial size/);
 
 new Memory({initial: 0, maximum: 65536});
 assertErrorMessage(() => new Memory({initial: 0, maximum: 65537}), RangeError, /bad Memory maximum size/);
 
 // Table size consistency and internal limits.
-assertErrorMessage(() => new Table({initial:2, maximum:1, element:"anyfunc"}), RangeError, /bad Table maximum size/);
-new Table({ initial: 10000000, element:"anyfunc" });
-assertErrorMessage(() => new Table({initial:10000001, element:"anyfunc"}), RangeError, /bad Table initial size/);
-new Table({ initial: 0, maximum: 10000000, element:"anyfunc" });
-assertErrorMessage(() => new Table({initial:0, maximum: 10000001, element:"anyfunc"}), RangeError, /bad Table maximum size/);
+assertErrorMessage(() => new Table({initial:2, maximum:1, element:"funcref"}), RangeError, /bad Table maximum size/);
+new Table({ initial: 10000000, element:"funcref" });
+assertErrorMessage(() => new Table({initial:10000001, element:"funcref"}), RangeError, /bad Table initial size/);
+new Table({ initial: 0, maximum: 10000000, element:"funcref" });
+assertErrorMessage(() => new Table({initial:0, maximum: 10000001, element:"funcref"}), RangeError, /bad Table maximum size/);
 
 const m1 = new Module(wasmTextToBinary('(module (import "foo" "bar") (import "baz" "quux"))'));
 assertErrorMessage(() => new Instance(m1), TypeError, /second argument must be an object/);
 assertErrorMessage(() => new Instance(m1, {foo:null}), TypeError, /import object field 'foo' is not an Object/);
 assertErrorMessage(() => new Instance(m1, {foo:{bar:{}}}), LinkError, /import object field 'bar' is not a Function/);
 assertErrorMessage(() => new Instance(m1, {foo:{bar:()=>{}}, baz:null}), TypeError, /import object field 'baz' is not an Object/);
 assertErrorMessage(() => new Instance(m1, {foo:{bar:()=>{}}, baz:{}}), LinkError, /import object field 'quux' is not a Function/);
 assertEq(new Instance(m1, {foo:{bar:()=>{}}, baz:{quux:()=>{}}}) instanceof Instance, true);
@@ -82,32 +82,32 @@ assertErrorMessage(() => new Instance(m4
 assertEq(new Instance(m3, {baz:{quux:()=>{}}, foo:{bar:mem1PageMax1}}) instanceof Instance, true);
 
 const m5 = new Module(wasmTextToBinary('(module (import "a" "b" (memory 2)))'));
 assertErrorMessage(() => new Instance(m5, {a:{b:mem1Page}}), LinkError, /imported Memory with incompatible size/);
 assertEq(new Instance(m5, {a:{b:mem2Page}}) instanceof Instance, true);
 assertEq(new Instance(m5, {a:{b:mem3Page}}) instanceof Instance, true);
 assertEq(new Instance(m5, {a:{b:mem4Page}}) instanceof Instance, true);
 
-const m6 = new Module(wasmTextToBinary('(module (import "a" "b" (table 2 anyfunc)))'));
+const m6 = new Module(wasmTextToBinary('(module (import "a" "b" (table 2 funcref)))'));
 assertErrorMessage(() => new Instance(m6, {a:{b:tab1Elem}}), LinkError, /imported Table with incompatible size/);
 assertEq(new Instance(m6, {a:{b:tab2Elem}}) instanceof Instance, true);
 assertEq(new Instance(m6, {a:{b:tab3Elem}}) instanceof Instance, true);
 assertEq(new Instance(m6, {a:{b:tab4Elem}}) instanceof Instance, true);
 
-const m7 = new Module(wasmTextToBinary('(module (import "a" "b" (table 2 3 anyfunc)))'));
+const m7 = new Module(wasmTextToBinary('(module (import "a" "b" (table 2 3 funcref)))'));
 assertErrorMessage(() => new Instance(m7, {a:{b:tab1Elem}}), LinkError, /imported Table with incompatible size/);
 assertErrorMessage(() => new Instance(m7, {a:{b:tab2Elem}}), LinkError, /imported Table with incompatible maximum size/);
 assertErrorMessage(() => new Instance(m7, {a:{b:tab3Elem}}), LinkError, /imported Table with incompatible maximum size/);
 assertErrorMessage(() => new Instance(m7, {a:{b:tab4Elem}}), LinkError, /imported Table with incompatible size/);
 
 wasmFailValidateText('(module (memory 2 1))', /maximum length 1 is less than initial length 2/);
 wasmFailValidateText('(module (import "a" "b" (memory 2 1)))', /maximum length 1 is less than initial length 2/);
-wasmFailValidateText('(module (table 2 1 anyfunc))', /maximum length 1 is less than initial length 2/);
-wasmFailValidateText('(module (import "a" "b" (table 2 1 anyfunc)))', /maximum length 1 is less than initial length 2/);
+wasmFailValidateText('(module (table 2 1 funcref))', /maximum length 1 is less than initial length 2/);
+wasmFailValidateText('(module (import "a" "b" (table 2 1 funcref)))', /maximum length 1 is less than initial length 2/);
 
 // Import wasm-wasm type mismatch
 
 var e = wasmEvalText('(module (func $i2v (param i32)) (export "i2v" $i2v) (func $f2v (param f32)) (export "f2v" $f2v))').exports;
 var i2vm = new Module(wasmTextToBinary('(module (import "a" "b" (param i32)))'));
 var f2vm = new Module(wasmTextToBinary('(module (import "a" "b" (param f32)))'));
 assertEq(new Instance(i2vm, {a:{b:e.i2v}}) instanceof Instance, true);
 assertErrorMessage(() => new Instance(i2vm, {a:{b:e.f2v}}), LinkError, /imported function 'a.b' signature mismatch/);
@@ -212,60 +212,60 @@ assertEq(e.foo(), undefined);
 assertEq(e.bar.buffer.byteLength, 64*1024);
 
 var code = wasmTextToBinary('(module (memory 1 1) (export "" memory))');
 var e = new Instance(new Module(code)).exports;
 assertEq(Object.keys(e).length, 1);
 assertEq(String(Object.keys(e)), "");
 assertEq(e[""] instanceof Memory, true);
 
-var code = wasmTextToBinary('(module (table 0 anyfunc) (export "tbl" table))');
+var code = wasmTextToBinary('(module (table 0 funcref) (export "tbl" table))');
 var e = new Instance(new Module(code)).exports;
 assertEq(Object.keys(e).join(), "tbl");
 assertEq(e.tbl instanceof Table, true);
 assertEq(e.tbl.length, 0);
 
-var code = wasmTextToBinary('(module (table 2 anyfunc) (export "t1" table) (export "t2" table))');
+var code = wasmTextToBinary('(module (table 2 funcref) (export "t1" table) (export "t2" table))');
 var e = new Instance(new Module(code)).exports;
 assertEq(Object.keys(e).join(), "t1,t2");
 assertEq(e.t1 instanceof Table, true);
 assertEq(e.t2 instanceof Table, true);
 assertEq(e.t1, e.t2);
 assertEq(e.t1.length, 2);
 
-var code = wasmTextToBinary('(module (table 2 anyfunc) (memory 1 1) (func) (export "t" table) (export "m" memory) (export "f" 0))');
+var code = wasmTextToBinary('(module (table 2 funcref) (memory 1 1) (func) (export "t" table) (export "m" memory) (export "f" 0))');
 var e = new Instance(new Module(code)).exports;
 assertEq(Object.keys(e).join(), "t,m,f");
 assertEq(e.f(), undefined);
 assertEq(e.t instanceof Table, true);
 assertEq(e.m instanceof Memory, true);
 assertEq(e.t.length, 2);
 
-var code = wasmTextToBinary('(module (table 1 anyfunc) (memory 1 1) (func) (export "m" memory) (export "f" 0) (export "t" table))');
+var code = wasmTextToBinary('(module (table 1 funcref) (memory 1 1) (func) (export "m" memory) (export "f" 0) (export "t" table))');
 var e = new Instance(new Module(code)).exports;
 assertEq(Object.keys(e).join(), "m,f,t");
 assertEq(e.f(), undefined);
 assertEq(e.t instanceof Table, true);
 assertEq(e.m instanceof Memory, true);
 +assertEq(e.t.length, 1);
 
-var code = wasmTextToBinary('(module (table 0 anyfunc) (export "" table))');
+var code = wasmTextToBinary('(module (table 0 funcref) (export "" table))');
 var e = new Instance(new Module(code)).exports;
 assertEq(Object.keys(e).length, 1);
 assertEq(String(Object.keys(e)), "");
 assertEq(e[""] instanceof Table, true);
 +assertEq(e[""].length, 0);
 
 // Table export function identity
 
 var text = `(module
     (func $f (result i32) (i32.const 1))
     (func $g (result i32) (i32.const 2))
     (func $h (result i32) (i32.const 3))
-    (table 4 anyfunc)
+    (table 4 funcref)
     (elem (i32.const 0) $f)
     (elem (i32.const 2) $g)
     (export "f1" $f)
     (export "tbl1" table)
     (export "f2" $f)
     (export "tbl2" table)
     (export "f3" $h)
     (func (export "run") (result i32) (call_indirect 0 (i32.const 2)))
@@ -332,36 +332,36 @@ assertEq(args.length, 0);
 // Re-exports and Identity:
 
 var code = wasmTextToBinary('(module (import "a" "b" (memory 1 1)) (export "foo" memory) (export "bar" memory))');
 var mem = new Memory({initial:1, maximum:1});
 var e = new Instance(new Module(code), {a:{b:mem}}).exports;
 assertEq(mem, e.foo);
 assertEq(mem, e.bar);
 
-var code = wasmTextToBinary('(module (import "a" "b" (table 1 1 anyfunc)) (export "foo" table) (export "bar" table))');
-var tbl = new Table({initial:1, maximum:1, element:"anyfunc"});
+var code = wasmTextToBinary('(module (import "a" "b" (table 1 1 funcref)) (export "foo" table) (export "bar" table))');
+var tbl = new Table({initial:1, maximum:1, element:"funcref"});
 var e = new Instance(new Module(code), {a:{b:tbl}}).exports;
 assertEq(tbl, e.foo);
 assertEq(tbl, e.bar);
 
-var code = wasmTextToBinary('(module (import "a" "b" (table 2 2 anyfunc)) (func $foo) (elem (i32.const 0) $foo) (export "foo" $foo))');
-var tbl = new Table({initial:2, maximum:2, element:"anyfunc"});
+var code = wasmTextToBinary('(module (import "a" "b" (table 2 2 funcref)) (func $foo) (elem (i32.const 0) $foo) (export "foo" $foo))');
+var tbl = new Table({initial:2, maximum:2, element:"funcref"});
 var e1 = new Instance(new Module(code), {a:{b:tbl}}).exports;
 assertEq(e1.foo, tbl.get(0));
 tbl.set(1, e1.foo);
 assertEq(e1.foo, tbl.get(1));
 var e2 = new Instance(new Module(code), {a:{b:tbl}}).exports;
 assertEq(e2.foo, tbl.get(0));
 assertEq(e1.foo, tbl.get(1));
 assertEq(tbl.get(0) === e1.foo, false);
 assertEq(e1.foo === e2.foo, false);
 
 var m = new Module(wasmTextToBinary(`(module
-    (table 3 anyfunc)
+    (table 3 funcref)
     (import $foo "" "foo" (result i32))
     (import $bar "" "bar" (result i32))
     (func $baz (result i32) (i32.const 13))
     (elem (i32.const 0) $foo $bar $baz)
     (export "foo" $foo)
     (export "bar" $bar)
     (export "baz" $baz)
     (export "tbl" table)
@@ -510,17 +510,17 @@ assertErrorMessage(() => new Instance(m)
 
 // Errors during segment initialization do not have observable effects
 // and are checked against the actual memory/table length, not the declared
 // initial length.
 
 var m = new Module(wasmTextToBinary(`
     (module
         (import "a" "mem" (memory 1))
-        (import "a" "tbl" (table 1 anyfunc))
+        (import "a" "tbl" (table 1 funcref))
         (import $memOff "a" "memOff" (global i32))
         (import $tblOff "a" "tblOff" (global i32))
         (func $f)
         (func $g)
         (data (i32.const 0) "\\01")
         (elem (i32.const 0) $f)
         (data (get_global $memOff) "\\02")
         (elem (get_global $tblOff) $g)
@@ -537,17 +537,17 @@ var m = new Module(wasmTextToBinary(`
 // memories.  Bounds checking happens for each byte or table element written.
 // The first OOB aborts the initialization process, leaving written data in
 // place.  Notably, any OOB in table initialization will prevent any memory
 // initialization from happening at all.
 
 var npages = 2;
 var mem = new Memory({initial:npages});
 var mem8 = new Uint8Array(mem.buffer);
-var tbl = new Table({initial:2, element:"anyfunc"});
+var tbl = new Table({initial:2, element:"funcref"});
 
 assertErrorMessage(() => new Instance(m, {a:{mem, tbl, memOff:1, tblOff:2}}),
                    LinkError,
                    /elem segment does not fit/);
 if (wasmBulkMemSupported()) {
     // The first active element segment is applied, but the second active
     // element segment is completely OOB.
     assertEq(typeof tbl.get(0), "function");
@@ -591,25 +591,25 @@ assertEq(tbl.get(1), i.exports.g);
 
 // Element segment applies partially and prevents subsequent elem segment and
 // data segment from being applied.
 
 if (wasmBulkMemSupported()) {
     let m = new Module(wasmTextToBinary(
         `(module
            (import "" "mem" (memory 1))
-           (import "" "tbl" (table 3 anyfunc))
+           (import "" "tbl" (table 3 funcref))
            (elem (i32.const 1) $f $g $h) ;; fails after $f and $g
            (elem (i32.const 0) $f)       ;; is not applied
            (data (i32.const 0) "\\01")   ;; is not applied
            (func $f)
            (func $g)
            (func $h))`));
     let mem = new Memory({initial:1});
-    let tbl = new Table({initial:3, element:"anyfunc"});
+    let tbl = new Table({initial:3, element:"funcref"});
     assertErrorMessage(() => new Instance(m, {"":{mem, tbl}}),
                        LinkError,
                        /elem segment does not fit/);
     assertEq(tbl.get(0), null);
     assertEq(typeof tbl.get(1), "function");
     assertEq(typeof tbl.get(2), "function");
     let v = new Uint8Array(mem.buffer);
     assertEq(v[0], 0);
@@ -634,46 +634,46 @@ if (wasmBulkMemSupported()) {
     assertEq(v[65535], 2);
     assertEq(v[0], 0);
 }
 
 // Elem segments on imported tables
 
 var m = new Module(wasmTextToBinary(`
     (module
-        (import "a" "b" (table 10 anyfunc))
+        (import "a" "b" (table 10 funcref))
         (elem (i32.const 0) $one $two)
         (elem (i32.const 3) $three $four)
         (func $one (result i32) (i32.const 1))
         (func $two (result i32) (i32.const 2))
         (func $three (result i32) (i32.const 3))
         (func $four (result i32) (i32.const 4)))
 `));
-var tbl = new Table({initial:10, element:"anyfunc"});
+var tbl = new Table({initial:10, element:"funcref"});
 new Instance(m, {a:{b:tbl}});
 assertEq(tbl.get(0)(), 1);
 assertEq(tbl.get(1)(), 2);
 assertEq(tbl.get(2), null);
 assertEq(tbl.get(3)(), 3);
 assertEq(tbl.get(4)(), 4);
 for (var i = 5; i < 10; i++)
     assertEq(tbl.get(i), null);
 
 var m = new Module(wasmTextToBinary(`
     (module
         (func $their1 (import "" "func") (result i32))
         (func $their2 (import "" "func"))
-        (table (import "" "table") 4 anyfunc)
+        (table (import "" "table") 4 funcref)
         (func $my (result i32) i32.const 13)
         (elem (i32.const 1) $my)
         (elem (i32.const 2) $their1)
         (elem (i32.const 3) $their2)
     )
 `));
-var tbl = new Table({initial:4, element:"anyfunc"});
+var tbl = new Table({initial:4, element:"funcref"});
 var f = () => 42;
 new Instance(m, { "": { table: tbl, func: f} });
 assertEq(tbl.get(0), null);
 assertEq(tbl.get(1)(), 13);
 assertEq(tbl.get(2)(), 42);
 assertEq(tbl.get(3)(), undefined);
 
 // Cross-instance calls
@@ -687,17 +687,17 @@ var i1 = new Instance(new Module(wasmTex
     (data (i32.const 0) "\\42")
     (func $f (result i32) (i32.load (i32.const 0)))
     (export "f" $f)
 )`)));
 var i2 = new Instance(new Module(wasmTextToBinary(`(module
     (import $imp "a" "b" (result i32))
     (memory 1 1)
     (data (i32.const 0) "\\13")
-    (table 2 2 anyfunc)
+    (table 2 2 funcref)
     (elem (i32.const 0) $imp $def)
     (func $def (result i32) (i32.load (i32.const 0)))
     (type $v2i (func (result i32)))
     (func $call (param i32) (result i32) (call_indirect $v2i (get_local 0)))
     (export "call" $call)
 )`)), {a:{b:i1.exports.f}});
 assertEq(i2.exports.call(0), 0x42);
 assertEq(i2.exports.call(1), 0x13);
--- a/js/src/jit-test/tests/wasm/ion-lazy-tables.js
+++ b/js/src/jit-test/tests/wasm/ion-lazy-tables.js
@@ -15,17 +15,17 @@ const EXPECTED_STACKS = [SLOW_ENTRY_STAC
 
 function main() {
     var { table } = wasmEvalText(`(module
         (func $add (result i32) (param i32) (param i32)
          get_local 0
          get_local 1
          i32.add
         )
-        (table (export "table") 10 anyfunc)
+        (table (export "table") 10 funcref)
         (elem (i32.const 0) $add)
     )`).exports;
 
     for (var i = 0; i < ITER; i++) {
         startProfiling();
         assertEq(table.get(0)(i, i+1), i*2+1);
         assertEqPreciseStacks(endProfiling(), EXPECTED_STACKS);
     }
@@ -35,17 +35,17 @@ function withTier2() {
     setJitCompilerOption('wasm.delay-tier2', 1);
 
     var module = new WebAssembly.Module(wasmTextToBinary(`(module
         (func $add (result i32) (param i32) (param i32)
          get_local 0
          get_local 1
          i32.add
         )
-        (table (export "table") 10 anyfunc)
+        (table (export "table") 10 funcref)
         (elem (i32.const 0) $add)
     )`));
     var { table } = new WebAssembly.Instance(module).exports;
 
     let i = 0;
     do {
         i++;
         startProfiling();
--- a/js/src/jit-test/tests/wasm/passive-segs-boundary.js
+++ b/js/src/jit-test/tests/wasm/passive-segs-boundary.js
@@ -25,17 +25,17 @@ function do_test(insn1, insn2, errKind, 
                        : "";
         preamble
             = `;; -------- Memories --------
                ${mem_def}
                ;; -------- Memory initialisers --------
                ${mem_init}
               `;
     } else {
-        let tab_def  = haveMemOrTable ? "(table 30 30 anyfunc)" : "";
+        let tab_def  = haveMemOrTable ? "(table 30 30 funcref)" : "";
         let tab_init = haveMemOrTable
                        ? `(elem (i32.const 2) 3 1 4 1)
                           (elem passive 2 7 1 8)
                           (elem (i32.const 12) 7 5 2 3 6)
                           (elem passive 5 9 2 7 6)`
                        : "";
         preamble
             = `;; -------- Tables --------
--- a/js/src/jit-test/tests/wasm/passive-segs-nonboundary.js
+++ b/js/src/jit-test/tests/wasm/passive-segs-nonboundary.js
@@ -31,17 +31,17 @@ let tab_expmod_t =
 // the table entry is empty.
 function gen_tab_impmod_t(insn)
 {
   let t =
   `(module
      ;; -------- Types --------
      (type (func (result i32)))  ;; type #0
      ;; -------- Tables --------
-     (table 30 30 anyfunc)
+     (table 30 30 funcref)
      ;; -------- Table initialisers --------
      (elem (i32.const 2) 3 1 4 1)
      (elem passive 2 7 1 8)
      (elem (i32.const 12) 7 5 2 3 6)
      (elem passive 5 9 2 7 6)
      ;; -------- Imports --------
      (import "a" "if0" (result i32))    ;; index 0
      (import "a" "if1" (result i32))
@@ -335,17 +335,17 @@ checkPassiveElemSegment("type", /passive
 checkPassiveElemSegment("ref.func", /failed to read initializer operation/);
 checkPassiveElemSegment("end", /failed to read end of initializer expression/);
 
 // Passive element segments can contain literal null values.
 
 {
     let txt =
         `(module
-           (table (export "t") 10 anyfunc)
+           (table (export "t") 10 funcref)
            (elem (i32.const 1) $m)
            (elem (i32.const 3) $m)
            (elem (i32.const 6) $m)
            (elem (i32.const 8) $m)
            (elem passive $f ref.null $g ref.null $h)
            (func $m)
            (func $f)
            (func $g)
--- a/js/src/jit-test/tests/wasm/passive-segs-partial-table.js
+++ b/js/src/jit-test/tests/wasm/passive-segs-partial-table.js
@@ -9,17 +9,17 @@
 // affect the behavior.
 
 // Note, the length of the element segment is 16.
 const tbl_init_len = 16;
 
 function tbl_init(min, max, backup, write, segoffs=0) {
     let ins = wasmEvalText(
         `(module
-           (table (export "tbl") ${min} ${max} anyfunc)
+           (table (export "tbl") ${min} ${max} funcref)
            (elem passive $f0 $f1 $f2 $f3 $f4 $f5 $f6 $f7 $f8 $f9 $f10 $f11 $f12 $f13 $f14 $f15)
            (func $f0 (export "f0"))
            (func $f1 (export "f1"))
            (func $f2 (export "f2"))
            (func $f3 (export "f3"))
            (func $f4 (export "f4"))
            (func $f5 (export "f5"))
            (func $f6 (export "f6"))
@@ -86,17 +86,17 @@ tbl_init(tbl_init_len, tbl_init_len, tbl
 // Note we do not test the multi-table case here because that is part of the
 // reftypes proposal; tests are in the gc/ subdirectory.
 
 const tbl_copy_len = 16;
 
 function tbl_copy(min, max, srcOffs, targetOffs, len, copyDown=false) {
     let ins = wasmEvalText(
         `(module
-           (table (export "tbl") ${min} ${max} anyfunc)
+           (table (export "tbl") ${min} ${max} funcref)
            (func $f0 (export "f0"))
            (func $f1 (export "f1"))
            (func $f2 (export "f2"))
            (func $f3 (export "f3"))
            (func $f4 (export "f4"))
            (func $f5 (export "f5"))
            (func $f6 (export "f6"))
            (func $f7 (export "f7"))
--- a/js/src/jit-test/tests/wasm/profiling.js
+++ b/js/src/jit-test/tests/wasm/profiling.js
@@ -39,26 +39,26 @@ test(
 )`,
 {},
 ["", ">", "0,>", "1,0,>", "0,>", ">", ""]);
 
 test(
 `(module
     (func $foo (call_indirect 0 (i32.const 0)))
     (func $bar)
-    (table anyfunc (elem $bar))
+    (table funcref (elem $bar))
     (export "" $foo)
 )`,
 {},
 ["", ">", "0,>", "1,0,>", "0,>", ">", ""]);
 
 test(
 `(module
     (import $foo "" "foo")
-    (table anyfunc (elem $foo))
+    (table funcref (elem $foo))
     (func $bar (call_indirect 0 (i32.const 0)))
     (export "" $bar)
 )`,
 {"":{foo:()=>{}}},
 ["", ">", "1,>", "0,1,>", "<,0,1,>", "0,1,>", "1,>", ">", ""]);
 
 test(`(module
     (import $f32 "Math" "sin" (param f32) (result f32))
@@ -146,31 +146,31 @@ for (let type of ['f32', 'f64']) {
     ["", ">", "1,>", "0,1,>", "1,>", "", ">", ""]);
 
     testError(
     `(module
         (type $good (func))
         (type $bad (func (param i32)))
         (func $foo (call_indirect $bad (i32.const 1) (i32.const 0)))
         (func $bar (type $good))
-        (table anyfunc (elem $bar))
+        (table funcref (elem $bar))
         (export "" $foo)
     )`,
     WebAssembly.RuntimeError,
     ["", ">", "0,>", "1,0,>", ">", "", ">", ""]);
 })();
 
 (function() {
     // Tables fun.
     var e = wasmEvalText(`
     (module
         (func $foo (result i32) (i32.const 42))
         (export "foo" $foo)
         (func $bar (result i32) (i32.const 13))
-        (table 10 anyfunc)
+        (table 10 funcref)
         (elem (i32.const 0) $foo $bar)
         (export "tbl" table)
     )`).exports;
     assertEq(e.foo(), 42);
     assertEq(e.tbl.get(0)(), 42);
     assertEq(e.tbl.get(1)(), 13);
 
     enableGeckoProfiling();
@@ -198,17 +198,17 @@ for (let type of ['f32', 'f64']) {
     assertEq(e.foo(), 42);
     assertEq(e.tbl.get(1)(), 13);
     assertEqImpreciseStacks(disableSingleStepProfiling(), ["", ">", "0,>", ">", "", ">", "1,>", ">", ""]);
     disableGeckoProfiling();
 
     var e2 = wasmEvalText(`
     (module
         (type $v2i (func (result i32)))
-        (import "a" "b" (table 10 anyfunc))
+        (import "a" "b" (table 10 funcref))
         (elem (i32.const 2) $bar)
         (func $bar (result i32) (i32.const 99))
         (func $baz (param $i i32) (result i32) (call_indirect $v2i (get_local $i)))
         (export "baz" $baz)
     )`, {a:{b:e.tbl}}).exports;
 
     enableGeckoProfiling();
     enableSingleStepProfiling();
--- a/js/src/jit-test/tests/wasm/regress/bug1491322.js
+++ b/js/src/jit-test/tests/wasm/regress/bug1491322.js
@@ -2,17 +2,17 @@
 var evalInFrame = (function(global) {
     var dbgGlobal = newGlobal({newCompartment: true});
     var dbg = new dbgGlobal.Debugger();
     dbg.addDebuggee(global);
 })(this);
 const Module = WebAssembly.Module;
 const Instance = WebAssembly.Instance;
 var m = new Module(wasmTextToBinary(`(module
-    (table 3 anyfunc)
+    (table 3 funcref)
     (import $foo "" "foo" (result i32))
     (import $bar "" "bar" (result i32))
     (func $baz (result i32) (i32.const 13))
     (elem (i32.const 0) $foo $bar $baz)
     (export "tbl" table)
 )`));
 var jsFun = () => 83;
 var wasmFun = new Instance(
--- a/js/src/jit-test/tests/wasm/regress/ion-lazy-stubs-jit.js
+++ b/js/src/jit-test/tests/wasm/regress/ion-lazy-stubs-jit.js
@@ -1,14 +1,14 @@
 (function coerceinplace() {
     var { table } = wasmEvalText(`(module
         (func $add (result i32) (param i32) (param i32)
          get_local 0
         )
-        (table (export "table") 10 anyfunc)
+        (table (export "table") 10 funcref)
         (elem (i32.const 0) $add)
     )`).exports;
 
     for (var i = 0; i < 100; i++) {
       table.get(0)((true).get++, i*2+1);
     }
 })();
 
@@ -22,17 +22,17 @@
 
         (func $addi64 (result i64) (param i32) (param i32)
             get_local 0
             get_local 1
             call $add
             i64.extend_s/i32
         )
 
-        (table (export "table") 10 anyfunc)
+        (table (export "table") 10 funcref)
         (elem (i32.const 0) $add $addi64)
     )`).exports;
 
     const EXCEPTION_ITER = 50;
 
     for (var i = 0; i < 100; i++) {
         var caught = null;
 
--- a/js/src/jit-test/tests/wasm/regress/lazy-table-nan.js
+++ b/js/src/jit-test/tests/wasm/regress/lazy-table-nan.js
@@ -1,10 +1,10 @@
 let i = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`
 (module
     (func $f (result f32)
         f32.const nan:0x42
     )
-    (table (export "table") 10 anyfunc)
+    (table (export "table") 10 funcref)
     (elem (i32.const 0) $f)
 )
 `))).exports;
 i.table.get(0)();
--- a/js/src/jit-test/tests/wasm/regress/proxy-get-trap-table.js
+++ b/js/src/jit-test/tests/wasm/regress/proxy-get-trap-table.js
@@ -1,14 +1,14 @@
 // The 'get' handler should be invoked directly when reading fields of the
 // descriptor.
 
 assertErrorMessage(() => {
     var desc = {
-        element: "anyfunc",
+        element: "funcref",
         initial: 1
     };
     var proxy = new Proxy({}, {
         get: true
     });
     Object.setPrototypeOf(desc, proxy);
     let table = new WebAssembly.Table(desc);
 }, TypeError, /proxy handler's get trap/);
--- a/js/src/jit-test/tests/wasm/resizing.js
+++ b/js/src/jit-test/tests/wasm/resizing.js
@@ -47,27 +47,27 @@ var exports = wasmEvalText(`(module
 
 setJitCompilerOption("baseline.warmup.trigger", 2);
 setJitCompilerOption("ion.warmup.trigger", 4);
 for (var i = 0; i < 10; i++)
     assertEq(exports.test(), 111);
 
 // Grow during call_indirect:
 var mem = new Memory({initial:1});
-var tbl = new Table({initial:1, element:"anyfunc"});
+var tbl = new Table({initial:1, element:"funcref"});
 var exports1 = wasmEvalText(`(module
     (import "" "mem" (memory 1))
     (func $grow
         (i32.store (i32.const 65532) (i32.const 10))
         (drop (memory.grow (i32.const 99)))
         (i32.store (i32.const 6553596) (i32.const 100)))
     (export "grow" $grow)
 )`, {"":{mem}}).exports;
 var exports2 = wasmEvalText(`(module
-    (import "" "tbl" (table 1 anyfunc))
+    (import "" "tbl" (table 1 funcref))
     (import "" "mem" (memory 1))
     (type $v2v (func))
     (func $test (result i32)
         (i32.store (i32.const 0) (i32.const 1))
         (call_indirect $v2v (i32.const 0))
         (i32.add
             (i32.load (i32.const 0))
             (i32.add
@@ -130,17 +130,17 @@ assertEq(mem.buffer.byteLength, 2 * 64*1
 // ======
 
 // Test for stale table base pointers after resize
 
 // Grow during import call:
 var exports = wasmEvalText(`(module
     (type $v2i (func (result i32)))
     (import $grow "" "grow")
-    (table (export "tbl") 1 anyfunc)
+    (table (export "tbl") 1 funcref)
     (func $test (result i32)
         (i32.add
             (call_indirect $v2i (i32.const 0))
             (block i32
                 (call $grow)
                 (call_indirect $v2i (i32.const 1)))))
     (func $one (result i32) (i32.const 1))
     (elem (i32.const 0) $one)
@@ -161,17 +161,17 @@ var exports1 = wasmEvalText(`(module
     (func $exp (call $grow))
     (export "exp" $exp)
 )`, {"":{grow() { exports2.tbl.grow(1); exports2.tbl.set(2, exports2.eleven) }}}).exports;
 var exports2 = wasmEvalText(`(module
     (type $v2v (func))
     (type $v2i (func (result i32)))
     (import $imp "" "imp")
     (elem (i32.const 0) $imp)
-    (table 2 anyfunc)
+    (table 2 funcref)
     (func $test (result i32)
         (i32.add
             (call_indirect $v2i (i32.const 1))
             (block i32
                 (call_indirect $v2v (i32.const 0))
                 (call_indirect $v2i (i32.const 2)))))
     (func $ten (result i32) (i32.const 10))
     (elem (i32.const 1) $ten)
@@ -187,22 +187,22 @@ assertEq(exports2.test(), 21);
 var src = wasmEvalText(`(module
     (func $one (result i32) (i32.const 1))
     (export "one" $one)
     (func $two (result i32) (i32.const 2))
     (export "two" $two)
     (func $three (result i32) (i32.const 3))
     (export "three" $three)
 )`).exports;
-var tbl = new Table({element:"anyfunc", initial:1});
+var tbl = new Table({element:"funcref", initial:1});
 tbl.set(0, src.one);
 
 var mod = new Module(wasmTextToBinary(`(module
     (type $v2i (func (result i32)))
-    (table (import "" "tbl") 1 anyfunc)
+    (table (import "" "tbl") 1 funcref)
     (func $ci (param i32) (result i32) (call_indirect $v2i (get_local 0)))
     (export "call_indirect" $ci)
 )`));
 var exp1 = new Instance(mod, {"":{tbl}}).exports;
 var exp2 = new Instance(mod, {"":{tbl}}).exports;
 assertEq(exp1.call_indirect(0), 1);
 assertErrorMessage(() => exp1.call_indirect(1), RuntimeError, /index out of bounds/);
 assertEq(exp2.call_indirect(0), 1);
@@ -218,14 +218,14 @@ assertEq(tbl.grow(2), 2);
 assertEq(tbl.length, 4);
 assertEq(exp2.call_indirect(0), 1);
 assertEq(exp2.call_indirect(1), 2);
 assertErrorMessage(() => exp2.call_indirect(2), Error, /indirect call to null/);
 assertErrorMessage(() => exp2.call_indirect(3), Error, /indirect call to null/);
 
 // Fail at maximum
 
-var tbl = new Table({initial:1, maximum:2, element:"anyfunc"});
+var tbl = new Table({initial:1, maximum:2, element:"funcref"});
 assertEq(tbl.length, 1);
 assertEq(tbl.grow(1), 1);
 assertEq(tbl.length, 2);
 assertErrorMessage(() => tbl.grow(1), RangeError, /failed to grow table/);
 assertEq(tbl.length, 2);
--- a/js/src/jit-test/tests/wasm/spec/harness/async_index.js
+++ b/js/src/jit-test/tests/wasm/spec/harness/async_index.js
@@ -74,17 +74,17 @@ function reinitializeRegistry() {
       print_f32: console.log.bind(console),
       print_f64: console.log.bind(console),
       global_i32: 666,
       global_f32: 666,
       global_f64: 666,
       table: new WebAssembly.Table({
         initial: 10,
         maximum: 20,
-        element: "anyfunc"
+        element: "funcref"
       }),
       memory: new WebAssembly.Memory({ initial: 1, maximum: 2 })
     };
     let handler = {
       get(target, prop) {
         return prop in target ? target[prop] : {};
       }
     };
--- a/js/src/jit-test/tests/wasm/spec/harness/sync_index.js
+++ b/js/src/jit-test/tests/wasm/spec/harness/sync_index.js
@@ -81,17 +81,17 @@ function reinitializeRegistry() {
         print_i32: console.log.bind(console),
         print_i32_f32: console.log.bind(console),
         print_f64_f64: console.log.bind(console),
         print_f32: console.log.bind(console),
         print_f64: console.log.bind(console),
         global_i32: 666,
         global_f32: 666,
         global_f64: 666,
-        table: new WebAssembly.Table({initial: 10, maximum: 20, element: 'anyfunc'}),
+        table: new WebAssembly.Table({initial: 10, maximum: 20, element: 'funcref'}),
         memory: new WebAssembly.Memory({initial: 1, maximum: 2})
     };
     let handler = {
         get(target, prop) {
         return (prop in target) ?  target[prop] : {};
       }
     };
     registry = new Proxy({spectest}, handler);
--- a/js/src/jit-test/tests/wasm/table-gc.js
+++ b/js/src/jit-test/tests/wasm/table-gc.js
@@ -10,17 +10,17 @@ const RuntimeError = WebAssembly.Runtime
 var caller = `(type $v2i (func (result i32))) (func $call (param $i i32) (result i32) (call_indirect $v2i (get_local $i))) (export "call" $call)`
 var callee = i => `(func $f${i} (type $v2i) (i32.const ${i}))`;
 
 // A table should not hold exported functions alive and exported functions
 // should not hold their originating table alive. Live exported functions should
 // hold instances alive and instances hold imported tables alive. Nothing
 // should hold the export object alive.
 resetFinalizeCount();
-var i = wasmEvalText(`(module (table 2 anyfunc) (export "tbl" table) (elem (i32.const 0) $f0) ${callee(0)} ${caller})`);
+var i = wasmEvalText(`(module (table 2 funcref) (export "tbl" table) (elem (i32.const 0) $f0) ${callee(0)} ${caller})`);
 var e = i.exports;
 var t = e.tbl;
 var f = t.get(0);
 assertEq(f(), e.call(0));
 assertErrorMessage(() => e.call(1), RuntimeError, /indirect call to null/);
 assertErrorMessage(() => e.call(2), RuntimeError, /index out of bounds/);
 assertEq(finalizeCount(), 0);
 i.edge = makeFinalizeObserver();
@@ -48,17 +48,17 @@ gc();
 assertEq(finalizeCount(), 0);
 assertEq(f(), 0);
 f = null;
 gc();
 assertEq(finalizeCount(), 3);
 
 // A table should hold the instance of any of its elements alive.
 resetFinalizeCount();
-var i = wasmEvalText(`(module (table 1 anyfunc) (export "tbl" table) (elem (i32.const 0) $f0) ${callee(0)} ${caller})`);
+var i = wasmEvalText(`(module (table 1 funcref) (export "tbl" table) (elem (i32.const 0) $f0) ${callee(0)} ${caller})`);
 var e = i.exports;
 var t = e.tbl;
 var f = t.get(0);
 i.edge = makeFinalizeObserver();
 t.edge = makeFinalizeObserver();
 f.edge = makeFinalizeObserver();
 gc();
 assertEq(finalizeCount(), 0);
@@ -73,17 +73,17 @@ i = null;
 gc();
 assertEq(finalizeCount(), 0);
 t = null;
 gc();
 assertEq(finalizeCount(), 3);
 
 // Null elements shouldn't keep anything alive.
 resetFinalizeCount();
-var i = wasmEvalText(`(module (table 2 anyfunc) (export "tbl" table) ${caller})`);
+var i = wasmEvalText(`(module (table 2 funcref) (export "tbl" table) ${caller})`);
 var e = i.exports;
 var t = e.tbl;
 i.edge = makeFinalizeObserver();
 t.edge = makeFinalizeObserver();
 gc();
 assertEq(finalizeCount(), 0);
 i.exports = null;
 e = null;
@@ -94,34 +94,34 @@ gc();
 assertEq(finalizeCount(), 1);
 t = null;
 gc();
 assertEq(finalizeCount(), 2);
 
 // Before initialization, a table is not bound to any instance.
 resetFinalizeCount();
 var i = wasmEvalText(`(module (func $f0 (result i32) (i32.const 0)) (export "f0" $f0))`);
-var t = new Table({initial:4, element:"anyfunc"});
+var t = new Table({initial:4, element:"funcref"});
 i.edge = makeFinalizeObserver();
 t.edge = makeFinalizeObserver();
 gc();
 assertEq(finalizeCount(), 0);
 i = null;
 gc();
 assertEq(finalizeCount(), 1);
 t = null;
 gc();
 assertEq(finalizeCount(), 2);
 
 // When a Table is created (uninitialized) and then first assigned, it keeps the
 // first element's Instance alive (as above).
 resetFinalizeCount();
 var i = wasmEvalText(`(module (func $f (result i32) (i32.const 42)) (export "f" $f))`);
 var f = i.exports.f;
-var t = new Table({initial:1, element:"anyfunc"});
+var t = new Table({initial:1, element:"funcref"});
 i.edge = makeFinalizeObserver();
 f.edge = makeFinalizeObserver();
 t.edge = makeFinalizeObserver();
 t.set(0, f);
 assertEq(t.get(0), f);
 assertEq(t.get(0)(), 42);
 gc();
 assertEq(finalizeCount(), 0);
@@ -143,17 +143,17 @@ assertEq(finalizeCount(), 3);
 
 // Once all of an instance's elements in a Table have been clobbered, the
 // Instance should not be reachable.
 resetFinalizeCount();
 var i1 = wasmEvalText(`(module (func $f1 (result i32) (i32.const 13)) (export "f1" $f1))`);
 var i2 = wasmEvalText(`(module (func $f2 (result i32) (i32.const 42)) (export "f2" $f2))`);
 var f1 = i1.exports.f1;
 var f2 = i2.exports.f2;
-var t = new Table({initial:2, element:"anyfunc"});
+var t = new Table({initial:2, element:"funcref"});
 i1.edge = makeFinalizeObserver();
 i2.edge = makeFinalizeObserver();
 f1.edge = makeFinalizeObserver();
 f2.edge = makeFinalizeObserver();
 t.edge = makeFinalizeObserver();
 t.set(0, f1);
 t.set(1, f2);
 gc();
@@ -177,17 +177,17 @@ assertEq(finalizeCount(), 4);
 t = null;
 gc();
 assertEq(finalizeCount(), 5);
 
 // Ensure that an instance that is only live on the stack cannot be GC even if
 // there are no outstanding references.
 resetFinalizeCount();
 const N = 10;
-var tbl = new Table({initial:N, element:"anyfunc"});
+var tbl = new Table({initial:N, element:"funcref"});
 tbl.edge = makeFinalizeObserver();
 function runTest() {
     tbl = null;
     gc();
     assertEq(finalizeCount(), 0);
     return 100;
 }
 var i = wasmEvalText(
@@ -196,17 +196,17 @@ var i = wasmEvalText(
         (func $f (param i32) (result i32) (call $imp))
         (export "f" $f)
     )`,
     {a:{b:runTest}}
 );
 i.edge = makeFinalizeObserver();
 tbl.set(0, i.exports.f);
 var m = new Module(wasmTextToBinary(`(module
-    (import "a" "b" (table ${N} anyfunc))
+    (import "a" "b" (table ${N} funcref))
     (type $i2i (func (param i32) (result i32)))
     (func $f (param $i i32) (result i32)
         (set_local $i (i32.sub (get_local $i) (i32.const 1)))
         (i32.add
             (i32.const 1)
             (call_indirect $i2i (get_local $i) (get_local $i))))
     (export "f" $f)
 )`));
--- a/js/src/jit-test/tests/wasm/table-pre-barrier.js
+++ b/js/src/jit-test/tests/wasm/table-pre-barrier.js
@@ -1,15 +1,15 @@
 const Module = WebAssembly.Module;
 const Instance = WebAssembly.Instance;
 const Table = WebAssembly.Table;
 
 var i42 = new Instance(new Module(wasmTextToBinary(`(module (func (result i32) (i32.const 42)) (export "f" 0))`)));
 var i13 = new Instance(new Module(wasmTextToBinary(`(module (func (result i32) (i32.const 13)) (export "f" 0))`)));
-var t = new Table({element:"anyfunc", initial:1});
+var t = new Table({element:"funcref", initial:1});
 t.set(0, i42.exports.f);
 
 assertEq(t.get(0)(), 42);
 
 verifyprebarriers();
 t.set(0, i13.exports.f);
 verifyprebarriers();
 
--- a/js/src/jit-test/tests/wasm/tables.js
+++ b/js/src/jit-test/tests/wasm/tables.js
@@ -3,147 +3,147 @@ const Instance = WebAssembly.Instance;
 const Table = WebAssembly.Table;
 const Memory = WebAssembly.Memory;
 const LinkError = WebAssembly.LinkError;
 const RuntimeError = WebAssembly.RuntimeError;
 
 var callee = i => `(func $f${i} (result i32) (i32.const ${i}))`;
 
 wasmFailValidateText(`(module (elem (i32.const 0) $f0) ${callee(0)})`, /elem segment requires a table section/);
-wasmFailValidateText(`(module (table 10 anyfunc) (elem (i32.const 0) 0))`, /table element out of range/);
-wasmFailValidateText(`(module (table 10 anyfunc) (func) (elem (i32.const 0) 0 1))`, /table element out of range/);
-wasmFailValidateText(`(module (table 10 anyfunc) (func) (elem (f32.const 0) 0) ${callee(0)})`, /type mismatch/);
+wasmFailValidateText(`(module (table 10 funcref) (elem (i32.const 0) 0))`, /table element out of range/);
+wasmFailValidateText(`(module (table 10 funcref) (func) (elem (i32.const 0) 0 1))`, /table element out of range/);
+wasmFailValidateText(`(module (table 10 funcref) (func) (elem (f32.const 0) 0) ${callee(0)})`, /type mismatch/);
 
-assertErrorMessage(() => wasmEvalText(`(module (table 10 anyfunc) (elem (i32.const 10) $f0) ${callee(0)})`), LinkError, /elem segment does not fit/);
-assertErrorMessage(() => wasmEvalText(`(module (table 10 anyfunc) (elem (i32.const 8) $f0 $f0 $f0) ${callee(0)})`), LinkError, /elem segment does not fit/);
-assertErrorMessage(() => wasmEvalText(`(module (table 0 anyfunc) (func) (elem (i32.const 0x10001)))`), LinkError, /elem segment does not fit/);
+assertErrorMessage(() => wasmEvalText(`(module (table 10 funcref) (elem (i32.const 10) $f0) ${callee(0)})`), LinkError, /elem segment does not fit/);
+assertErrorMessage(() => wasmEvalText(`(module (table 10 funcref) (elem (i32.const 8) $f0 $f0 $f0) ${callee(0)})`), LinkError, /elem segment does not fit/);
+assertErrorMessage(() => wasmEvalText(`(module (table 0 funcref) (func) (elem (i32.const 0x10001)))`), LinkError, /elem segment does not fit/);
 
-assertErrorMessage(() => wasmEvalText(`(module (table 10 anyfunc) (import "globals" "a" (global i32)) (elem (get_global 0) $f0) ${callee(0)})`, {globals:{a:10}}), LinkError, /elem segment does not fit/);
-assertErrorMessage(() => wasmEvalText(`(module (table 10 anyfunc) (import "globals" "a" (global i32)) (elem (get_global 0) $f0 $f0 $f0) ${callee(0)})`, {globals:{a:8}}), LinkError, /elem segment does not fit/);
+assertErrorMessage(() => wasmEvalText(`(module (table 10 funcref) (import "globals" "a" (global i32)) (elem (get_global 0) $f0) ${callee(0)})`, {globals:{a:10}}), LinkError, /elem segment does not fit/);
+assertErrorMessage(() => wasmEvalText(`(module (table 10 funcref) (import "globals" "a" (global i32)) (elem (get_global 0) $f0 $f0 $f0) ${callee(0)})`, {globals:{a:8}}), LinkError, /elem segment does not fit/);
 
-assertEq(new Module(wasmTextToBinary(`(module (table 10 anyfunc) (elem (i32.const 1) $f0 $f0) (elem (i32.const 0) $f0) ${callee(0)})`)) instanceof Module, true);
-assertEq(new Module(wasmTextToBinary(`(module (table 10 anyfunc) (elem (i32.const 1) $f0 $f0) (elem (i32.const 2) $f0) ${callee(0)})`)) instanceof Module, true);
-wasmEvalText(`(module (table 10 anyfunc) (import "globals" "a" (global i32)) (elem (i32.const 1) $f0 $f0) (elem (get_global 0) $f0) ${callee(0)})`, {globals:{a:0}});
-wasmEvalText(`(module (table 10 anyfunc) (import "globals" "a" (global i32)) (elem (get_global 0) $f0 $f0) (elem (i32.const 2) $f0) ${callee(0)})`, {globals:{a:1}});
+assertEq(new Module(wasmTextToBinary(`(module (table 10 funcref) (elem (i32.const 1) $f0 $f0) (elem (i32.const 0) $f0) ${callee(0)})`)) instanceof Module, true);
+assertEq(new Module(wasmTextToBinary(`(module (table 10 funcref) (elem (i32.const 1) $f0 $f0) (elem (i32.const 2) $f0) ${callee(0)})`)) instanceof Module, true);
+wasmEvalText(`(module (table 10 funcref) (import "globals" "a" (global i32)) (elem (i32.const 1) $f0 $f0) (elem (get_global 0) $f0) ${callee(0)})`, {globals:{a:0}});
+wasmEvalText(`(module (table 10 funcref) (import "globals" "a" (global i32)) (elem (get_global 0) $f0 $f0) (elem (i32.const 2) $f0) ${callee(0)})`, {globals:{a:1}});
 
 var m = new Module(wasmTextToBinary(`
     (module
-        (import "globals" "table" (table 10 anyfunc))
+        (import "globals" "table" (table 10 funcref))
         (import "globals" "a" (global i32))
         (elem (get_global 0) $f0 $f0)
         ${callee(0)})
 `));
-var tbl = new Table({initial:50, element:"anyfunc"});
+var tbl = new Table({initial:50, element:"funcref"});
 assertEq(new Instance(m, {globals:{a:20, table:tbl}}) instanceof Instance, true);
 assertErrorMessage(() => new Instance(m, {globals:{a:50, table:tbl}}), LinkError, /elem segment does not fit/);
 
 var caller = `(type $v2i (func (result i32))) (func $call (param $i i32) (result i32) (call_indirect $v2i (get_local $i))) (export "call" $call)`
 var callee = i => `(func $f${i} (type $v2i) (i32.const ${i}))`;
 
-var call = wasmEvalText(`(module (table 10 anyfunc) ${callee(0)} ${caller})`).exports.call;
+var call = wasmEvalText(`(module (table 10 funcref) ${callee(0)} ${caller})`).exports.call;
 assertErrorMessage(() => call(0), RuntimeError, /indirect call to null/);
 assertErrorMessage(() => call(10), RuntimeError, /index out of bounds/);
 
-var call = wasmEvalText(`(module (table 10 anyfunc) (elem (i32.const 0)) ${callee(0)} ${caller})`).exports.call;
+var call = wasmEvalText(`(module (table 10 funcref) (elem (i32.const 0)) ${callee(0)} ${caller})`).exports.call;
 assertErrorMessage(() => call(0), RuntimeError, /indirect call to null/);
 assertErrorMessage(() => call(10), RuntimeError, /index out of bounds/);
 
-var call = wasmEvalText(`(module (table 10 anyfunc) (elem (i32.const 0) $f0) ${callee(0)} ${caller})`).exports.call;
+var call = wasmEvalText(`(module (table 10 funcref) (elem (i32.const 0) $f0) ${callee(0)} ${caller})`).exports.call;
 assertEq(call(0), 0);
 assertErrorMessage(() => call(1), RuntimeError, /indirect call to null/);
 assertErrorMessage(() => call(2), RuntimeError, /indirect call to null/);
 assertErrorMessage(() => call(10), RuntimeError, /index out of bounds/);
 
-var call = wasmEvalText(`(module (table 10 anyfunc) (elem (i32.const 1) $f0 $f1) (elem (i32.const 4) $f0 $f2) ${callee(0)} ${callee(1)} ${callee(2)} ${caller})`).exports.call;
+var call = wasmEvalText(`(module (table 10 funcref) (elem (i32.const 1) $f0 $f1) (elem (i32.const 4) $f0 $f2) ${callee(0)} ${callee(1)} ${callee(2)} ${caller})`).exports.call;
 assertErrorMessage(() => call(0), RuntimeError, /indirect call to null/);
 assertEq(call(1), 0);
 assertEq(call(2), 1);
 assertErrorMessage(() => call(3), RuntimeError, /indirect call to null/);
 assertEq(call(4), 0);
 assertEq(call(5), 2);
 assertErrorMessage(() => call(6), RuntimeError, /indirect call to null/);
 assertErrorMessage(() => call(10), RuntimeError, /index out of bounds/);
 
 var imports = {a:{b:()=>42}};
-var call = wasmEvalText(`(module (table 10 anyfunc) (elem (i32.const 0) $f0 $f1 $f2) ${callee(0)} (import "a" "b" (func $f1)) (import "a" "b" (func $f2 (result i32))) ${caller})`, imports).exports.call;
+var call = wasmEvalText(`(module (table 10 funcref) (elem (i32.const 0) $f0 $f1 $f2) ${callee(0)} (import "a" "b" (func $f1)) (import "a" "b" (func $f2 (result i32))) ${caller})`, imports).exports.call;
 assertEq(call(0), 0);
 assertErrorMessage(() => call(1), RuntimeError, /indirect call signature mismatch/);
 assertEq(call(2), 42);
 
-var tbl = new Table({initial:3, element:"anyfunc"});
-var call = wasmEvalText(`(module (import "a" "b" (table 3 anyfunc)) (export "tbl" table) (elem (i32.const 0) $f0 $f1) ${callee(0)} ${callee(1)} ${caller})`, {a:{b:tbl}}).exports.call;
+var tbl = new Table({initial:3, element:"funcref"});
+var call = wasmEvalText(`(module (import "a" "b" (table 3 funcref)) (export "tbl" table) (elem (i32.const 0) $f0 $f1) ${callee(0)} ${callee(1)} ${caller})`, {a:{b:tbl}}).exports.call;
 assertEq(call(0), 0);
 assertEq(call(1), 1);
 assertEq(tbl.get(0)(), 0);
 assertEq(tbl.get(1)(), 1);
 assertErrorMessage(() => call(2), RuntimeError, /indirect call to null/);
 assertEq(tbl.get(2), null);
 
-var exp = wasmEvalText(`(module (import "a" "b" (table 3 anyfunc)) (export "tbl" table) (elem (i32.const 2) $f2) ${callee(2)} ${caller})`, {a:{b:tbl}}).exports;
+var exp = wasmEvalText(`(module (import "a" "b" (table 3 funcref)) (export "tbl" table) (elem (i32.const 2) $f2) ${callee(2)} ${caller})`, {a:{b:tbl}}).exports;
 assertEq(exp.tbl, tbl);
 assertEq(exp.call(0), 0);
 assertEq(exp.call(1), 1);
 assertEq(exp.call(2), 2);
 assertEq(call(0), 0);
 assertEq(call(1), 1);
 assertEq(call(2), 2);
 assertEq(tbl.get(0)(), 0);
 assertEq(tbl.get(1)(), 1);
 assertEq(tbl.get(2)(), 2);
 
-var exp1 = wasmEvalText(`(module (table 10 anyfunc) (export "tbl" table) (elem (i32.const 0) $f0 $f0) ${callee(0)} (export "f0" $f0) ${caller})`).exports
+var exp1 = wasmEvalText(`(module (table 10 funcref) (export "tbl" table) (elem (i32.const 0) $f0 $f0) ${callee(0)} (export "f0" $f0) ${caller})`).exports
 assertEq(exp1.tbl.get(0), exp1.f0);
 assertEq(exp1.tbl.get(1), exp1.f0);
 assertEq(exp1.tbl.get(2), null);
 assertEq(exp1.call(0), 0);
 assertEq(exp1.call(1), 0);
 assertErrorMessage(() => exp1.call(2), RuntimeError, /indirect call to null/);
-var exp2 = wasmEvalText(`(module (import "a" "b" (table 10 anyfunc)) (export "tbl" table) (elem (i32.const 1) $f1 $f1) ${callee(1)} (export "f1" $f1) ${caller})`, {a:{b:exp1.tbl}}).exports
+var exp2 = wasmEvalText(`(module (import "a" "b" (table 10 funcref)) (export "tbl" table) (elem (i32.const 1) $f1 $f1) ${callee(1)} (export "f1" $f1) ${caller})`, {a:{b:exp1.tbl}}).exports
 assertEq(exp1.tbl, exp2.tbl);
 assertEq(exp2.tbl.get(0), exp1.f0);
 assertEq(exp2.tbl.get(1), exp2.f1);
 assertEq(exp2.tbl.get(2), exp2.f1);
 assertEq(exp1.call(0), 0);
 assertEq(exp1.call(1), 1);
 assertEq(exp1.call(2), 1);
 assertEq(exp2.call(0), 0);
 assertEq(exp2.call(1), 1);
 assertEq(exp2.call(2), 1);
 
-var tbl = new Table({initial:3, element:"anyfunc"});
+var tbl = new Table({initial:3, element:"funcref"});
 var e1 = wasmEvalText(`(module (func $f (result i32) (i32.const 42)) (export "f" $f))`).exports;
 var e2 = wasmEvalText(`(module (func $g (result f32) (f32.const 10)) (export "g" $g))`).exports;
 var e3 = wasmEvalText(`(module (func $h (result i32) (i32.const 13)) (export "h" $h))`).exports;
 tbl.set(0, e1.f);
 tbl.set(1, e2.g);
 tbl.set(2, e3.h);
-var e4 = wasmEvalText(`(module (import "a" "b" (table 3 anyfunc)) ${caller})`, {a:{b:tbl}}).exports;
+var e4 = wasmEvalText(`(module (import "a" "b" (table 3 funcref)) ${caller})`, {a:{b:tbl}}).exports;
 assertEq(e4.call(0), 42);
 assertErrorMessage(() => e4.call(1), RuntimeError, /indirect call signature mismatch/);
 assertEq(e4.call(2), 13);
 
 var m = new Module(wasmTextToBinary(`(module
     (type $i2i (func (param i32) (result i32)))
     (import "a" "mem" (memory 1))
-    (import "a" "tbl" (table 10 anyfunc))
+    (import "a" "tbl" (table 10 funcref))
     (import $imp "a" "imp" (result i32))
     (func $call (param $i i32) (result i32)
         (i32.add
             (call $imp)
             (i32.add
                 (i32.load (i32.const 0))
                 (if i32 (i32.eqz (get_local $i))
                     (then (i32.const 0))
                     (else
                         (set_local $i (i32.sub (get_local $i) (i32.const 1)))
                         (call_indirect $i2i (get_local $i) (get_local $i)))))))
     (export "call" $call)
 )`));
 var failTime = false;
-var tbl = new Table({initial:10, element:"anyfunc"});
+var tbl = new Table({initial:10, element:"funcref"});
 var mem1 = new Memory({initial:1});
 var e1 = new Instance(m, {a:{mem:mem1, tbl, imp() {if (failTime) throw new Error("ohai"); return 1}}}).exports;
 tbl.set(0, e1.call);
 var mem2 = new Memory({initial:1});
 var e2 = new Instance(m, {a:{mem:mem2, tbl, imp() {return 10} }}).exports;
 tbl.set(1, e2.call);
 var mem3 = new Memory({initial:1});
 var e3 = new Instance(m, {a:{mem:mem3, tbl, imp() {return 100} }}).exports;
@@ -155,17 +155,17 @@ failTime = true;
 assertErrorMessage(() => e3.call(2), Error, "ohai");
 
 // Call signatures are matched structurally:
 
 var call = wasmEvalText(`(module
     (type $v2i1 (func (result i32)))
     (type $v2i2 (func (result i32)))
     (type $i2v (func (param i32)))
-    (table anyfunc (elem $a $b $c))
+    (table funcref (elem $a $b $c))
     (func $a (type $v2i1) (i32.const 0))
     (func $b (type $v2i2) (i32.const 1))
     (func $c (type $i2v))
     (func $call (param i32) (result i32) (call_indirect $v2i1 (get_local 0)))
     (export "call" $call)
 )`).exports.call;
 assertEq(call(0), 0);
 assertEq(call(1), 1);
@@ -174,17 +174,17 @@ assertErrorMessage(() => call(2), Runtim
 var call = wasmEvalText(`(module
     (type $A (func (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (result i32)))
     (type $B (func (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (result i32)))
     (type $C (func (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (result i32)))
     (type $D (func (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (result i32)))
     (type $E (func (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (result i32)))
     (type $F (func (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (result i32)))
     (type $G (func (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (result i32)))
-    (table anyfunc (elem $a $b $c $d $e $f $g))
+    (table funcref (elem $a $b $c $d $e $f $g))
     (func $a (type $A) (get_local 7))
     (func $b (type $B) (get_local 8))
     (func $c (type $C) (get_local 9))
     (func $d (type $D) (get_local 10))
     (func $e (type $E) (get_local 11))
     (func $f (type $F) (get_local 12))
     (func $g (type $G) (get_local 13))
     (func $call (param i32) (result i32)
@@ -192,40 +192,40 @@ var call = wasmEvalText(`(module
     (export "call" $call)
 )`).exports.call;
 assertEq(call(0), 42);
 for (var i = 1; i < 7; i++)
     assertErrorMessage(() => call(i), RuntimeError, /indirect call signature mismatch/);
 assertErrorMessage(() => call(7), RuntimeError, /index out of bounds/);
 
 // Function identity isn't lost:
-var tbl = wasmEvalText(`(module (table (export "tbl") anyfunc (elem $f)) (func $f))`).exports.tbl;
+var tbl = wasmEvalText(`(module (table (export "tbl") funcref (elem $f)) (func $f))`).exports.tbl;
 tbl.get(0).foo = 42;
 gc();
 assertEq(tbl.get(0).foo, 42);
 
 (function testCrossRealmCall() {
     var g = newGlobal({sameCompartmentAs: this});
 
     // The memory.size builtin asserts cx->realm matches instance->realm so
     // we call it here.
     var src = `
         (module
-            (import "a" "t" (table 3 anyfunc))
+            (import "a" "t" (table 3 funcref))
             (import "a" "m" (memory 1))
             (func $f (result i32) (i32.add (i32.const 3) (memory.size)))
             (elem (i32.const 0) $f))
     `;
     g.mem = new Memory({initial:4});
-    g.tbl = new Table({initial:3, element:"anyfunc"});
+    g.tbl = new Table({initial:3, element:"funcref"});
     var i1 = g.evaluate("new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`" + src + "`)), {a:{t:tbl,m:mem}})");
 
     var call = new Instance(new Module(wasmTextToBinary(`
         (module
-            (import "a" "t" (table 3 anyfunc))
+            (import "a" "t" (table 3 funcref))
             (import "a" "m" (memory 1))
             (type $v2i (func (result i32)))
             (func $call (param $i i32) (result i32) (i32.add (call_indirect $v2i (get_local $i)) (memory.size)))
             (export "call" $call))
     `)), {a:{t:g.tbl,m:g.mem}}).exports.call;
 
     for (var i = 0; i < 10; i++)
         assertEq(call(0), 11);
@@ -236,17 +236,17 @@ assertEq(tbl.get(0).foo, 42);
 
 {
     function makeIt(flag, tblindex) {
         return new Uint8Array([0x00, 0x61, 0x73, 0x6d,
                                0x01, 0x00, 0x00, 0x00,
                                0x04,                   // Table section
                                0x04,                   // Section size
                                0x01,                   // One table
-                               0x70,                   // Type: Anyfunc
+                               0x70,                   // Type: FuncRef
                                0x00,                   // Limits: Min only
                                0x01,                   // Limits: Min
                                0x09,                   // Elements section
                                0x07,                   // Section size
                                0x01,                   // One element segment
                                flag,                   // Flag should be 2, or > 2 if invalid
                                tblindex,               // Table index must be 0, or > 0 if invalid
                                0x41,                   // Init expr: i32.const
--- a/js/src/jit-test/tests/wasm/text.js
+++ b/js/src/jit-test/tests/wasm/text.js
@@ -35,36 +35,36 @@ wasmEvalText('(module (func (local i32 i
 assertErrorMessage(() => wasmEvalText('(module (func (local $a)))'), SyntaxError, parsingError);
 assertErrorMessage(() => wasmEvalText('(module (func (local $a i32 i32)))'), SyntaxError, parsingError);
 
 // Table
 assertErrorMessage(() => wasmEvalText('(module (table (local $a)))'), SyntaxError, parsingError);
 assertErrorMessage(() => wasmEvalText('(module (table $t))'), SyntaxError, parsingError);
 assertErrorMessage(() => wasmEvalText('(module (table $t 1))'), SyntaxError, parsingError);
 assertErrorMessage(() => wasmEvalText('(module (table $t 1 10))'), SyntaxError, parsingError);
-wasmEvalText('(module (table $t 1 10 anyfunc))');
-wasmEvalText('(module (table $t 1 anyfunc))');
-wasmEvalText('(module (table 0 anyfunc))');
+wasmEvalText('(module (table $t 1 10 funcref))');
+wasmEvalText('(module (table $t 1 funcref))');
+wasmEvalText('(module (table 0 funcref))');
 
-assertErrorMessage(() => wasmEvalText('(module (table $t anyfunc))'), SyntaxError, parsingError);
-wasmEvalText('(module (table $t anyfunc (elem)))');
-wasmEvalText('(module (func) (table $t anyfunc (elem 0 0 0)))');
+assertErrorMessage(() => wasmEvalText('(module (table $t funcref))'), SyntaxError, parsingError);
+wasmEvalText('(module (table $t funcref (elem)))');
+wasmEvalText('(module (func) (table $t funcref (elem 0 0 0)))');
 
 const { Table } = WebAssembly;
-const table = new Table({initial:1, element:"anyfunc"});
-assertErrorMessage(() => wasmEvalText('(module (table $t (import) 1 anyfunc))'), SyntaxError, parsingError);
-assertErrorMessage(() => wasmEvalText('(module (table $t (import "mod") 1 anyfunc))'), SyntaxError, parsingError);
-assertErrorMessage(() => wasmEvalText('(module (table $t (import "mod" "field") 1 anyfunc (elem 1 2 3)))'), SyntaxError, parsingError);
-wasmEvalText('(module (table $t (import "mod" "field") 1 anyfunc))', {mod: {field: table}});
+const table = new Table({initial:1, element:"funcref"});
+assertErrorMessage(() => wasmEvalText('(module (table $t (import) 1 funcref))'), SyntaxError, parsingError);
+assertErrorMessage(() => wasmEvalText('(module (table $t (import "mod") 1 funcref))'), SyntaxError, parsingError);
+assertErrorMessage(() => wasmEvalText('(module (table $t (import "mod" "field") 1 funcref (elem 1 2 3)))'), SyntaxError, parsingError);
+wasmEvalText('(module (table $t (import "mod" "field") 1 funcref))', {mod: {field: table}});
 
 assertErrorMessage(() => wasmEvalText('(module (table $t (export "mod") 1))'), SyntaxError, parsingError);
-assertErrorMessage(() => wasmEvalText('(module (table $t (export "mod") anyfunc))'), SyntaxError, parsingError);
-assertErrorMessage(() => wasmEvalText('(module (table $t (export "mod") anyfunc 1 2 3))'), SyntaxError, parsingError);
-assertEq(wasmEvalText('(module (table $t (export "tbl") anyfunc (elem)))').exports.tbl instanceof Table, true);
-assertEq(wasmEvalText('(module (func) (table $t (export "tbl") anyfunc (elem 0 0 0)))').exports.tbl instanceof Table, true);
+assertErrorMessage(() => wasmEvalText('(module (table $t (export "mod") funcref))'), SyntaxError, parsingError);
+assertErrorMessage(() => wasmEvalText('(module (table $t (export "mod") funcref 1 2 3))'), SyntaxError, parsingError);
+assertEq(wasmEvalText('(module (table $t (export "tbl") funcref (elem)))').exports.tbl instanceof Table, true);
+assertEq(wasmEvalText('(module (func) (table $t (export "tbl") funcref (elem 0 0 0)))').exports.tbl instanceof Table, true);
 
 // Functions.
 assertErrorMessage(() => wasmEvalText('(module (func $t import))'), SyntaxError, parsingError);
 assertErrorMessage(() => wasmEvalText('(module (func $t (import)))'), SyntaxError, parsingError);
 assertErrorMessage(() => wasmEvalText('(module (func $t (import "mod")))'), SyntaxError, parsingError);
 assertErrorMessage(() => wasmEvalText('(module (func $t (import "mod" "func" (local i32))))'), SyntaxError, parsingError);
 
 const func = i => 42 + i;
--- a/js/src/jit-test/tests/wasm/timeout/2.js
+++ b/js/src/jit-test/tests/wasm/timeout/2.js
@@ -1,27 +1,27 @@
 // |jit-test| exitstatus: 6; skip-if: !wasmIsSupported()
 
 // Don't include wasm.js in timeout tests: when wasm isn't supported, it will
 // quit(0) which will cause the test to fail.
 
-var tbl = new WebAssembly.Table({initial:1, element:"anyfunc"});
+var tbl = new WebAssembly.Table({initial:1, element:"funcref"});
 
 new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`(module
     (func $iloop
         loop $top
             br $top
         end
     )
-    (import "imports" "tbl" (table 1 anyfunc))
+    (import "imports" "tbl" (table 1 funcref))
     (elem (i32.const 0) $iloop)
 )`)), {imports:{tbl}});
 
 var outer = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`(module
-    (import "imports" "tbl" (table 1 anyfunc))
+    (import "imports" "tbl" (table 1 funcref))
     (type $v2v (func))
     (func (export "run")
         i32.const 0
         call_indirect $v2v
     )
 )`)), {imports:{tbl}});
 
 setJitCompilerOption('simulator.always-interrupt', 1);
--- a/js/src/jit-test/tests/wasm/timeout/debug-noprofiling.js
+++ b/js/src/jit-test/tests/wasm/timeout/debug-noprofiling.js
@@ -2,29 +2,29 @@
 
 // Don't include wasm.js in timeout tests: when wasm isn't supported, it will
 // quit(0) which will cause the test to fail.
 
 newGlobal({newCompartment: true}).Debugger().addDebuggee(this);
 
 var t = new WebAssembly.Table({
     initial: 1,
-    element: "anyfunc"
+    element: "funcref"
 });
 
 new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`
 (module
     (func $iloop loop $top br $top end)
-    (import "imports" "t" (table1 anyfunc))
+    (import "imports" "t" (table1 funcref))
     (elem (i32.const0) $iloop))
 `)), { imports: { t } });
 
 outer = new WebAssembly.Instance(new WebAssembly.Module(wasmTextToBinary(`
 (module
-    (import "imports" "t" (table1 anyfunc))
+    (import "imports" "t" (table1 funcref))
     (type $v2v (func))
     (func (export "run")
         i32.const0
         call_indirect $v2v)
     )`)), { imports: { t } });
 
 setJitCompilerOption('simulator.always-interrupt', 1);
 timeout(1);
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -403,18 +403,18 @@ MSG_DEF(JSMSG_WASM_BAD_RANGE ,         2
 MSG_DEF(JSMSG_WASM_BAD_GROW,           1, JSEXN_RANGEERR,    "failed to grow {0}")
 MSG_DEF(JSMSG_WASM_BAD_TBL_GROW_INIT,  1, JSEXN_TYPEERR,     "bad initializer to {0} table")
 MSG_DEF(JSMSG_WASM_TABLE_OUT_OF_BOUNDS, 0, JSEXN_RANGEERR,   "table index out of bounds")
 MSG_DEF(JSMSG_WASM_BAD_UINT32,         2, JSEXN_TYPEERR,     "bad {0} {1}")
 MSG_DEF(JSMSG_WASM_BAD_BUF_ARG,        0, JSEXN_TYPEERR,     "first argument must be an ArrayBuffer or typed array object")
 MSG_DEF(JSMSG_WASM_BAD_MOD_ARG,        0, JSEXN_TYPEERR,     "first argument must be a WebAssembly.Module")
 MSG_DEF(JSMSG_WASM_BAD_BUF_MOD_ARG,    0, JSEXN_TYPEERR,     "first argument must be a WebAssembly.Module, ArrayBuffer or typed array object")
 MSG_DEF(JSMSG_WASM_BAD_DESC_ARG,       1, JSEXN_TYPEERR,     "first argument must be a {0} descriptor")
-MSG_DEF(JSMSG_WASM_BAD_ELEMENT,        0, JSEXN_TYPEERR,     "\"element\" property of table descriptor must be \"anyfunc\"")
-MSG_DEF(JSMSG_WASM_BAD_ELEMENT_GENERALIZED, 0, JSEXN_TYPEERR, "\"element\" property of table descriptor must be \"anyfunc\" or \"anyref\"")
+MSG_DEF(JSMSG_WASM_BAD_ELEMENT,        0, JSEXN_TYPEERR,     "\"element\" property of table descriptor must be \"funcref\"")
+MSG_DEF(JSMSG_WASM_BAD_ELEMENT_GENERALIZED, 0, JSEXN_TYPEERR, "\"element\" property of table descriptor must be \"funcref\" or \"anyref\"")
 MSG_DEF(JSMSG_WASM_BAD_IMPORT_ARG,     0, JSEXN_TYPEERR,     "second argument must be an object")
 MSG_DEF(JSMSG_WASM_BAD_IMPORT_FIELD,   1, JSEXN_TYPEERR,     "import object field '{0}' is not an Object")
 MSG_DEF(JSMSG_WASM_BAD_TABLE_VALUE,    0, JSEXN_TYPEERR,     "can only assign WebAssembly exported functions to Table")
 MSG_DEF(JSMSG_WASM_BAD_I64_TYPE,       0, JSEXN_TYPEERR,     "cannot pass i64 to or from JS")
 MSG_DEF(JSMSG_WASM_BAD_GLOBAL_TYPE,    0, JSEXN_TYPEERR,     "bad type for a WebAssembly.Global")
 MSG_DEF(JSMSG_WASM_NO_TRANSFER,        0, JSEXN_TYPEERR,     "cannot transfer WebAssembly/asm.js ArrayBuffer")
 MSG_DEF(JSMSG_WASM_TEXT_FAIL,          1, JSEXN_SYNTAXERR,   "wasm text error: {0}")
 MSG_DEF(JSMSG_WASM_MISSING_MAXIMUM,    0, JSEXN_TYPEERR,     "'shared' is true but maximum is not specified")
--- a/js/src/tests/jstests.list
+++ b/js/src/tests/jstests.list
@@ -1124,33 +1124,24 @@ skip script test262/annexB/language/eval
 skip script test262/annexB/language/eval-code/indirect/global-if-decl-else-stmt-eval-global-existing-global-init.js
 skip script test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-b-eval-global-existing-global-init.js
 skip script test262/annexB/language/eval-code/indirect/global-if-decl-else-decl-a-eval-global-existing-global-init.js
 skip script test262/annexB/language/eval-code/indirect/global-block-decl-eval-global-existing-global-init.js
 skip script test262/annexB/language/eval-code/indirect/global-switch-case-eval-global-existing-global-init.js
 
 # Need to fix increment/decrement of arguments or eval -- bug 1530883.
 skip script test262/language/expressions/postfix-increment/eval.js
-skip script test262/language/expressions/postfix-increment/eval-nostrict.js
-skip script test262/language/expressions/postfix-increment/arguments-nostrict.js
 skip script test262/language/expressions/postfix-increment/arguments.js
 skip script test262/language/expressions/prefix-decrement/eval.js
-skip script test262/language/expressions/prefix-decrement/eval-nostrict.js
-skip script test262/language/expressions/prefix-decrement/arguments-nostrict.js
 skip script test262/language/expressions/prefix-decrement/arguments.js
 skip script test262/language/expressions/prefix-increment/eval.js
-skip script test262/language/expressions/prefix-increment/eval-nostrict.js
-skip script test262/language/expressions/prefix-increment/arguments-nostrict.js
 skip script test262/language/expressions/prefix-increment/arguments.js
 skip script test262/language/expressions/postfix-decrement/eval.js
-skip script test262/language/expressions/postfix-decrement/eval-nostrict.js
-skip script test262/language/expressions/postfix-decrement/arguments-nostrict.js
 skip script test262/language/expressions/postfix-decrement/arguments.js
 
-
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1340307
 skip script test262/language/module-code/instn-resolve-empty-export.js
 skip script test262/language/module-code/instn-resolve-empty-import.js
 skip script test262/language/module-code/instn-resolve-err-reference.js
 skip script test262/language/module-code/instn-resolve-order-depth.js
 skip script test262/language/module-code/instn-resolve-order-src.js
 skip script test262/language/module-code/parse-err-reference.js
 skip script test262/language/expressions/postfix-increment/target-cover-yieldexpr.js
@@ -1218,21 +1209,16 @@ skip script test262/annexB/built-ins/Fun
 skip script test262/annexB/language/function-code/block-decl-nested-blocks-with-fun-decl.js
 
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1406171
 skip script test262/built-ins/Reflect/ownKeys/return-on-corresponding-order-large-index.js
 
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1473229
 skip include test262/intl402/RelativeTimeFormat/prototype/formatToParts/jstests.list
 
-# SupportedLocales in the Intl spec returns a non-frozen array after
-# https://github.com/tc39/ecma402/pull/278 -- bug 1530848.
-skip script test262/intl402/RelativeTimeFormat/constructor/supportedLocalesOf/result-type.js
-skip script test262/intl402/supportedLocalesOf-returned-array-elements-are-not-frozen.js
-
 # Need to add "numberingSystem" to resolvedOptions() to address
 # https://github.com/tc39/test262/pull/2011 apparently -- bug 1521819.
 skip script test262/intl402/RelativeTimeFormat/prototype/resolvedOptions/order.js
 
 # https://bugzilla.mozilla.org/show_bug.cgi?id=1508683
 skip script test262/built-ins/RegExp/prototype/multiline/cross-realm.js
 skip script test262/built-ins/RegExp/prototype/global/cross-realm.js
 skip script test262/built-ins/RegExp/prototype/sticky/cross-realm.js
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -144,22 +144,22 @@ class DebuggerWeakMap
 
   explicit DebuggerWeakMap(JSContext* cx)
       : Base(cx), zoneCounts(cx->zone()), compartment(cx->compartment()) {}
 
  public:
   // Expose those parts of HashMap public interface that are used by Debugger
   // methods.
 
-  typedef typename Base::Entry Entry;
-  typedef typename Base::Ptr Ptr;
-  typedef typename Base::AddPtr AddPtr;
-  typedef typename Base::Range Range;
-  typedef typename Base::Enum Enum;
-  typedef typename Base::Lookup Lookup;
+  using Entry = typename Base::Entry;
+  using Ptr = typename Base::Ptr;
+  using AddPtr = typename Base::AddPtr;
+  using Range = typename Base::Range;
+  using Enum = typename Base::Enum;
+  using Lookup = typename Base::Lookup;
 
   // Expose WeakMap public interface.
 
   using Base::all;
   using Base::lookup;
   using Base::lookupForAdd;
   using Base::remove;
   using Base::trace;
--- a/js/src/vm/Realm.cpp
+++ b/js/src/vm/Realm.cpp
@@ -298,18 +298,18 @@ void ObjectRealm::trace(JSTracer* trc) {
   if (nonSyntacticLexicalEnvironments_) {
     nonSyntacticLexicalEnvironments_->trace(trc);
   }
 }
 
 void Realm::traceRoots(JSTracer* trc,
                        js::gc::GCRuntime::TraceOrMarkRuntime traceOrMark) {
   if (objectMetadataState_.is<PendingMetadata>()) {
-    TraceRoot(trc, &objectMetadataState_.as<PendingMetadata>(),
-              "on-stack object pending metadata");
+    GCPolicy<NewObjectMetadataState>::trace(trc, &objectMetadataState_,
+                                            "on-stack object pending metadata");
   }
 
   if (!JS::RuntimeHeapIsMinorCollecting()) {
     // The global is never nursery allocated, so we don't need to
     // trace it when doing a minor collection.
     //
     // If a compartment is on-stack, we mark its global so that
     // JSContext::global() remains valid.
@@ -919,19 +919,18 @@ void Realm::addSizeOfIncludingThis(
 
 mozilla::HashCodeScrambler Realm::randomHashCodeScrambler() {
   return mozilla::HashCodeScrambler(randomKeyGenerator_.next(),
                                     randomKeyGenerator_.next());
 }
 
 AutoSetNewObjectMetadata::AutoSetNewObjectMetadata(
     JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
-    : CustomAutoRooter(cx),
-      cx_(cx->helperThread() ? nullptr : cx),
-      prevState_(cx->realm()->objectMetadataState_) {
+    : cx_(cx->helperThread() ? nullptr : cx),
+      prevState_(cx, cx->realm()->objectMetadataState_) {
   MOZ_GUARD_OBJECT_NOTIFIER_INIT;
   if (cx_) {
     cx_->realm()->objectMetadataState_ =
         NewObjectMetadataState(DelayMetadata());
   }
 }
 
 AutoSetNewObjectMetadata::~AutoSetNewObjectMetadata() {
--- a/js/src/vm/Realm.h
+++ b/js/src/vm/Realm.h
@@ -15,16 +15,17 @@
 #include "mozilla/Tuple.h"
 #include "mozilla/Variant.h"
 #include "mozilla/XorShift128PlusRNG.h"
 
 #include <stddef.h>
 
 #include "builtin/Array.h"
 #include "gc/Barrier.h"
+#include "js/GCVariant.h"
 #include "js/UniquePtr.h"
 #include "vm/ArrayBufferObject.h"
 #include "vm/Compartment.h"
 #include "vm/ReceiverGuard.h"
 #include "vm/RegExpShared.h"
 #include "vm/SavedStacks.h"
 #include "vm/Time.h"
 #include "wasm/WasmRealm.h"
@@ -169,40 +170,34 @@ class NewProxyCache {
 //           |   |                                  |
 //           V   V                                  |
 //     DelayMetadata -------------------------> PendingMetadata
 //                         via allocation
 //
 // In the presence of internal errors, we do not set the new object's metadata
 // (if it was even allocated) and reset to the previous state on the stack.
 
+// See below in namespace JS for the template specialization for
+// ImmediateMetadata and DelayMetadata.
 struct ImmediateMetadata {};
 struct DelayMetadata {};
 using PendingMetadata = JSObject*;
 
 using NewObjectMetadataState =
     mozilla::Variant<ImmediateMetadata, DelayMetadata, PendingMetadata>;
 
-class MOZ_RAII AutoSetNewObjectMetadata : private JS::CustomAutoRooter {
+class MOZ_RAII AutoSetNewObjectMetadata {
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER;
 
   JSContext* cx_;
-  NewObjectMetadataState prevState_;
+  Rooted<NewObjectMetadataState> prevState_;
 
   AutoSetNewObjectMetadata(const AutoSetNewObjectMetadata& aOther) = delete;
   void operator=(const AutoSetNewObjectMetadata& aOther) = delete;
 
- protected:
-  virtual void trace(JSTracer* trc) override {
-    if (prevState_.is<PendingMetadata>()) {
-      TraceRoot(trc, &prevState_.as<PendingMetadata>(),
-                "Object pending metadata");
-    }
-  }
-
  public:
   explicit AutoSetNewObjectMetadata(
       JSContext* cx MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
   ~AutoSetNewObjectMetadata();
 };
 
 class PropertyIteratorObject;
 
@@ -289,16 +284,23 @@ class ObjectRealm {
       JSContext* cx, js::HandleObject enclosing, js::HandleObject key,
       js::HandleObject thisv);
   js::LexicalEnvironmentObject* getNonSyntacticLexicalEnvironment(
       JSObject* key) const;
 };
 
 }  // namespace js
 
+namespace JS {
+template <> struct GCPolicy<js::ImmediateMetadata>:
+  public IgnoreGCPolicy<js::ImmediateMetadata> {};
+template <> struct GCPolicy<js::DelayMetadata>:
+  public IgnoreGCPolicy<js::DelayMetadata> {};
+} // namespace JS
+
 class JS::Realm : public JS::shadow::Realm {
   JS::Zone* zone_;
   JSRuntime* runtime_;
 
   const JS::RealmCreationOptions creationOptions_;
   JS::RealmBehaviors behaviors_;
 
   friend struct ::JSContext;
--- a/js/src/vm/Runtime.h
+++ b/js/src/vm/Runtime.h
@@ -9,17 +9,16 @@
 
 #include "mozilla/Atomics.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/DoublyLinkedList.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/MaybeOneOf.h"
 #include "mozilla/MemoryReporting.h"
-#include "mozilla/Scoped.h"
 #include "mozilla/ThreadLocal.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Vector.h"
 
 #include <algorithm>
 #include <setjmp.h>
 
 #include "builtin/AtomicsObject.h"
--- a/js/src/vm/SavedFrame.h
+++ b/js/src/vm/SavedFrame.h
@@ -105,36 +105,22 @@ class SavedFrame : public NativeObject {
 
   struct Lookup;
   struct HashPolicy;
 
   typedef JS::GCHashSet<ReadBarriered<SavedFrame*>, HashPolicy,
                         SystemAllocPolicy>
       Set;
 
-  class AutoLookupVector;
-
-  class MOZ_STACK_CLASS HandleLookup {
-    friend class AutoLookupVector;
-
-    Lookup& lookup;
-
-    explicit HandleLookup(Lookup& lookup) : lookup(lookup) {}
-
-   public:
-    inline Lookup& get() { return lookup; }
-    inline Lookup* operator->() { return &lookup; }
-  };
-
  private:
   static SavedFrame* create(JSContext* cx);
   static MOZ_MUST_USE bool finishSavedFrameInit(JSContext* cx,
                                                 HandleObject ctor,
                                                 HandleObject proto);
-  void initFromLookup(JSContext* cx, HandleLookup lookup);
+  void initFromLookup(JSContext* cx, Handle<Lookup> lookup);
   void initSource(JSAtom* source);
   void initSourceId(uint32_t id);
   void initLine(uint32_t line);
   void initColumn(uint32_t column);
   void initFunctionDisplayName(JSAtom* maybeName);
   void initAsyncCause(JSAtom* maybeCause);
   void initParent(SavedFrame* maybeParent);
   void initPrincipalsAlreadyHeld(JSPrincipals* principals);
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -237,34 +237,52 @@ struct SavedFrame::Lookup {
                                  "SavedFrame::Lookup::asyncCause");
     }
     if (parent) {
       TraceManuallyBarrieredEdge(trc, &parent, "SavedFrame::Lookup::parent");
     }
   }
 };
 
-class MOZ_STACK_CLASS SavedFrame::AutoLookupVector
-    : public JS::CustomAutoRooter {
- public:
-  explicit AutoLookupVector(JSContext* cx)
-      : JS::CustomAutoRooter(cx), lookups(cx) {}
+using GCLookupVector = GCVector<SavedFrame::Lookup, ASYNC_STACK_MAX_FRAME_COUNT>;
+
+template <class Wrapper>
+class WrappedPtrOperations<SavedFrame::Lookup, Wrapper> {
+  const SavedFrame::Lookup& value() const {
+    return static_cast<const Wrapper*>(this)->get();
+  }
 
-  typedef Vector<Lookup, ASYNC_STACK_MAX_FRAME_COUNT> LookupVector;
-  inline LookupVector* operator->() { return &lookups; }
-  inline HandleLookup operator[](size_t i) { return HandleLookup(lookups[i]); }
-  inline HandleLookup back() { return HandleLookup(lookups.back()); }
+ public:
+  JSAtom* source() { return value().source; }
+  uint32_t sourceId() { return value().sourceId; }
+  uint32_t line() { return value().line; }
+  uint32_t column() { return value().column; }
+  JSAtom* functionDisplayName() { return value().functionDisplayName; }
+  JSAtom* asyncCause() { return value().asyncCause; }
+  SavedFrame* parent() { return value().parent; }
+  JSPrincipals* principals() { return value().principals; }
+  Maybe<LiveSavedFrameCache::FramePtr> framePtr() { return value().framePtr; }
+  jsbytecode* pc() { return value().pc; }
+  Activation* activation() { return value().activation; }
+};
 
- private:
-  LookupVector lookups;
+template <typename Wrapper>
+class MutableWrappedPtrOperations<SavedFrame::Lookup, Wrapper>
+    : public WrappedPtrOperations<SavedFrame::Lookup, Wrapper> {
+  SavedFrame::Lookup& value() {
+    return static_cast<Wrapper*>(this)->get();
+  }
 
-  virtual void trace(JSTracer* trc) override {
-    for (size_t i = 0; i < lookups.length(); i++) {
-      lookups[i].trace(trc);
-    }
+ public:
+  void setParent(SavedFrame* parent) {
+    value().parent = parent;
+  }
+
+  void setAsyncCause(HandleAtom asyncCause) {
+    value().asyncCause = asyncCause;
   }
 };
 
 /* static */ bool SavedFrame::HashPolicy::hasHash(const Lookup& l) {
   return SavedFramePtrHasher::hasHash(l.parent);
 }
 
 /* static */ bool SavedFrame::HashPolicy::ensureHash(const Lookup& l) {
@@ -485,40 +503,40 @@ void SavedFrame::initAsyncCause(JSAtom* 
                    maybeCause ? StringValue(maybeCause) : NullValue());
 }
 
 void SavedFrame::initParent(SavedFrame* maybeParent) {
   initReservedSlot(JSSLOT_PARENT, ObjectOrNullValue(maybeParent));
 }
 
 void SavedFrame::initFromLookup(JSContext* cx,
-                                SavedFrame::HandleLookup lookup) {
+                                Handle<Lookup> lookup) {
   // Make sure any atoms used in the lookup are marked in the current zone.
   // Normally we would try to keep these mark bits up to date around the
   // points where the context moves between compartments, but Lookups live on
   // the stack (where the atoms are kept alive regardless) and this is a
   // more convenient pinchpoint.
-  if (lookup->source) {
-    cx->markAtom(lookup->source);
+  if (lookup.source()) {
+    cx->markAtom(lookup.source());
   }
-  if (lookup->functionDisplayName) {
-    cx->markAtom(lookup->functionDisplayName);
+  if (lookup.functionDisplayName()) {
+    cx->markAtom(lookup.functionDisplayName());
   }
-  if (lookup->asyncCause) {
-    cx->markAtom(lookup->asyncCause);
+  if (lookup.asyncCause()) {
+    cx->markAtom(lookup.asyncCause());
   }
 
-  initSource(lookup->source);
-  initSourceId(lookup->sourceId);
-  initLine(lookup->line);
-  initColumn(lookup->column);
-  initFunctionDisplayName(lookup->functionDisplayName);
-  initAsyncCause(lookup->asyncCause);
-  initParent(lookup->parent);
-  initPrincipals(lookup->principals);
+  initSource(lookup.source());
+  initSourceId(lookup.sourceId());
+  initLine(lookup.line());
+  initColumn(lookup.column());
+  initFunctionDisplayName(lookup.functionDisplayName());
+  initAsyncCause(lookup.asyncCause());
+  initParent(lookup.parent());
+  initPrincipals(lookup.principals());
 }
 
 /* static */ SavedFrame* SavedFrame::create(JSContext* cx) {
   RootedGlobalObject global(cx, cx->global());
   cx->check(global);
 
   // Ensure that we don't try to capture the stack again in the
   // `SavedStacksMetadataBuilder` for this new SavedFrame object, and
@@ -1309,17 +1327,17 @@ bool SavedStacks::insertFrames(JSContext
   // To avoid making many copies of FrameIter (whose copy constructor is
   // relatively slow), we use a vector of `SavedFrame::Lookup` objects, which
   // only contain the FrameIter data we need. The `SavedFrame::Lookup`
   // objects are partially initialized with everything except their parent
   // pointers on the first pass, and then we fill in the parent pointers as we
   // return in the second pass.
 
   // Accumulate the vector of Lookup objects here, youngest to oldest.
-  SavedFrame::AutoLookupVector stackChain(cx);
+  Rooted<js::GCLookupVector> stackChain(cx, js::GCLookupVector(cx));
 
   // If we find an async parent or a cached saved frame, then that supplies
   // the parent of the frames we have placed in stackChain. If we walk the
   // stack all the way to the end, this remains null.
   RootedSavedFrame parent(cx, nullptr);
 
   // Choose the right frame iteration strategy to accomodate both
   // evalInFramePrev links and the LiveSavedFrameCache. For background, see
@@ -1387,17 +1405,17 @@ bool SavedStacks::insertFrames(JSContext
       }
     }
 
     RootedAtom displayAtom(cx, iter.maybeFunctionDisplayAtom());
 
     auto principals = iter.realm()->principals();
     MOZ_ASSERT_IF(framePtr && !iter.isWasm(), iter.pc());
 
-    if (!stackChain->emplaceBack(
+    if (!stackChain.emplaceBack(
             location.source(), location.sourceId(),
             location.line(), location.column(), displayAtom,
             nullptr,  // asyncCause
             nullptr,  // parent (not known yet)
             principals, framePtr, iter.pc(), &activation)) {
       ReportOutOfMemory(cx);
       return false;
     }
@@ -1461,39 +1479,39 @@ bool SavedStacks::insertFrames(JSContext
     if (capture.is<JS::MaxFrames>()) {
       capture.as<JS::MaxFrames>().maxFrames--;
     }
   }
 
   // Iterate through |stackChain| in reverse order and get or create the
   // actual SavedFrame instances.
   frame.set(parent);
-  for (size_t i = stackChain->length(); i != 0; i--) {
-    SavedFrame::HandleLookup lookup = stackChain[i - 1];
-    lookup->parent = frame;
+  for (size_t i = stackChain.length(); i != 0; i--) {
+    MutableHandle<SavedFrame::Lookup> lookup = stackChain[i - 1];
+    lookup.setParent(frame);
 
     // If necessary, adjust the parent of a debugger eval frame to point to
     // the frame in whose scope the eval occurs - if we're using
     // LiveSavedFrameCache. Otherwise, we simply ask the FrameIter to follow
     // evalInFramePrev links, so that the parent is always the last frame we
     // created.
-    if (capture.is<JS::AllFrames>() && lookup->framePtr) {
+    if (capture.is<JS::AllFrames>() && lookup.framePtr()) {
       if (!checkForEvalInFramePrev(cx, lookup)) {
         return false;
       }
     }
 
     frame.set(getOrCreateSavedFrame(cx, lookup));
     if (!frame) {
       return false;
     }
 
-    if (capture.is<JS::AllFrames>() && lookup->framePtr) {
-      auto* cache = lookup->activation->getLiveSavedFrameCache(cx);
-      if (!cache || !cache->insert(cx, *lookup->framePtr, lookup->pc, frame)) {
+    if (capture.is<JS::AllFrames>() && lookup.framePtr()) {
+      auto* cache = lookup.activation()->getLiveSavedFrameCache(cx);
+      if (!cache || !cache->insert(cx, *lookup.framePtr(), lookup.pc(), frame)) {
         return false;
       }
     }
   }
 
   return true;
 }
 
@@ -1507,60 +1525,60 @@ bool SavedStacks::adoptAsyncStack(JSCont
   // If maxFrameCount is Nothing, the caller asked for an unlimited number of
   // stack frames, but async stacks are not limited by the available stack
   // memory, so we need to set an arbitrary limit when collecting them. We
   // still don't enforce an upper limit if the caller requested more frames.
   size_t maxFrames = maxFrameCount.valueOr(ASYNC_STACK_MAX_FRAME_COUNT);
 
   // Turn the chain of frames starting with asyncStack into a vector of Lookup
   // objects in |stackChain|, youngest to oldest.
-  SavedFrame::AutoLookupVector stackChain(cx);
+  Rooted<js::GCLookupVector> stackChain(cx, js::GCLookupVector(cx));
   SavedFrame* currentSavedFrame = asyncStack;
-  while (currentSavedFrame && stackChain->length() < maxFrames) {
-    if (!stackChain->emplaceBack(*currentSavedFrame)) {
+  while (currentSavedFrame && stackChain.length() < maxFrames) {
+    if (!stackChain.emplaceBack(*currentSavedFrame)) {
       ReportOutOfMemory(cx);
       return false;
     }
 
     currentSavedFrame = currentSavedFrame->getParent();
   }
 
   // Attach the asyncCause to the youngest frame.
-  stackChain[0]->asyncCause = asyncCause;
+  stackChain[0].setAsyncCause(asyncCause);
 
   // If we walked the entire stack, and it's in cx's realm, we don't
   // need to rebuild the full chain again using the lookup objects - we can
   // just use the existing chain. Only the asyncCause on the youngest frame
   // needs to be changed.
   if (currentSavedFrame == nullptr && asyncStack->realm() == cx->realm()) {
-    SavedFrame::HandleLookup lookup = stackChain[0];
-    lookup->parent = asyncStack->getParent();
+    MutableHandle<SavedFrame::Lookup> lookup = stackChain[0];
+    lookup.setParent(asyncStack->getParent());
     asyncStack.set(getOrCreateSavedFrame(cx, lookup));
     return !!asyncStack;
   }
 
   // If we captured the maximum number of frames and the caller requested no
   // specific limit, we only return half of them. This means that if we do
   // many subsequent captures with the same async stack, it's likely we can
   // use the optimization above.
   if (maxFrameCount.isNothing() && currentSavedFrame) {
-    stackChain->shrinkBy(ASYNC_STACK_MAX_FRAME_COUNT / 2);
+    stackChain.shrinkBy(ASYNC_STACK_MAX_FRAME_COUNT / 2);
   }
 
   // Iterate through |stackChain| in reverse order and get or create the
   // actual SavedFrame instances.
   asyncStack.set(nullptr);
-  while (!stackChain->empty()) {
-    SavedFrame::HandleLookup lookup = stackChain.back();
-    lookup->parent = asyncStack;
+  while (!stackChain.empty()) {
+    Rooted<SavedFrame::Lookup> lookup(cx, stackChain.back());
+    lookup.setParent(asyncStack);
     asyncStack.set(getOrCreateSavedFrame(cx, lookup));
     if (!asyncStack) {
       return false;
     }
-    stackChain->popBack();
+    stackChain.popBack();
   }
 
   return true;
 }
 
 // Given a |lookup| for which we're about to construct a SavedFrame, if it
 // refers to a Debugger eval frame, adjust |lookup|'s parent to be the frame's
 // evalInFramePrev target.
@@ -1569,38 +1587,38 @@ bool SavedStacks::adoptAsyncStack(JSCont
 // stack (the 'target' frame). It is our custom to report the target as the
 // immediate parent of the eval frame. The LiveSavedFrameCache requires us not
 // to skip frames, so instead we walk the entire stack, and just give Debugger
 // eval frames the right parents as we encounter them.
 //
 // Call this function only if we are using the LiveSavedFrameCache; otherwise,
 // FrameIter has already taken care of getting us the right parent.
 bool SavedStacks::checkForEvalInFramePrev(JSContext* cx,
-                                          SavedFrame::HandleLookup lookup) {
-  MOZ_ASSERT(lookup->framePtr);
-  if (!lookup->framePtr->isInterpreterFrame()) {
+                                          MutableHandle<SavedFrame::Lookup> lookup) {
+  MOZ_ASSERT(lookup.framePtr());
+  if (!lookup.framePtr()->isInterpreterFrame()) {
     return true;
   }
 
-  InterpreterFrame& interpreterFrame = lookup->framePtr->asInterpreterFrame();
+  InterpreterFrame& interpreterFrame = lookup.framePtr()->asInterpreterFrame();
   if (!interpreterFrame.isDebuggerEvalFrame()) {
     return true;
   }
 
   LiveSavedFrameCache::FramePtr target =
       LiveSavedFrameCache::FramePtr::create(interpreterFrame.evalInFramePrev());
 
   // If we're caching the frame to which |lookup| refers, then we should
   // definitely have the target frame in the cache as well.
   MOZ_ASSERT(target.hasCachedSavedFrame());
 
   // Search the chain of activations for a LiveSavedFrameCache that has an
   // entry for target.
   RootedSavedFrame saved(cx, nullptr);
-  for (Activation* act = lookup->activation; act; act = act->prev()) {
+  for (Activation* act = lookup.activation(); act; act = act->prev()) {
     // It's okay to force allocation of a cache here; we're about to put
     // something in the top cache, and all the lower ones should exist
     // already.
     auto* cache = act->getLiveSavedFrameCache(cx);
     if (!cache) {
       return false;
     }
 
@@ -1608,22 +1626,22 @@ bool SavedStacks::checkForEvalInFramePre
     if (saved) {
       break;
     }
   }
 
   // Since |target| has its cached bit set, we should have found it.
   MOZ_ALWAYS_TRUE(saved);
 
-  lookup->parent = saved;
+  lookup.setParent(saved);
   return true;
 }
 
 SavedFrame* SavedStacks::getOrCreateSavedFrame(
-    JSContext* cx, SavedFrame::HandleLookup lookup) {
+    JSContext* cx, Handle<SavedFrame::Lookup> lookup) {
   const SavedFrame::Lookup& lookupInstance = lookup.get();
   DependentAddPtr<SavedFrame::Set> p(cx, frames, lookupInstance);
   if (p) {
     MOZ_ASSERT(*p);
     return *p;
   }
 
   RootedSavedFrame frame(cx, createFrameFromLookup(cx, lookup));
@@ -1634,17 +1652,17 @@ SavedFrame* SavedStacks::getOrCreateSave
   if (!p.add(cx, frames, lookupInstance, frame)) {
     return nullptr;
   }
 
   return frame;
 }
 
 SavedFrame* SavedStacks::createFrameFromLookup(
-    JSContext* cx, SavedFrame::HandleLookup lookup) {
+    JSContext* cx, Handle<SavedFrame::Lookup> lookup) {
   RootedSavedFrame frame(cx, SavedFrame::create(cx));
   if (!frame) {
     return nullptr;
   }
   frame->initFromLookup(cx, lookup);
 
   if (!FreezeObject(cx, frame)) {
     return nullptr;
@@ -1859,17 +1877,17 @@ struct MOZ_STACK_CLASS AtomizingMatcher 
     MOZ_ASSERT(chars);
     return AtomizeChars(cx, chars, length);
   }
 };
 
 JS_PUBLIC_API bool ConstructSavedFrameStackSlow(
     JSContext* cx, JS::ubi::StackFrame& frame,
     MutableHandleObject outSavedFrameStack) {
-  SavedFrame::AutoLookupVector stackChain(cx);
+  Rooted<js::GCLookupVector> stackChain(cx, js::GCLookupVector(cx));
   Rooted<JS::ubi::StackFrame> ubiFrame(cx, frame);
 
   while (ubiFrame.get()) {
     // Convert the source and functionDisplayName strings to atoms.
 
     js::RootedAtom source(cx);
     AtomizingMatcher atomizer(cx, ubiFrame.get().sourceLength());
     source = ubiFrame.get().source().match(atomizer);
@@ -1886,32 +1904,32 @@ JS_PUBLIC_API bool ConstructSavedFrameSt
       if (!functionDisplayName) {
         return false;
       }
     }
 
     auto principals =
         js::ReconstructedSavedFramePrincipals::getSingleton(ubiFrame.get());
 
-    if (!stackChain->emplaceBack(source, ubiFrame.get().sourceId(),
+    if (!stackChain.emplaceBack(source, ubiFrame.get().sourceId(),
                                  ubiFrame.get().line(),
                                  ubiFrame.get().column(), functionDisplayName,
                                  /* asyncCause */ nullptr,
                                  /* parent */ nullptr, principals)) {
       ReportOutOfMemory(cx);
       return false;
     }
 
     ubiFrame = ubiFrame.get().parent();
   }
 
   js::RootedSavedFrame parentFrame(cx);
-  for (size_t i = stackChain->length(); i != 0; i--) {
-    SavedFrame::HandleLookup lookup = stackChain[i - 1];
-    lookup->parent = parentFrame;
+  for (size_t i = stackChain.length(); i != 0; i--) {
+    MutableHandle<SavedFrame::Lookup> lookup = stackChain[i - 1];
+    lookup.setParent(parentFrame);
     parentFrame = cx->realm()->savedStacks().getOrCreateSavedFrame(cx, lookup);
     if (!parentFrame) {
       return false;
     }
   }
 
   outSavedFrameStack.set(parentFrame);
   return true;
--- a/js/src/vm/SavedStacks.h
+++ b/js/src/vm/SavedStacks.h
@@ -217,21 +217,21 @@ class SavedStacks {
   };
 
   MOZ_MUST_USE bool insertFrames(JSContext* cx, MutableHandleSavedFrame frame,
                                  JS::StackCapture&& capture);
   MOZ_MUST_USE bool adoptAsyncStack(
       JSContext* cx, MutableHandleSavedFrame asyncStack, HandleAtom asyncCause,
       const mozilla::Maybe<size_t>& maxFrameCount);
   MOZ_MUST_USE bool checkForEvalInFramePrev(JSContext* cx,
-                                            SavedFrame::HandleLookup lookup);
+                                            MutableHandle<SavedFrame::Lookup> lookup);
   SavedFrame* getOrCreateSavedFrame(JSContext* cx,
-                                    SavedFrame::HandleLookup lookup);
+                                    Handle<SavedFrame::Lookup> lookup);
   SavedFrame* createFrameFromLookup(JSContext* cx,
-                                    SavedFrame::HandleLookup lookup);
+                                    Handle<SavedFrame::Lookup> lookup);
 
   // Cache for memoizing PCToLineNumber lookups.
 
   struct PCKey {
     PCKey(JSScript* script, jsbytecode* pc) : script(script), pc(pc) {}
 
     HeapPtr<JSScript*> script;
     jsbytecode* pc;
--- a/js/src/vm/Shape-inl.h
+++ b/js/src/vm/Shape-inl.h
@@ -221,29 +221,28 @@ template <class ObjectSubclass>
 
   // Cache the initial shape for non-prototype objects, however, so that
   // future instances will begin life with that shape.
   RootedObject proto(cx, obj->staticPrototype());
   EmptyShape::insertInitialShape(cx, shape, proto);
   return true;
 }
 
-inline AutoRooterGetterSetter::Inner::Inner(JSContext* cx, uint8_t attrs,
+inline AutoRooterGetterSetter::Inner::Inner(uint8_t attrs,
                                             GetterOp* pgetter_,
                                             SetterOp* psetter_)
-    : CustomAutoRooter(cx),
-      attrs(attrs),
+    : attrs(attrs),
       pgetter(pgetter_),
       psetter(psetter_) {}
 
 inline AutoRooterGetterSetter::AutoRooterGetterSetter(
     JSContext* cx, uint8_t attrs, GetterOp* pgetter,
     SetterOp* psetter MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) {
   if (attrs & (JSPROP_GETTER | JSPROP_SETTER)) {
-    inner.emplace(cx, attrs, pgetter, psetter);
+    inner.emplace(cx, Inner(attrs, pgetter, psetter));
   }
   MOZ_GUARD_OBJECT_NOTIFIER_INIT;
 }
 
 static inline uint8_t GetPropertyAttributes(JSObject* obj,
                                             PropertyResult prop) {
   MOZ_ASSERT(obj->isNative());
 
--- a/js/src/vm/Shape.h
+++ b/js/src/vm/Shape.h
@@ -1435,36 +1435,35 @@ class AccessorShape : public Shape {
   /* Get a shape identical to this one, without parent/kids information. */
   inline AccessorShape(const StackShape& other, uint32_t nfixed);
 };
 
 inline StackBaseShape::StackBaseShape(Shape* shape)
     : flags(shape->getObjectFlags()), clasp(shape->getObjectClass()) {}
 
 class MOZ_RAII AutoRooterGetterSetter {
-  class Inner final : private JS::CustomAutoRooter {
+  class Inner {
    public:
-    inline Inner(JSContext* cx, uint8_t attrs, GetterOp* pgetter_,
-                 SetterOp* psetter_);
+    inline Inner(uint8_t attrs, GetterOp* pgetter_, SetterOp* psetter_);
+
+    void trace(JSTracer* trc);
 
    private:
-    virtual void trace(JSTracer* trc) override;
-
     uint8_t attrs;
     GetterOp* pgetter;
     SetterOp* psetter;
   };
 
  public:
   inline AutoRooterGetterSetter(JSContext* cx, uint8_t attrs, GetterOp* pgetter,
                                 SetterOp* psetter
-                                    MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
+                                MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
 
  private:
-  mozilla::Maybe<Inner> inner;
+  mozilla::Maybe<Rooted<Inner>> inner;
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 struct EmptyShape : public js::Shape {
   EmptyShape(UnownedBaseShape* base, uint32_t nfixed)
       : js::Shape(base, nfixed) {}
 
   static Shape* new_(JSContext* cx, Handle<UnownedBaseShape*> base,
--- a/js/src/vm/UbiNode.cpp
+++ b/js/src/vm/UbiNode.cpp
@@ -4,17 +4,16 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "js/UbiNode.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/Attributes.h"
 #include "mozilla/Range.h"
-#include "mozilla/Scoped.h"
 
 #include <algorithm>
 
 #include "builtin/String.h"
 
 #include "jit/IonCode.h"
 #include "js/Debug.h"
 #include "js/TracingAPI.h"
--- a/js/src/wasm/WasmJS.cpp
+++ b/js/src/wasm/WasmJS.cpp
@@ -2079,17 +2079,19 @@ bool WasmTableObject::isNewborn() const 
   }
 
   RootedLinearString elementLinearStr(cx, elementStr->ensureLinear(cx));
   if (!elementLinearStr) {
     return false;
   }
 
   TableKind tableKind;
-  if (StringEqualsAscii(elementLinearStr, "anyfunc")) {
+  if (StringEqualsAscii(elementLinearStr, "anyfunc") ||
+      StringEqualsAscii(elementLinearStr, "funcref"))
+  {
     tableKind = TableKind::AnyFunction;
 #ifdef ENABLE_WASM_GENERALIZED_TABLES
   } else if (StringEqualsAscii(elementLinearStr, "anyref")) {
     if (!HasReftypesSupport(cx)) {
       JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
                                JSMSG_WASM_BAD_ELEMENT);
       return false;
     }
@@ -2456,17 +2458,17 @@ const Class WasmGlobalObject::class_ = {
   AutoSetNewObjectMetadata metadata(cx);
   RootedWasmGlobalObject obj(
       cx, NewObjectWithGivenProto<WasmGlobalObject>(cx, proto));
   if (!obj) {
     return nullptr;
   }
 
   MOZ_ASSERT(obj->isNewborn());
-  MOZ_ASSERT(obj->isTenured(), "assumed by set_global post barriers");
+  MOZ_ASSERT(obj->isTenured(), "assumed by global.set post barriers");
 
   // It's simpler to initialize the cell after the object has been created,
   // to avoid needing to root the cell before the object creation.
 
   Cell* cell = js_new<Cell>();
   if (!cell) {
     ReportOutOfMemory(cx);
     return nullptr;
--- a/js/src/wasm/WasmOpIter.h
+++ b/js/src/wasm/WasmOpIter.h
@@ -1346,79 +1346,79 @@ inline bool OpIter<Policy>::readGetLocal
                                          uint32_t* id) {
   MOZ_ASSERT(Classify(op_) == OpKind::GetLocal);
 
   if (!readVarU32(id)) {
     return false;
   }
 
   if (*id >= locals.length()) {
-    return fail("get_local index out of range");
+    return fail("local.get index out of range");
   }
 
   return push(locals[*id]);
 }
 
 template <typename Policy>
 inline bool OpIter<Policy>::readSetLocal(const ValTypeVector& locals,
                                          uint32_t* id, Value* value) {
   MOZ_ASSERT(Classify(op_) == OpKind::SetLocal);
 
   if (!readVarU32(id)) {
     return false;
   }
 
   if (*id >= locals.length()) {
-    return fail("set_local index out of range");
+    return fail("local.set index out of range");
   }
 
   return popWithType(locals[*id], value);
 }
 
 template <typename Policy>
 inline bool OpIter<Policy>::readTeeLocal(const ValTypeVector& locals,
                                          uint32_t* id, Value* value) {
   MOZ_ASSERT(Classify(op_) == OpKind::TeeLocal);
 
   if (!readVarU32(id)) {
     return false;
   }
 
   if (*id >= locals.length()) {
-    return fail("set_local index out of range");
+    return fail("local.set index out of range");
   }
 
   return topWithType(locals[*id], value);
 }
 
 template <typename Policy>
 inline bool OpIter<Policy>::readGetGlobal(uint32_t* id) {
   MOZ_ASSERT(Classify(op_) == OpKind::GetGlobal);
 
   if (!readVarU32(id)) {
     return false;
   }
 
   if (*id >= env_.globals.length()) {
-    return fail("get_global index out of range");
+    return fail("global.get index out of range");
   }
 
   return push(env_.globals[*id].type());
 }
 
 template <typename Policy>
 inline bool OpIter<Policy>::readSetGlobal(uint32_t* id, Value* value) {
   MOZ_ASSERT(Classify(op_) == OpKind::SetGlobal);
 
   if (!readVarU32(id)) {
     return false;
   }
 
   if (*id >= env_.globals.length()) {
-    return fail("set_global index out of range");
+    return fail("global.set index out of range");
   }
 
   if (!env_.globals[*id].isMutable()) {
     return fail("can't write an immutable global");
   }
 
   return popWithType(env_.globals[*id].type(), value);
 }
@@ -1427,17 +1427,17 @@ template <typename Policy>
 inline bool OpIter<Policy>::readTeeGlobal(uint32_t* id, Value* value) {
   MOZ_ASSERT(Classify(op_) == OpKind::TeeGlobal);
 
   if (!readVarU32(id)) {
     return false;
   }
 
   if (*id >= env_.globals.length()) {
-    return fail("set_global index out of range");
+    return fail("global.set index out of range");
   }
 
   if (!env_.globals[*id].isMutable()) {
     return fail("can't write an immutable global");
   }
 
   return topWithType(env_.globals[*id].type(), value);
 }
@@ -1555,17 +1555,17 @@ inline bool OpIter<Policy>::readCallIndi
   if (*tableIndex >= env_.tables.length()) {
     // Special case this for improved user experience.
     if (!env_.tables.length()) {
       return fail("can't call_indirect without a table");
     }
     return fail("table index out of range for call_indirect");
   }
   if (env_.tables[*tableIndex].kind != TableKind::AnyFunction) {
-    return fail("indirect calls must go through a table of 'anyfunc'");
+    return fail("indirect calls must go through a table of 'funcref'");
   }
 
   if (!popWithType(ValType::I32, callee)) {
     return false;
   }
 
   if (!env_.types[*funcTypeIndex].isFuncType()) {
     return fail("expected signature type");
@@ -1956,17 +1956,17 @@ inline bool OpIter<Policy>::readMemOrTab
     if (memOrTableIndex >= env_.tables.length()) {
       return fail("table index out of range for table.init");
     }
     *dstTableIndex = memOrTableIndex;
 
     // Element segments must carry functions exclusively and anyfunc is not
     // yet a subtype of anyref.
     if (env_.tables[*dstTableIndex].kind != TableKind::AnyFunction) {
-      return fail("only tables of 'anyfunc' may have element segments");
+      return fail("only tables of 'funcref' may have element segments");
     }
     if (*segIndex >= env_.elemSegments.length()) {
       return fail("table.init segment index out of range");
     }
   }
 
   return true;
 }
--- a/js/src/wasm/WasmTextToBinary.cpp
+++ b/js/src/wasm/WasmTextToBinary.cpp
@@ -53,17 +53,16 @@ using mozilla::PositiveInfinity;
 namespace {
 
 class WasmToken {
  public:
   enum FloatLiteralKind { HexNumber, DecNumber, Infinity, NaN };
 
   enum Kind {
     Align,
-    AnyFunc,
     AtomicCmpXchg,
     AtomicLoad,
     AtomicRMW,
     AtomicStore,
     BinaryOpcode,
     Block,
     Br,
     BrIf,
@@ -86,16 +85,17 @@ class WasmToken {
     EndOfFile,
     Equal,
     Error,
     Export,
     ExtraConversionOpcode,
     Field,
     Float,
     Func,
+    FuncRef,
 #ifdef ENABLE_WASM_REFTYPES
     GcFeatureOptIn,
 #endif
     GetGlobal,
     GetLocal,
     Global,
     If,
     Import,
@@ -354,32 +354,32 @@ class WasmToken {
       case TeeLocal:
       case TernaryOpcode:
       case UnaryOpcode:
       case Unreachable:
       case Wait:
       case Wake:
         return true;
       case Align:
-      case AnyFunc:
       case CloseParen:
       case Data:
 #ifdef ENABLE_WASM_BULKMEM_OPS
       case DataCount:
 #endif
       case Elem:
       case Else:
       case EndOfFile:
       case Equal:
       case End:
       case Error:
       case Export:
       case Field:
       case Float:
       case Func:
+      case FuncRef:
 #ifdef ENABLE_WASM_REFTYPES
       case GcFeatureOptIn:
 #endif
       case Global:
       case Mutable:
       case Import:
       case Index:
       case Memory:
@@ -947,17 +947,17 @@ WasmToken WasmTokenStream::next() {
     case '9':
       return literal(begin);
 
     case 'a':
       if (consume(u"align")) {
         return WasmToken(WasmToken::Align, begin, cur_);
       }
       if (consume(u"anyfunc")) {
-        return WasmToken(WasmToken::AnyFunc, begin, cur_);
+        return WasmToken(WasmToken::FuncRef, begin, cur_);
       }
       if (consume(u"anyref")) {
         return WasmToken(WasmToken::ValueType, ValType::AnyRef, begin, cur_);
       }
       if (consume(u"atomic.")) {
         if (consume(u"wake") || consume(u"notify")) {
           return WasmToken(WasmToken::Wake, ThreadOp::Wake, begin, cur_);
         }
@@ -1029,16 +1029,20 @@ WasmToken WasmTokenStream::next() {
       }
       break;
 
     case 'f':
       if (consume(u"field")) {
         return WasmToken(WasmToken::Field, begin, cur_);
       }
 
+      if (consume(u"funcref")) {
+        return WasmToken(WasmToken::FuncRef, begin, cur_);
+      }
+
       if (consume(u"func")) {
         return WasmToken(WasmToken::Func, begin, cur_);
       }
 
       if (consume(u"f32")) {
         if (!consume(u".")) {
           return WasmToken(WasmToken::ValueType, ValType::F32, begin, cur_);
         }
@@ -1338,16 +1342,22 @@ WasmToken WasmTokenStream::next() {
 #endif
       if (consume(u"get_global")) {
         return WasmToken(WasmToken::GetGlobal, begin, cur_);
       }
       if (consume(u"get_local")) {
         return WasmToken(WasmToken::GetLocal, begin, cur_);
       }
       if (consume(u"global")) {
+        if (consume(u".get")) {
+          return WasmToken(WasmToken::GetGlobal, begin, cur_);
+        }
+        if (consume(u".set")) {
+          return WasmToken(WasmToken::SetGlobal, begin, cur_);
+        }
         return WasmToken(WasmToken::Global, begin, cur_);
       }
       if (consume(u"grow_memory")) {
         return WasmToken(WasmToken::MemoryGrow, begin, cur_);
       }
       break;
 
     case 'i':
@@ -2104,16 +2114,22 @@ WasmToken WasmTokenStream::next() {
       }
       if (consume(u"if")) {
         return WasmToken(WasmToken::If, begin, cur_);
       }
       break;
 
     case 'l':
       if (consume(u"local")) {
+        if (consume(u".get")) {
+          return WasmToken(WasmToken::GetLocal, begin, cur_);
+        }
+        if (consume(u".set")) {
+          return WasmToken(WasmToken::SetLocal, begin, cur_);
+        }
         return WasmToken(WasmToken::Local, begin, cur_);
       }
       if (consume(u"loop")) {
         return WasmToken(WasmToken::Loop, begin, cur_);
       }
       break;
 
     case 'm':
@@ -4631,17 +4647,17 @@ static bool ParseGlobalType(WasmParseCon
     return false;
   }
 
   return true;
 }
 
 static bool ParseElemType(WasmParseContext& c, TableKind* tableKind) {
   WasmToken token;
-  if (c.ts.getIf(WasmToken::AnyFunc, &token)) {
+  if (c.ts.getIf(WasmToken::FuncRef, &token)) {
     *tableKind = TableKind::AnyFunction;
     return true;
   }
 #ifdef ENABLE_WASM_GENERALIZED_TABLES
   if (c.ts.getIf(WasmToken::ValueType, &token) &&
       token.valueType() == ValType::AnyRef) {
     *tableKind = TableKind::AnyRef;
     return true;
--- a/js/src/wasm/WasmValidate.cpp
+++ b/js/src/wasm/WasmValidate.cpp
@@ -1949,17 +1949,17 @@ static bool DecodeInitializerExpression(
       }
       break;
     }
     case uint16_t(Op::GetGlobal): {
       uint32_t i;
       const GlobalDescVector& globals = env->globals;
       if (!d.readVarU32(&i)) {
         return d.fail(
-            "failed to read get_global index in initializer expression");
+            "failed to read global.get index in initializer expression");
       }
       if (i >= globals.length()) {
         return d.fail("global index out of range in initializer expression");
       }
       if (!globals[i].isImport() || globals[i].isMutable()) {
         return d.fail(
             "initializer expression must reference a global immutable import");
       }
@@ -2258,17 +2258,17 @@ static bool DecodeElemSection(Decoder& d
       return d.fail("table index out of range for element segment");
     }
     if (initializerKind == InitializerKind::Passive) {
       // Too many bugs result from keeping this value zero.  For passive
       // segments, there really is no segment index, and we should never
       // touch the field.
       tableIndex = (uint32_t)-1;
     } else if (env->tables[tableIndex].kind != TableKind::AnyFunction) {
-      return d.fail("only tables of 'anyfunc' may have element segments");
+      return d.fail("only tables of 'funcref' may have element segments");
     }
 
     seg->tableIndex = tableIndex;
 
     switch (initializerKind) {
       case InitializerKind::Active:
       case InitializerKind::ActiveWithIndex: {
         InitExpr offset;
--- a/security/nss.symbols
+++ b/security/nss.symbols
@@ -170,70 +170,39 @@ DSAU_DecodeDerSigToLen
 DSAU_EncodeDerSigWithLen
 DTLS_GetHandshakeTimeout
 DTLS_ImportFD
 HASH_Begin
 HASH_Create
 HASH_Destroy
 HASH_End
 HASH_GetHashObject
+HASH_GetHashOidTagByHashType
 HASH_GetType
 HASH_HashBuf
 HASH_ResultLenByOidTag
 HASH_Update
 NSSBase64_EncodeItem_Util
 NSS_CMSContentInfo_GetContent
 NSS_CMSContentInfo_GetContentTypeTag
-NSS_CMSContentInfo_SetContent_Data
-NSS_CMSContentInfo_SetContent_EnvelopedData
 NSS_CMSContentInfo_SetContent_SignedData
-NSS_CMSDecoder_Cancel
-NSS_CMSDecoder_Finish
-NSS_CMSDecoder_Start
-NSS_CMSDecoder_Update
-NSS_CMSEncoder_Cancel
 NSS_CMSEncoder_Finish
 NSS_CMSEncoder_Start
-NSS_CMSEncoder_Update
-NSS_CMSEnvelopedData_AddRecipient
-NSS_CMSEnvelopedData_Create
-NSS_CMSEnvelopedData_GetContentInfo
 NSS_CMSMessage_ContentLevel
-NSS_CMSMessage_ContentLevelCount
 NSS_CMSMessage_Create
 NSS_CMSMessage_CreateFromDER
 NSS_CMSMessage_Destroy
-NSS_CMSMessage_GetContent
 NSS_CMSMessage_GetContentInfo
-NSS_CMSMessage_IsEncrypted
 NSS_CMSMessage_IsSigned
-NSS_CMSRecipientInfo_Create
 NSS_CMSSignedData_AddCertificate
-NSS_CMSSignedData_AddCertList
-NSS_CMSSignedData_AddSignerInfo
-NSS_CMSSignedData_Create
 NSS_CMSSignedData_CreateCertsOnly
 NSS_CMSSignedData_Destroy
-NSS_CMSSignedData_GetContentInfo
-NSS_CMSSignedData_GetDigestAlgs
 NSS_CMSSignedData_GetSignerInfo
-NSS_CMSSignedData_HasDigests
-NSS_CMSSignedData_ImportCerts
-NSS_CMSSignedData_SetDigestValue
 NSS_CMSSignedData_SignerInfoCount
-NSS_CMSSignedData_VerifySignerInfo
-NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs
-NSS_CMSSignerInfo_AddSigningTime
-NSS_CMSSignerInfo_AddSMIMECaps
-NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs
-NSS_CMSSignerInfo_Create
-NSS_CMSSignerInfo_GetSignerCommonName
-NSS_CMSSignerInfo_GetSignerEmailAddress
 NSS_CMSSignerInfo_GetSigningCertificate
-NSS_CMSSignerInfo_IncludeCerts
 NSS_CMSSignerInfo_Verify
 NSS_FindCertKEAType
 NSS_GetAlgorithmPolicy
 NSS_Get_CERT_CertificateRequestTemplate
 NSS_Get_CERT_CertificateTemplate
 NSS_Get_CERT_CrlTemplate
 NSS_Get_CERT_NameTemplate
 NSS_Get_CERT_SequenceOfCertExtensionTemplate
@@ -261,16 +230,17 @@ NSS_Get_SECOID_AlgorithmIDTemplate
 NSS_Get_SECOID_AlgorithmIDTemplate_Util
 NSS_Get_SEC_SignedCertificateTemplate
 NSS_Get_SEC_UTF8StringTemplate
 NSS_Get_SEC_UTF8StringTemplate_Util
 NSS_GetVersion
 NSS_Init
 NSS_InitContext
 NSS_Initialize
+NSS_InitReadWrite
 NSS_InitWithMerge
 NSS_IsInitialized
 NSS_OptionGet
 NSS_OptionSet
 NSS_NoDB_Init
 NSS_SecureMemcmp
 NSS_SetAlgorithmPolicy
 NSS_SetDomesticPolicy