Source/JavaScriptCore/jsc.cpp

6969#include "TestRunnerUtils.h"
7070#include "TypeProfilerLog.h"
7171#include "WasmPlan.h"
 72#include "WasmMemory.h"
7273#include <locale.h>
7374#include <math.h>
7475#include <stdio.h>

@@static EncodedJSValue JSC_HOST_CALL func
26222623 });
26232624 }
26242625
 2626 void* memoryBytes = nullptr;
 2627 uint32_t memorySize = 0;
 2628 std::unique_ptr<Wasm::Memory> memory;
 2629 if (!!plan.getModuleInformation()->memory) {
 2630 memory = std::make_unique<Wasm::Memory>(plan.getModuleInformation()->memory.minSize(), plan.getModuleInformation()->memory.maxSize());
 2631 memoryBytes = memory->memory();
 2632 memorySize = memory->size();
 2633 }
 2634 vm.wasmMemoryPointer = memoryBytes;
 2635 vm.wasmMemorySize = memorySize;
 2636
26252637 for (uint32_t i = 0; i < functionCount; ++i) {
26262638 JSArray* testCases = jsCast<JSArray*>(exec->argument(i + 2));
26272639 for (unsigned testIndex = 0; testIndex < testCases->length(); ++testIndex) {
209463

Source/JavaScriptCore/testWasm.cpp

@@static void checkPlan(Plan& plan, unsign
302302// For now we inline the test files.
303303static void runWasmTests()
304304{
 305 UNUSED_PARAM(checkPlan);
 306 /*
305307 {
306308 // Generated from:
307309 // (module

@@static void runWasmTests()
14301432 CHECK_EQ(invoke<int>(*plan.compiledFunction(0)->jsEntryPoint, { box(100), box(6) }), 0);
14311433 }
14321434
 1435 */
14331436}
14341437
14351438#endif // ENABLE(WEBASSEMBLY)
209463

Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

14071407 795B19971D78BE3500262FA0 /* MapBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 795B19951D78BE3500262FA0 /* MapBase.cpp */; };
14081408 795B19981D78BE3500262FA0 /* MapBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 795B19961D78BE3500262FA0 /* MapBase.h */; settings = {ATTRIBUTES = (Private, ); }; };
14091409 7964656A1B952FF0003059EE /* GetPutInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 796465681B952FF0003059EE /* GetPutInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
 1410 797D466F1DF8A850008B529F /* WasmPageCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 797D466E1DF8A850008B529F /* WasmPageCount.h */; settings = {ATTRIBUTES = (Private, ); }; };
14101411 797E07A91B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */; };
14111412 797E07AA1B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
14121413 798937781DCAB57300F8D4FB /* JSFixedArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 798937761DCAB57300F8D4FB /* JSFixedArray.cpp */; };
14131414 798937791DCAB57300F8D4FB /* JSFixedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 798937771DCAB57300F8D4FB /* JSFixedArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
 1415 798F84591DF8B15000094D19 /* WasmMemoryInformation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 798F84581DF8B15000094D19 /* WasmMemoryInformation.cpp */; };
14141416 799EF7C41C56ED96002B0534 /* B3PCToOriginMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 799EF7C31C56ED96002B0534 /* B3PCToOriginMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
14151417 79A0907F1D768465008B889B /* HashMapImpl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79A0907D1D768465008B889B /* HashMapImpl.cpp */; };
14161418 79A090801D768465008B889B /* HashMapImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = 79A0907E1D768465008B889B /* HashMapImpl.h */; settings = {ATTRIBUTES = (Private, ); }; };

14231425 79B00CBF1C6AB07E0088C65D /* ProxyObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 79B00CBB1C6AB07E0088C65D /* ProxyObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
14241426 79B1788E1D399B8000B1A567 /* JITMathICForwards.h in Headers */ = {isa = PBXBuildFile; fileRef = 79A899FE1D38612E00D18C73 /* JITMathICForwards.h */; settings = {ATTRIBUTES = (Private, ); }; };
14251427 79B819931DD25CF500DDC714 /* JSGlobalObjectInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 79B819921DD25CF500DDC714 /* JSGlobalObjectInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
 1428 79C0962D1DF8ACF4009B8499 /* WasmMemoryInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 79C0962C1DF8ACF4009B8499 /* WasmMemoryInformation.h */; settings = {ATTRIBUTES = (Private, ); }; };
14261429 79C4B15D1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79C4B15B1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp */; };
14271430 79C4B15E1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 79C4B15C1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
14281431 79CFC6F01C33B10000C768EA /* LLIntPCRanges.h in Headers */ = {isa = PBXBuildFile; fileRef = 79CFC6EF1C33B10000C768EA /* LLIntPCRanges.h */; settings = {ATTRIBUTES = (Private, ); }; };

