JSWebAssemblyHelpers.h [plain text]
#pragma once
#if ENABLE(WEBASSEMBLY)
#include "JSArrayBuffer.h"
#include "JSCJSValue.h"
#include "WebAssemblyFunction.h"
#include "WebAssemblyWrapperFunction.h"
namespace JSC {
ALWAYS_INLINE uint32_t toNonWrappingUint32(ExecState* exec, JSValue value)
{
VM& vm = exec->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
double doubleValue = value.toInteger(exec);
RETURN_IF_EXCEPTION(throwScope, { });
if (doubleValue < 0 || doubleValue > UINT_MAX) {
throwException(exec, throwScope,
createRangeError(exec, ASCIILiteral("Expect an integer argument in the range: [0, 2^32 - 1]")));
return { };
}
return static_cast<uint32_t>(doubleValue);
}
ALWAYS_INLINE uint8_t* getWasmBufferFromValue(ExecState* exec, JSValue value, size_t& byteOffset, size_t& byteSize)
{
VM& vm = exec->vm();
auto throwScope = DECLARE_THROW_SCOPE(vm);
JSArrayBuffer* arrayBuffer = value.getObject() ? jsDynamicCast<JSArrayBuffer*>(vm, value.getObject()) : nullptr;
JSArrayBufferView* arrayBufferView = value.getObject() ? jsDynamicCast<JSArrayBufferView*>(vm, value.getObject()) : nullptr;
if (!(arrayBuffer || arrayBufferView)) {
throwException(exec, throwScope, createTypeError(exec,
ASCIILiteral("first argument must be an ArrayBufferView or an ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(value)));
return nullptr;
}
if (arrayBufferView ? arrayBufferView->isNeutered() : arrayBuffer->impl()->isNeutered()) {
throwException(exec, throwScope, createTypeError(exec,
ASCIILiteral("underlying TypedArray has been detatched from the ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(value)));
return nullptr;
}
byteOffset = arrayBufferView ? arrayBufferView->byteOffset() : 0;
byteSize = arrayBufferView ? arrayBufferView->length() : arrayBuffer->impl()->byteLength();
return arrayBufferView ? static_cast<uint8_t*>(arrayBufferView->vector()) : static_cast<uint8_t*>(arrayBuffer->impl()->data());
}
ALWAYS_INLINE Vector<uint8_t> createSourceBufferFromValue(VM& vm, ExecState* exec, JSValue value)
{
auto throwScope = DECLARE_THROW_SCOPE(vm);
size_t byteOffset;
size_t byteSize;
uint8_t* data = getWasmBufferFromValue(exec, value, byteOffset, byteSize);
RETURN_IF_EXCEPTION(throwScope, Vector<uint8_t>());
Vector<uint8_t> result;
if (!result.tryReserveCapacity(byteSize)) {
throwException(exec, throwScope, createOutOfMemoryError(exec));
return result;
}
result.grow(byteSize);
memcpy(result.data(), data + byteOffset, byteSize);
return result;
}
ALWAYS_INLINE bool isWebAssemblyHostFunction(VM& vm, JSObject* object, WebAssemblyFunction*& wasmFunction, WebAssemblyWrapperFunction*& wasmWrapperFunction)
{
if (object->inherits(vm, WebAssemblyFunction::info())) {
wasmFunction = jsCast<WebAssemblyFunction*>(object);
wasmWrapperFunction = nullptr;
return true;
}
if (object->inherits(vm, WebAssemblyWrapperFunction::info())) {
wasmWrapperFunction = jsCast<WebAssemblyWrapperFunction*>(object);
wasmFunction = nullptr;
return true;
}
return false;
}
ALWAYS_INLINE bool isWebAssemblyHostFunction(VM& vm, JSValue value, WebAssemblyFunction*& wasmFunction, WebAssemblyWrapperFunction*& wasmWrapperFunction)
{
if (!value.isObject())
return false;
return isWebAssemblyHostFunction(vm, jsCast<JSObject*>(value), wasmFunction, wasmWrapperFunction);
}
ALWAYS_INLINE bool isWebAssemblyHostFunction(VM& vm, JSObject* object)
{
WebAssemblyFunction* unused;
WebAssemblyWrapperFunction* unused2;
return isWebAssemblyHostFunction(vm, object, unused, unused2);
}
}
#endif // ENABLE(WEBASSEMBLY)