Title: [226687] branches/safari-605-branch

Diff

Modified: branches/safari-605-branch/JSTests/ChangeLog (226686 => 226687)


--- branches/safari-605-branch/JSTests/ChangeLog	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/JSTests/ChangeLog	2018-01-10 04:31:37 UTC (rev 226687)
@@ -1,3 +1,20 @@
+2018-01-09  Jason Marcell  <[email protected]>
+
+        Cherry-pick r226615. rdar://problem/36392328
+
+    2018-01-08  JF Bastien  <[email protected]>
+
+            WebAssembly: mask indexed accesses to Table
+            https://bugs.webkit.org/show_bug.cgi?id=181412
+            <rdar://problem/36363236>
+
+            Reviewed by Saam Barati.
+
+            Update error messages.
+
+            * wasm/js-api/table.js:
+            (assert.throws.WebAssembly.Table.prototype.grow):
+
 2018-01-06  Yusuke Suzuki  <[email protected]>
 
         Object.getOwnPropertyNames includes "arguments" and "caller" for bound functions

Modified: branches/safari-605-branch/JSTests/wasm/js-api/table.js (226686 => 226687)


--- branches/safari-605-branch/JSTests/wasm/js-api/table.js	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/JSTests/wasm/js-api/table.js	2018-01-10 04:31:37 UTC (rev 226687)
@@ -243,7 +243,7 @@
 
     {
         const table = new WebAssembly.Table({element: "anyfunc", initial: 20});
-        assert.throws(() => table.get(20), RangeError, "WebAssembly.Table.prototype.get expects an integer less than the size of the table");
+        assert.throws(() => table.get(20), RangeError, "WebAssembly.Table.prototype.get expects an integer less than the length of the table");
         for (let i = 0; i < 20; i++)
             assert.eq(table.get(i), null);
     }
@@ -250,7 +250,7 @@
 
     {
         const table = new WebAssembly.Table({element: "anyfunc", initial: 20});
-        assert.throws(() => table.set(20, null), RangeError, "WebAssembly.Table.prototype.set expects an integer less than the size of the table");
+        assert.throws(() => table.set(20, null), RangeError, "WebAssembly.Table.prototype.set expects an integer less than the length of the table");
         for (let i = 0; i < 20; i++)
             table.set(i, null);
     }

Modified: branches/safari-605-branch/Source/_javascript_Core/ChangeLog (226686 => 226687)


--- branches/safari-605-branch/Source/_javascript_Core/ChangeLog	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/Source/_javascript_Core/ChangeLog	2018-01-10 04:31:37 UTC (rev 226687)
@@ -1,5 +1,72 @@
 2018-01-09  Jason Marcell  <[email protected]>
 
