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; }
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); }
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; }
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. }
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; }
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(); }
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; }
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)); }
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; }
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); }
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()); }
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; }
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); }
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; }
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(); }
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); }
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)); }
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); }
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); }
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(); }
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(); }
inline int32_t Int(v8::Handle<v8::Value> hdl) { return hdl->Int32Value(); }
static int32_t apply(v8::Handle<v8::Value> const& value) { return value->Int32Value(); }
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)); } }
int SBController::jsValToInt(const v8::Handle<v8::Value>& str) { if (!str->IsNumber()) return 0; return str->Int32Value(); }
void ArrayType::IntegerSet(ArrayType *arr, JNIEnv *jniEnv, jobject ob, uint32_t index, v8::Handle<v8::Value> elt) { jniEnv->CallVoidMethod(ob, arr->setElement, index, (jint)elt->Int32Value()); }
/** * 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 ¶ms) { // 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 ¶m: 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; }