V8Value V8ContextImpl::ExportValue()

in ClearScriptV8/V8ContextImpl.cpp [2889:3069]


V8Value V8ContextImpl::ExportValue(v8::Local<v8::Value> hValue)
{
    FROM_MAYBE_TRY

        if (hValue.IsEmpty())
        {
            return V8Value(V8Value::Nonexistent);
        }

        if (hValue->IsUndefined())
        {
            return V8Value(V8Value::Undefined);
        }

        if (hValue->IsNull())
        {
            return V8Value(V8Value::Null);
        }

        if (hValue->IsBoolean())
        {
            return V8Value(m_spIsolateImpl->BooleanValue(hValue));
        }

        if (hValue->IsNumber())
        {
            return V8Value(FROM_MAYBE(hValue->NumberValue(m_hContext)));
        }

        if (hValue->IsInt32())
        {
            return V8Value(FROM_MAYBE(hValue->Int32Value(m_hContext)));
        }

        if (hValue->IsUint32())
        {
            return V8Value(FROM_MAYBE(hValue->Uint32Value(m_hContext)));
        }

        if (hValue->IsString())
        {
            return V8Value(new StdString(CreateStdString(hValue)));
        }

        if (m_DateTimeConversionEnabled && hValue->IsDate())
        {
            return V8Value(V8Value::DateTime, hValue.As<v8::Date>()->ValueOf());
        }

        auto hBigInt = ::ValueAsBigInt(hValue);
        if (!hBigInt.IsEmpty())
        {
            auto signBit = 0;
            std::vector<uint64_t> words;

            auto wordCount = hBigInt->WordCount();
            if (wordCount > 0)
            {
                words.resize(wordCount);
                hBigInt->ToWordsArray(&signBit, &wordCount, words.data());
            }

            return V8Value(new V8BigInt(signBit, std::move(words)));
        }

        auto hObject = ::ValueAsObject(hValue);
        if (!hObject.IsEmpty())
        {
            auto pHolder = GetHostObjectHolder(hObject);
            if (pHolder != nullptr)
            {
                return V8Value(pHolder->Clone());
            }

            auto subtype = V8Value::Subtype::None;
            auto flags = V8Value::Flags::None;
            SharedPtr<V8SharedObjectInfo> spSharedObjectInfo;

            if (hObject->IsPromise())
            {
                subtype = V8Value::Subtype::Promise;
            }
            else if (hObject->IsArray())
            {
                subtype = V8Value::Subtype::Array;
            }
            else if (hObject->IsArrayBuffer())
            {
                subtype = V8Value::Subtype::ArrayBuffer;
            }
            else if (hObject->IsSharedArrayBuffer())
            {
                subtype = V8Value::Subtype::ArrayBuffer;
                flags = CombineFlags(flags, V8Value::Flags::Shared);

                auto hSharedArrayBuffer = v8::Local<v8::SharedArrayBuffer>::Cast(hObject);
                auto size = hSharedArrayBuffer->ByteLength();
                spSharedObjectInfo = new V8SharedObjectInfo(hSharedArrayBuffer->GetBackingStore(), 0, size, size);
            }
            else if (hObject->IsArrayBufferView())
            {
                auto hArrayBufferView = v8::Local<v8::ArrayBufferView>::Cast(hObject);
                auto offset = hArrayBufferView->ByteOffset();
                auto size = hArrayBufferView->ByteLength();

                auto spBackingStore = hArrayBufferView->Buffer()->GetBackingStore();
                if (spBackingStore->IsShared())
                {
                    flags = CombineFlags(flags, V8Value::Flags::Shared);
                }

                if (hObject->IsDataView())
                {
                    subtype = V8Value::Subtype::DataView;
                    if (HasFlag(flags, V8Value::Flags::Shared))
                    {
                        spSharedObjectInfo = new V8SharedObjectInfo(std::move(spBackingStore), offset, size, size);
                    }
                }
                else if (hObject->IsTypedArray())
                {
                    if (hObject->IsUint8Array())
                    {
                        subtype = V8Value::Subtype::Uint8Array;
                    }
                    else if (hObject->IsUint8ClampedArray())
                    {
                        subtype = V8Value::Subtype::Uint8ClampedArray;
                    }
                    else if (hObject->IsInt8Array())
                    {
                        subtype = V8Value::Subtype::Int8Array;
                    }
                    else if (hObject->IsUint16Array())
                    {
                        subtype = V8Value::Subtype::Uint16Array;
                    }
                    else if (hObject->IsInt16Array())
                    {
                        subtype = V8Value::Subtype::Int16Array;
                    }
                    else if (hObject->IsUint32Array())
                    {
                        subtype = V8Value::Subtype::Uint32Array;
                    }
                    else if (hObject->IsInt32Array())
                    {
                        subtype = V8Value::Subtype::Int32Array;
                    }
                    else if (hObject->IsBigUint64Array())
                    {
                        subtype = V8Value::Subtype::BigUint64Array;
                    }
                    else if (hObject->IsBigInt64Array())
                    {
                        subtype = V8Value::Subtype::BigInt64Array;
                    }
                    else if (hObject->IsFloat32Array())
                    {
                        subtype = V8Value::Subtype::Float32Array;
                    }
                    else if (hObject->IsFloat64Array())
                    {
                        subtype = V8Value::Subtype::Float64Array;
                    }

                    if (HasFlag(flags, V8Value::Flags::Shared) && (subtype != V8Value::Subtype::None))
                    {
                        auto hTypedArray = v8::Local<v8::TypedArray>::Cast(hObject);
                        spSharedObjectInfo = new V8SharedObjectInfo(std::move(spBackingStore), offset, size, hTypedArray->Length());
                    }
                }
            }

            return V8Value(new V8ObjectHolderImpl(GetWeakBinding(), ::PtrFromHandle(CreatePersistent(hObject)), spSharedObjectInfo), subtype, flags);
        }

    FROM_MAYBE_CATCH_CONSUME

    return V8Value(V8Value::Undefined);
}