+        Cherry-pick r226615. rdar://problem/36392328
+
+    2018-01-08  JF Bastien  <[email protected]>
+
+            WebAssembly: mask indexed accesses to Table
+            https://bugs.webkit.org/show_bug.cgi?id=181412
+            <rdar://problem/36363236>
+
+            Reviewed by Saam Barati.
+
+            WebAssembly Table indexed accesses are user-controlled and
+            bounds-checked. Force allocations of Table data to be a
+            power-of-two, and explicitly mask accesses after bounds-check
+            branches.
+
+            Rename misleading usage of "size" when "length" of a Table was
+            intended.
+
+            Rename the Spectre option from "disable" to "enable".
+
+            * dfg/DFGSpeculativeJIT.cpp:
+            (JSC::DFG::SpeculativeJIT::SpeculativeJIT):
+            * ftl/FTLLowerDFGToB3.cpp:
+            (JSC::FTL::DFG::LowerDFGToB3::LowerDFGToB3):
+            * jit/JIT.cpp:
+            (JSC::JIT::JIT):
+            * runtime/Options.h:
+            * wasm/WasmB3IRGenerator.cpp:
+            (JSC::Wasm::B3IRGenerator::emitCheckAndPreparePointer):
+            (JSC::Wasm::B3IRGenerator::addCallIndirect):
+            * wasm/WasmTable.cpp:
+            (JSC::Wasm::Table::allocatedLength):
+            (JSC::Wasm::Table::setLength):
+            (JSC::Wasm::Table::create):
+            (JSC::Wasm::Table::Table):
+            (JSC::Wasm::Table::grow):
+            (JSC::Wasm::Table::clearFunction):
+            (JSC::Wasm::Table::setFunction):
+            * wasm/WasmTable.h:
+            (JSC::Wasm::Table::length const):
+            (JSC::Wasm::Table::offsetOfLength):
+            (JSC::Wasm::Table::offsetOfMask):
+            (JSC::Wasm::Table::mask const):
+            (JSC::Wasm::Table::isValidLength):
+            * wasm/js/JSWebAssemblyInstance.cpp:
+            (JSC::JSWebAssemblyInstance::create):
+            * wasm/js/JSWebAssemblyTable.cpp:
+            (JSC::JSWebAssemblyTable::JSWebAssemblyTable):
+            (JSC::JSWebAssemblyTable::visitChildren):
+            (JSC::JSWebAssemblyTable::grow):
+            (JSC::JSWebAssemblyTable::getFunction):
+            (JSC::JSWebAssemblyTable::clearFunction):
+            (JSC::JSWebAssemblyTable::setFunction):
+            * wasm/js/JSWebAssemblyTable.h:
+            (JSC::JSWebAssemblyTable::isValidLength):
+            (JSC::JSWebAssemblyTable::length const):
+            (JSC::JSWebAssemblyTable::allocatedLength const):
+            * wasm/js/WebAssemblyModuleRecord.cpp:
+            (JSC::WebAssemblyModuleRecord::evaluate):
+            * wasm/js/WebAssemblyTablePrototype.cpp:
+            (JSC::webAssemblyTableProtoFuncLength):
+            (JSC::webAssemblyTableProtoFuncGrow):
+            (JSC::webAssemblyTableProtoFuncGet):
+            (JSC::webAssemblyTableProtoFuncSet):
+
+2018-01-09  Jason Marcell  <[email protected]>
+
         Cherry-pick r226556. rdar://problem/36392331
 
     2018-01-08  Mark Lam  <[email protected]>

Modified: branches/safari-605-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (226686 => 226687)


--- branches/safari-605-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2018-01-10 04:31:37 UTC (rev 226687)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -74,7 +74,7 @@
     , m_currentNode(0)
     , m_lastGeneratedNode(LastNodeType)
     , m_indexInBlock(0)
-    , m_indexMaskingMode(Options::disableSpectreMitigations() ? IndexMaskingDisabled : IndexMaskingEnabled)
+    , m_indexMaskingMode(Options::enableSpectreMitigations() ? IndexMaskingEnabled : IndexMaskingDisabled)
     , m_generationInfo(m_jit.graph().frameRegisterCount())
     , m_state(m_jit.graph())
     , m_interpreter(m_jit.graph(), m_state)

Modified: branches/safari-605-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (226686 => 226687)


--- branches/safari-605-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2018-01-10 04:31:37 UTC (rev 226687)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -149,7 +149,7 @@
         , m_availabilityCalculator(m_graph)
         , m_state(state.graph)
         , m_interpreter(state.graph, m_state)
-        , m_indexMaskingMode(Options::disableSpectreMitigations() ? IndexMaskingDisabled : IndexMaskingEnabled)
+        , m_indexMaskingMode(Options::enableSpectreMitigations() ?  IndexMaskingEnabled : IndexMaskingDisabled)
     {
     }
     

Modified: branches/safari-605-branch/Source/_javascript_Core/jit/JIT.cpp (226686 => 226687)


--- branches/safari-605-branch/Source/_javascript_Core/jit/JIT.cpp	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/Source/_javascript_Core/jit/JIT.cpp	2018-01-10 04:31:37 UTC (rev 226687)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -84,7 +84,7 @@
     , m_pcToCodeOriginMapBuilder(*vm)
     , m_canBeOptimized(false)
     , m_shouldEmitProfiling(false)
-    , m_shouldUseIndexMasking(Options::disableSpectreMitigations() ? false : true)
+    , m_shouldUseIndexMasking(Options::enableSpectreMitigations())
     , m_loopOSREntryBytecodeOffset(loopOSREntryBytecodeOffset)
 {
 }

Modified: branches/safari-605-branch/Source/_javascript_Core/runtime/Options.h (226686 => 226687)


