Exemplo n.º 1
0
int32_t toInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
    // Fast case. The value is already a 32-bit integer.
    if (value->IsInt32())
        return value->Int32Value();

    // Can the value be converted to a number?
    V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
    if (numberObject.IsEmpty()) {
        exceptionState.throwTypeError("Not convertible to a number value (of type 'long'.)");
        return 0;
    }

    if (configuration == EnforceRange)
        return enforceRange(numberObject->Value(), kMinInt32, kMaxInt32, "long", exceptionState);

    // Does the value convert to nan or to an infinity?
    double numberValue = numberObject->Value();
    if (std::isnan(numberValue) || std::isinf(numberValue))
        return 0;

    if (configuration == Clamp)
        return clampTo<int32_t>(numberObject->Value());

    V8TRYCATCH_EXCEPTION_RETURN(int32_t, result, numberObject->Int32Value(), exceptionState, 0);
    return result;
}
Exemplo n.º 2
0
int64_t toInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
{
    ok = true;

    // Fast case. The value is a 32-bit integer.
    if (value->IsInt32())
        return value->Int32Value();

    // Can the value be converted to a number?
    v8::Local<v8::Number> numberObject = value->ToNumber();
    if (numberObject.IsEmpty()) {
        ok = false;
        return 0;
    }

    double x = numberObject->Value();

    if (configuration == EnforceRange)
        return enforceRange(x, -kJSMaxInteger, kJSMaxInteger, ok);

    // NaNs and +/-Infinity should be 0, otherwise modulo 2^64.
    unsigned long long integer;
    doubleToInteger(x, integer);
    return integer;
}
Exemplo n.º 3
0
uint8_t toUInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
{
    ok = true;

    // Fast case. The value is a 32-bit signed integer - possibly positive?
    if (value->IsInt32()) {
        int32_t result = value->Int32Value();
        if (result >= 0 && result <= kMaxUInt8)
            return static_cast<uint8_t>(result);
        if (configuration == EnforceRange) {
            ok = false;
            return 0;
        }
        // Converting to uint8_t will cause the resulting value to be the value modulo 2^8.
        return static_cast<uint8_t>(result);
    }

    // Can the value be converted to a number?
    v8::Local<v8::Number> numberObject = value->ToNumber();
    if (numberObject.IsEmpty()) {
        ok = false;
        return 0;
    }

    if (configuration == EnforceRange)
        return enforceRange(numberObject->Value(), 0, kMaxUInt8, ok);

    // Does the value convert to nan or to an infinity?
    double numberValue = numberObject->Value();
    if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue)
        return 0;

    numberValue = numberValue < 0 ? -floor(abs(numberValue)) : floor(abs(numberValue));
    return static_cast<uint8_t>(fmod(numberValue, 256)); // 2^8.
}
String v8NonStringValueToWebCoreString(v8::Handle<v8::Value> object)
{
    ASSERT(!object->IsString());
    if (object->IsInt32()) {
        int value = object->Int32Value();
        // Most numbers used are <= 100. Even if they aren't used there's very little in using the space.
        const int kLowNumbers = 100;
        static AtomicString lowNumbers[kLowNumbers + 1];
        String webCoreString;
        if (0 <= value && value <= kLowNumbers) {
            webCoreString = lowNumbers[value];
            if (!webCoreString) {
                AtomicString valueString = AtomicString(String::number(value));
                lowNumbers[value] = valueString;
                webCoreString = valueString;
            }
        } else
            webCoreString = String::number(value);
        return webCoreString;
    }

    v8::TryCatch block;
    v8::Handle<v8::String> v8String = object->ToString();
    // Handle the case where an exception is thrown as part of invoking toString on the object.
    if (block.HasCaught()) {
        throwError(block.Exception());
        return StringImpl::empty();
    }
    return v8StringToWebCoreString<String>(v8String, DoNotExternalize);
}
Exemplo n.º 5
0
std::string jsHistory::go(v8::Handle<v8::Value> pos)
{
    string retval = "";

    if (pos->IsInt32()) {
        // process offset
        int offs = pos->Int32Value();
        offs += index;
        if (offs > 0 && offs < (int)history.size()) {
            index = offs;
            retval = history[index];
            if (window != NULL) {
                window->load(retval);
            }
        }
    } else if (pos->IsString()) {
        // search for substring
        string srch = value_to_string(Local<Value>::New(pos));
        for( size_t i = 0 ; i < history.size(); ++i) {
            if (history[i].find(srch) != string::npos) {
                index = i;
                retval = history[index];
                if (window != NULL) {
                    window->load(retval);
                }
                break;
            }
        }
    }

    return retval;
}
Exemplo n.º 6
0
int64_t toInt64(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
    // Fast case. The value is a 32-bit integer.
    if (value->IsInt32())
        return value->Int32Value();

    // Can the value be converted to a number?
    V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
    if (numberObject.IsEmpty()) {
        exceptionState.throwTypeError("Not convertible to a number value (of type 'long long'.)");
        return 0;
    }

    double x = numberObject->Value();

    if (configuration == EnforceRange)
        return enforceRange(x, -kJSMaxInteger, kJSMaxInteger, "long long", exceptionState);

    // Does the value convert to nan or to an infinity?
    if (std::isnan(x) || std::isinf(x))
        return 0;

    // NaNs and +/-Infinity should be 0, otherwise modulo 2^64.
    unsigned long long integer;
    doubleToInteger(x, integer);
    return integer;
}
int toInt32(v8::Handle<v8::Value> value, bool& ok)
{
    ok = true;
    
    // Fast case. The value is already a 32-bit integer.
    if (value->IsInt32())
        return value->Int32Value();
    
    // Can the value be converted to a number?
    v8::Local<v8::Number> numberObject = value->ToNumber();
    if (numberObject.IsEmpty()) {
        ok = false;
        return 0;
    }
    
    // Does the value convert to nan or to an infinity?
    double numberValue = numberObject->Value();
    if (isnan(numberValue) || isinf(numberValue)) {
        ok = false;
        return 0;
    }
    
    // Can the value be converted to a 32-bit integer?
    v8::Local<v8::Int32> intValue = value->ToInt32();
    if (intValue.IsEmpty()) {
        ok = false;
        return 0;
    }
    
    // Return the result of the int32 conversion.
    return intValue->Value();
}
Exemplo n.º 8
0
static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
{
    typedef IntTypeLimits<T> LimitsTrait;
    ok = true;

    // Fast case. The value is a 32-bit signed integer - possibly positive?
    if (value->IsInt32()) {
        int32_t result = value->Int32Value();
        if (result >= 0 && result <= LimitsTrait::maxValue)
            return static_cast<T>(result);
        if (configuration == EnforceRange) {
            ok = false;
            return 0;
        }
        return static_cast<T>(result);
    }

    // Can the value be converted to a number?
    v8::Local<v8::Number> numberObject = value->ToNumber();
    if (numberObject.IsEmpty()) {
        ok = false;
        return 0;
    }

    if (configuration == EnforceRange)
        return enforceRange(numberObject->Value(), 0, LimitsTrait::maxValue, ok);

    // Does the value convert to nan or to an infinity?
    double numberValue = numberObject->Value();
    if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue)
        return 0;

    numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numberValue));
    return static_cast<T>(fmod(numberValue, LimitsTrait::numberOfValues));
}
Exemplo n.º 9
0
PassRefPtr<IDBKey> createIDBKeyFromValue(v8::Handle<v8::Value> value)
{
    if (value->IsNull())
        return IDBKey::create();
    if (value->IsInt32())
        return IDBKey::create(value->Int32Value());
    if (value->IsString())
        return IDBKey::create(v8ValueToWebCoreString(value));
    // FIXME: Implement dates.
    return 0;
}
Exemplo n.º 10
0
String v8NonStringValueToWebCoreString(v8::Handle<v8::Value> object)
{
    ASSERT(!object->IsString());
    if (object->IsInt32())
        return int32ToWebCoreString(object->Int32Value());

    v8::TryCatch block;
    v8::Handle<v8::String> v8String = object->ToString();
    // Handle the case where an exception is thrown as part of invoking toString on the object.
    if (block.HasCaught()) {
        throwError(block.Exception());
        return StringImpl::empty();
    }
    return v8StringToWebCoreString<String>(v8String, DoNotExternalize);
}
Exemplo n.º 11
0
uint32_t toUInt32(v8::Handle<v8::Value> value, bool& ok)
{
    ok = true;

    // FIXME: there is currently no Value::IsUint32(). This code does
    // some contortions to avoid silently converting out-of-range
    // values to uint32_t.

    // Fast case.  The value is already a 32-bit positive integer.
    if (value->IsInt32()) {
        int32_t result = value->Int32Value();
        if (result >= 0)
            return result;
    }

    // Can the value be converted to a number?
    v8::Local<v8::Number> numberObject = value->ToNumber();
    if (numberObject.IsEmpty()) {
        ok = false;
        return 0;
    }

    // Does the value convert to nan or to an infinity?
    double numberValue = numberObject->Value();
    if (isnan(numberValue) || isinf(numberValue)) {
        ok = false;
        return 0;
    }

    // Can the value be converted to a 32-bit unsigned integer?
    v8::Local<v8::Uint32> uintValue = value->ToUint32();
    if (uintValue.IsEmpty()) {
        ok = false;
        return 0;
    }

    // FIXME: v8::Uint32::Value is not defined!
    // http://code.google.com/p/v8/issues/detail?id=624
    v8::Local<v8::Int32> intValue = value->ToInt32();
    if (intValue.IsEmpty()) {
        ok = false;
        return 0;
    }

    return static_cast<uint32_t>(intValue->Value());
}
Exemplo n.º 12
0
jobject wrapJSObject(JNIEnv *pEnv, v8::Handle<v8::Value> value)
{
  v8::HandleScope handle_scope;

  if (value.IsEmpty() || value->IsNull() || value->IsUndefined()) return NULL;
  if (value->IsTrue()) return NewBoolean(pEnv, JNI_TRUE);
  if (value->IsFalse()) return NewBoolean(pEnv, JNI_FALSE);

  if (value->IsInt32()) return NewInt(pEnv, value->Int32Value());
  if (value->IsUint32()) return NewLong(pEnv, value->IntegerValue());
  if (value->IsString()) return NewString(pEnv, v8::Handle<v8::String>::Cast(value));
  if (value->IsDate()) return NewDate(pEnv, v8::Handle<v8::Date>::Cast(value));
  if (value->IsNumber()) return NewDouble(pEnv, value->NumberValue());

//  return wrap(value->ToObject());
  return NULL;
}
Exemplo n.º 13
0
    Object^ V8Interop::FromV8(v8::Handle<v8::Value> value) 
    {
        if (value->IsString()) 
        {
            return FromV8String(value);
        } 
        else if (value->IsBoolean()) 
        {
            return FromV8Boolean(value);
        } 
        else if (value->IsInt32()) 
        {
            return FromV8Int32(value);
        } 
        else if (value->IsArray()) 
        {
            return FromV8Array(value);
        } 
        else if (value->IsDate()) 
        {
            return FromV8Date(value);
        } 
        else if (value->IsNumber()) 
        {
            return FromV8Double(value);
        } 
        else if (value->IsFunction()) 
        {
            return FromV8Function(value);
        } 
        else if (value->IsExternal()) 
        {
            return FromV8External(value);
        } 
        else if (value->IsObject()) 
        {
            return FromV8Object(value);
        } 
        else if (value->IsUndefined() || value->IsNull()) 
        {
            return nullptr;
        }

        return nullptr;
    }