38283831 795B19951D78BE3500262FA0 /* MapBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MapBase.cpp; sourceTree = "<group>"; };
38293832 795B19961D78BE3500262FA0 /* MapBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapBase.h; sourceTree = "<group>"; };
38303833 796465681B952FF0003059EE /* GetPutInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetPutInfo.h; sourceTree = "<group>"; };
 3834 797D466E1DF8A850008B529F /* WasmPageCount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmPageCount.h; sourceTree = "<group>"; };
38313835 797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalLexicalEnvironment.cpp; sourceTree = "<group>"; };
38323836 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalLexicalEnvironment.h; sourceTree = "<group>"; };
38333837 798937761DCAB57300F8D4FB /* JSFixedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFixedArray.cpp; sourceTree = "<group>"; };
38343838 798937771DCAB57300F8D4FB /* JSFixedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFixedArray.h; sourceTree = "<group>"; };
 3839 798F84581DF8B15000094D19 /* WasmMemoryInformation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmMemoryInformation.cpp; sourceTree = "<group>"; };
38353840 799EF7C31C56ED96002B0534 /* B3PCToOriginMap.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3PCToOriginMap.h; path = b3/B3PCToOriginMap.h; sourceTree = "<group>"; };
38363841 79A0907D1D768465008B889B /* HashMapImpl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HashMapImpl.cpp; sourceTree = "<group>"; };
38373842 79A0907E1D768465008B889B /* HashMapImpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HashMapImpl.h; sourceTree = "<group>"; };

38443849 79B00CBA1C6AB07E0088C65D /* ProxyObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyObject.cpp; sourceTree = "<group>"; };
38453850 79B00CBB1C6AB07E0088C65D /* ProxyObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProxyObject.h; sourceTree = "<group>"; };
38463851 79B819921DD25CF500DDC714 /* JSGlobalObjectInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObjectInlines.h; sourceTree = "<group>"; };
 3852 79C0962C1DF8ACF4009B8499 /* WasmMemoryInformation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmMemoryInformation.h; sourceTree = "<group>"; };
38473853 79C4B15B1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLiveCatchVariablePreservationPhase.cpp; path = dfg/DFGLiveCatchVariablePreservationPhase.cpp; sourceTree = "<group>"; };
38483854 79C4B15C1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLiveCatchVariablePreservationPhase.h; path = dfg/DFGLiveCatchVariablePreservationPhase.h; sourceTree = "<group>"; };
38493855 79CFC6EF1C33B10000C768EA /* LLIntPCRanges.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LLIntPCRanges.h; path = llint/LLIntPCRanges.h; sourceTree = "<group>"; };

59966002 53F40E8A1D5901BB0099A1B6 /* WasmFunctionParser.h */,
59976003 535557151D9DFA32006D583B /* WasmMemory.cpp */,
59986004 535557131D9D9EA5006D583B /* WasmMemory.h */,
 6005 79C0962C1DF8ACF4009B8499 /* WasmMemoryInformation.h */,
 6006 798F84581DF8B15000094D19 /* WasmMemoryInformation.cpp */,
59996007 53F40E961D5A7BEC0099A1B6 /* WasmModuleParser.cpp */,
60006008 53F40E941D5A7AEF0099A1B6 /* WasmModuleParser.h */,
 6009 797D466E1DF8A850008B529F /* WasmPageCount.h */,
60016010 531374BE1D5CE95000AF7A0B /* WasmPlan.cpp */,
60026011 531374BC1D5CE67600AF7A0B /* WasmPlan.h */,
60036012 53F40E8C1D5901F20099A1B6 /* WasmParser.h */,

77617770 79233C2B1D34715700C5A834 /* JITMathIC.h in Headers */,
77627771 0FEC85021BDACDAC0080FF74 /* B3BasicBlockInlines.h in Headers */,
77637772 0FEC85031BDACDAC0080FF74 /* B3BasicBlockUtils.h in Headers */,
 7773 79C0962D1DF8ACF4009B8499 /* WasmMemoryInformation.h in Headers */,
77647774 0FEC85041BDACDAC0080FF74 /* B3BlockWorklist.h in Headers */,
77657775 0FEC85061BDACDAC0080FF74 /* B3CheckSpecial.h in Headers */,
77667776 0FA762071DB9243300B7A2FD /* MutatorState.h in Headers */,

81868196 FEB58C15187B8B160098EF0B /* ErrorHandlingScope.h in Headers */,
81878197 BC02E98D0E183E38000F9297 /* ErrorInstance.h in Headers */,
81888198 BC02E90F0E1839DB000F9297 /* ErrorPrototype.h in Headers */,
 8199 797D466F1DF8A850008B529F /* WasmPageCount.h in Headers */,
81898200 996B731B1BDA08D100331B84 /* ErrorPrototype.lut.h in Headers */,
81908201 969A07980ED1D3AE00F1F681 /* DirectEvalCodeCache.h in Headers */,
81918202 A54982041891D0B00081E5B8 /* EventLoop.h in Headers */,

98379848 0FDDBFB51666EED800C55FEF /* DFGVariableAccessDataDump.cpp in Sources */,
98389849 14386A781DD6989C008652C4 /* IndirectEvalExecutable.cpp in Sources */,
98399850 0F9495871C57F47500413A48 /* B3StackSlot.cpp in Sources */,
 9851 798F84591DF8B15000094D19 /* WasmMemoryInformation.cpp in Sources */,
98409852 0F2BDC5115228FFD00CD8910 /* DFGVariableEvent.cpp in Sources */,
98419853 AD2FCBF21DB58DAD00B3E736 /* WebAssemblyInstancePrototype.cpp in Sources */,
98429854 0F2BDC4A1522809A00CD8910 /* DFGVariableEventStream.cpp in Sources */,
209463

Source/JavaScriptCore/runtime/VM.h

@@public:
293293 // FIXME: This should be a void*, because it might not point to a CallFrame.
294294 // https://bugs.webkit.org/show_bug.cgi?id=160441
295295 ExecState* topCallFrame;
 296 void* wasmMemoryPointer;
 297 uint32_t wasmMemorySize;
296298 Strong<Structure> structureStructure;
297299 Strong<Structure> structureRareDataStructure;
298300 Strong<Structure> terminatedExecutionErrorStructure;
209463

Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp

@@public:
130130
131131 static constexpr ExpressionType emptyExpression = nullptr;
132132
133  B3IRGenerator(Memory*, Procedure&, FunctionCompilation*);
 133 B3IRGenerator(MemoryInformation&, Procedure&, FunctionCompilation*);
134134
135135 bool WARN_UNUSED_RETURN addArguments(const Vector<Type>&);
136136 bool WARN_UNUSED_RETURN addLocal(Type, uint32_t);

@@private:
179179 void unifyValuesWithBlock(const ExpressionList& resultStack, ResultList& stack);
180180 Value* zeroForType(Type);
181181
182  Memory* m_memory;
183182 Procedure& m_proc;
184183 BasicBlock* m_currentBlock;
185184 Vector<Variable*> m_locals;