--- branches/safari-605-branch/Source/_javascript_Core/runtime/Options.h	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/Source/_javascript_Core/runtime/Options.h	2018-01-10 04:31:37 UTC (rev 226687)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2011-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -458,7 +458,7 @@
     \
     v(bool, useWebAssembly, true, Normal, "Expose the WebAssembly global object.") \
     \
-    v(bool, disableSpectreMitigations, false, Restricted, "Disable Spectre mitigations.") \
+    v(bool, enableSpectreMitigations, true, Restricted, "Enable Spectre mitigations.") \
     \
     v(bool, useAsyncIterator, enableAsyncIteration, Normal, "Allow to use Async Iterator in JS.") \
     \

Modified: branches/safari-605-branch/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp (226686 => 226687)


--- branches/safari-605-branch/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/Source/_javascript_Core/wasm/WasmB3IRGenerator.cpp	2018-01-10 04:31:37 UTC (rev 226687)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -650,7 +650,7 @@
         // We're not using signal handling at all, we must therefore check that no memory access exceeds the current memory size.
         ASSERT(m_memorySizeGPR);
         ASSERT(sizeOfOperation + offset > offset);
-        GPRReg indexingMask = (shouldMask == ShouldMask::Yes && !Options::disableSpectreMitigations()) ? m_indexingMaskGPR : InvalidGPRReg;
+        GPRReg indexingMask = (shouldMask == ShouldMask::Yes && Options::enableSpectreMitigations()) ? m_indexingMaskGPR : InvalidGPRReg;
         m_currentBlock->appendNew<WasmBoundsCheckValue>(m_proc, origin(), m_memorySizeGPR, indexingMask, pointer, sizeOfOperation + offset - 1);
         break;
     }
@@ -1200,7 +1200,8 @@
 
     ExpressionType callableFunctionBuffer;
     ExpressionType instancesBuffer;
-    ExpressionType callableFunctionBufferSize;
+    ExpressionType callableFunctionBufferLength;
+    ExpressionType mask;
     {
         ExpressionType table = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
             instanceValue(), safeCast<int32_t>(Instance::offsetOfTable()));
@@ -1208,14 +1209,17 @@
             table, safeCast<int32_t>(Table::offsetOfFunctions()));
         instancesBuffer = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
             table, safeCast<int32_t>(Table::offsetOfInstances()));
-        callableFunctionBufferSize = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int32, origin(),
-            table, safeCast<int32_t>(Table::offsetOfSize()));
+        callableFunctionBufferLength = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int32, origin(),
+            table, safeCast<int32_t>(Table::offsetOfLength()));
+        mask = m_currentBlock->appendNew<Value>(m_proc, ZExt32, origin(),
+            m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int32, origin(),
+                table, safeCast<int32_t>(Table::offsetOfMask())));
     }
 
     // Check the index we are looking for is valid.
     {
         CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(),
-            m_currentBlock->appendNew<Value>(m_proc, AboveEqual, origin(), calleeIndex, callableFunctionBufferSize));
+            m_currentBlock->appendNew<Value>(m_proc, AboveEqual, origin(), calleeIndex, callableFunctionBufferLength));
 
         check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
             this->emitExceptionCheck(jit, ExceptionType::OutOfBoundsCallIndirect);
@@ -1222,43 +1226,49 @@
         });
     }
 
-    // Compute the offset in the table index space we are looking for.
-    ExpressionType offset = m_currentBlock->appendNew<Value>(m_proc, Mul, origin(),
-        m_currentBlock->appendNew<Value>(m_proc, ZExt32, origin(), calleeIndex),
-        constant(pointerType(), sizeof(CallableFunction)));
-    ExpressionType callableFunction = m_currentBlock->appendNew<Value>(m_proc, Add, origin(), callableFunctionBuffer, offset);
+    calleeIndex = m_currentBlock->appendNew<Value>(m_proc, ZExt32, origin(), calleeIndex);
 
