// asm.js module instantiation supplies its own buffer, but for wasm, create and // initialize the buffer if one is requested. Either way, the buffer is wrapped // in a WebAssembly.Memory object which is what the Instance stores. bool Module::instantiateMemory(JSContext* cx, MutableHandleWasmMemoryObject memory) const { if (!metadata_->usesMemory()) { MOZ_ASSERT(!memory); MOZ_ASSERT(dataSegments_.empty()); return true; } RootedArrayBufferObjectMaybeShared buffer(cx); if (memory) { buffer = &memory->buffer(); uint32_t length = buffer->byteLength(); if (length < metadata_->minMemoryLength || length > metadata_->maxMemoryLength) { JS_ReportErrorNumber(cx, GetErrorMessage, nullptr, JSMSG_WASM_BAD_IMP_SIZE, "Memory"); return false; } // This can't happen except via the shell toggling signals.enabled. if (metadata_->assumptions.usesSignal.forOOB && !buffer->is<SharedArrayBufferObject>() && !buffer->as<ArrayBufferObject>().isWasmMapped()) { JS_ReportError(cx, "can't access same buffer with and without signals enabled"); return false; } } else { buffer = ArrayBufferObject::createForWasm(cx, metadata_->minMemoryLength, metadata_->assumptions.usesSignal.forOOB); if (!buffer) return false; RootedObject proto(cx); if (metadata_->assumptions.newFormat) proto = &cx->global()->getPrototype(JSProto_WasmMemory).toObject(); memory.set(WasmMemoryObject::create(cx, buffer, proto)); if (!memory) return false; } MOZ_ASSERT(buffer->is<SharedArrayBufferObject>() || buffer->as<ArrayBufferObject>().isWasm()); uint8_t* memoryBase = memory->buffer().dataPointerEither().unwrap(/* memcpy */); for (const DataSegment& seg : dataSegments_) memcpy(memoryBase + seg.memoryOffset, bytecode_->begin() + seg.bytecodeOffset, seg.length); return true; }
// asm.js module instantiation supplies its own buffer, but for wasm, create and // initialize the buffer if one is requested. Either way, the buffer is wrapped // in a WebAssembly.Memory object which is what the Instance stores. bool Module::instantiateMemory(JSContext* cx, MutableHandleWasmMemoryObject memory) const { if (!metadata_->usesMemory()) { MOZ_ASSERT(!memory); MOZ_ASSERT(dataSegments_.empty()); return true; } uint32_t declaredMin = metadata_->minMemoryLength; Maybe<uint32_t> declaredMax = metadata_->maxMemoryLength; if (memory) { ArrayBufferObjectMaybeShared& buffer = memory->buffer(); MOZ_ASSERT_IF(metadata_->isAsmJS(), buffer.isPreparedForAsmJS()); MOZ_ASSERT_IF(!metadata_->isAsmJS(), buffer.as<ArrayBufferObject>().isWasm()); if (!CheckLimits(cx, declaredMin, declaredMax, buffer.byteLength(), buffer.wasmMaxSize(), metadata_->isAsmJS(), "Memory")) { return false; } } else { MOZ_ASSERT(!metadata_->isAsmJS()); MOZ_ASSERT(metadata_->memoryUsage == MemoryUsage::Unshared); RootedArrayBufferObjectMaybeShared buffer(cx, ArrayBufferObject::createForWasm(cx, declaredMin, declaredMax)); if (!buffer) return false; RootedObject proto(cx, &cx->global()->getPrototype(JSProto_WasmMemory).toObject()); memory.set(WasmMemoryObject::create(cx, buffer, proto)); if (!memory) return false; } return true; }