@@private:
190189 Value* m_zeroValues[numTypes];
191190};
192191
193 B3IRGenerator::B3IRGenerator(Memory* memory, Procedure& procedure, FunctionCompilation* compilation)
194  : m_memory(memory)
195  , m_proc(procedure)
 192B3IRGenerator::B3IRGenerator(MemoryInformation& memory, Procedure& procedure, FunctionCompilation* compilation)
 193 : m_proc(procedure)
196194 , m_unlinkedCalls(compilation->unlinkedCalls)
197195{
198196 m_currentBlock = m_proc.addBlock();

@@B3IRGenerator::B3IRGenerator(Memory* mem
211209 }
212210 }
213211
214  if (m_memory) {
215  m_memoryBaseGPR = m_memory->pinnedRegisters().baseMemoryPointer;
 212 if (!!memory) {
 213 m_memoryBaseGPR = memory.pinnedRegisters().baseMemoryPointer;
216214 m_proc.pinRegister(m_memoryBaseGPR);
217  ASSERT(!m_memory->pinnedRegisters().sizeRegisters[0].sizeOffset);
218  m_memorySizeGPR = m_memory->pinnedRegisters().sizeRegisters[0].sizeRegister;
219  for (const PinnedSizeRegisterInfo& info : m_memory->pinnedRegisters().sizeRegisters)
 215 ASSERT(!memory.pinnedRegisters().sizeRegisters[0].sizeOffset);
 216 m_memorySizeGPR = memory.pinnedRegisters().sizeRegisters[0].sizeRegister;
 217 for (const PinnedSizeRegisterInfo& info : memory.pinnedRegisters().sizeRegisters)
220218 m_proc.pinRegister(info.sizeRegister);
221219
222220 m_proc.setWasmBoundsCheckGenerator([=] (CCallHelpers& jit, GPRReg pinnedGPR, unsigned) {

@@void B3IRGenerator::dump(const Vector<Co
660658 dataLogLn("\n");
661659}
662660
663 static std::unique_ptr<Compilation> createJSWrapper(VM& vm, const Signature* signature, MacroAssemblerCodePtr mainFunction, Memory* memory)
 661static std::unique_ptr<Compilation> createJSWrapper(VM& vm, const Signature* signature, MacroAssemblerCodePtr mainFunction, MemoryInformation& memory)
664662{
665663 Procedure proc;
666664 BasicBlock* block = proc.addBlock();

@@static std::unique_ptr<Compilation> crea
682680 // Move memory values to the approriate places, if needed.
683681 Value* baseMemory = nullptr;
684682 Vector<Value*> sizes;
685  if (memory) {
686  baseMemory = block->appendNew<ConstPtrValue>(proc, Origin(), memory->memory());
 683 if (!!memory) {
 684 baseMemory = block->appendNew<MemoryValue>(proc, Load, Int64, Origin(),
 685 block->appendNew<ConstPtrValue>(proc, Origin(), &vm.wasmMemoryPointer));
687686 Value* size = block->appendNew<MemoryValue>(proc, Load, Int32, Origin(),
688  block->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<char*>(memory) + Memory::offsetOfSize()));
689  sizes.reserveCapacity(memory->pinnedRegisters().sizeRegisters.size());
690  for (auto info : memory->pinnedRegisters().sizeRegisters) {
 687 block->appendNew<ConstPtrValue>(proc, Origin(), &vm.wasmMemorySize));
 688 sizes.reserveCapacity(memory.pinnedRegisters().sizeRegisters.size());
 689 for (auto info : memory.pinnedRegisters().sizeRegisters) {
691690 sizes.append(block->appendNew<Value>(proc, Sub, Origin(), size,
692691 block->appendNew<Const32Value>(proc, Origin(), info.sizeOffset)));
693692 }

@@static std::unique_ptr<Compilation> crea
701700
702701 // Move the arguments into place.
703702 Value* result = wasmCallingConvention().setupCall(proc, block, Origin(), arguments, toB3Type(signature->returnType), [&] (PatchpointValue* patchpoint) {
704  if (memory) {
705  ASSERT(sizes.size() == memory->pinnedRegisters().sizeRegisters.size());
706  patchpoint->append(ConstrainedValue(baseMemory, ValueRep::reg(memory->pinnedRegisters().baseMemoryPointer)));
 703 if (!!memory) {
 704 ASSERT(sizes.size() == memory.pinnedRegisters().sizeRegisters.size());
 705 patchpoint->append(ConstrainedValue(baseMemory, ValueRep::reg(memory.pinnedRegisters().baseMemoryPointer)));
707706 for (unsigned i = 0; i < sizes.size(); ++i)
708  patchpoint->append(ConstrainedValue(sizes[i], ValueRep::reg(memory->pinnedRegisters().sizeRegisters[i].sizeRegister)));
 707 patchpoint->append(ConstrainedValue(sizes[i], ValueRep::reg(memory.pinnedRegisters().sizeRegisters[i].sizeRegister)));
709708 }
710709
711710 patchpoint->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {

@@static std::unique_ptr<Compilation> crea
739738 return std::make_unique<Compilation>(vm, proc);
740739}
741740
742 std::unique_ptr<FunctionCompilation> parseAndCompile(VM& vm, const uint8_t* functionStart, size_t functionLength, Memory* memory, const Signature* signature, const Vector<FunctionInformation>& functions, unsigned optLevel)
 741std::unique_ptr<FunctionCompilation> parseAndCompile(VM& vm, const uint8_t* functionStart, size_t functionLength, MemoryInformation& memory, const Signature* signature, const Vector<FunctionInformation>& functions, unsigned optLevel)
743742{
744743 auto result = std::make_unique<FunctionCompilation>();
745744
209463

Source/JavaScriptCore/wasm/WasmB3IRGenerator.h

@@extern "C" void dumpProcedure(void*);
3535
3636namespace JSC { namespace Wasm {
3737
38 class Memory;
 38class MemoryInformation;
3939
40 std::unique_ptr<FunctionCompilation> parseAndCompile(VM&, const uint8_t*, size_t, Memory*, const Signature*, const Vector<FunctionInformation>&, unsigned optLevel = 1);
 40std::unique_ptr<FunctionCompilation> parseAndCompile(VM&, const uint8_t*, size_t, MemoryInformation&, const Signature*, const Vector<FunctionInformation>&, unsigned optLevel = 1);
4141
4242} } // namespace JSC::Wasm
4343
209463

Source/JavaScriptCore/wasm/WasmFormat.h

3131#include "B3Type.h"
3232#include "CodeLocation.h"
3333#include "Identifier.h"
 34#include "WasmMemoryInformation.h"
3435#include "WasmOps.h"
 36#include "WasmPageCount.h"
3537#include <wtf/Vector.h>
3638
3739namespace JSC {

@@struct FunctionInformation {
105107 size_t end;
106108};
107109
108 class Memory;
109 
110110struct Export {
111111 Identifier field;
112112 External::Kind kind;

@@struct ModuleInformation {
122122 Vector<Signature> signatures;
123123 Vector<Import> imports;
124124 Vector<FunctionInformation> functions;
125  std::unique_ptr<Memory> memory;
 125 MemoryInformation memory;
126126 Vector<Export> exports;
127127
128128 ~ModuleInformation();
209463

Source/JavaScriptCore/wasm/WasmMemory.cpp

3030
3131namespace JSC { namespace Wasm {
3232
33 Memory::Memory(uint32_t startingSize, uint32_t capacity, const Vector<unsigned>& pinnedSizeRegisters)
 33Memory::Memory(PageCount startingSize, PageCount capacity)
3434 : m_mode(Mode::BoundsChecking)
35  , m_size(startingSize)
36  , m_capacity(capacity)
 35 , m_size(startingSize.bytes())
 36 , m_capacity(capacity.bytes())
3737 // FIXME: If we add signal based bounds checking then we need extra space for overflow on load.
3838 // see: https://bugs.webkit.org/show_bug.cgi?id=162693
39  , m_mappedCapacity(static_cast<uint64_t>(maxPageCount) * static_cast<uint64_t>(pageSize))
 39 , m_mappedCapacity(PageCount::max().bytes())
4040{
4141 ASSERT(pinnedSizeRegisters.size() > 0);
4242

@@Memory::Memory(uint32_t startingSize, ui
5050 return;
5151 }
5252
53  ASSERT(startingSize <= m_mappedCapacity);
54  if (mprotect(result, startingSize, PROT_READ | PROT_WRITE)) {
 53 ASSERT(m_size <= m_mappedCapacity);
 54 if (mprotect(result, m_size, PROT_READ | PROT_WRITE)) {
5555 munmap(result, m_mappedCapacity);
5656 return;
5757 }
5858
59  unsigned remainingPinnedRegisters = pinnedSizeRegisters.size() + 1;
60  jscCallingConvention().m_calleeSaveRegisters.forEach([&] (Reg reg) {
61  GPRReg gpr = reg.gpr();
62  if (!remainingPinnedRegisters || RegisterSet::stackRegisters().get(reg))
63  return;
64  if (remainingPinnedRegisters == 1) {
65  m_pinnedRegisters.baseMemoryPointer = gpr;
66  remainingPinnedRegisters--;
67  } else
68  m_pinnedRegisters.sizeRegisters.append({ gpr, pinnedSizeRegisters[--remainingPinnedRegisters - 1] });
69  });
70 
71  ASSERT(!remainingPinnedRegisters);
7259 m_memory = result;
7360}
7461
209463

Source/JavaScriptCore/wasm/WasmMemory.h

2727
2828#if ENABLE(WEBASSEMBLY)
2929
30 #include "WasmCallingConvention.h"
 30#include "WasmPageCount.h"
3131
3232#include <wtf/Vector.h>
3333
3434namespace JSC { namespace Wasm {
3535
36 struct PinnedSizeRegisterInfo {
37  GPRReg sizeRegister;
38  unsigned sizeOffset;
39 };
40 
41 // FIXME: We should support more than one memory size register. Right now we take a vector with only one
42 // entry. Specifically an entry where the sizeOffset == 0. If we have more than one size register,
43 // we can have one for each load size class. see: https://bugs.webkit.org/show_bug.cgi?id=162952
44 struct PinnedRegisterInfo {
45  Vector<PinnedSizeRegisterInfo> sizeRegisters;
46  GPRReg baseMemoryPointer;
47 };
48 
49 constexpr uint32_t pageSize = 64 * KB;
50 constexpr uint32_t maxPageCount = static_cast<uint32_t>((1ull << 32) / pageSize);
51 
5236class Memory {
5337 WTF_MAKE_NONCOPYABLE(Memory);
5438 WTF_MAKE_FAST_ALLOCATED;

@@public:
5943 BoundsChecking
6044 };
6145
62  Memory() = default;
63  Memory(uint32_t startingSize, uint32_t capacity, const Vector<unsigned>& pinnedSizeRegisters);
 46 JS_EXPORT_PRIVATE Memory(PageCount startingSize, PageCount capacity);
6447
6548 ~Memory()
6649 {

@@public:
7053
7154 void* memory() const { return m_memory; }
7255 uint32_t size() const { return m_size; }
73  const PinnedRegisterInfo& pinnedRegisters() const { return m_pinnedRegisters; }
7456
7557 Mode mode() const { return m_mode; }
7658

@@public:
8769
8870private:
8971 void* m_memory { nullptr };
90  PinnedRegisterInfo m_pinnedRegisters;
9172 Mode m_mode;
9273 uint32_t m_size { 0 };
9374 uint32_t m_capacity { 0 };
209463

Source/JavaScriptCore/wasm/WasmMemoryInformation.cpp

 1/*
 2 * Copyright (C) 2016 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#include "config.h"
 27#include "WasmMemoryInformation.h"
 28
 29#include "WasmCallingConvention.h"
 30
 31#if ENABLE(WEBASSEMBLY)
 32
 33namespace JSC { namespace Wasm {
 34
 35MemoryInformation::MemoryInformation(PageCount minSize, PageCount maxSize, const Vector<unsigned>& pinnedSizeRegisters)
 36 : m_minSize(minSize)
 37 , m_maxSize(maxSize)
 38{
 39 ASSERT(!!m_minSize);
 40 ASSERT(!!m_maxSize);
 41 ASSERT(!!*this);
 42
 43 unsigned remainingPinnedRegisters = pinnedSizeRegisters.size() + 1;
 44 jscCallingConvention().m_calleeSaveRegisters.forEach([&] (Reg reg) {
 45 GPRReg gpr = reg.gpr();
 46 if (!remainingPinnedRegisters || RegisterSet::stackRegisters().get(reg))
 47 return;
 48 if (remainingPinnedRegisters == 1) {
 49 m_pinnedRegisters.baseMemoryPointer = gpr;
 50 remainingPinnedRegisters--;
 51 } else
 52 m_pinnedRegisters.sizeRegisters.append({ gpr, pinnedSizeRegisters[--remainingPinnedRegisters - 1] });
 53 });
 54
 55 ASSERT(!remainingPinnedRegisters);
 56}
 57
 58} } // namespace JSC::Wasm
 59
 60#endif // ENABLE(WEBASSEMBLY)
nonexistent

Source/JavaScriptCore/wasm/WasmMemoryInformation.h

 1/*
 2 * Copyright (C) 2016 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#pragma once
 27
 28#if ENABLE(WEBASSEMBLY)
 29
 30#include "GPRInfo.h"
 31#include "WasmPageCount.h"
 32#include <wtf/Vector.h>
 33
 34namespace JSC { namespace Wasm {
 35
 36struct PinnedSizeRegisterInfo {
 37 GPRReg sizeRegister;
 38 unsigned sizeOffset;
 39};
 40
 41// FIXME: We should support more than one memory size register. Right now we take a vector with only one
 42// entry. Specifically an entry where the sizeOffset == 0. If we have more than one size register,
 43// we can have one for each load size class. see: https://bugs.webkit.org/show_bug.cgi?id=162952
 44struct PinnedRegisterInfo {
 45 Vector<PinnedSizeRegisterInfo> sizeRegisters;
 46 GPRReg baseMemoryPointer;
 47};
 48
 49class MemoryInformation {
 50public:
 51 MemoryInformation()
 52 {
 53 ASSERT(!*this);
 54 }
 55
 56 MemoryInformation(PageCount minSize, PageCount maxSize, const Vector<unsigned>& pinnedSizeRegisters);
 57
 58 const PinnedRegisterInfo& pinnedRegisters() const { return m_pinnedRegisters; }
 59 PageCount minSize() const { return m_minSize; }
 60 PageCount maxSize() const { return m_maxSize; }
 61
 62 explicit operator bool() const { return !!m_minSize && !!m_maxSize; }
 63
 64private:
 65 PageCount m_minSize { };
 66 PageCount m_maxSize { };
 67 PinnedRegisterInfo m_pinnedRegisters { };
 68};
 69
 70} } // namespace JSC::Wasm
 71
 72#endif // ENABLE(WASM)
nonexistent

Source/JavaScriptCore/wasm/WasmModuleParser.cpp

3030
3131#include "IdentifierInlines.h"
3232#include "WasmFormat.h"
33 #include "WasmMemory.h"
 33#include "WasmMemoryInformation.h"
3434#include "WasmOps.h"
3535#include "WasmSections.h"
3636

@@bool ModuleParser::parseMemory()
314314 if (!parseVarUInt1(flags))
315315 return false;
316316
317  uint32_t size;
318  if (!parseVarUInt32(size))
319  return false;
320  if (size > maxPageCount)
321  return false;
 317 PageCount minSize;
 318 {
 319 uint32_t size;
 320 if (!parseVarUInt32(size))
 321 return false;
 322 if (!PageCount::isValid(size))
 323 return false;
 324 minSize = PageCount(size);
 325 }
322326
323  uint32_t capacity = maxPageCount;
 327 PageCount maxSize = PageCount::max();
324328 if (flags) {
325  if (!parseVarUInt32(capacity))
 329 uint32_t size;
 330 if (!parseVarUInt32(size))
 331 return false;
 332 if (!PageCount::isValid(size))
326333 return false;
327  if (size > capacity || capacity > maxPageCount)
 334 maxSize = PageCount(size);
 335 if (minSize > maxSize)
328336 return false;
329337 }
330338
331  capacity *= pageSize;
332  size *= pageSize;
333 
334339 Vector<unsigned> pinnedSizes = { 0 };
335  m_module->memory = std::make_unique<Memory>(size, capacity, pinnedSizes);
336  return m_module->memory->memory();
 340 m_module->memory = MemoryInformation(minSize, maxSize, pinnedSizes);
 341 return true;
337342}
338343
339344bool ModuleParser::parseGlobal()
209463

Source/JavaScriptCore/wasm/WasmPageCount.h

 1/*
 2 * Copyright (C) 2016 Apple Inc. All rights reserved.
 3 *
 4 * Redistribution and use in source and binary forms, with or without
 5 * modification, are permitted provided that the following conditions
 6 * are met:
 7 * 1. Redistributions of source code must retain the above copyright
 8 * notice, this list of conditions and the following disclaimer.
 9 * 2. Redistributions in binary form must reproduce the above copyright
 10 * notice, this list of conditions and the following disclaimer in the
 11 * documentation and/or other materials provided with the distribution.
 12 *
 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24 */
 25
 26#pragma once
 27
 28#if ENABLE(WEBASSEMBLY)
 29
 30namespace JSC { namespace Wasm {
 31
 32class PageCount {
 33
 34public:
 35 PageCount()
 36 : m_pageCount(UINT_MAX)
 37 {
 38 static_assert(maxPageCount < UINT_MAX, "We rely on this here.");
 39 }
 40
 41 PageCount(uint32_t pageCount)
 42 : m_pageCount(pageCount)
 43 { }
 44
 45 size_t bytes() { return m_pageCount * pageSize; }
 46
 47 static bool isValid(uint32_t pageCount)
 48 {
 49 return pageCount <= maxPageCount;
 50 }
 51
 52 static PageCount max()
 53 {
 54 return PageCount(maxPageCount);
 55 }
 56
 57 explicit operator bool() const
 58 {
 59 return m_pageCount != UINT_MAX;
 60 }
 61
 62 bool operator<(const PageCount& other) const
 63 {
 64 return m_pageCount < other.m_pageCount;
 65 }
 66 bool operator>(const PageCount& other) const
 67 {
 68 return m_pageCount > other.m_pageCount;
 69 }
 70
 71private:
 72 static constexpr uint32_t pageSize = 64 * KB;
 73 static constexpr uint32_t maxPageCount = static_cast<uint32_t>((1ull << 32) / pageSize);
 74
 75 uint32_t m_pageCount;
 76};
 77
 78} } // namespace JSC::Wasm
 79
 80#endif // ENABLE(WASM)
nonexistent

Source/JavaScriptCore/wasm/WasmPlan.cpp

@@void Plan::run()
100100 return;
101101 }
102102
103  m_compiledFunctions.uncheckedAppend(parseAndCompile(*m_vm, functionStart, functionLength, m_moduleInformation->memory.get(), info.signature, m_moduleInformation->functions));
 103 m_compiledFunctions.uncheckedAppend(parseAndCompile(*m_vm, functionStart, functionLength, m_moduleInformation->memory, info.signature, m_moduleInformation->functions));
104104 }
105105
106106 // Patch the call sites for each function.
209463

Source/JavaScriptCore/wasm/WasmPlan.h

@@public:
6464 RELEASE_ASSERT(!failed());
6565 return m_moduleInformation;
6666 }
 67 /*
6768 const Memory* memory() const
6869 {
6970 RELEASE_ASSERT(!failed());
7071 return m_moduleInformation->memory.get();
7172 }
 73 */
7274 size_t compiledFunctionCount() const
7375 {
7476 RELEASE_ASSERT(!failed());
209463

Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp

3232#include "JSCInlines.h"
3333#include "JSModuleEnvironment.h"
3434#include "JSModuleNamespaceObject.h"
 35#include "JSWebAssemblyMemory.h"
3536#include "JSWebAssemblyModule.h"
3637
3738namespace JSC {

@@void JSWebAssemblyInstance::visitChildre
7576 Base::visitChildren(thisObject, visitor);
7677 visitor.append(&thisObject->m_module);
7778 visitor.append(&thisObject->m_moduleNamespaceObject);
 79 visitor.append(&thisObject->m_memory);
7880}
7981
8082const ClassInfo JSWebAssemblyInstance::s_info = { "WebAssembly.Instance", &Base::s_info, 0, CREATE_METHOD_TABLE(JSWebAssemblyInstance) };
209463

Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h

@@namespace JSC {
3434
3535class JSModuleNamespaceObject;
3636class JSWebAssemblyModule;
 37class JSWebAssemblyMemory;
3738
3839class JSWebAssemblyInstance : public JSDestructibleObject {
3940public:

@@public:
5152 return m_module.get();
5253 }
5354
 55 JSWebAssemblyMemory* memory() { return m_memory.get(); }
 56 void setMemory(VM& vm, JSWebAssemblyMemory* memory) { m_memory.set(vm, this, memory); }
 57
5458protected:
5559 JSWebAssemblyInstance(VM&, Structure*);
5660 void finishCreation(VM&, JSWebAssemblyModule*, JSModuleNamespaceObject*);

@@protected:
6064private:
6165 WriteBarrier<JSWebAssemblyModule> m_module;
6266 WriteBarrier<JSModuleNamespaceObject> m_moduleNamespaceObject;
 67 WriteBarrier<JSWebAssemblyMemory> m_memory;
6368};
6469
6570} // namespace JSC
209463

Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.cpp

3232
3333namespace JSC {
3434
35 JSWebAssemblyMemory* JSWebAssemblyMemory::create(VM& vm, Structure* structure)
 35const ClassInfo JSWebAssemblyMemory::s_info = { "WebAssembly.Memory", &Base::s_info, 0, CREATE_METHOD_TABLE(JSWebAssemblyMemory) };
 36
 37JSWebAssemblyMemory* JSWebAssemblyMemory::create(VM& vm, Structure* structure, std::unique_ptr<Wasm::Memory>&& memory)
3638{
37  auto* instance = new (NotNull, allocateCell<JSWebAssemblyMemory>(vm.heap)) JSWebAssemblyMemory(vm, structure);
 39 auto* instance = new (NotNull, allocateCell<JSWebAssemblyMemory>(vm.heap)) JSWebAssemblyMemory(vm, structure, WTFMove(memory));
3840 instance->finishCreation(vm);
3941 return instance;
4042}

@@Structure* JSWebAssemblyMemory::createSt
4446 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
4547}
4648
47 JSWebAssemblyMemory::JSWebAssemblyMemory(VM& vm, Structure* structure)
 49JSWebAssemblyMemory::JSWebAssemblyMemory(VM& vm, Structure* structure, std::unique_ptr<Wasm::Memory>&& memory)
4850 : Base(vm, structure)
 51 , m_memory(WTFMove(memory))
4952{
5053}
5154

@@void JSWebAssemblyMemory::visitChildren(
6871 Base::visitChildren(thisObject, visitor);
6972}
7073
71 const ClassInfo JSWebAssemblyMemory::s_info = { "WebAssembly.Memory", &Base::s_info, 0, CREATE_METHOD_TABLE(JSWebAssemblyMemory) };
72 
7374} // namespace JSC
7475
7576#endif // ENABLE(WEBASSEMBLY)
209463

Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h

2929
3030#include "JSDestructibleObject.h"
3131#include "JSObject.h"
 32#include "WasmMemory.h"
3233
3334namespace JSC {
3435

@@class JSWebAssemblyMemory : public JSDes
3637public:
3738 typedef JSDestructibleObject Base;
3839
39  static JSWebAssemblyMemory* create(VM&, Structure*);
 40 static JSWebAssemblyMemory* create(VM&, Structure*, std::unique_ptr<Wasm::Memory>&&);
4041 static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
4142
4243 DECLARE_INFO;
4344
 45 Wasm::Memory* memory() { return m_memory.get(); }
 46
4447protected:
45  JSWebAssemblyMemory(VM&, Structure*);
 48 JSWebAssemblyMemory(VM&, Structure*, std::unique_ptr<Wasm::Memory>&&);
4649 void finishCreation(VM&);
4750 static void destroy(JSCell*);
4851 static void visitChildren(JSCell*, SlotVisitor&);
 52
 53 std::unique_ptr<Wasm::Memory> m_memory;
4954};
5055
5156} // namespace JSC
209463

Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp

3434#include "JSObject.h"
3535#include "JSWebAssemblyCallee.h"
3636#include "JSWebAssemblyInstance.h"
 37#include "JSWebAssemblyMemory.h"
3738#include "LLIntThunks.h"
3839#include "ProtoCallFrame.h"
3940#include "VM.h"
4041#include "WasmFormat.h"
 42#include "WasmMemory.h"
4143
4244namespace JSC {
4345

@@static EncodedJSValue JSC_HOST_CALL call
9092 argCount = boxedArgs.size();
9193 }
9294
 95 // Setup the memory that the entrance loads.
 96 if (JSWebAssemblyMemory* memory = wasmFunction->instance()->memory()) {
 97 Wasm::Memory* wasmMemory = memory->memory();
 98 vm.wasmMemoryPointer = wasmMemory->memory();
 99 vm.wasmMemorySize = wasmMemory->size();
 100 }
 101
93102 // Note: we specifically use the WebAsseblyFunction as the callee to begin with in the ProtoCallFrame.
94103 // The reason for this is that calling into the llint may stack overflow, and the stack overflow
95104 // handler might read the global object from the callee. The JSWebAssemblyCallee doesn't have a
209463

Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h

@@public:
5656 static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
5757
5858 JSWebAssemblyCallee* webAssemblyCallee() const { return m_wasmCallee.get(); }
59  const JSWebAssemblyInstance* instance() const { return m_instance.get(); }
 59 JSWebAssemblyInstance* instance() const { return m_instance.get(); }
6060 const Wasm::Signature* signature()
6161 {
6262 ASSERT(m_signature);
209463

Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp

@@static EncodedJSValue JSC_HOST_CALL cons
8181 JSWebAssemblyInstance* instance = JSWebAssemblyInstance::create(vm, instanceStructure, jsModule, moduleRecord->getModuleNamespace(state));
8282 RETURN_IF_EXCEPTION(scope, encodedJSValue());
8383
84  moduleRecord->link(state, instance);
 84 moduleRecord->link(state, instance, importObject);
8585 RETURN_IF_EXCEPTION(scope, encodedJSValue());
8686 if (verbose)
8787 moduleRecord->dump();
209463

Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp

3030
3131#include "FunctionPrototype.h"
3232#include "JSCInlines.h"
 33#include "JSWebAssemblyMemory.h"
 34#include "WasmMemory.h"
 35#include "WasmPageCount.h"
3336#include "WebAssemblyMemoryPrototype.h"
 37#include <wtf/Optional.h>
3438
3539#include "WebAssemblyMemoryConstructor.lut.h"
3640

@@const ClassInfo WebAssemblyMemoryConstru
4347 @end
4448 */
4549
46 static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyMemory(ExecState* state)
 50static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyMemory(ExecState* exec)
4751{
48  VM& vm = state->vm();
49  auto scope = DECLARE_THROW_SCOPE(vm);
50  // FIXME https://bugs.webkit.org/show_bug.cgi?id=164134
51  return JSValue::encode(throwException(state, scope, createError(state, ASCIILiteral("WebAssembly doesn't yet implement the Memory constructor property"))));
 52 VM& vm = exec->vm();
 53 auto throwScope = DECLARE_THROW_SCOPE(vm);
 54 if (exec->argumentCount() != 1)
 55 return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Memory expects exactly one argument"))));
 56
 57 auto getUint32 = [&] (JSValue value) -> uint32_t {
 58 double doubleValue = value.toInteger(exec);
 59 RETURN_IF_EXCEPTION(throwScope, { });
 60 if (doubleValue < 0 || doubleValue > UINT_MAX) {
 61 throwException(exec, throwScope,
 62 createTypeError(exec, ASCIILiteral("WebAssembly.Memory expects the 'initial' property to be an integer in the range: [0, 2^32 - 1]")));
 63 return 0;
 64 }
 65 return static_cast<uint32_t>(doubleValue);
 66 };
 67
 68 JSObject* memoryDescriptor;
 69 {
 70 JSValue argument = exec->argument(0);
 71 if (!argument.isObject())
 72 return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Memory excepts its first argument to be an object"))));
 73 memoryDescriptor = jsCast<JSObject*>(argument);
 74 }
 75
 76 Wasm::PageCount minSize;
 77 {
 78 Identifier initial = Identifier::fromString(&vm, "initial");
 79 JSValue minSizeValue = memoryDescriptor->get(exec, initial);
 80 RETURN_IF_EXCEPTION(throwScope, { });
 81 uint32_t size = getUint32(minSizeValue);
 82 RETURN_IF_EXCEPTION(throwScope, { });
 83 if (!Wasm::PageCount::isValid(size))
 84 return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Memory invalid 'initial' page count"))));
 85 minSize = Wasm::PageCount(size);
 86 }
 87
 88 Wasm::PageCount maxSize;
 89 {
 90 Identifier maximum = Identifier::fromString(&vm, "maximum");
 91 bool hasProperty = memoryDescriptor->hasProperty(exec, maximum);
 92 RETURN_IF_EXCEPTION(throwScope, { });
 93 if (hasProperty) {
 94 JSValue maxSizeValue = memoryDescriptor->get(exec, maximum);
 95 RETURN_IF_EXCEPTION(throwScope, { });
 96 uint32_t size = getUint32(maxSizeValue);
 97 if (!Wasm::PageCount::isValid(size))
 98 return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("WebAssembly.Memory invalid 'initial' page count"))));
 99 RETURN_IF_EXCEPTION(throwScope, { });
 100 maxSize = Wasm::PageCount(size);
 101
 102 if (minSize > maxSize) {
 103 return JSValue::encode(throwException(exec, throwScope,
 104 createTypeError(exec, ASCIILiteral("WebAssembly.Memory provided a 'maximum' page count that smaller than the 'initial' page count"))));
 105 }
 106 } else {
 107 // FIXME: what does the spec say to do here.
 108 maxSize = minSize;
 109 }
 110 }
 111
 112 std::unique_ptr<Wasm::Memory> memory = std::make_unique<Wasm::Memory>(minSize, maxSize);
 113
 114 return JSValue::encode(JSWebAssemblyMemory::create(vm, exec->lexicalGlobalObject()->WebAssemblyMemoryStructure(), WTFMove(memory)));
52115}
53116
54117static EncodedJSValue JSC_HOST_CALL callJSWebAssemblyMemory(ExecState* state)
55118{
56119 VM& vm = state->vm();
57  auto scope = DECLARE_THROW_SCOPE(vm);
58  return JSValue::encode(throwConstructorCannotBeCalledAsFunctionTypeError(state, scope, "WebAssembly.Memory"));
 120 auto throwScope = DECLARE_THROW_SCOPE(vm);
 121 return JSValue::encode(throwConstructorCannotBeCalledAsFunctionTypeError(state, throwScope, "WebAssembly.Memory"));
59122}
60123
61124WebAssemblyMemoryConstructor* WebAssemblyMemoryConstructor::create(VM& vm, Structure* structure, WebAssemblyMemoryPrototype* thisPrototype)
209463

Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp

3333#include "JSLexicalEnvironment.h"
3434#include "JSModuleEnvironment.h"
3535#include "JSWebAssemblyInstance.h"
 36#include "JSWebAssemblyMemory.h"
3637#include "JSWebAssemblyModule.h"
3738#include "WasmFormat.h"
3839#include "WebAssemblyFunction.h"

@@void WebAssemblyModuleRecord::visitChild
9899 visitor.append(&thisObject->m_instance);
99100}
100101
101 void WebAssemblyModuleRecord::link(ExecState* state, JSWebAssemblyInstance* instance)
 102void WebAssemblyModuleRecord::link(ExecState* state, JSWebAssemblyInstance* instance, JSObject* dictionary)
102103{
103104 VM& vm = state->vm();
104105 auto scope = DECLARE_THROW_SCOPE(vm);

@@void WebAssemblyModuleRecord::link(ExecS
151152 RELEASE_ASSERT(putResult);
152153 }
153154
 155 bool hasMemory = false;
 156 for (const Wasm::Import& importInfo : moduleInformation.imports) {
 157 JSValue importWrapper = dictionary->get(state, importInfo.module);
 158 RETURN_IF_EXCEPTION(scope, void());
 159 if (!importWrapper.isObject()) {
 160 throwException(state, scope, createTypeError(state, ASCIILiteral("Import not an object")));
 161 return;
 162 }
 163 JSValue import = jsCast<JSObject*>(importWrapper)->get(state, importInfo.field);
 164
 165 switch (importInfo.kind) {
 166 case Wasm::External::Memory: {
 167 RELEASE_ASSERT(!hasMemory); // FIXME: what to do if we import more than one memory?
 168 hasMemory = true;
 169 JSWebAssemblyMemory* memory = jsDynamicCast<JSWebAssemblyMemory*>(import);
 170 if (!memory) {
 171 throwException(state, scope, createTypeError(state, ASCIILiteral("Memory import is not an instance of WebAssembly.Memory")));
 172 return;
 173 }
 174 instance->setMemory(vm, memory);
 175 break;
 176 }
 177
 178 case Wasm::External::Function:
 179 case Wasm::External::Table:
 180 case Wasm::External::Global:
 181 break;
 182 }
 183 }
 184
 185 bool expectsMemory = !!moduleInformation.memory;
 186 if (expectsMemory && !hasMemory) {
 187 throwException(state, scope, createTypeError(state, ASCIILiteral("Module expecting a memory import but one was not provided")));
 188 return;
 189 }
 190
154191 RELEASE_ASSERT(!m_instance);
155192 m_instance.set(vm, this, instance);
156193 m_moduleEnvironment.set(vm, this, moduleEnvironment);
209463

Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.h

@@public:
4646 static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
4747 static WebAssemblyModuleRecord* create(ExecState*, VM&, Structure*, const Identifier&, const Wasm::ModuleInformation&);
4848
49  void link(ExecState*, JSWebAssemblyInstance*);
 49 void link(ExecState*, JSWebAssemblyInstance*, JSObject* dictionary);
5050 JS_EXPORT_PRIVATE JSValue evaluate(ExecState*);
5151
5252private:
209463