-    // Check that the CallableFunction is initialized. We trap if it isn't. An "invalid" SignatureIndex indicates it's not initialized.
-    // FIXME: when we have trap handlers, we can just let the call fail because Signature::invalidIndex is 0. https://bugs.webkit.org/show_bug.cgi?id=177210
-    static_assert(sizeof(CallableFunction::signatureIndex) == sizeof(uint32_t), "Load codegen assumes i32");
-    ExpressionType calleeSignatureIndex = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int32, origin(), callableFunction, safeCast<int32_t>(OBJECT_OFFSETOF(CallableFunction, signatureIndex)));
+    if (Options::enableSpectreMitigations())
+        calleeIndex = m_currentBlock->appendNew<Value>(m_proc, BitAnd, origin(), mask, calleeIndex);
+
+    ExpressionType callableFunction;
     {
-        CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(),
-            m_currentBlock->appendNew<Value>(m_proc, Equal, origin(),
-                calleeSignatureIndex,
-                m_currentBlock->appendNew<Const32Value>(m_proc, origin(), Signature::invalidIndex)));
+        // Compute the offset in the table index space we are looking for.
+        ExpressionType offset = m_currentBlock->appendNew<Value>(m_proc, Mul, origin(),
+            calleeIndex, constant(pointerType(), sizeof(CallableFunction)));
+        callableFunction = m_currentBlock->appendNew<Value>(m_proc, Add, origin(), callableFunctionBuffer, offset);
 
-        check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
-            this->emitExceptionCheck(jit, ExceptionType::NullTableEntry);
-        });
-    }
+        // Check that the CallableFunction is initialized. We trap if it isn't. An "invalid" SignatureIndex indicates it's not initialized.
+        // FIXME: when we have trap handlers, we can just let the call fail because Signature::invalidIndex is 0. https://bugs.webkit.org/show_bug.cgi?id=177210
+        static_assert(sizeof(CallableFunction::signatureIndex) == sizeof(uint32_t), "Load codegen assumes i32");
+        ExpressionType calleeSignatureIndex = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int32, origin(), callableFunction, safeCast<int32_t>(OBJECT_OFFSETOF(CallableFunction, signatureIndex)));
+        {
+            CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(),
+                m_currentBlock->appendNew<Value>(m_proc, Equal, origin(),
+                    calleeSignatureIndex,
+                    m_currentBlock->appendNew<Const32Value>(m_proc, origin(), Signature::invalidIndex)));
 
-    // Check the signature matches the value we expect.
-    {
-        ExpressionType expectedSignatureIndex = m_currentBlock->appendNew<Const32Value>(m_proc, origin(), SignatureInformation::get(signature));
-        CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(),
-            m_currentBlock->appendNew<Value>(m_proc, NotEqual, origin(), calleeSignatureIndex, expectedSignatureIndex));
+            check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
+                this->emitExceptionCheck(jit, ExceptionType::NullTableEntry);
+            });
+        }
 
-        check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
-            this->emitExceptionCheck(jit, ExceptionType::BadSignature);
-        });
+        // Check the signature matches the value we expect.
+        {
+            ExpressionType expectedSignatureIndex = m_currentBlock->appendNew<Const32Value>(m_proc, origin(), SignatureInformation::get(signature));
+            CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, origin(),
+                m_currentBlock->appendNew<Value>(m_proc, NotEqual, origin(), calleeSignatureIndex, expectedSignatureIndex));
+
+            check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
+                this->emitExceptionCheck(jit, ExceptionType::BadSignature);
+            });
+        }
     }
 
     // Do a context switch if needed.
     {
         Value* offset = m_currentBlock->appendNew<Value>(m_proc, Mul, origin(),
-            m_currentBlock->appendNew<Value>(m_proc, ZExt32, origin(), calleeIndex),
-            constant(pointerType(), sizeof(Instance*)));
+            calleeIndex, constant(pointerType(), sizeof(Instance*)));
         Value* newContextInstance = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
             m_currentBlock->appendNew<Value>(m_proc, Add, origin(), instancesBuffer, offset));
 

Modified: branches/safari-605-branch/Source/_javascript_Core/wasm/WasmTable.cpp (226686 => 226687)


