mirror of
https://github.com/overte-org/overte.git
synced 2025-04-23 15:13:41 +02:00
Added JS exceptions + fixed up floating precision mess up
This commit is contained in:
parent
d456adff1d
commit
b9fe5b2ef1
7 changed files with 105 additions and 52 deletions
|
@ -48,7 +48,17 @@ _scriptEngine(scriptEngine) {
|
|||
engine()->globalObject().setProperty(name(), _ctor);
|
||||
}
|
||||
|
||||
QScriptValue ArrayBufferClass::newInstance(quint32 size) {
|
||||
QScriptValue ArrayBufferClass::newInstance(qint32 size) {
|
||||
const qint32 MAX_LENGTH = 100000000;
|
||||
if (size < 0) {
|
||||
engine()->evaluate("throw \"ArgumentError: negative length\"");
|
||||
return QScriptValue();
|
||||
}
|
||||
if (size > MAX_LENGTH) {
|
||||
engine()->evaluate("throw \"ArgumentError: absurd length\"");
|
||||
return QScriptValue();
|
||||
}
|
||||
|
||||
engine()->reportAdditionalMemoryCost(size);
|
||||
QScriptEngine* eng = engine();
|
||||
QVariant variant = QVariant::fromValue(QByteArray(size, 0));
|
||||
|
|
|
@ -26,7 +26,7 @@ class ArrayBufferClass : public QObject, public QScriptClass {
|
|||
Q_OBJECT
|
||||
public:
|
||||
ArrayBufferClass(ScriptEngine* scriptEngine);
|
||||
QScriptValue newInstance(quint32 size);
|
||||
QScriptValue newInstance(qint32 size);
|
||||
QScriptValue newInstance(const QByteArray& ba);
|
||||
|
||||
ScriptEngine* getScriptEngine() { return _scriptEngine; }
|
||||
|
|
|
@ -64,7 +64,7 @@ QScriptValue DataViewClass::construct(QScriptContext *context, QScriptEngine *en
|
|||
}
|
||||
if (byteOffsetArg.isNumber() &&
|
||||
(byteOffsetArg.toInt32() < 0 ||
|
||||
byteOffsetArg.toInt32() >= arrayBuffer->size())) {
|
||||
byteOffsetArg.toInt32() > arrayBuffer->size())) {
|
||||
engine->evaluate("throw \"RangeError: byteOffset out of range\"");
|
||||
return QScriptValue();
|
||||
}
|
||||
|
|
|
@ -26,7 +26,10 @@ QByteArray* DataViewPrototype::thisArrayBuffer() const {
|
|||
return qscriptvalue_cast<QByteArray*>(bufferObject.data());
|
||||
}
|
||||
|
||||
bool DataViewPrototype::realOffset(quint32& offset, size_t size) const {
|
||||
bool DataViewPrototype::realOffset(qint32& offset, size_t size) const {
|
||||
if (offset < 0) {
|
||||
return false;
|
||||
}
|
||||
quint32 viewOffset = thisObject().data().property(BYTE_OFFSET_PROPERTY_NAME).toInt32();
|
||||
quint32 viewLength = thisObject().data().property(BYTE_LENGTH_PROPERTY_NAME).toInt32();
|
||||
//qDebug() << "View Offset: " << viewOffset << ", View Lenght: " << viewLength;
|
||||
|
@ -38,7 +41,7 @@ bool DataViewPrototype::realOffset(quint32& offset, size_t size) const {
|
|||
|
||||
///////////////// GETTERS ////////////////////////////
|
||||
|
||||
qint32 DataViewPrototype::getInt8(quint32 byteOffset) {
|
||||
qint32 DataViewPrototype::getInt8(qint32 byteOffset) {
|
||||
if (realOffset(byteOffset, sizeof(qint8))) {
|
||||
QDataStream stream(*thisArrayBuffer());
|
||||
stream.skipRawData(byteOffset);
|
||||
|
@ -51,7 +54,7 @@ qint32 DataViewPrototype::getInt8(quint32 byteOffset) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
quint32 DataViewPrototype::getUint8(quint32 byteOffset) {
|
||||
quint32 DataViewPrototype::getUint8(qint32 byteOffset) {
|
||||
if (realOffset(byteOffset, sizeof(quint8))) {
|
||||
QDataStream stream(*thisArrayBuffer());
|
||||
stream.skipRawData(byteOffset);
|
||||
|
@ -64,7 +67,7 @@ quint32 DataViewPrototype::getUint8(quint32 byteOffset) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
qint32 DataViewPrototype::getInt16(quint32 byteOffset, bool littleEndian) {
|
||||
qint32 DataViewPrototype::getInt16(qint32 byteOffset, bool littleEndian) {
|
||||
if (realOffset(byteOffset, sizeof(qint16))) {
|
||||
QDataStream stream(*thisArrayBuffer());
|
||||
stream.skipRawData(byteOffset);
|
||||
|
@ -78,7 +81,7 @@ qint32 DataViewPrototype::getInt16(quint32 byteOffset, bool littleEndian) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
quint32 DataViewPrototype::getUint16(quint32 byteOffset, bool littleEndian) {
|
||||
quint32 DataViewPrototype::getUint16(qint32 byteOffset, bool littleEndian) {
|
||||
if (realOffset(byteOffset, sizeof(quint16))) {
|
||||
QDataStream stream(*thisArrayBuffer());
|
||||
stream.skipRawData(byteOffset);
|
||||
|
@ -92,7 +95,7 @@ quint32 DataViewPrototype::getUint16(quint32 byteOffset, bool littleEndian) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
qint32 DataViewPrototype::getInt32(quint32 byteOffset, bool littleEndian) {
|
||||
qint32 DataViewPrototype::getInt32(qint32 byteOffset, bool littleEndian) {
|
||||
if (realOffset(byteOffset, sizeof(qint32))) {
|
||||
QDataStream stream(*thisArrayBuffer());
|
||||
stream.skipRawData(byteOffset);
|
||||
|
@ -106,7 +109,7 @@ qint32 DataViewPrototype::getInt32(quint32 byteOffset, bool littleEndian) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
quint32 DataViewPrototype::getUint32(quint32 byteOffset, bool littleEndian) {
|
||||
quint32 DataViewPrototype::getUint32(qint32 byteOffset, bool littleEndian) {
|
||||
if (realOffset(byteOffset, sizeof(quint32))) {
|
||||
QDataStream stream(*thisArrayBuffer());
|
||||
stream.skipRawData(byteOffset);
|
||||
|
@ -120,25 +123,28 @@ quint32 DataViewPrototype::getUint32(quint32 byteOffset, bool littleEndian) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
float DataViewPrototype::getFloat32(quint32 byteOffset, bool littleEndian) {
|
||||
float DataViewPrototype::getFloat32(qint32 byteOffset, bool littleEndian) {
|
||||
if (realOffset(byteOffset, sizeof(float))) {
|
||||
QDataStream stream(*thisArrayBuffer());
|
||||
stream.skipRawData(byteOffset);
|
||||
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
|
||||
stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
|
||||
|
||||
float result;
|
||||
stream >> result;
|
||||
qDebug() << "Get: " << result;
|
||||
return result;
|
||||
}
|
||||
thisObject().engine()->evaluate("throw \"RangeError: byteOffset out of range\"");
|
||||
return 0;
|
||||
}
|
||||
|
||||
double DataViewPrototype::getFloat64(quint32 byteOffset, bool littleEndian) {
|
||||
double DataViewPrototype::getFloat64(qint32 byteOffset, bool littleEndian) {
|
||||
if (realOffset(byteOffset, sizeof(double))) {
|
||||
QDataStream stream(*thisArrayBuffer());
|
||||
stream.skipRawData(byteOffset);
|
||||
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
|
||||
stream.setFloatingPointPrecision(QDataStream::DoublePrecision);
|
||||
|
||||
double result;
|
||||
stream >> result;
|
||||
|
@ -150,7 +156,7 @@ double DataViewPrototype::getFloat64(quint32 byteOffset, bool littleEndian) {
|
|||
|
||||
///////////////// SETTERS ////////////////////////////
|
||||
|
||||
void DataViewPrototype::setInt8(quint32 byteOffset, qint32 value) {
|
||||
void DataViewPrototype::setInt8(qint32 byteOffset, qint32 value) {
|
||||
if (realOffset(byteOffset, sizeof(qint8))) {
|
||||
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
|
||||
stream.skipRawData(byteOffset);
|
||||
|
@ -161,7 +167,7 @@ void DataViewPrototype::setInt8(quint32 byteOffset, qint32 value) {
|
|||
}
|
||||
}
|
||||
|
||||
void DataViewPrototype::setUint8(quint32 byteOffset, quint32 value) {
|
||||
void DataViewPrototype::setUint8(qint32 byteOffset, quint32 value) {
|
||||
if (realOffset(byteOffset, sizeof(quint8))) {
|
||||
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
|
||||
stream.skipRawData(byteOffset);
|
||||
|
@ -172,7 +178,7 @@ void DataViewPrototype::setUint8(quint32 byteOffset, quint32 value) {
|
|||
}
|
||||
}
|
||||
|
||||
void DataViewPrototype::setInt16(quint32 byteOffset, qint32 value, bool littleEndian) {
|
||||
void DataViewPrototype::setInt16(qint32 byteOffset, qint32 value, bool littleEndian) {
|
||||
if (realOffset(byteOffset, sizeof(qint16))) {
|
||||
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
|
||||
stream.skipRawData(byteOffset);
|
||||
|
@ -184,7 +190,7 @@ void DataViewPrototype::setInt16(quint32 byteOffset, qint32 value, bool littleEn
|
|||
}
|
||||
}
|
||||
|
||||
void DataViewPrototype::setUint16(quint32 byteOffset, quint32 value, bool littleEndian) {
|
||||
void DataViewPrototype::setUint16(qint32 byteOffset, quint32 value, bool littleEndian) {
|
||||
if (realOffset(byteOffset, sizeof(quint16))) {
|
||||
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
|
||||
stream.skipRawData(byteOffset);
|
||||
|
@ -196,7 +202,7 @@ void DataViewPrototype::setUint16(quint32 byteOffset, quint32 value, bool little
|
|||
}
|
||||
}
|
||||
|
||||
void DataViewPrototype::setInt32(quint32 byteOffset, qint32 value, bool littleEndian) {
|
||||
void DataViewPrototype::setInt32(qint32 byteOffset, qint32 value, bool littleEndian) {
|
||||
if (realOffset(byteOffset, sizeof(qint32))) {
|
||||
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
|
||||
stream.skipRawData(byteOffset);
|
||||
|
@ -208,7 +214,7 @@ void DataViewPrototype::setInt32(quint32 byteOffset, qint32 value, bool littleEn
|
|||
}
|
||||
}
|
||||
|
||||
void DataViewPrototype::setUint32(quint32 byteOffset, quint32 value, bool littleEndian) {
|
||||
void DataViewPrototype::setUint32(qint32 byteOffset, quint32 value, bool littleEndian) {
|
||||
if (realOffset(byteOffset, sizeof(quint32))) {
|
||||
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
|
||||
stream.skipRawData(byteOffset);
|
||||
|
@ -220,11 +226,12 @@ void DataViewPrototype::setUint32(quint32 byteOffset, quint32 value, bool little
|
|||
}
|
||||
}
|
||||
|
||||
void DataViewPrototype::setFloat32(quint32 byteOffset, float value, bool littleEndian) {
|
||||
void DataViewPrototype::setFloat32(qint32 byteOffset, float value, bool littleEndian) {
|
||||
if (realOffset(byteOffset, sizeof(float))) {
|
||||
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
|
||||
stream.skipRawData(byteOffset);
|
||||
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
|
||||
stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
|
||||
|
||||
stream << value;
|
||||
} else {
|
||||
|
@ -232,11 +239,12 @@ void DataViewPrototype::setFloat32(quint32 byteOffset, float value, bool littleE
|
|||
}
|
||||
}
|
||||
|
||||
void DataViewPrototype::setFloat64(quint32 byteOffset, double value, bool littleEndian) {
|
||||
void DataViewPrototype::setFloat64(qint32 byteOffset, double value, bool littleEndian) {
|
||||
if (realOffset(byteOffset, sizeof(double))) {
|
||||
QDataStream stream(thisArrayBuffer(), QIODevice::ReadWrite);
|
||||
stream.skipRawData(byteOffset);
|
||||
stream.setByteOrder((littleEndian) ? QDataStream::LittleEndian : QDataStream::BigEndian);
|
||||
stream.setFloatingPointPrecision(QDataStream::DoublePrecision);
|
||||
|
||||
stream << value;
|
||||
} else {
|
||||
|
|
|
@ -31,14 +31,14 @@ public slots:
|
|||
//
|
||||
// These methods raise an exception if they would read
|
||||
// beyond the end of the view.
|
||||
qint32 getInt8(quint32 byteOffset);
|
||||
quint32 getUint8(quint32 byteOffset);
|
||||
qint32 getInt16(quint32 byteOffset, bool littleEndian = false);
|
||||
quint32 getUint16(quint32 byteOffset, bool littleEndian = false);
|
||||
qint32 getInt32(quint32 byteOffset, bool littleEndian = false);
|
||||
quint32 getUint32(quint32 byteOffset, bool littleEndian = false);
|
||||
float getFloat32(quint32 byteOffset, bool littleEndian = false);
|
||||
double getFloat64(quint32 byteOffset, bool littleEndian = false);
|
||||
qint32 getInt8(qint32 byteOffset);
|
||||
quint32 getUint8(qint32 byteOffset);
|
||||
qint32 getInt16(qint32 byteOffset, bool littleEndian = false);
|
||||
quint32 getUint16(qint32 byteOffset, bool littleEndian = false);
|
||||
qint32 getInt32(qint32 byteOffset, bool littleEndian = false);
|
||||
quint32 getUint32(qint32 byteOffset, bool littleEndian = false);
|
||||
float getFloat32(qint32 byteOffset, bool littleEndian = false);
|
||||
double getFloat64(qint32 byteOffset, bool littleEndian = false);
|
||||
|
||||
// Stores a value of the given type at the specified byte offset
|
||||
// from the start of the view. There is no alignment constraint;
|
||||
|
@ -51,18 +51,18 @@ public slots:
|
|||
//
|
||||
// These methods raise an exception if they would write
|
||||
// beyond the end of the view.
|
||||
void setInt8(quint32 byteOffset, qint32 value);
|
||||
void setUint8(quint32 byteOffset, quint32 value);
|
||||
void setInt16(quint32 byteOffset, qint32 value, bool littleEndian = false);
|
||||
void setUint16(quint32 byteOffset, quint32 value, bool littleEndian = false);
|
||||
void setInt32(quint32 byteOffset, qint32 value, bool littleEndian = false);
|
||||
void setUint32(quint32 byteOffset, quint32 value, bool littleEndian = false);
|
||||
void setFloat32(quint32 byteOffset, float value, bool littleEndian = false);
|
||||
void setFloat64(quint32 byteOffset, double value, bool littleEndian = false);
|
||||
void setInt8(qint32 byteOffset, qint32 value);
|
||||
void setUint8(qint32 byteOffset, quint32 value);
|
||||
void setInt16(qint32 byteOffset, qint32 value, bool littleEndian = false);
|
||||
void setUint16(qint32 byteOffset, quint32 value, bool littleEndian = false);
|
||||
void setInt32(qint32 byteOffset, qint32 value, bool littleEndian = false);
|
||||
void setUint32(qint32 byteOffset, quint32 value, bool littleEndian = false);
|
||||
void setFloat32(qint32 byteOffset, float value, bool littleEndian = false);
|
||||
void setFloat64(qint32 byteOffset, double value, bool littleEndian = false);
|
||||
|
||||
private:
|
||||
QByteArray* thisArrayBuffer() const;
|
||||
bool realOffset(quint32& offset, size_t size) const;
|
||||
bool realOffset(qint32& offset, size_t size) const;
|
||||
};
|
||||
|
||||
#endif // hifi_DataViewPrototype_h
|
|
@ -56,6 +56,7 @@ QScriptValue TypedArray::newInstance(QScriptValue array) {
|
|||
}
|
||||
return newArray;
|
||||
}
|
||||
engine()->evaluate("throw \"ArgumentError: not an array\"");
|
||||
return QScriptValue();
|
||||
}
|
||||
|
||||
|
@ -200,19 +201,23 @@ QByteArray* TypedArrayPrototype::thisArrayBuffer() const {
|
|||
return qscriptvalue_cast<QByteArray*>(bufferObject.data());
|
||||
}
|
||||
|
||||
void TypedArrayPrototype::set(QScriptValue array, quint32 offset) {
|
||||
void TypedArrayPrototype::set(QScriptValue array, qint32 offset) {
|
||||
TypedArray* typedArray = static_cast<TypedArray*>(parent());
|
||||
if (array.isArray()) {
|
||||
if (array.isArray() || typedArray) {
|
||||
if (offset < 0) {
|
||||
engine()->evaluate("throw \"ArgumentError: negative offset\"");
|
||||
}
|
||||
quint32 length = array.property("length").toInt32();
|
||||
if (offset + length > thisObject().data().property(typedArray->_lengthName).toInt32()) {
|
||||
// TODO throw an error maybe?
|
||||
engine()->evaluate("throw \"ArgumentError: array does not fit\"");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < length; ++i) {
|
||||
thisObject().setProperty(QString::number(offset + i), array.property(QString::number(i)));
|
||||
}
|
||||
} else {
|
||||
engine()->evaluate("throw \"ArgumentError: not an array\"");
|
||||
}
|
||||
// TODO handle typed arrays
|
||||
}
|
||||
|
||||
QScriptValue TypedArrayPrototype::subarray(qint32 begin) {
|
||||
|
@ -411,15 +416,31 @@ Float32ArrayClass::Float32ArrayClass(ScriptEngine* scriptEngine) : TypedArray(sc
|
|||
|
||||
QScriptValue Float32ArrayClass::property(const QScriptValue &object, const QScriptString &name, uint id) {
|
||||
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
QScriptValue result = propertyHelper<float>(arrayBuffer, name, id);
|
||||
return (result.isValid()) ? result : TypedArray::property(object, name, id);
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());bool ok = false;
|
||||
name.toArrayIndex(&ok);
|
||||
|
||||
if (ok && arrayBuffer) {
|
||||
QDataStream stream(*arrayBuffer);
|
||||
stream.skipRawData(id);
|
||||
stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
|
||||
|
||||
float result;
|
||||
stream >> result;
|
||||
return result;
|
||||
}
|
||||
return TypedArray::property(object, name, id);
|
||||
}
|
||||
|
||||
void Float32ArrayClass::setProperty(QScriptValue &object, const QScriptString &name,
|
||||
uint id, const QScriptValue &value) {
|
||||
QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
setPropertyHelper<float>(ba, name, id, value);
|
||||
if (ba && value.isNumber()) {
|
||||
QDataStream stream(ba, QIODevice::ReadWrite);
|
||||
stream.skipRawData(id);
|
||||
stream.setFloatingPointPrecision(QDataStream::SinglePrecision);
|
||||
|
||||
stream << (float)value.toNumber();
|
||||
}
|
||||
}
|
||||
|
||||
Float64ArrayClass::Float64ArrayClass(ScriptEngine* scriptEngine) : TypedArray(scriptEngine, FLOAT_64_ARRAY_CLASS_NAME) {
|
||||
|
@ -428,16 +449,30 @@ Float64ArrayClass::Float64ArrayClass(ScriptEngine* scriptEngine) : TypedArray(sc
|
|||
|
||||
QScriptValue Float64ArrayClass::property(const QScriptValue &object, const QScriptString &name, uint id) {
|
||||
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
QScriptValue result = propertyHelper<double>(arrayBuffer, name, id);
|
||||
return (result.isValid()) ? result : TypedArray::property(object, name, id);
|
||||
QByteArray* arrayBuffer = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());bool ok = false;
|
||||
name.toArrayIndex(&ok);
|
||||
|
||||
if (ok && arrayBuffer) {
|
||||
QDataStream stream(*arrayBuffer);
|
||||
stream.skipRawData(id);
|
||||
stream.setFloatingPointPrecision(QDataStream::DoublePrecision);
|
||||
|
||||
double result;
|
||||
stream >> result;
|
||||
return result;
|
||||
}
|
||||
return TypedArray::property(object, name, id);
|
||||
}
|
||||
|
||||
void Float64ArrayClass::setProperty(QScriptValue &object, const QScriptString &name,
|
||||
uint id, const QScriptValue &value) {
|
||||
QByteArray *ba = qscriptvalue_cast<QByteArray*>(object.data().property(_bufferName).data());
|
||||
setPropertyHelper<double>(ba, name, id, value);
|
||||
if (ba && value.isNumber()) {
|
||||
QDataStream stream(ba, QIODevice::ReadWrite);
|
||||
stream.skipRawData(id);
|
||||
stream.setFloatingPointPrecision(QDataStream::DoublePrecision);
|
||||
|
||||
stream << (double)value.toNumber();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ public:
|
|||
TypedArrayPrototype(QObject* parent = NULL);
|
||||
|
||||
public slots:
|
||||
void set(QScriptValue array, quint32 offset = 0);
|
||||
void set(QScriptValue array, qint32 offset = 0);
|
||||
QScriptValue subarray(qint32 begin);
|
||||
QScriptValue subarray(qint32 begin, qint32 end);
|
||||
|
||||
|
|
Loading…
Reference in a new issue