<commit_before>#include "debug.h"
#include "fpe.h"
#include "gl4es.h"
#include "glstate.h"
#include "loader.h"
#include "oldprogram.h"
#include "shaderconv.h"
#include "vertexattrib.h"
#include "arbconverter.h"
#include "debug.h"

//#define DEBUG
#ifdef DEBUG
#define DBG(a) a
#else
#define DBG(a)
#endif

// Implement "Old program" handling: so ARB_vertex_program and ARB_fragment_program extensions
// the core of this is a conversion between ARB ASM-like syntax to GLSL, then using regular functions
// Note that a program in this context is in fact a shader in ARB_vertex_shader (and GLSL) extension

KHASH_MAP_INIT_INT(oldprograms, oldprogram_t *);

void freeOldProgram(oldprogram_t* old)
{
    if(!old)
        return;
    if(old->string)
        free(old->string);
    if(old->shader)
        gl4es_glDeleteShader(old->shader->id);
    if(old->prog_local_params)
        free(old->prog_local_params);
    free(old);
}

void InitOldProgramMap(glstate_t* glstate)
{
    if(glstate->glsl) {
        glstate->glsl->oldprograms = kh_init(oldprograms);
        glstate->glsl->error_msg = NULL;
        glstate->glsl->error_ptr = -1;
    }
}
void FreeOldProgramMap(glstate_t* glstate)
{
    if(!glstate->glsl)
        return;
    if(glstate->glsl->error_msg)
        free(glstate->glsl->error_msg);
    oldprogram_t* old;
    kh_foreach_value(glstate->glsl->oldprograms, old, freeOldProgram(old));
    kh_destroy(oldprograms, glstate->glsl->oldprograms);
}

GLuint getUniqueProgramID(GLuint last) {
    // avoid recycling prog id (that may messup FPE Cache)
    static GLuint upper = 0;
    if(last>upper) last = upper;
    khint_t k;
    do {
        ++last;
        k = kh_get(oldprograms, glstate->glsl->oldprograms, last);
    } while(k!=kh_end(glstate->glsl->oldprograms));
    upper = last;
    return last;
}

oldprogram_t* getOldProgram(GLuint program)
{
    kh_oldprograms_t * oldprograms = glstate->glsl->oldprograms;
    if(program) {
        khint_t k = kh_get(oldprograms, oldprograms, program);
        if(k != kh_end(oldprograms))
            return kh_value(oldprograms, k);
    }
    return NULL;
}


// Vertex function are also defined with ARB_vertex_shader
/*
void gl4es_glVertexAttrib1sARB(GLuint index, GLshort x)
void gl4es_glVertexAttrib1fARB(GLuint index, GLfloat x);
void gl4es_glVertexAttrib1dARB(GLuint index, GLdouble x);
void gl4es_glVertexAttrib2sARB(GLuint index, GLshort x, GLshort y);
void gl4es_glVertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y);
void gl4es_glVertexAttrib2dARB(GLuint index, GLdouble x, GLdouble y);
void gl4es_glVertexAttrib3sARB(GLuint index, GLshort x, GLshort y, GLshort z);
void gl4es_glVertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z);
void gl4es_glVertexAttrib3dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z);
void gl4es_glVertexAttrib4sARB(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
void gl4es_glVertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void gl4es_glVertexAttrib4dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
void gl4es_glVertexAttrib4NubARB(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
void gl4es_glVertexAttrib1svARB(GLuint index, const GLshort *v);
void gl4es_glVertexAttrib1fvARB(GLuint index, const GLfloat *v);
void gl4es_glVertexAttrib1dvARB(GLuint index, const GLdouble *v);
void gl4es_glVertexAttrib2svARB(GLuint index, const GLshort *v);
void gl4es_glVertexAttrib2fvARB(GLuint index, const GLfloat *v);
void gl4es_glVertexAttrib2dvARB(GLuint index, const GLdouble *v);
void gl4es_glVertexAttrib3svARB(GLuint index, const GLshort *v);
void gl4es_glVertexAttrib3fvARB(GLuint index, const GLfloat *v);
void gl4es_glVertexAttrib3dvARB(GLuint index, const GLdouble *v);
void gl4es_glVertexAttrib4bvARB(GLuint index, const GLbyte *v);
void gl4es_glVertexAttrib4svARB(GLuint index, const GLshort *v);
void gl4es_glVertexAttrib4ivARB(GLuint index, const GLint *v);
void gl4es_glVertexAttrib4ubvARB(GLuint index, const GLubyte *v);
void gl4es_glVertexAttrib4usvARB(GLuint index, const GLushort *v);
void gl4es_glVertexAttrib4uivARB(GLuint index, const GLuint *v);
void gl4es_glVertexAttrib4fvARB(GLuint index, const GLfloat *v);
void gl4es_glVertexAttrib4dvARB(GLuint index, const GLdouble *v);
void gl4es_glVertexAttrib4NbvARB(GLuint index, const GLbyte *v);
void gl4es_glVertexAttrib4NsvARB(GLuint index, const GLshort *v);
void gl4es_glVertexAttrib4NivARB(GLuint index, const GLint *v);
void gl4es_glVertexAttrib4NubvARB(GLuint index, const GLubyte *v);
void gl4es_glVertexAttrib4NusvARB(GLuint index, const GLushort *v);
void gl4es_glVertexAttrib4NuivARB(GLuint index, const GLuint *v);
void gl4es_glVertexAttribPointerARB(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
void gl4es_glEnableVertexAttribArrayARB(GLuint index);
void gl4es_glDisableVertexAttribArrayARB(GLuint index);
*/