--- branches/safari-605-branch/Source/_javascript_Core/wasm/WasmTable.cpp	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/Source/_javascript_Core/wasm/WasmTable.cpp	2018-01-10 04:31:37 UTC (rev 226687)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -34,9 +34,22 @@
 
 namespace JSC { namespace Wasm {
 
+uint32_t Table::allocatedLength(uint32_t length)
+{
+    return WTF::roundUpToPowerOfTwo(length);
+}
+
+void Table::setLength(uint32_t length)
+{
+    m_length = length;
+    m_mask = WTF::maskForSize(length);
+    ASSERT(isValidLength(length));
+    ASSERT(m_mask == WTF::maskForSize(allocatedLength(length)));
+}
+
 RefPtr<Table> Table::create(uint32_t initial, std::optional<uint32_t> maximum)
 {
-    if (!isValidSize(initial))
+    if (!isValidLength(initial))
         return nullptr;
     return adoptRef(new (NotNull, fastMalloc(sizeof(Table))) Table(initial, maximum));
 }
@@ -47,16 +60,16 @@
 
 Table::Table(uint32_t initial, std::optional<uint32_t> maximum)
 {
-    m_size = initial;
+    setLength(initial);
     m_maximum = maximum;
-    ASSERT(isValidSize(m_size));
-    ASSERT(!m_maximum || *m_maximum >= m_size);
+    ASSERT(!m_maximum || *m_maximum >= m_length);
 
     // FIXME: It might be worth trying to pre-allocate maximum here. The spec recommends doing so.
     // But for now, we're not doing that.
-    m_functions = MallocPtr<Wasm::CallableFunction>::malloc((sizeof(Wasm::CallableFunction) * Checked<size_t>(size())).unsafeGet());
-    m_instances = MallocPtr<Instance*>::malloc((sizeof(Instance*) * Checked<size_t>(size())).unsafeGet());
-    for (uint32_t i = 0; i < size(); ++i) {
+    m_functions = MallocPtr<Wasm::CallableFunction>::malloc((sizeof(Wasm::CallableFunction) * Checked<size_t>(allocatedLength(m_length))).unsafeGet());
+    // FIXME this over-allocates and could be smarter about not committing all of that memory https://bugs.webkit.org/show_bug.cgi?id=181425
+    m_instances = MallocPtr<Instance*>::malloc((sizeof(Instance*) * Checked<size_t>(allocatedLength(m_length))).unsafeGet());
+    for (uint32_t i = 0; i < allocatedLength(m_length); ++i) {
         new (&m_functions.get()[i]) CallableFunction();
         ASSERT(m_functions.get()[i].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code.
         m_instances.get()[i] = nullptr;
@@ -66,28 +79,31 @@
 std::optional<uint32_t> Table::grow(uint32_t delta)
 {
     if (delta == 0)
-        return size();
+        return length();
 
     using Checked = Checked<uint32_t, RecordOverflow>;
-    Checked newSizeChecked = size();
-    newSizeChecked += delta;
-    uint32_t newSize;
-    if (newSizeChecked.safeGet(newSize) == CheckedState::DidOverflow)
+    Checked newLengthChecked = length();
+    newLengthChecked += delta;
+    uint32_t newLength;
+    if (newLengthChecked.safeGet(newLength) == CheckedState::DidOverflow)
         return std::nullopt;
 
-    if (maximum() && newSize > *maximum())
+    if (maximum() && newLength > *maximum())
         return std::nullopt;
-    if (!isValidSize(newSize))
+    if (!isValidLength(newLength))
         return std::nullopt;
 
     auto checkedGrow = [&] (auto& container) {
-        Checked reallocSizeChecked = newSizeChecked;
-        reallocSizeChecked *= sizeof(*container.get());
-        uint32_t reallocSize;
-        if (reallocSizeChecked.safeGet(reallocSize) == CheckedState::DidOverflow)
-            return false;
-        container.realloc(reallocSize);
-        for (uint32_t i = m_size; i < newSize; ++i)
+        if (newLengthChecked.unsafeGet() > allocatedLength(m_length)) {
+            Checked reallocSizeChecked = allocatedLength(newLengthChecked.unsafeGet());
+            reallocSizeChecked *= sizeof(*container.get());
+            uint32_t reallocSize;
+            if (reallocSizeChecked.safeGet(reallocSize) == CheckedState::DidOverflow)
+                return false;
+            // FIXME this over-allocates and could be smarter about not committing all of that memory https://bugs.webkit.org/show_bug.cgi?id=181425
+            container.realloc(reallocSize);
+        }
+        for (uint32_t i = m_length; i < allocatedLength(newLength); ++i)
             new (&container.get()[i]) std::remove_reference_t<decltype(*container.get())>();
         return true;
     };
@@ -97,24 +113,24 @@
     if (!checkedGrow(m_instances))
         return std::nullopt;
 
-    m_size = newSize;
+    setLength(newLength);
 
-    return newSize;
+    return newLength;
 }
 
 void Table::clearFunction(uint32_t index)
 {
-    RELEASE_ASSERT(index < size());
-    m_functions.get()[index] = Wasm::CallableFunction();
-    ASSERT(m_functions.get()[index].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code.
-    m_instances.get()[index] = nullptr;
+    RELEASE_ASSERT(index < length());
+    m_functions.get()[index & m_mask] = Wasm::CallableFunction();
+    ASSERT(m_functions.get()[index & m_mask].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code.
+    m_instances.get()[index & m_mask] = nullptr;
 }
 
 void Table::setFunction(uint32_t index, CallableFunction function, Instance* instance)
 {
-    RELEASE_ASSERT(index < size());
-    m_functions.get()[index] = function;
-    m_instances.get()[index] = instance;
+    RELEASE_ASSERT(index < length());
+    m_functions.get()[index & m_mask] = function;
+    m_instances.get()[index & m_mask] = instance;
 }
 
 } } // namespace JSC::Table

Modified: branches/safari-605-branch/Source/_javascript_Core/wasm/WasmTable.h (226686 => 226687)


--- branches/safari-605-branch/Source/_javascript_Core/wasm/WasmTable.h	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/Source/_javascript_Core/wasm/WasmTable.h	2018-01-10 04:31:37 UTC (rev 226687)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,25 +45,31 @@
     JS_EXPORT_PRIVATE ~Table();
 
     std::optional<uint32_t> maximum() const { return m_maximum; }
-    uint32_t size() const { return m_size; }
+    uint32_t length() const { return m_length; }
     std::optional<uint32_t> grow(uint32_t delta) WARN_UNUSED_RETURN;
     void clearFunction(uint32_t);
     void setFunction(uint32_t, CallableFunction, Instance*);
 
-    static ptrdiff_t offsetOfSize() { return OBJECT_OFFSETOF(Table, m_size); }
     static ptrdiff_t offsetOfFunctions() { return OBJECT_OFFSETOF(Table, m_functions); }
     static ptrdiff_t offsetOfInstances() { return OBJECT_OFFSETOF(Table, m_instances); }
+    static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(Table, m_length); }
+    static ptrdiff_t offsetOfMask() { return OBJECT_OFFSETOF(Table, m_mask); }
 
-    static bool isValidSize(uint32_t size) { return size < maxTableEntries; }
+    static uint32_t allocatedLength(uint32_t length);
+    uint32_t mask() const { return m_mask; }
+    static bool isValidLength(uint32_t length) { return length < maxTableEntries; }
 
 private:
     Table(uint32_t initial, std::optional<uint32_t> maximum);
 
-    std::optional<uint32_t> m_maximum;
-    uint32_t m_size;
+    void setLength(uint32_t);
+
     MallocPtr<CallableFunction> m_functions;
     // call_indirect needs to do an Instance check to potentially context switch when calling a function to another instance. We can hold raw pointers to Instance here because the embedder ensures that Table keeps all the instances alive. We couldn't hold a Ref here because it would cause cycles.
     MallocPtr<Instance*> m_instances;
+    uint32_t m_length;
+    uint32_t m_mask;
+    std::optional<uint32_t> m_maximum;
 };
 
 } } // namespace JSC::Wasm

Modified: branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp (226686 => 226687)


--- branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp	2018-01-10 04:31:37 UTC (rev 226687)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -251,7 +251,7 @@
                 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "Table import", "is not an instance of WebAssembly.Table")));
 
             uint32_t expectedInitial = moduleInformation.tableInformation.initial();
