static PassRefPtr<JSONValue> v8ToJSONValue(v8::Handle<v8::Value> value, int maxDepth, v8::Isolate* isolate) { if (value.IsEmpty()) { ASSERT_NOT_REACHED(); return 0; } if (!maxDepth) return 0; maxDepth--; if (value->IsNull() || value->IsUndefined()) return JSONValue::null(); if (value->IsBoolean()) return JSONBasicValue::create(value->BooleanValue()); if (value->IsNumber()) return JSONBasicValue::create(value->NumberValue()); if (value->IsString()) return JSONString::create(toCoreString(value.As<v8::String>())); if (value->IsArray()) { v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value); RefPtr<JSONArray> inspectorArray = JSONArray::create(); uint32_t length = array->Length(); for (uint32_t i = 0; i < length; i++) { v8::Local<v8::Value> value = array->Get(v8::Int32::New(isolate, i)); RefPtr<JSONValue> element = v8ToJSONValue(value, maxDepth, isolate); if (!element) return 0; inspectorArray->pushValue(element); } return inspectorArray; } if (value->IsObject()) { RefPtr<JSONObject> jsonObject = JSONObject::create(); v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); v8::Local<v8::Array> propertyNames = object->GetPropertyNames(); uint32_t length = propertyNames->Length(); for (uint32_t i = 0; i < length; i++) { v8::Local<v8::Value> name = propertyNames->Get(v8::Int32::New(isolate, i)); // FIXME(yurys): v8::Object should support GetOwnPropertyNames if (name->IsString() && !object->HasRealNamedProperty(v8::Handle<v8::String>::Cast(name))) continue; RefPtr<JSONValue> propertyValue = v8ToJSONValue(object->Get(name), maxDepth, isolate); if (!propertyValue) return 0; V8TRYCATCH_FOR_V8STRINGRESOURCE_RETURN(V8StringResource<WithNullCheck>, nameString, name, 0); jsonObject->setValue(nameString, propertyValue); } return jsonObject; } ASSERT_NOT_REACHED(); return 0; }
static PassRefPtr<InspectorValue> v8ToInspectorValue(v8::Handle<v8::Value> value, int maxDepth) { if (value.IsEmpty()) { ASSERT_NOT_REACHED(); return 0; } if (!maxDepth) return 0; maxDepth--; if (value->IsNull() || value->IsUndefined()) return InspectorValue::null(); if (value->IsBoolean()) return InspectorBasicValue::create(value->BooleanValue()); if (value->IsNumber()) return InspectorBasicValue::create(value->NumberValue()); if (value->IsString()) return InspectorString::create(toWebCoreString(value)); if (value->IsArray()) { v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(value); RefPtr<InspectorArray> inspectorArray = InspectorArray::create(); uint32_t length = array->Length(); for (uint32_t i = 0; i < length; i++) { v8::Local<v8::Value> value = array->Get(v8::Int32::New(i)); RefPtr<InspectorValue> element = v8ToInspectorValue(value, maxDepth); if (!element) return 0; inspectorArray->pushValue(element); } return inspectorArray; } if (value->IsObject()) { RefPtr<InspectorObject> inspectorObject = InspectorObject::create(); v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value); v8::Local<v8::Array> propertyNames = object->GetPropertyNames(); uint32_t length = propertyNames->Length(); for (uint32_t i = 0; i < length; i++) { v8::Local<v8::Value> name = propertyNames->Get(v8::Int32::New(i)); // FIXME(yurys): v8::Object should support GetOwnPropertyNames if (name->IsString() && !object->HasRealNamedProperty(v8::Handle<v8::String>::Cast(name))) continue; RefPtr<InspectorValue> propertyValue = v8ToInspectorValue(object->Get(name), maxDepth); if (!propertyValue) return 0; inspectorObject->setValue(toWebCoreStringWithNullCheck(name), propertyValue); } return inspectorObject; } ASSERT_NOT_REACHED(); return 0; }
static bool FillShapeValueBoolean (TRI_shaper_t* shaper, TRI_shape_value_t* dst, v8::Handle<v8::BooleanObject> json) { TRI_shape_boolean_t* ptr; dst->_type = TRI_SHAPE_BOOLEAN; dst->_sid = shaper->_sidBoolean; dst->_fixedSized = true; dst->_size = sizeof(TRI_shape_boolean_t); dst->_value = (char*)(ptr = (TRI_shape_boolean_t*) TRI_Allocate(shaper->_memoryZone, dst->_size, true)); if (dst->_value == NULL) { return false; } *ptr = json->BooleanValue() ? 1 : 0; return true; }
QJsonValue QV8JsonWrapper::toJsonValue(v8::Handle<v8::Value> value, V8ObjectSet &visitedObjects) { if (value->IsString()) return QJsonValue(QJSConverter::toString(value.As<v8::String>())); else if (value->IsNumber()) return QJsonValue(value->NumberValue()); else if (value->IsBoolean()) return QJsonValue(value->BooleanValue()); else if (value->IsArray()) return toJsonArray(value.As<v8::Array>(), visitedObjects); else if (value->IsObject()) return toJsonObject(value.As<v8::Object>(), visitedObjects); else if (value->IsNull()) return QJsonValue(QJsonValue::Null); else return QJsonValue(QJsonValue::Undefined); }
static int FillShapeValueBoolean (VocShaper* shaper, TRI_shape_value_t* dst, v8::Handle<v8::BooleanObject> const json) { TRI_shape_boolean_t* ptr; dst->_type = TRI_SHAPE_BOOLEAN; dst->_sid = BasicShapes::TRI_SHAPE_SID_BOOLEAN; dst->_fixedSized = true; dst->_size = sizeof(TRI_shape_boolean_t); dst->_value = (char*) (ptr = (TRI_shape_boolean_t*) TRI_Allocate(shaper->memoryZone(), dst->_size, false)); if (dst->_value == nullptr) { return TRI_ERROR_OUT_OF_MEMORY; } *ptr = json->BooleanValue() ? 1 : 0; return TRI_ERROR_NO_ERROR; }
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 bool apply(v8::Handle<v8::Value> const& value) { return value->BooleanValue(); }
/** * 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; }
inline bool Bool(v8::Handle<v8::Value> hdl) { return hdl->BooleanValue(); }