Exemplo n.º 14
0
static Value v8ValueToValue(v8::Handle<v8::Value> v8Value)
{
    v8::HandleScope scope;
    if (v8Value->IsArray()) {
        List<Value> value;
        const v8::Handle<v8::Array> v8Array = v8::Handle<v8::Array>::Cast(v8Value);
        const uint32_t size = v8Array->Length();
        for (uint32_t i = 0; i < size; ++i) {
            if (v8Array->Has(i))
                value.append(v8ValueToValue(v8Array->Get(i)));
            else
                value.append(Value());
        }
        return Value(value);
    } else if (v8Value->IsObject()) {
        Map<String, Value> value;
        const v8::Handle<v8::Object> v8Object = v8Value->ToObject();
        const v8::Handle<v8::Array> props = v8Object->GetPropertyNames();
        const uint32_t size = props->Length();
        for (uint32_t i = 0; i < size; ++i) {
            assert(props->Has(i));
            const v8::Handle<v8::Value> name = props->Get(i);
            value[String(*v8::String::Utf8Value(name))] = v8ValueToValue(v8Object->Get(name));
        }
        return Value(value);
    } else if (v8Value->IsBoolean()) {
        return Value(v8Value->BooleanValue());
    } else if (v8Value->IsInt32() || v8Value->IsUint32()) {
        return Value(v8Value->Int32Value());
    } else if (v8Value->IsNumber()) {
        return Value(v8Value->NumberValue());
    } else if (v8Value->IsString()) {
        return Value(String(*v8::String::Utf8Value(v8Value)));
    } else {
        error() << "Unexpected v8 value type in JSONParser";
    }
    // undefined or null?
    return Value();
}
static String v8NonStringValueToWebCoreString(v8::Handle<v8::Value> object)
{
    ASSERT(!object->IsString());
    if (object->IsInt32())
        return int32ToWebCoreString(object->Int32Value());

    v8::TryCatch block;
    v8::Handle<v8::String> v8String = object->ToString();
    // Handle the case where an exception is thrown as part of invoking toString on the object.
    if (block.HasCaught()) {
        throwError(block.Exception());
        return StringImpl::empty();
    }
    // This path is unexpected. However there is hypothesis that it
    // might be combination of v8 and v8 bindings bugs. For now
    // just bailout as we'll crash if attempt to convert empty handle into a string.
    if (v8String.IsEmpty()) {
        ASSERT_NOT_REACHED();
        return StringImpl::empty();
    }
    return v8StringToWebCoreString<String>(v8String, DoNotExternalize);
}
Exemplo n.º 16
0
Arquivo: Wrapper.cpp Projeto: pix/jav8
bool CJavaFunction::CanConvert(jclass clazz, v8::Handle<v8::Value> value)
{
  jni::V8Env env(m_pEnv);

  if (value->IsTrue() || value->IsFalse() || value->IsBoolean())
  {
    return env.IsAssignableFrom(env.buildins.java.lang.Boolean, clazz);
  }
  else if (value->IsInt32() || value->IsUint32())
  {
    return env.IsAssignableFrom(env.buildins.java.lang.Long, clazz) ||
           env.IsAssignableFrom(env.buildins.java.lang.Integer, clazz) ||
           env.IsAssignableFrom(env.buildins.java.lang.Short, clazz) ||
           env.IsAssignableFrom(env.buildins.java.lang.Byte, clazz);
  }
  else if (value->IsNumber())
  {
    return env.IsAssignableFrom(env.buildins.java.lang.Double, clazz) ||
           env.IsAssignableFrom(env.buildins.java.lang.Float, clazz);
  }
  else if (value->IsString())
  {
    return env.IsAssignableFrom(env.buildins.java.lang.String, clazz);
  }
  else if (value->IsDate())
  {
    return env.IsAssignableFrom(env.buildins.java.util.Date, clazz);
  }
  else if (value->IsArray())
  {
    return env.IsAssignableFrom(env.buildins.lu.flier.script.V8Array, clazz);
  }
  else if (value.IsEmpty() || value->IsNull() || value->IsUndefined() || value->IsObject())
  {
    return true;
  }
  
  return false;
}
Exemplo n.º 17
0
uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, ExceptionState& exceptionState)
{
    // Fast case. The value is already a 32-bit unsigned integer.
    if (value->IsUint32())
        return value->Uint32Value();

    // Fast case. The value is a 32-bit signed integer - possibly positive?
    if (value->IsInt32()) {
        int32_t result = value->Int32Value();
        if (result >= 0)
            return result;
        if (configuration == EnforceRange) {
            exceptionState.throwTypeError("Value is outside the 'unsigned long' value range.");
            return 0;
        }
        return result;
    }

    // Can the value be converted to a number?
    V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
    if (numberObject.IsEmpty()) {
        exceptionState.throwTypeError("Not convertible to a number value (of type 'unsigned long'.)");
        return 0;
    }

    if (configuration == EnforceRange)
        return enforceRange(numberObject->Value(), 0, kMaxUInt32, "unsigned long", exceptionState);

    // Does the value convert to nan or to an infinity?
    double numberValue = numberObject->Value();
    if (std::isnan(numberValue) || std::isinf(numberValue))
        return 0;

    if (configuration == Clamp)
        return clampTo<uint32_t>(numberObject->Value());

    V8TRYCATCH_RETURN(uint32_t, result, numberObject->Uint32Value(), 0);
    return result;
}
Exemplo n.º 18
0
inline Value InterpreterData::v8ValueToValue(const v8::Handle<v8::Value>& value)
{
    if (value.IsEmpty() || value->IsNull() || value->IsUndefined())
        return Value();
    else if (value->IsTrue())
        return Value(true);
    else if (value->IsFalse())
        return Value(false);
    else if (value->IsInt32())
        return Value(value->ToInt32()->Value());
    else if (value->IsNumber())
        return Value(value->ToNumber()->Value());
    else if (value->IsString()) {
        const v8::String::Utf8Value str(value);
        return Value(ToCString(str));
    } else if (value->IsObject()) {
        const v8::String::Utf8Value str(toJSON(value));
        return Value::fromJSON(ToCString(str));
    } else {
        error() << "Unknown v8 value in Interpreter::v8ValueToValue";
    }
    return Value();
}
uint32_t toUInt32(v8::Handle<v8::Value> value, bool& ok)
{
    ok = true;

    // Fast case. The value is already a 32-bit unsigned integer.
    if (value->IsUint32())
        return value->Uint32Value();

    if (value->IsInt32()) {
        int32_t result = value->Int32Value();
        if (result >= 0)
            return result;
    }

    // Can the value be converted to a number?
    v8::Local<v8::Number> numberObject = value->ToNumber();
    if (numberObject.IsEmpty()) {
        ok = false;
        return 0;
    }

    // Does the value convert to nan or to an infinity?
    double numberValue = numberObject->Value();
    if (isnan(numberValue) || isinf(numberValue)) {
        ok = false;
        return 0;
    }

    // Can the value be converted to a 32-bit unsigned integer?
    v8::Local<v8::Uint32> uintValue = value->ToUint32();
    if (uintValue.IsEmpty()) {
        ok = false;
        return 0;
    }

    return uintValue->Value();
}
Exemplo n.º 20
0
static inline T toSmallerUInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, const char* typeName, ExceptionState& exceptionState)
{
    typedef IntTypeLimits<T> LimitsTrait;

    // Fast case. The value is a 32-bit signed integer - possibly positive?
    if (value->IsInt32()) {
        int32_t result = value->Int32Value();
        if (result >= 0 && result <= LimitsTrait::maxValue)
            return static_cast<T>(result);
        if (configuration == EnforceRange) {
            exceptionState.throwTypeError("Value is outside the '" + String(typeName) + "' value range.");
            return 0;
        }
        return static_cast<T>(result);
    }

    // Can the value be converted to a number?
    V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
    if (numberObject.IsEmpty()) {
        exceptionState.throwTypeError("Not convertible to a number value (of type '" + String(typeName) + "'.");
        return 0;
    }

    if (configuration == EnforceRange)
        return enforceRange(numberObject->Value(), 0, LimitsTrait::maxValue, typeName, exceptionState);

    // Does the value convert to nan or to an infinity?
    double numberValue = numberObject->Value();
    if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue)
        return 0;

    if (configuration == Clamp)
        return clampTo<T>(numberObject->Value());

    numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numberValue));
    return static_cast<T>(fmod(numberValue, LimitsTrait::numberOfValues));
}
Exemplo n.º 21
0
static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
{
    typedef IntTypeLimits<T> LimitsTrait;
    ok = true;

    // Fast case. The value is already a 32-bit integer in the right range.
    if (value->IsInt32()) {
        int32_t result = value->Int32Value();
        if (result >= LimitsTrait::minValue && result <= LimitsTrait::maxValue)
            return static_cast<T>(result);
        if (configuration == EnforceRange) {
            ok = false;
            return 0;
        }
        result %= LimitsTrait::numberOfValues;
        return static_cast<T>(result > LimitsTrait::maxValue ? result - LimitsTrait::numberOfValues : result);
    }

    // Can the value be converted to a number?
    v8::Local<v8::Number> numberObject = value->ToNumber();
    if (numberObject.IsEmpty()) {
        ok = false;
        return 0;
    }

    if (configuration == EnforceRange)
        return enforceRange(numberObject->Value(), LimitsTrait::minValue, LimitsTrait::maxValue, ok);

    double numberValue = numberObject->Value();
    if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue)
        return 0;

    numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numberValue));
    numberValue = fmod(numberValue, LimitsTrait::numberOfValues);

    return static_cast<T>(numberValue > LimitsTrait::maxValue ? numberValue - LimitsTrait::numberOfValues : numberValue);
}
Exemplo n.º 22
0
int8_t toInt8(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
{
    ok = true;

    // Fast case. The value is already a 32-bit integer in the right range.
    if (value->IsInt32()) {
        int32_t result = value->Int32Value();
        if (result >= kMinInt8 && result <= kMaxInt8)
            return static_cast<int8_t>(result);
        if (configuration == EnforceRange) {
            ok = false;
            return 0;
        }
        result %= 256; // 2^8.
        return static_cast<int8_t>(result > kMaxInt8 ? result - 256 : result);
    }

    // Can the value be converted to a number?
    v8::Local<v8::Number> numberObject = value->ToNumber();
    if (numberObject.IsEmpty()) {
        ok = false;
        return 0;
    }

    if (configuration == EnforceRange)
        return enforceRange(numberObject->Value(), kMinInt8, kMaxInt8, ok);

    double numberValue = numberObject->Value();
    if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue)
        return 0;

    numberValue = numberValue < 0 ? -floor(abs(numberValue)) : floor(abs(numberValue));
    numberValue = fmod(numberValue, 256); // 2^8.

    return static_cast<int8_t>(numberValue > kMaxInt8 ? numberValue - 256 : numberValue);
}
Exemplo n.º 23
0
static inline T toSmallerInt(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, const char* typeName, ExceptionState& exceptionState)
{
    typedef IntTypeLimits<T> LimitsTrait;

    // Fast case. The value is already a 32-bit integer in the right range.
    if (value->IsInt32()) {
        int32_t result = value->Int32Value();
        if (result >= LimitsTrait::minValue && result <= LimitsTrait::maxValue)
            return static_cast<T>(result);
        if (configuration == EnforceRange) {
            exceptionState.throwTypeError("Value is outside the '" + String(typeName) + "' value range.");
            return 0;
        }
        result %= LimitsTrait::numberOfValues;
        return static_cast<T>(result > LimitsTrait::maxValue ? result - LimitsTrait::numberOfValues : result);
    }

    // Can the value be converted to a number?
    V8TRYCATCH_EXCEPTION_RETURN(v8::Local<v8::Number>, numberObject, value->ToNumber(), exceptionState, 0);
    if (numberObject.IsEmpty()) {
        exceptionState.throwTypeError("Not convertible to a number value (of type '" + String(typeName) + "'.");
        return 0;
    }

    if (configuration == EnforceRange)
        return enforceRange(numberObject->Value(), LimitsTrait::minValue, LimitsTrait::maxValue, typeName, exceptionState);

    double numberValue = numberObject->Value();
    if (std::isnan(numberValue) || std::isinf(numberValue) || !numberValue)
        return 0;

    numberValue = numberValue < 0 ? -floor(fabs(numberValue)) : floor(fabs(numberValue));
    numberValue = fmod(numberValue, LimitsTrait::numberOfValues);

    return static_cast<T>(numberValue > LimitsTrait::maxValue ? numberValue - LimitsTrait::numberOfValues : numberValue);
}
Exemplo n.º 24
0
uint32_t toUInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
{
    ok = true;

    // Fast case. The value is already a 32-bit unsigned integer.
    if (value->IsUint32())
        return value->Uint32Value();

    // Fast case. The value is a 32-bit signed integer - possibly positive?
    if (value->IsInt32()) {
        int32_t result = value->Int32Value();
        if (result >= 0)
            return result;
        if (configuration == EnforceRange) {
            ok = false;
            return 0;
        }
        return result;
    }

    // Can the value be converted to a number?
    v8::Local<v8::Number> numberObject = value->ToNumber();
    if (numberObject.IsEmpty()) {
        ok = false;
        return 0;
    }

    if (configuration == EnforceRange)
        return enforceRange(numberObject->Value(), 0, kMaxUInt32, ok);

    // Does the value convert to nan or to an infinity?
    double numberValue = numberObject->Value();
    if (std::isnan(numberValue) || std::isinf(numberValue))
        return 0;
    return numberObject->Uint32Value();
}
Exemplo n.º 25
0
int32_t toInt32(v8::Handle<v8::Value> value, IntegerConversionConfiguration configuration, bool& ok)
{
    ok = true;

    // Fast case. The value is already a 32-bit integer.
    if (value->IsInt32())
        return value->Int32Value();

    // Can the value be converted to a number?
    v8::Local<v8::Number> numberObject = value->ToNumber();
    if (numberObject.IsEmpty()) {
        ok = false;
        return 0;
    }

    if (configuration == EnforceRange)
        return enforceRange(numberObject->Value(), kMinInt32, kMaxInt32, ok);

    // Does the value convert to nan or to an infinity?
    double numberValue = numberObject->Value();
    if (std::isnan(numberValue) || std::isinf(numberValue))
        return 0;
    return numberObject->Int32Value();
}
Exemplo n.º 26
0
static int V8ToVPack(BuilderContext& context,
                     v8::Handle<v8::Value> const parameter,
                     std::string const& attributeName, bool inObject) {
  
  if (parameter->IsNull() || parameter->IsUndefined()) {
    AddValue(context, attributeName, inObject,
             VPackValue(VPackValueType::Null));
    return TRI_ERROR_NO_ERROR;
  }

  if (parameter->IsBoolean()) {
    AddValue(context, attributeName, inObject,
             VPackValue(parameter->ToBoolean()->Value()));
    return TRI_ERROR_NO_ERROR;
  }
  
  if (parameter->IsNumber()) {
    if (parameter->IsInt32()) {
      AddValue(context, attributeName, inObject,
               VPackValue(parameter->ToInt32()->Value()));
      return TRI_ERROR_NO_ERROR;
    }
  
    if (parameter->IsUint32()) {
      AddValue(context, attributeName, inObject,
               VPackValue(parameter->ToUint32()->Value()));
      return TRI_ERROR_NO_ERROR;
    }

    AddValue(context, attributeName, inObject,
             VPackValue(parameter->ToNumber()->Value()));
    return TRI_ERROR_NO_ERROR;
  }

  if (parameter->IsString()) {
    v8::String::Utf8Value str(parameter->ToString());

    if (*str == nullptr) {
      return TRI_ERROR_OUT_OF_MEMORY;
    }

    AddValuePair(context, attributeName, inObject, VPackValuePair(*str, str.length(), VPackValueType::String));
    return TRI_ERROR_NO_ERROR;
  }

  if (parameter->IsArray()) {
    v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(parameter);

    AddValue(context, attributeName, inObject,
             VPackValue(VPackValueType::Array));
    uint32_t const n = array->Length();

    for (uint32_t i = 0; i < n; ++i) {
      v8::Handle<v8::Value> value = array->Get(i);
      if (value->IsUndefined()) {
        // ignore array values which are undefined
        continue;
      }

      if (++context.level > MaxLevels) {
        // too much recursion
        return TRI_ERROR_BAD_PARAMETER;
      }

      int res = V8ToVPack<performAllChecks>(context, value, NoAttribute, false);
      
      --context.level;

      if (res != TRI_ERROR_NO_ERROR) {
        return res;
      }
    }

    if (!context.keepTopLevelOpen || context.level > 0) {
      context.builder.close();
    }
    return TRI_ERROR_NO_ERROR;
  }

  if (parameter->IsObject()) {
    if (performAllChecks) {
      if (parameter->IsBooleanObject()) {
        AddValue(context, attributeName, inObject,
                VPackValue(v8::Handle<v8::BooleanObject>::Cast(parameter)
                                ->BooleanValue()));
        return TRI_ERROR_NO_ERROR;
      }

      if (parameter->IsNumberObject()) {
        AddValue(context, attributeName, inObject,
                VPackValue(v8::Handle<v8::NumberObject>::Cast(parameter)
                                ->NumberValue()));
        return TRI_ERROR_NO_ERROR;
      }

      if (parameter->IsStringObject()) {
        v8::String::Utf8Value str(parameter->ToString());

        if (*str == nullptr) {
          return TRI_ERROR_OUT_OF_MEMORY;
        }

        AddValuePair(context, attributeName, inObject, VPackValuePair(*str, str.length(), VPackValueType::String));
        return TRI_ERROR_NO_ERROR;
      }

      if (parameter->IsRegExp() || parameter->IsFunction() ||
          parameter->IsExternal()) {
        return TRI_ERROR_BAD_PARAMETER;
      }
    }

    v8::Handle<v8::Object> o = parameter->ToObject();

    if (performAllChecks) {
      // first check if the object has a "toJSON" function
      if (o->Has(context.toJsonKey)) {
        // call it if yes
        v8::Handle<v8::Value> func = o->Get(context.toJsonKey);
        if (func->IsFunction()) {
          v8::Handle<v8::Function> toJson = v8::Handle<v8::Function>::Cast(func);

          v8::Handle<v8::Value> args;
          v8::Handle<v8::Value> converted = toJson->Call(o, 0, &args);

          if (!converted.IsEmpty()) {
            // return whatever toJSON returned
            v8::String::Utf8Value str(converted->ToString());

            if (*str == nullptr) {
              return TRI_ERROR_OUT_OF_MEMORY;
            }

            // this passes ownership for the utf8 string to the JSON object
            AddValuePair(context, attributeName, inObject, VPackValuePair(*str, str.length(), VPackValueType::String));
            return TRI_ERROR_NO_ERROR;
          }
        }

        // fall-through intentional
      }
    }

    v8::Handle<v8::Array> names = o->GetOwnPropertyNames();
    uint32_t const n = names->Length();

    AddValue(context, attributeName, inObject,
             VPackValue(VPackValueType::Object));

    for (uint32_t i = 0; i < n; ++i) {
      // process attribute name
      v8::Handle<v8::Value> key = names->Get(i);
      v8::String::Utf8Value str(key);

      if (*str == nullptr) {
        return TRI_ERROR_OUT_OF_MEMORY;
      }

      v8::Handle<v8::Value> value = o->Get(key);
      if (value->IsUndefined()) {
        // ignore object values which are undefined
        continue;
      }

      if (++context.level > MaxLevels) {
        // too much recursion
        return TRI_ERROR_BAD_PARAMETER;
      }

      int res = V8ToVPack<performAllChecks>(context, value, *str, true);
      
      --context.level;

      if (res != TRI_ERROR_NO_ERROR) {
        return res;
      }
    }

    if (!context.keepTopLevelOpen || context.level > 0) {
      context.builder.close();
    }
    return TRI_ERROR_NO_ERROR;
  }

  return TRI_ERROR_BAD_PARAMETER;
}
Exemplo n.º 27
0
    void v8ToMongoElement( BSONObjBuilder & b , v8::Handle<v8::String> name , const string sname , v8::Handle<v8::Value> value ){
        
        if ( value->IsString() ){
            b.append( sname.c_str() , toSTLString( value ).c_str() );
            return;
        }
        
        if ( value->IsFunction() ){
            b.appendCode( sname.c_str() , toSTLString( value ).c_str() );
            return;
        }
    
        if ( value->IsNumber() ){
            if ( value->IsInt32() )
                b.append( sname.c_str(), int( value->ToInt32()->Value() ) );
            else
                b.append( sname.c_str() , value->ToNumber()->Value() );
            return;
        }
    
        if ( value->IsArray() ){
            BSONObj sub = v8ToMongo( value->ToObject() );
            b.appendArray( sname.c_str() , sub );
            return;
        }
    
        if ( value->IsDate() ){
            b.appendDate( sname.c_str() , Date_t(v8::Date::Cast( *value )->NumberValue()) );
            return;
        }

        if ( value->IsExternal() )
            return;
        
        if ( value->IsObject() ){
            // The user could potentially modify the fields of these special objects,
            // wreaking havoc when we attempt to reinterpret them.  Not doing any validation
            // for now...
            Local< v8::Object > obj = value->ToObject();
            if ( obj->InternalFieldCount() && obj->GetInternalField( 0 )->IsNumber() ) {
                switch( obj->GetInternalField( 0 )->ToInt32()->Value() ) { // NOTE Uint32's Value() gave me a linking error, so going with this instead
                    case Timestamp:
                        b.appendTimestamp( sname.c_str(),
                                          Date_t( v8::Date::Cast( *obj->Get( v8::String::New( "time" ) ) )->NumberValue() ),
                                          obj->Get( v8::String::New( "i" ) )->ToInt32()->Value() );
                        return;
                    case MinKey:
                        b.appendMinKey( sname.c_str() );
                        return;
                    case MaxKey:
                        b.appendMaxKey( sname.c_str() );
                        return;
                    default:
                        assert( "invalid internal field" == 0 );
                }
            }
            string s = toSTLString( value );
            if ( s.size() && s[0] == '/' ){
                s = s.substr( 1 );
                string r = s.substr( 0 , s.rfind( "/" ) );
                string o = s.substr( s.rfind( "/" ) + 1 );
                b.appendRegex( sname.c_str() , r.c_str() , o.c_str() );
            }
            else if ( value->ToObject()->GetPrototype()->IsObject() &&
                      value->ToObject()->GetPrototype()->ToObject()->HasRealNamedProperty( v8::String::New( "isObjectId" ) ) ){
                OID oid;
                oid.init( toSTLString( value ) );
                b.appendOID( sname.c_str() , &oid );
            }
            else if ( !value->ToObject()->GetHiddenValue( v8::String::New( "__NumberLong" ) ).IsEmpty() ) {
                // TODO might be nice to potentially speed this up with an indexed internal
                // field, but I don't yet know how to use an ObjectTemplate with a
                // constructor.
                unsigned long long val =
                ( (unsigned long long)( value->ToObject()->Get( v8::String::New( "top" ) )->ToInt32()->Value() ) << 32 ) +
                (unsigned)( value->ToObject()->Get( v8::String::New( "bottom" ) )->ToInt32()->Value() );
                b.append( sname.c_str(), (long long)val );
            }
            else if ( !value->ToObject()->GetHiddenValue( v8::String::New( "__DBPointer" ) ).IsEmpty() ) {
                OID oid;
                oid.init( toSTLString( value->ToObject()->Get( v8::String::New( "id" ) ) ) );
                string ns = toSTLString( value->ToObject()->Get( v8::String::New( "ns" ) ) );
                b.appendDBRef( sname.c_str(), ns.c_str(), oid );                
            }
            else if ( !value->ToObject()->GetHiddenValue( v8::String::New( "__BinData" ) ).IsEmpty() ) {
                int len = obj->Get( v8::String::New( "len" ) )->ToInt32()->Value();
                v8::String::Utf8Value data( obj->Get( v8::String::New( "data" ) ) );
                const char *dataArray = *data;
                assert( data.length() == len );
                b.appendBinData( sname.c_str(),
                                len,
                                mongo::BinDataType( obj->Get( v8::String::New( "type" ) )->ToInt32()->Value() ),
                                dataArray );
            } else {
                BSONObj sub = v8ToMongo( value->ToObject() );
                b.append( sname.c_str() , sub );
            }
            return;
        }
    
        if ( value->IsBoolean() ){
            b.appendBool( sname.c_str() , value->ToBoolean()->Value() );
            return;
        }
    
        else if ( value->IsUndefined() ){
            b.appendUndefined( sname.c_str() );
            return;
        }
    
        else if ( value->IsNull() ){
            b.appendNull( sname.c_str() );
            return;
        }

        cout << "don't know how to convert to mongo field [" << name << "]\t" << value << endl;
    }