-            uint32_t actualInitial = table->size();
+            uint32_t actualInitial = table->length();
             if (actualInitial < expectedInitial)
                 return exception(createJSWebAssemblyLinkError(exec, vm, importFailMessage(import, "Table import", "provided an 'initial' that is too small")));
 

Modified: branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.cpp (226686 => 226687)


--- branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.cpp	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.cpp	2018-01-10 04:31:37 UTC (rev 226687)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -62,8 +62,9 @@
 {
     // FIXME: It might be worth trying to pre-allocate maximum here. The spec recommends doing so.
     // But for now, we're not doing that.
-    m_jsFunctions = MallocPtr<WriteBarrier<JSObject>>::malloc((sizeof(WriteBarrier<JSObject>) * Checked<size_t>(size())).unsafeGet());
-    for (uint32_t i = 0; i < size(); ++i)
+    // FIXME this over-allocates and could be smarter about not committing all of that memory https://bugs.webkit.org/show_bug.cgi?id=181425
+    m_jsFunctions = MallocPtr<WriteBarrier<JSObject>>::malloc((sizeof(WriteBarrier<JSObject>) * Checked<size_t>(allocatedLength())).unsafeGet());
+    for (uint32_t i = 0; i < allocatedLength(); ++i)
         new(&m_jsFunctions.get()[i]) WriteBarrier<JSObject>();
 }
 