void gl4es_glProgramStringARB(GLenum target, GLenum format, GLsizei len, const GLvoid *string) {
    DBG(printf("glProgramStringARB(%s, %s, %d, %p), source is\n%s\n=======\n", PrintEnum(target), PrintEnum(format), len, string, string);)
    oldprogram_t* old = NULL;
    int vertex;
    switch(target) {
        case GL_VERTEX_PROGRAM_ARB:
            old = glstate->glsl->vtx_prog;
            vertex = 1;
            break;
        case GL_FRAGMENT_PROGRAM_ARB:
            old = glstate->glsl->frg_prog;
            vertex = 0;
            break;
        default:
            errorShim(GL_INVALID_VALUE);
            return;
    }
    if(format!=GL_PROGRAM_FORMAT_ASCII_ARB) {
        errorShim(GL_INVALID_ENUM);
        return;
    }
    if(old->string)
        free(old->string);
    // grab the new program
    old->string = calloc(1, len + 1);
    memcpy(old->string, string, len);
    // Convert to GLSL
    const GLchar * p[1] = {0};
    p[0] = gl4es_convertARB(old->string, vertex, &glstate->glsl->error_msg, &glstate->glsl->error_ptr);
    if(!p[0]) {
        DBG(printf("Error with ARB->GLSL conversion\nsource is:\n%s\n======\n", old->shader->source);)
        errorShim(GL_INVALID_OPERATION);
        return;
    }
    gl4es_glShaderSource(old->shader->id, 1, p , NULL);
    DBG(printf("converted source is:\n%s\n======\n", old->shader->source?old->shader->source:"**error**");)<commit_msg>[GLES2] Try to avoid a crash on glProgramStringARB if there is a bad context<commit_after>#include "debug.h"
#include "fpe.h"
#include "gl4es.h"
#include "glstate.h"
#include "loader.h"
#include "oldprogram.h"
#include "shaderconv.h"
#include "vertexattrib.h"
#include "arbconverter.h"
#include "debug.h"

//#define DEBUG
#ifdef DEBUG
#define DBG(a) a
#else
#define DBG(a)
#endif

// Implement "Old program" handling: so ARB_vertex_program and ARB_fragment_program extensions
// the core of this is a conversion between ARB ASM-like syntax to GLSL, then using regular functions
// Note that a program in this context is in fact a shader in ARB_vertex_shader (and GLSL) extension

KHASH_MAP_INIT_INT(oldprograms, oldprogram_t *);

void freeOldProgram(oldprogram_t* old)
{
    if(!old)
        return;
    if(old->string)
        free(old->string);
    if(old->shader)
        gl4es_glDeleteShader(old->shader->id);
    if(old->prog_local_params)
        free(old->prog_local_params);
    free(old);
}

void InitOldProgramMap(glstate_t* glstate)
{
    if(glstate->glsl) {
        glstate->glsl->oldprograms = kh_init(oldprograms);
        glstate->glsl->error_msg = NULL;
        glstate->glsl->error_ptr = -1;
    }
}
void FreeOldProgramMap(glstate_t* glstate)
{
    if(!glstate->glsl)
        return;
    if(glstate->glsl->error_msg)
        free(glstate->glsl->error_msg);
    oldprogram_t* old;
    kh_foreach_value(glstate->glsl->oldprograms, old, freeOldProgram(old));
    kh_destroy(oldprograms, glstate->glsl->oldprograms);
}

GLuint getUniqueProgramID(GLuint last) {
    // avoid recycling prog id (that may messup FPE Cache)
    static GLuint upper = 0;
    if(last>upper) last = upper;
    khint_t k;
    do {
        ++last;
        k = kh_get(oldprograms, glstate->glsl->oldprograms, last);
    } while(k!=kh_end(glstate->glsl->oldprograms));
    upper = last;
    return last;
}

oldprogram_t* getOldProgram(GLuint program)
{
    kh_oldprograms_t * oldprograms = glstate->glsl->oldprograms;
    if(program) {
        khint_t k = kh_get(oldprograms, oldprograms, program);
        if(k != kh_end(oldprograms))
            return kh_value(oldprograms, k);
    }
    return NULL;
}


// Vertex function are also defined with ARB_vertex_shader
/*
void gl4es_glVertexAttrib1sARB(GLuint index, GLshort x)
void gl4es_glVertexAttrib1fARB(GLuint index, GLfloat x);
void gl4es_glVertexAttrib1dARB(GLuint index, GLdouble x);
void gl4es_glVertexAttrib2sARB(GLuint index, GLshort x, GLshort y);
void gl4es_glVertexAttrib2fARB(GLuint index, GLfloat x, GLfloat y);
void gl4es_glVertexAttrib2dARB(GLuint index, GLdouble x, GLdouble y);
void gl4es_glVertexAttrib3sARB(GLuint index, GLshort x, GLshort y, GLshort z);
void gl4es_glVertexAttrib3fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z);
void gl4es_glVertexAttrib3dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z);
void gl4es_glVertexAttrib4sARB(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w);
void gl4es_glVertexAttrib4fARB(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
void gl4es_glVertexAttrib4dARB(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w);
void gl4es_glVertexAttrib4NubARB(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w);
void gl4es_glVertexAttrib1svARB(GLuint index, const GLshort *v);
void gl4es_glVertexAttrib1fvARB(GLuint index, const GLfloat *v);
void gl4es_glVertexAttrib1dvARB(GLuint index, const GLdouble *v);
void gl4es_glVertexAttrib2svARB(GLuint index, const GLshort *v);
void gl4es_glVertexAttrib2fvARB(GLuint index, const GLfloat *v);
void gl4es_glVertexAttrib2dvARB(GLuint index, const GLdouble *v);
void gl4es_glVertexAttrib3svARB(GLuint index, const GLshort *v);
void gl4es_glVertexAttrib3fvARB(GLuint index, const GLfloat *v);
void gl4es_glVertexAttrib3dvARB(GLuint index, const GLdouble *v);
void gl4es_glVertexAttrib4bvARB(GLuint index, const GLbyte *v);
void gl4es_glVertexAttrib4svARB(GLuint index, const GLshort *v);
void gl4es_glVertexAttrib4ivARB(GLuint index, const GLint *v);
void gl4es_glVertexAttrib4ubvARB(GLuint index, const GLubyte *v);
void gl4es_glVertexAttrib4usvARB(GLuint index, const GLushort *v);
void gl4es_glVertexAttrib4uivARB(GLuint index, const GLuint *v);
void gl4es_glVertexAttrib4fvARB(GLuint index, const GLfloat *v);
void gl4es_glVertexAttrib4dvARB(GLuint index, const GLdouble *v);
void gl4es_glVertexAttrib4NbvARB(GLuint index, const GLbyte *v);
void gl4es_glVertexAttrib4NsvARB(GLuint index, const GLshort *v);
void gl4es_glVertexAttrib4NivARB(GLuint index, const GLint *v);
void gl4es_glVertexAttrib4NubvARB(GLuint index, const GLubyte *v);
void gl4es_glVertexAttrib4NusvARB(GLuint index, const GLushort *v);
void gl4es_glVertexAttrib4NuivARB(GLuint index, const GLuint *v);
void gl4es_glVertexAttribPointerARB(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
void gl4es_glEnableVertexAttribArrayARB(GLuint index);
void gl4es_glDisableVertexAttribArrayARB(GLuint index);
*/

void gl4es_glProgramStringARB(GLenum target, GLenum format, GLsizei len, const GLvoid *string) {
    DBG(printf("glProgramStringARB(%s, %s, %d, %p), source is\n%s\n=======\n", PrintEnum(target), PrintEnum(format), len, string, string);)
    oldprogram_t* old = NULL;
    int vertex;
    switch(target) {
        case GL_VERTEX_PROGRAM_ARB:
            old = glstate->glsl->vtx_prog;
            vertex = 1;
            break;
        case GL_FRAGMENT_PROGRAM_ARB:
            old = glstate->glsl->frg_prog;
            vertex = 0;
            break;
        default:
            errorShim(GL_INVALID_VALUE);
            return;
    }
    if(format!=GL_PROGRAM_FORMAT_ASCII_ARB) {
        errorShim(GL_INVALID_ENUM);
        return;
    }
    if(old->string)
        free(old->string);
    // grab the new program
    old->string = calloc(1, len + 1);
    memcpy(old->string, string, len);
    // check if a shader is actually attached
    if(!old->shader) {
        DBG(printf("Error, no shader attached but glProgramStringARB(...) called\n");)
        errorShim(GL_INVALID_OPERATION);
        return;
    }
    // Convert to GLSL
    const GLchar * p[1] = {0};
    p[0] = gl4es_convertARB(old->string, vertex, &glstate->glsl->error_msg, &glstate->glsl->error_ptr);
    if(!p[0]) {
        DBG(printf("Error with ARB->GLSL conversion\nsource is:\n%s\n======\n", old->shader->source);)
        errorShim(GL_INVALID_OPERATION);
        return;
    }
    gl4es_glShaderSource(old->shader->id, 1, p , NULL);
    DBG(printf("converted source is:\n%s\n======\n", old->shader->source?old->shader->source:"**error**");)
{'fraction_non_alphanumeric': 0.11082753286929621, 'fraction_numerical': 0.014153132250580047, 'mean_word_length': 4.528430953398888, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 108, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2087698', 'n_tokens_mistral': 4648, 'n_tokens_neox': 4757, 'n_words': 1077}