Exemplo n.º 28
0
void QV8Worker::serialize(QByteArray &data, v8::Handle<v8::Value> v, QV8Engine *engine)
{
    if (v.IsEmpty()) {
    } else if (v->IsUndefined()) {
        push(data, valueheader(WorkerUndefined));
    } else if (v->IsNull()) {
        push(data, valueheader(WorkerNull));
    } else if (v->IsTrue()) {
        push(data, valueheader(WorkerTrue));
    } else if (v->IsFalse()) {
        push(data, valueheader(WorkerFalse));
    } else if (v->IsString()) {
        v8::Handle<v8::String> string = v->ToString();
        int length = string->Length() + 1;
        if (length > 0xFFFFFF) {
            push(data, valueheader(WorkerUndefined));
            return;
        }
        int utf16size = ALIGN(length * sizeof(uint16_t));

        reserve(data, utf16size + sizeof(quint32));
        push(data, valueheader(WorkerString, length));
        
        int offset = data.size();
        data.resize(data.size() + utf16size);
        char *buffer = data.data() + offset;

        string->Write((uint16_t*)buffer);
    } else if (v->IsFunction()) {
        // XXX TODO: Implement passing function objects between the main and
        // worker scripts
        push(data, valueheader(WorkerUndefined));
    } else if (v->IsArray()) {
        v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(v);
        uint32_t length = array->Length();
        if (length > 0xFFFFFF) {
            push(data, valueheader(WorkerUndefined));
            return;
        }
        reserve(data, sizeof(quint32) + length * sizeof(quint32));
        push(data, valueheader(WorkerArray, length));
        for (uint32_t ii = 0; ii < length; ++ii)
            serialize(data, array->Get(ii), engine);
    } else if (v->IsInt32()) {
        reserve(data, 2 * sizeof(quint32));
        push(data, valueheader(WorkerInt32));
        push(data, (quint32)v->Int32Value());
    } else if (v->IsUint32()) {
        reserve(data, 2 * sizeof(quint32));
        push(data, valueheader(WorkerUint32));
        push(data, v->Uint32Value());
    } else if (v->IsNumber()) {
        reserve(data, sizeof(quint32) + sizeof(double));
        push(data, valueheader(WorkerNumber));
        push(data, v->NumberValue());
    } else if (v->IsDate()) {
        reserve(data, sizeof(quint32) + sizeof(double));
        push(data, valueheader(WorkerDate));
        push(data, v8::Handle<v8::Date>::Cast(v)->NumberValue());
    } else if (v->IsRegExp()) {
        v8::Handle<v8::RegExp> regexp = v8::Handle<v8::RegExp>::Cast(v);
        quint32 flags = regexp->GetFlags();
        v8::Local<v8::String> source = regexp->GetSource();

        int length = source->Length() + 1;
        if (length > 0xFFFFFF) {
            push(data, valueheader(WorkerUndefined));
            return;
        }
        int utf16size = ALIGN(length * sizeof(uint16_t));

        reserve(data, sizeof(quint32) + utf16size);
        push(data, valueheader(WorkerRegexp, flags));
        push(data, (quint32)length);
        int offset = data.size();
        data.resize(data.size() + utf16size);
        char *buffer = data.data() + offset;

        source->Write((uint16_t*)buffer);
    } else if (v->IsObject() && !v->ToObject()->GetExternalResource()) {
        v8::Handle<v8::Object> object = v->ToObject();
        v8::Local<v8::Array> properties = engine->getOwnPropertyNames(object);
        quint32 length = properties->Length();
        if (length > 0xFFFFFF) {
            push(data, valueheader(WorkerUndefined));
            return;
        }
        push(data, valueheader(WorkerObject, length));
        v8::TryCatch tc;
        for (quint32 ii = 0; ii < length; ++ii) {
            v8::Local<v8::String> str = properties->Get(ii)->ToString();
            serialize(data, str, engine);

            v8::Local<v8::Value> val = object->Get(str);
            if (tc.HasCaught()) {
                serialize(data, v8::Undefined(), engine);
                tc.Reset();
            } else {
                serialize(data, val, engine);
            }
        }
    } else if (engine->isQObject(v)) {
        // XXX TODO: Generalize passing objects between the main thread and worker scripts so 
        // that others can trivially plug in their elements.
        QDeclarativeListModel *lm = qobject_cast<QDeclarativeListModel *>(engine->toQObject(v));
        if (lm && lm->agent()) {
            QDeclarativeListModelWorkerAgent *agent = lm->agent();
            agent->addref();
            push(data, valueheader(WorkerListModel));
            push(data, (void *)agent);
            return;
        } 
        // No other QObject's are allowed to be sent
        push(data, valueheader(WorkerUndefined));
    } else {
        push(data, valueheader(WorkerUndefined));
    }
}
Exemplo n.º 29
0
/**
 *  Cast an ecmascript value to a PHP runtime value
 *
 *  @note   The value cannot be const, as retrieving properties
 *          from arrays and objects cannot be done on const values
 *
 *  @param  input   the value to cast
 *  @return Php::Value
 */