@@ -85,7 +86,7 @@
 
     Base::visitChildren(thisObject, visitor);
 
-    for (unsigned i = 0; i < thisObject->size(); ++i)
+    for (unsigned i = 0; i < thisObject->length(); ++i)
         visitor.append(thisObject->m_jsFunctions.get()[i]);
 }
 
@@ -94,16 +95,18 @@
     if (delta == 0)
         return true;
 
-    size_t oldSize = size();
+    size_t oldLength = length();
 
     auto grew = m_table->grow(delta);
     if (!grew)
         return false;
 
-    size_t newSize = grew.value();
-    m_jsFunctions.realloc((sizeof(WriteBarrier<JSObject>) * Checked<size_t>(newSize)).unsafeGet());
+    size_t newLength = grew.value();
+    if (newLength > m_table->allocatedLength(oldLength))
+        // FIXME this over-allocates and could be smarter about not committing all of that memory https://bugs.webkit.org/show_bug.cgi?id=181425
+        m_jsFunctions.realloc((sizeof(WriteBarrier<JSObject>) * Checked<size_t>(m_table->allocatedLength(newLength))).unsafeGet());
 
-    for (size_t i = oldSize; i < newSize; ++i)
+    for (size_t i = oldLength; i < m_table->allocatedLength(newLength); ++i)
         new (&m_jsFunctions.get()[i]) WriteBarrier<JSObject>();
 
     return true;
@@ -111,26 +114,26 @@
 
 JSObject* JSWebAssemblyTable::getFunction(uint32_t index)
 {
-    RELEASE_ASSERT(index < size());
-    return m_jsFunctions.get()[index].get();
+    RELEASE_ASSERT(index < length());
+    return m_jsFunctions.get()[index & m_table->mask()].get();
 }
 
 void JSWebAssemblyTable::clearFunction(uint32_t index)
 {
     m_table->clearFunction(index);
-    m_jsFunctions.get()[index] = WriteBarrier<JSObject>();
+    m_jsFunctions.get()[index & m_table->mask()] = WriteBarrier<JSObject>();
 }
 
 void JSWebAssemblyTable::setFunction(VM& vm, uint32_t index, WebAssemblyFunction* function)
 {
     m_table->setFunction(index, function->callableFunction(), &function->instance()->instance());
-    m_jsFunctions.get()[index].set(vm, this, function);
+    m_jsFunctions.get()[index & m_table->mask()].set(vm, this, function);
 }
 
 void JSWebAssemblyTable::setFunction(VM& vm, uint32_t index, WebAssemblyWrapperFunction* function)
 {
     m_table->setFunction(index, function->callableFunction(), &function->instance()->instance());
-    m_jsFunctions.get()[index].set(vm, this, function);
+    m_jsFunctions.get()[index & m_table->mask()].set(vm, this, function);
 }
 
 } // namespace JSC

Modified: branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.h (226686 => 226687)


--- branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.h	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.h	2018-01-10 04:31:37 UTC (rev 226687)
@@ -48,9 +48,10 @@
 
     DECLARE_INFO;
 
