RefPtr<ArrayBuffer> ArrayBuffer::sliceImpl(unsigned begin, unsigned end) const { unsigned size = begin <= end ? end - begin : 0; RefPtr<ArrayBuffer> result = ArrayBuffer::create(static_cast<const char*>(data()) + begin, size); result->setSharingMode(sharingMode()); return result; }
static EncodedJSValue JSC_HOST_CALL constructArrayBuffer(ExecState* exec) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSArrayBufferConstructor* constructor = jsCast<JSArrayBufferConstructor*>(exec->jsCallee()); unsigned length; if (exec->argumentCount()) { length = exec->uncheckedArgument(0).toIndex(exec, "length"); RETURN_IF_EXCEPTION(scope, encodedJSValue()); } else { // Although the documentation doesn't say so, it is in fact correct to say // "new ArrayBuffer()". The result is the same as allocating an array buffer // with a zero length. length = 0; } auto buffer = ArrayBuffer::tryCreate(length, 1); if (!buffer) return JSValue::encode(throwOutOfMemoryError(exec, scope)); if (constructor->sharingMode() == ArrayBufferSharingMode::Shared) buffer->makeShared(); ASSERT(constructor->sharingMode() == buffer->sharingMode()); Structure* arrayBufferStructure = InternalFunction::createSubclassStructure(exec, exec->newTarget(), constructor->globalObject()->arrayBufferStructure(constructor->sharingMode())); RETURN_IF_EXCEPTION(scope, encodedJSValue()); JSArrayBuffer* result = JSArrayBuffer::create(vm, arrayBufferStructure, WTFMove(buffer)); return JSValue::encode(result); }
void ArrayBuffer::setSharingMode(ArrayBufferSharingMode newSharingMode) { if (newSharingMode == sharingMode()) return; RELEASE_ASSERT(!isShared()); // Cannot revert sharing. RELEASE_ASSERT(newSharingMode == ArrayBufferSharingMode::Shared); makeShared(); }