Php::Value value(v8::Handle<v8::Value> input)
{
    // if we received an invalid input we simply return an empty PHP value
    if (input.IsEmpty())            return nullptr;

    // as is typical in javascript, a value can be of many types
    // check the type of value that we have received so we can cast
    if (input->IsBoolean())         return input->BooleanValue();
    if (input->IsBooleanObject())   return input->BooleanValue();
    if (input->IsInt32())           return input->Int32Value();
    if (input->IsNumber())          return input->NumberValue();
    if (input->IsNumberObject())    return input->NumberValue();
    if (input->IsNull())            return nullptr;
    if (input->IsUndefined())       return nullptr;

    // special treatment for string-like types
    // TODO: javascript dates might possibly be cast to a DateTime object
    if (input->IsString() || input->IsStringObject() || input->IsRegExp())
    {
        // create the utf8 value (the only way to retrieve the content)
        v8::String::Utf8Value   utf8(input->ToString());

        // and create the value to return
        return {*utf8, utf8.length()};
    }

    // it could be callable too
    if (input->IsFunction())
    {
        // create the function as a pointer that can be captured
        auto function = std::make_shared<Stack<v8::Function>>(input.As<v8::Function>());

        // the result to return
        Php::Function result([function](Php::Parameters &params) {
            // create a "scope", so variables get destructed, retrieve the context and "enter" it
            v8::HandleScope                     scope(Isolate::get());
            v8::Local<v8::Context>              context((*function)->CreationContext());
            v8::Context::Scope                  contextScope(context);

            // catch any errors that occur while either compiling or running the script
            v8::TryCatch                        catcher;

            // create a new array with parameters
            std::vector<v8::Local<v8::Value>>   array;
            array.reserve(params.size());

            // iterate over all the given parameters and add them to the arrau
            for (auto &param: params) array.push_back(value(param));

            // now we can actually call the function
            v8::Local<v8::Value> result((*function)->Call(context->Global(), array.size(), array.data()));

            // did we catch an exception?
            if (catcher.HasCaught())
            {
                // retrieve the message describing the problem
                v8::Local<v8::Message>  message(catcher.Message());
                v8::Local<v8::String>   description(message->Get());

                // convert the description to utf so we can dump it
                v8::String::Utf8Value   string(description);

                // pass this exception on to PHP userspace
                throw Php::Exception(std::string(*string, string.length()));
            }

            // convert the result to a PHP value and return it
            return value(result);
        });

        // now return the result
        return result;
    }

    // or perhaps an object
    if (input->IsObject())
    {
        // retrieve the object and the first internal field
        auto object = input.As<v8::Object>();

        // does the object have internal fields?
        if (object->InternalFieldCount())
        {
            // retrieve the field
            auto field  = object->GetInternalField(0);

            // does it have an internal field and is it external? we are converting back
            // an original PHP object, just retrieve the original thing that came from PHP
            if (!field.IsEmpty() && field->IsExternal())
            {
                // the PHP value is stored in the first internal field,
                // retrieve it and create the handle around it
                Handle handle(field);

                // dereference and return it
                return *handle;
            }
        }

        // create a new js object and convert it to userspace
        return Php::Object("JS\\Object", new JSObject(object));
    }

    // we sadly don't support this type of value
    return nullptr;
}