-    static bool isValidSize(uint32_t size) { return Wasm::Table::isValidSize(size); }
+    static bool isValidLength(uint32_t length) { return Wasm::Table::isValidLength(length); }
     std::optional<uint32_t> maximum() const { return m_table->maximum(); }
-    uint32_t size() const { return m_table->size(); }
+    uint32_t length() const { return m_table->length(); }
+    uint32_t allocatedLength() const { return m_table->allocatedLength(length()); }
     bool grow(uint32_t delta) WARN_UNUSED_RETURN;
     JSObject* getFunction(uint32_t);
     void clearFunction(uint32_t);

Modified: branches/safari-605-branch/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp (226686 => 226687)


--- branches/safari-605-branch/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp	2018-01-10 04:31:37 UTC (rev 226687)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -268,7 +268,7 @@
     // Validation of all element ranges comes before all Table and Memory initialization.
     forEachElement([&] (const Wasm::Element& element, uint32_t tableIndex) {
         uint64_t lastWrittenIndex = static_cast<uint64_t>(tableIndex) + static_cast<uint64_t>(element.functionIndices.size()) - 1;
-        if (UNLIKELY(lastWrittenIndex >= table->size()))
+        if (UNLIKELY(lastWrittenIndex >= table->length()))
             exception = JSValue(throwException(exec, scope, createJSWebAssemblyLinkError(exec, vm, ASCIILiteral("Element is trying to set an out of bounds table index"))));
     });
 

Modified: branches/safari-605-branch/Source/_javascript_Core/wasm/js/WebAssemblyTablePrototype.cpp (226686 => 226687)


--- branches/safari-605-branch/Source/_javascript_Core/wasm/js/WebAssemblyTablePrototype.cpp	2018-01-10 04:31:33 UTC (rev 226686)
+++ branches/safari-605-branch/Source/_javascript_Core/wasm/js/WebAssemblyTablePrototype.cpp	2018-01-10 04:31:37 UTC (rev 226687)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -74,7 +74,7 @@
 
     JSWebAssemblyTable* table = getTable(exec, vm, exec->thisValue());
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
-    return JSValue::encode(jsNumber(table->size()));
+    return JSValue::encode(jsNumber(table->length()));
 }
 
 static EncodedJSValue JSC_HOST_CALL webAssemblyTableProtoFuncGrow(ExecState* exec)
@@ -88,12 +88,12 @@
     uint32_t delta = toNonWrappingUint32(exec, exec->argument(0));
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
 
-    uint32_t oldSize = table->size();
+    uint32_t oldLength = table->length();
 
     if (!table->grow(delta))
         return JSValue::encode(throwException(exec, throwScope, createRangeError(exec, ASCIILiteral("WebAssembly.Table.prototype.grow could not grow the table"))));
 
-    return JSValue::encode(jsNumber(oldSize));
+    return JSValue::encode(jsNumber(oldLength));
 }
 
 static EncodedJSValue JSC_HOST_CALL webAssemblyTableProtoFuncGet(ExecState* exec)
@@ -106,8 +106,8 @@
 
     uint32_t index = toNonWrappingUint32(exec, exec->argument(0));
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
-    if (index >= table->size())
-        return JSValue::encode(throwException(exec, throwScope, createRangeError(exec, ASCIILiteral("WebAssembly.Table.prototype.get expects an integer less than the size of the table"))));
+    if (index >= table->length())
+        return JSValue::encode(throwException(exec, throwScope, createRangeError(exec, ASCIILiteral("WebAssembly.Table.prototype.get expects an integer less than the length of the table"))));
 
     if (JSObject* result = table->getFunction(index))
         return JSValue::encode(result);
@@ -131,8 +131,8 @@
     uint32_t index = toNonWrappingUint32(exec, exec->argument(0));
     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
 
-    if (index >= table->size())
-        return JSValue::encode(throwException(exec, throwScope, createRangeError(exec, ASCIILiteral("WebAssembly.Table.prototype.set expects an integer less than the size of the table"))));
+    if (index >= table->length())
+        return JSValue::encode(throwException(exec, throwScope, createRangeError(exec, ASCIILiteral("WebAssembly.Table.prototype.set expects an integer less than the length of the table"))));
 
     if (value.isNull())
         table->clearFunction(index);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to