std::unique_ptr V8ValueConverter::FromV8ValueImpl()

in shell/common/v8_value_converter.cc [296:379]


std::unique_ptr<base::Value> V8ValueConverter::FromV8ValueImpl(
    FromV8ValueState* state,
    v8::Local<v8::Value> val,
    v8::Isolate* isolate) const {
  FromV8ValueState::Level state_level(state);
  if (state->HasReachedMaxRecursionDepth())
    return nullptr;

  if (val->IsExternal())
    return std::make_unique<base::Value>();

  if (val->IsNull())
    return std::make_unique<base::Value>();

  auto context = isolate->GetCurrentContext();

  if (val->IsBoolean())
    return std::make_unique<base::Value>(val->ToBoolean(isolate)->Value());

  if (val->IsInt32())
    return std::make_unique<base::Value>(val.As<v8::Int32>()->Value());

  if (val->IsNumber()) {
    double val_as_double = val.As<v8::Number>()->Value();
    if (!std::isfinite(val_as_double))
      return nullptr;
    return std::make_unique<base::Value>(val_as_double);
  }

  if (val->IsString()) {
    v8::String::Utf8Value utf8(isolate, val);
    return std::make_unique<base::Value>(std::string(*utf8, utf8.length()));
  }

  if (val->IsUndefined())
    // JSON.stringify ignores undefined.
    return nullptr;

  if (val->IsDate()) {
    v8::Date* date = v8::Date::Cast(*val);
    v8::Local<v8::Value> toISOString =
        date->Get(context, v8::String::NewFromUtf8(isolate, "toISOString",
                                                   v8::NewStringType::kNormal)
                               .ToLocalChecked())
            .ToLocalChecked();
    if (toISOString->IsFunction()) {
      v8::MaybeLocal<v8::Value> result =
          toISOString.As<v8::Function>()->Call(context, val, 0, nullptr);
      if (!result.IsEmpty()) {
        v8::String::Utf8Value utf8(isolate, result.ToLocalChecked());
        return std::make_unique<base::Value>(std::string(*utf8, utf8.length()));
      }
    }
  }

  if (val->IsRegExp()) {
    if (!reg_exp_allowed_)
      // JSON.stringify converts to an object.
      return FromV8Object(val.As<v8::Object>(), state, isolate);
    return std::make_unique<base::Value>(*v8::String::Utf8Value(isolate, val));
  }

  // v8::Value doesn't have a ToArray() method for some reason.
  if (val->IsArray())
    return FromV8Array(val.As<v8::Array>(), state, isolate);

  if (val->IsFunction()) {
    if (!function_allowed_)
      // JSON.stringify refuses to convert function(){}.
      return nullptr;
    return FromV8Object(val.As<v8::Object>(), state, isolate);
  }

  if (node::Buffer::HasInstance(val)) {
    return FromNodeBuffer(val, state, isolate);
  }

  if (val->IsObject()) {
    return FromV8Object(val.As<v8::Object>(), state, isolate);
  }

  LOG(ERROR) << "Unexpected v8 value type encountered.";
  return nullptr;
}