JSGenericTypedArrayViewConstructorInlines.h [plain text]
#ifndef JSGenericTypedArrayViewConstructorInlines_h
#define JSGenericTypedArrayViewConstructorInlines_h
#include "Error.h"
#include "JSArrayBuffer.h"
#include "JSGenericTypedArrayViewConstructor.h"
#include "JSGlobalObject.h"
namespace JSC {
template<typename ViewClass>
JSGenericTypedArrayViewConstructor<ViewClass>::JSGenericTypedArrayViewConstructor(VM& vm, Structure* structure)
: Base(vm, structure)
{
}
template<typename ViewClass>
void JSGenericTypedArrayViewConstructor<ViewClass>::finishCreation(VM& vm, JSObject* prototype, const String& name)
{
Base::finishCreation(vm, name);
putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, DontEnum | DontDelete | ReadOnly);
putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(3), DontEnum | DontDelete | ReadOnly);
putDirectWithoutTransition(vm, vm.propertyNames->BYTES_PER_ELEMENT, jsNumber(ViewClass::elementSize), DontEnum | ReadOnly | DontDelete);
}
template<typename ViewClass>
JSGenericTypedArrayViewConstructor<ViewClass>*
JSGenericTypedArrayViewConstructor<ViewClass>::create(
VM& vm, Structure* structure, JSObject* prototype,
const String& name)
{
JSGenericTypedArrayViewConstructor* result =
new (NotNull, allocateCell<JSGenericTypedArrayViewConstructor>(vm.heap))
JSGenericTypedArrayViewConstructor(vm, structure);
result->finishCreation(vm, prototype, name);
return result;
}
template<typename ViewClass>
Structure* JSGenericTypedArrayViewConstructor<ViewClass>::createStructure(
VM& vm, JSGlobalObject* globalObject, JSValue prototype)
{
return Structure::create(
vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
}
template<typename ViewClass>
static EncodedJSValue JSC_HOST_CALL constructGenericTypedArrayView(ExecState* exec)
{
Structure* structure =
asInternalFunction(exec->callee())->globalObject()->typedArrayStructure(
ViewClass::TypedArrayStorageType);
if (!exec->argumentCount()) {
if (ViewClass::TypedArrayStorageType == TypeDataView)
return throwVMError(exec, createTypeError(exec, "DataView constructor requires at least one argument."));
return JSValue::encode(ViewClass::create(exec, structure, 0));
}
if (JSArrayBuffer* jsBuffer = jsDynamicCast<JSArrayBuffer*>(exec->argument(0))) {
RefPtr<ArrayBuffer> buffer = jsBuffer->impl();
unsigned offset = (exec->argumentCount() > 1) ? exec->uncheckedArgument(1).toUInt32(exec) : 0;
if (exec->hadException())
return JSValue::encode(jsUndefined());
unsigned length = 0;
if (exec->argumentCount() > 2) {
length = exec->uncheckedArgument(2).toUInt32(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
} else {
if ((buffer->byteLength() - offset) % ViewClass::elementSize)
return throwVMError(exec, createRangeError(exec, "ArrayBuffer length minus the byteOffset is not a multiple of the element size"));
length = (buffer->byteLength() - offset) / ViewClass::elementSize;
}
return JSValue::encode(ViewClass::create(exec, structure, buffer, offset, length));
}
if (ViewClass::TypedArrayStorageType == TypeDataView)
return throwVMError(exec, createTypeError(exec, "Expected ArrayBuffer for the first argument."));
if (JSObject* object = jsDynamicCast<JSObject*>(exec->uncheckedArgument(0))) {
unsigned length =
object->get(exec, exec->vm().propertyNames->length).toUInt32(exec);
if (exec->hadException())
return JSValue::encode(jsUndefined());
ViewClass* result = ViewClass::createUninitialized(exec, structure, length);
if (!result) {
ASSERT(exec->hadException());
return JSValue::encode(jsUndefined());
}
if (!result->set(exec, object, 0, length))
return JSValue::encode(jsUndefined());
return JSValue::encode(result);
}
int length;
if (exec->uncheckedArgument(0).isInt32())
length = exec->uncheckedArgument(0).asInt32();
else if (!exec->uncheckedArgument(0).isNumber())
return throwVMError(exec, createTypeError(exec, "Invalid array length argument"));
else {
length = static_cast<int>(exec->uncheckedArgument(0).asNumber());
if (length != exec->uncheckedArgument(0).asNumber())
return throwVMError(exec, createTypeError(exec, "Invalid array length argument (fractional lengths not allowed)"));
}
if (length < 0)
return throwVMError(exec, createRangeError(exec, "Requested length is negative"));
return JSValue::encode(ViewClass::create(exec, structure, length));
}
template<typename ViewClass>
ConstructType JSGenericTypedArrayViewConstructor<ViewClass>::getConstructData(JSCell*, ConstructData& constructData)
{
constructData.native.function = constructGenericTypedArrayView<ViewClass>;
return ConstructTypeHost;
}
template<typename ViewClass>
CallType JSGenericTypedArrayViewConstructor<ViewClass>::getCallData(JSCell*, CallData& callData)
{
callData.native.function = constructGenericTypedArrayView<ViewClass>;
return CallTypeNone;
}
}
#endif // JSGenericTypedArrayViewConstructorInlines_h