Example #1
0
inline ArrayBuffer* toArrayBufferView(JSValue value)
{
    JSArrayBufferView* wrapper = jsDynamicCast<JSArrayBufferView*>(value);
    if (!wrapper)
        return 0;
	return wrapper->buffer();
}
bool ArrayBuffer::transfer(ArrayBufferContents& result)
{
    Ref<ArrayBuffer> protect(*this);

    if (!m_contents.m_data) {
        result.m_data = 0;
        return false;
    }

    bool isNeuterable = !m_pinCount;

    if (isNeuterable)
        m_contents.transfer(result);
    else {
        m_contents.copyTo(result);
        if (!result.m_data)
            return false;
    }

    for (size_t i = numberOfIncomingReferences(); i--;) {
        JSArrayBufferView* view = jsDynamicCast<JSArrayBufferView*>(incomingReferenceAt(i));
        if (view)
            view->neuter();
    }
    return true;
}
Example #3
0
void JSArrayBufferView::visitChildren(JSCell* cell, SlotVisitor& visitor)
{
    JSArrayBufferView* thisObject = jsCast<JSArrayBufferView*>(cell);

    if (thisObject->hasArrayBuffer()) {
        ArrayBuffer* buffer = thisObject->buffer();
        RELEASE_ASSERT(buffer);
        visitor.addOpaqueRoot(buffer);
    }
    
    Base::visitChildren(thisObject, visitor);
}
EncodedJSValue JSC_HOST_CALL typedArrayViewPrivateFuncLength(ExecState* exec)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    JSValue argument = exec->argument(0);
    if (!argument.isCell() || !isTypedView(argument.asCell()->classInfo()->typedArrayStorageType))
        return throwVMTypeError(exec, scope, ASCIILiteral("Receiver should be a typed array view"));

    JSArrayBufferView* thisObject = jsCast<JSArrayBufferView*>(argument);

    if (thisObject->isNeutered())
        return throwVMTypeError(exec, scope, ASCIILiteral("Underlying ArrayBuffer has been detached from the view"));

    return JSValue::encode(jsNumber(thisObject->length()));
}
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);
}
Example #6
0
bool JSArrayBufferView::getOwnPropertySlot(
    JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
    JSArrayBufferView* thisObject = jsCast<JSArrayBufferView*>(object);
    if (propertyName == exec->propertyNames().byteOffset) {
        slot.setValue(thisObject, DontDelete | ReadOnly, jsNumber(thisObject->byteOffset()));
        return true;
    }
    
    if (propertyName == exec->propertyNames().buffer) {
        slot.setValue(
            thisObject, DontDelete | ReadOnly, exec->vm().m_typedArrayController->toJS(
                exec, thisObject->globalObject(), thisObject->buffer()));
        return true;
    }
    
    return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
}