Repository: LadybirdBrowser/ladybird
File: Libraries/LibWeb/WebGL/WebGL2RenderingContextImpl.cpp (C++)

Code before:
            return {};
        }
        program_handle = handle_or_error.release_value();
    }

    auto name_null_terminated = null_terminated_string(name);

    // "This function returns -1 if name does not correspond to an active uniform variable in program or if name starts
    //  with the reserved prefix "gl_"."
    // WebGL Spec: The return value is null if name does not correspond to an active uniform variable in the passed program.
    auto location = glGetUniformLocation(program_handle, name_null_terminated.data());
    if (location == -1)
        return nullptr;

    return WebGLUniformLocation::create(m_realm, location);
}

JS::Value WebGL2RenderingContextImpl::get_vertex_attrib(WebIDL::UnsignedLong index, WebIDL::UnsignedLong pname)
{
    switch (pname) {
    case GL_CURRENT_VERTEX_ATTRIB: {
        Array<GLfloat, 4> result;
        result.fill(0);
        glGetVertexAttribfvRobustANGLE(index, GL_CURRENT_VERTEX_ATTRIB, result.size(), nullptr, result.data());

        auto byte_buffer = MUST(ByteBuffer::copy(result.data(), result.span().reinterpret<u8>().size()));
        auto array_buffer = JS::ArrayBuffer::create(m_realm, move(byte_buffer));
        return JS::Float32Array::create(m_realm, result.size(), array_buffer);
    }
    case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: {
        GLint handle { 0 };
        glGetVertexAttribivRobustANGLE(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, 1, nullptr, &handle);
        return WebGLBuffer::create(m_realm, *this, handle);
    }
    case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: {
        GLint result { 0 };
        glGetVertexAttribivRobustANGLE(index, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 1, nullptr, &result);
        return JS::Value(result);
    }
    case GL_VERTEX_ATTRIB_ARRAY_ENABLED: {
        GLint result { 0 };
        glGetVertexAttribivRobustANGLE(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, 1, nullptr, &result);
        return JS::Value(result == GL_TRUE);
    }
    case GL_VERTEX_ATTRIB_ARRAY_INTEGER: {
        GLint result { 0 };
        glGetVertexAttribivRobustANGLE(index, GL_VERTEX_ATTRIB_ARRAY_INTEGER, 1, nullptr, &result);
        return JS::Value(result == GL_TRUE);
    }
    case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: {
        GLint result { 0 };

Review comment (suggestion):
`::copy()` takes a `ReadonlyBytes` which is an alias for `ReadonlySpan<u8>`:

```cpp
auto byte_buffer = MUST(ByteBuffer::copy(result.span().reinterpret<u8>()));
```

Code after:
    m_context->make_current();

    GLuint shader_handle = 0;
    if (shader) {
        auto handle_or_error = shader->handle(this);
        if (handle_or_error.is_error()) {
            set_error(GL_INVALID_OPERATION);
            return {};
        }
        shader_handle = handle_or_error.release_value();
    }

    GLint info_log_length = 0;
    glGetShaderiv(shader_handle, GL_INFO_LOG_LENGTH, &info_log_length);
    Vector<GLchar> info_log;
    info_log.resize(info_log_length);
    if (!info_log_length)
        return String {};
    glGetShaderInfoLog(shader_handle, info_log_length, nullptr, info_log.data());
    return String::from_utf8_without_validation(ReadonlyBytes { info_log.data(), static_cast<size_t>(info_log_length - 1) });
}

Optional<String> WebGL2RenderingContextImpl::get_shader_source(GC::Root<WebGLShader> shader)
{
    m_context->make_current();

    GLuint shader_handle = 0;
    if (shader) {
        auto handle_or_error = shader->handle(this);
        if (handle_or_error.is_error()) {
            set_error(GL_INVALID_OPERATION);
            return {};
        }
        shader_handle = handle_or_error.release_value();
    }

    GLint shader_source_length = 0;
    glGetShaderiv(shader_handle, GL_SHADER_SOURCE_LENGTH, &shader_source_length);
    if (!shader_source_length)
        return String {};

    auto shader_source = MUST(ByteBuffer::create_uninitialized(shader_source_length));
    glGetShaderSource(shader_handle, shader_source_length, nullptr, reinterpret_cast<GLchar*>(shader_source.data()));
    return String::from_utf8_without_validation(ReadonlyBytes { shader_source.data(), static_cast<size_t>(shader_source_length - 1) });
}

JS::Value WebGL2RenderingContextImpl::get_uniform(GC::Root<WebGLProgram>, GC::Root<WebGLUniformLocation>)
{
    dbgln("FIXME: Implement get_uniform");
    return JS::Value(0);
}