static EncodedJSValue JSC_HOST_CALL arrayBufferProtoFuncSlice(ExecState* exec) { JSFunction* callee = jsCast<JSFunction*>(exec->callee()); JSArrayBuffer* thisObject = jsDynamicCast<JSArrayBuffer*>(exec->thisValue()); if (!thisObject) return throwVMError(exec, createTypeError(exec, ASCIILiteral("Receiver of slice must be an array buffer."))); if (!exec->argumentCount()) return throwVMError(exec, createTypeError(exec, ASCIILiteral("Slice requires at least one argument."))); int32_t begin = exec->argument(0).toInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); int32_t end; if (exec->argumentCount() >= 2) { end = exec->uncheckedArgument(1).toInt32(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); } else end = thisObject->impl()->byteLength(); RefPtr<ArrayBuffer> newBuffer = thisObject->impl()->slice(begin, end); if (!newBuffer) return throwVMError(exec, createOutOfMemoryError(exec)); Structure* structure = callee->globalObject()->arrayBufferStructure(); JSArrayBuffer* result = JSArrayBuffer::create(exec->vm(), structure, newBuffer); return JSValue::encode(result); }
void WebCoreTypedArrayController::JSArrayBufferOwner::finalize( Handle<JSC::Unknown> handle, void* context) { JSArrayBuffer* jsArrayBuffer = static_cast<JSArrayBuffer*>(handle.get().asCell()); DOMWrapperWorld* world = static_cast<DOMWrapperWorld*>(context); uncacheWrapper(world, jsArrayBuffer->impl(), jsArrayBuffer); jsArrayBuffer->impl()->deref(); }
static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyModule(ExecState* state) { VM& vm = state->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSValue val = state->argument(0); // If the given bytes argument is not a BufferSource, a TypeError exception is thrown. JSArrayBuffer* arrayBuffer = val.getObject() ? jsDynamicCast<JSArrayBuffer*>(val.getObject()) : nullptr; JSArrayBufferView* arrayBufferView = val.getObject() ? jsDynamicCast<JSArrayBufferView*>(val.getObject()) : nullptr; if (!(arrayBuffer || arrayBufferView)) return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("first argument to WebAssembly.Module must be an ArrayBufferView or an ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(val)))); if (arrayBufferView ? arrayBufferView->isNeutered() : arrayBuffer->impl()->isNeutered()) return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("underlying TypedArray has been detatched from the ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(val)))); size_t byteOffset = arrayBufferView ? arrayBufferView->byteOffset() : 0; size_t byteSize = arrayBufferView ? arrayBufferView->length() : arrayBuffer->impl()->byteLength(); const auto* base = arrayBufferView ? static_cast<uint8_t*>(arrayBufferView->vector()) : static_cast<uint8_t*>(arrayBuffer->impl()->data()); Wasm::Plan plan(&vm, base + byteOffset, byteSize); // On failure, a new WebAssembly.CompileError is thrown. plan.run(); if (plan.failed()) return JSValue::encode(throwException(state, scope, createWebAssemblyCompileError(state, plan.errorMessage()))); // On success, a new WebAssembly.Module object is returned with [[Module]] set to the validated Ast.module. auto* structure = InternalFunction::createSubclassStructure(state, state->newTarget(), asInternalFunction(state->jsCallee())->globalObject()->WebAssemblyModuleStructure()); RETURN_IF_EXCEPTION(scope, { }); // The export symbol table is the same for all Instances of a Module. SymbolTable* exportSymbolTable = SymbolTable::create(vm); for (auto& exp : plan.exports()) { auto offset = exportSymbolTable->takeNextScopeOffset(NoLockingNecessary); exportSymbolTable->set(NoLockingNecessary, exp.field.impl(), SymbolTableEntry(VarOffset(offset))); } // Only wasm-internal functions have a callee, stubs to JS do not. unsigned calleeCount = plan.internalFunctionCount(); JSWebAssemblyModule* result = JSWebAssemblyModule::create(vm, structure, plan.takeModuleInformation(), plan.takeCallLinkInfos(), plan.takeWasmToJSStubs(), plan.takeFunctionIndexSpace(), exportSymbolTable, calleeCount); plan.initializeCallees(state->jsCallee()->globalObject(), [&] (unsigned calleeIndex, JSWebAssemblyCallee* jsEntrypointCallee, JSWebAssemblyCallee* wasmEntrypointCallee) { result->setJSEntrypointCallee(vm, calleeIndex, jsEntrypointCallee); result->setWasmEntrypointCallee(vm, calleeIndex, wasmEntrypointCallee); }); return JSValue::encode(result); }
bool WebCoreTypedArrayController::JSArrayBufferOwner::isReachableFromOpaqueRoots( Handle<JSC::Unknown> handle, void*, SlotVisitor& visitor) { JSArrayBuffer* jsArrayBuffer = jsCast<JSArrayBuffer*>(handle.get().asCell()); if (!jsArrayBuffer->hasCustomProperties()) return false; ArrayBuffer* root = jsArrayBuffer->impl(); return visitor.containsOpaqueRoot(root); }
bool JSArrayBuffer::getOwnPropertySlot( JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { JSArrayBuffer* thisObject = jsCast<JSArrayBuffer*>(object); if (propertyName == exec->propertyNames().byteLength) { slot.setValue(thisObject, DontDelete | ReadOnly, jsNumber(thisObject->impl()->byteLength())); return true; } return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot); }
EncodedJSValue JSC_HOST_CALL functionTransferArrayBuffer(ExecState* exec) { if (exec->argumentCount() < 1) return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Not enough arguments"))); JSArrayBuffer* buffer = jsDynamicCast<JSArrayBuffer*>(exec->argument(0)); if (!buffer) return JSValue::encode(exec->vm().throwException(exec, createError(exec, "Expected an array buffer"))); ArrayBufferContents dummyContents; buffer->impl()->transfer(dummyContents); return JSValue::encode(jsUndefined()); }
size_t JSArrayBuffer::estimatedSize(JSCell* cell) { JSArrayBuffer* thisObject = jsCast<JSArrayBuffer*>(cell); size_t bufferEstimatedSize = thisObject->impl()->gcSizeEstimateInBytes(); return Base::estimatedSize(cell) + bufferEstimatedSize; }