mojoshader_compiler.c
changeset 935 bef902f8b4d9
parent 932 079c62f868eb
child 936 b4a15ef390c4
equal deleted inserted replaced
934:f6ecea50c607 935:bef902f8b4d9
    86     MOJOSHADER_malloc malloc;
    86     MOJOSHADER_malloc malloc;
    87     MOJOSHADER_free free;
    87     MOJOSHADER_free free;
    88     void *malloc_data;
    88     void *malloc_data;
    89     int error_count;
    89     int error_count;
    90     ErrorList *errors;
    90     ErrorList *errors;
       
    91     int warning_count;
       
    92     ErrorList *warnings;
    91     StringCache *strcache;
    93     StringCache *strcache;
    92     const char *sourcefile;  // current source file that we're parsing.
    94     const char *sourcefile;  // current source file that we're parsing.
    93     unsigned int sourceline; // current line in sourcefile that we're parsing.
    95     unsigned int sourceline; // current line in sourcefile that we're parsing.
    94     SymbolMap usertypes;
    96     SymbolMap usertypes;
    95     SymbolMap variables;
    97     SymbolMap variables;
  2168         destroy_symbolmap(ctx, &ctx->variables);
  2170         destroy_symbolmap(ctx, &ctx->variables);
  2169 
  2171 
  2170         if (ctx->strcache)
  2172         if (ctx->strcache)
  2171             stringcache_destroy(ctx->strcache);
  2173             stringcache_destroy(ctx->strcache);
  2172 
  2174 
       
  2175         // !!! FIXME: more to clean up here, now.
       
  2176 
  2173         f(ctx, d);
  2177         f(ctx, d);
  2174     } // if
  2178     } // if
  2175 } // destroy_context
  2179 } // destroy_context
  2176 
  2180 
  2177 static Context *build_context(MOJOSHADER_malloc m, MOJOSHADER_free f, void *d)
  2181 static Context *build_context(MOJOSHADER_malloc m, MOJOSHADER_free f, void *d)
  2363 static MOJOSHADER_astData MOJOSHADER_out_of_mem_ast_data = {
  2367 static MOJOSHADER_astData MOJOSHADER_out_of_mem_ast_data = {
  2364     1, &MOJOSHADER_out_of_mem_error, 0, 0, 0, 0, 0
  2368     1, &MOJOSHADER_out_of_mem_error, 0, 0, 0, 0, 0
  2365 };
  2369 };
  2366 
  2370 
  2367 // !!! FIXME: cut and paste from assembler.
  2371 // !!! FIXME: cut and paste from assembler.
  2368 static MOJOSHADER_error *build_errors(Context *ctx)
  2372 // !!! FIXME: make ErrorList into something with a head/tail and count
       
  2373 // !!! FIXME:  inherent.
       
  2374 static MOJOSHADER_error *build_errors(Context *ctx, ErrorList **list, const int count)
  2369 {
  2375 {
  2370     int total = 0;
  2376     int total = 0;
  2371     MOJOSHADER_error *retval = (MOJOSHADER_error *)
  2377     MOJOSHADER_error *retval = (MOJOSHADER_error *)
  2372             Malloc(ctx, sizeof (MOJOSHADER_error) * ctx->error_count);
  2378             Malloc(ctx, sizeof (MOJOSHADER_error) * count);
  2373     if (retval == NULL)
  2379     if (retval == NULL)
  2374         return NULL;
  2380         return NULL;
  2375 
  2381 
  2376     ErrorList *item = ctx->errors;
  2382     ErrorList *item = *list;
  2377     while (item != NULL)
  2383     while (item != NULL)
  2378     {
  2384     {
  2379         ErrorList *next = item->next;
  2385         ErrorList *next = item->next;
  2380         // reuse the string allocations
  2386         // reuse the string allocations
  2381         memcpy(&retval[total], &item->error, sizeof (MOJOSHADER_error));
  2387         memcpy(&retval[total], &item->error, sizeof (MOJOSHADER_error));
  2382         Free(ctx, item);
  2388         Free(ctx, item);
  2383         item = next;
  2389         item = next;
  2384         total++;
  2390         total++;
  2385     } // while
  2391     } // while
  2386     ctx->errors = NULL;
  2392     *list = NULL;
  2387 
  2393 
  2388     assert(total == ctx->error_count);
  2394     assert(total == count);
  2389     return retval;
  2395     return retval;
  2390 } // build_errors
  2396 } // build_errors
  2391 
  2397 
  2392 
  2398 
  2393 // !!! FIXME: cut and paste from assembler.
  2399 // !!! FIXME: cut and paste from assembler.
  2402     retval = (MOJOSHADER_astData *) Malloc(ctx, sizeof (MOJOSHADER_astData));
  2408     retval = (MOJOSHADER_astData *) Malloc(ctx, sizeof (MOJOSHADER_astData));
  2403     if (retval == NULL)
  2409     if (retval == NULL)
  2404         return &MOJOSHADER_out_of_mem_ast_data;
  2410         return &MOJOSHADER_out_of_mem_ast_data;
  2405 
  2411 
  2406     memset(retval, '\0', sizeof (MOJOSHADER_astData));
  2412     memset(retval, '\0', sizeof (MOJOSHADER_astData));
       
  2413     retval->source_profile = ctx->source_profile;
  2407     retval->malloc = (ctx->malloc == MOJOSHADER_internal_malloc) ? NULL : ctx->malloc;
  2414     retval->malloc = (ctx->malloc == MOJOSHADER_internal_malloc) ? NULL : ctx->malloc;
  2408     retval->free = (ctx->free == MOJOSHADER_internal_free) ? NULL : ctx->free;
  2415     retval->free = (ctx->free == MOJOSHADER_internal_free) ? NULL : ctx->free;
  2409     retval->malloc_data = ctx->malloc_data;
  2416     retval->malloc_data = ctx->malloc_data;
  2410 
  2417 
  2411     retval->error_count = ctx->error_count;
  2418     retval->error_count = ctx->error_count;
  2412     retval->errors = build_errors(ctx);
  2419     retval->errors = build_errors(ctx, &ctx->errors, ctx->error_count);
  2413     if ((retval->errors == NULL) && (ctx->error_count > 0))
  2420     if ((retval->errors == NULL) && (ctx->error_count > 0))
  2414     {
  2421     {
  2415         Free(ctx, retval);
  2422         Free(ctx, retval);
  2416         return &MOJOSHADER_out_of_mem_ast_data;
  2423         return &MOJOSHADER_out_of_mem_ast_data;
  2417     } // if
  2424     } // if
  2434     memset(retval, '\0', sizeof (MOJOSHADER_astData));
  2441     memset(retval, '\0', sizeof (MOJOSHADER_astData));
  2435 
  2442 
  2436     if (!isfail(ctx))
  2443     if (!isfail(ctx))
  2437     {
  2444     {
  2438         retval->source_profile = ctx->source_profile;
  2445         retval->source_profile = ctx->source_profile;
  2439         ctx->source_profile = NULL;  // don't free this with the context, now.
       
  2440         retval->ast = ctx->ast;
  2446         retval->ast = ctx->ast;
  2441         ctx->ast = NULL;  // don't free this with the context, now.
  2447         ctx->ast = NULL;  // don't free this with the context, now.
  2442     } // if
  2448     } // if
  2443 
  2449 
  2444     retval->error_count = ctx->error_count;
  2450     retval->error_count = ctx->error_count;
  2445     retval->errors = build_errors(ctx);
  2451     retval->errors = build_errors(ctx, &ctx->errors, ctx->error_count);
       
  2452     if (retval->errors == NULL)
       
  2453     {
       
  2454         Free(ctx, retval);
       
  2455         return &MOJOSHADER_out_of_mem_ast_data;
       
  2456     } // if
       
  2457 
  2446     retval->malloc = (ctx->malloc == MOJOSHADER_internal_malloc) ? NULL : ctx->malloc;
  2458     retval->malloc = (ctx->malloc == MOJOSHADER_internal_malloc) ? NULL : ctx->malloc;
  2447     retval->free = (ctx->free == MOJOSHADER_internal_free) ? NULL : ctx->free;
  2459     retval->free = (ctx->free == MOJOSHADER_internal_free) ? NULL : ctx->free;
  2448     retval->malloc_data = ctx->malloc_data;
  2460     retval->malloc_data = ctx->malloc_data;
  2449 
  2461 
  2450     return retval;
  2462     return retval;
  2451 } // build_astdata
  2463 } // build_astdata
       
  2464 
  2452 
  2465 
  2453 static void choose_src_profile(Context *ctx, const char *srcprofile)
  2466 static void choose_src_profile(Context *ctx, const char *srcprofile)
  2454 {
  2467 {
  2455     #define TEST_PROFILE(x) do { \
  2468     #define TEST_PROFILE(x) do { \
  2456         if (strcmp(srcprofile, x) == 0) { \
  2469         if (strcmp(srcprofile, x) == 0) { \
  2471 
  2484 
  2472     #undef TEST_PROFILE
  2485     #undef TEST_PROFILE
  2473 
  2486 
  2474     fail(ctx, "Unknown profile");
  2487     fail(ctx, "Unknown profile");
  2475 } // choose_src_profile
  2488 } // choose_src_profile
       
  2489 
       
  2490 
       
  2491 static MOJOSHADER_compileData MOJOSHADER_out_of_mem_compile_data = {
       
  2492     1, &MOJOSHADER_out_of_mem_error, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
       
  2493 };
       
  2494 
       
  2495 
       
  2496 // !!! FIXME: cut and paste from assembler.
       
  2497 static const MOJOSHADER_compileData *build_failed_compile(Context *ctx)
       
  2498 {
       
  2499     assert(isfail(ctx));
       
  2500 
       
  2501     if (ctx->out_of_memory)
       
  2502         return &MOJOSHADER_out_of_mem_compile_data;
       
  2503         
       
  2504     MOJOSHADER_compileData *retval = NULL;
       
  2505     retval = (MOJOSHADER_compileData *) Malloc(ctx, sizeof (MOJOSHADER_compileData));
       
  2506     if (retval == NULL)
       
  2507         return &MOJOSHADER_out_of_mem_compile_data;
       
  2508 
       
  2509     memset(retval, '\0', sizeof (MOJOSHADER_compileData));
       
  2510     retval->malloc = (ctx->malloc == MOJOSHADER_internal_malloc) ? NULL : ctx->malloc;
       
  2511     retval->free = (ctx->free == MOJOSHADER_internal_free) ? NULL : ctx->free;
       
  2512     retval->malloc_data = ctx->malloc_data;
       
  2513 
       
  2514     retval->source_profile = ctx->source_profile;
       
  2515 
       
  2516     retval->error_count = ctx->error_count;
       
  2517     retval->errors = build_errors(ctx, &ctx->errors, ctx->error_count);
       
  2518     if ((retval->errors == NULL) && (retval->error_count > 0))
       
  2519     {
       
  2520         MOJOSHADER_freeCompileData(retval);
       
  2521         return &MOJOSHADER_out_of_mem_compile_data;
       
  2522     } // if
       
  2523 
       
  2524     retval->warning_count = ctx->warning_count;
       
  2525     retval->warnings = build_errors(ctx, &ctx->warnings, ctx->warning_count);
       
  2526     if ((retval->warnings == NULL) && (retval->warning_count > 0))
       
  2527     {
       
  2528         MOJOSHADER_freeCompileData(retval);
       
  2529         return &MOJOSHADER_out_of_mem_compile_data;
       
  2530     } // if
       
  2531 
       
  2532     return retval;
       
  2533 } // build_failed_compile
       
  2534 
       
  2535 
       
  2536 static const MOJOSHADER_compileData *build_compiledata(Context *ctx)
       
  2537 {
       
  2538     MOJOSHADER_compileData *retval = NULL;
       
  2539 
       
  2540     if (ctx->out_of_memory)
       
  2541         return &MOJOSHADER_out_of_mem_compile_data;
       
  2542 
       
  2543     retval = (MOJOSHADER_compileData *) Malloc(ctx, sizeof (MOJOSHADER_compileData));
       
  2544     if (retval == NULL)
       
  2545         return &MOJOSHADER_out_of_mem_compile_data;
       
  2546 
       
  2547     memset(retval, '\0', sizeof (MOJOSHADER_compileData));
       
  2548     retval->malloc = (ctx->malloc == MOJOSHADER_internal_malloc) ? NULL : ctx->malloc;
       
  2549     retval->free = (ctx->free == MOJOSHADER_internal_free) ? NULL : ctx->free;
       
  2550     retval->malloc_data = ctx->malloc_data;
       
  2551 
       
  2552     retval->source_profile = ctx->source_profile;
       
  2553 
       
  2554     if (!isfail(ctx))
       
  2555     {
       
  2556         // !!! FIXME: build output and output_len here.
       
  2557     } // if
       
  2558 
       
  2559     if (!isfail(ctx))
       
  2560     {
       
  2561         // !!! FIXME: build symbols and symbol_count here.
       
  2562     } // if
       
  2563 
       
  2564     if (!isfail(ctx))
       
  2565     {
       
  2566         retval->error_count = ctx->error_count;
       
  2567         retval->errors = build_errors(ctx, &ctx->errors, ctx->error_count);
       
  2568         if ((retval->errors == NULL) && (retval->error_count > 0))
       
  2569         {
       
  2570             MOJOSHADER_freeCompileData(retval);
       
  2571             return &MOJOSHADER_out_of_mem_compile_data;
       
  2572         } // if
       
  2573     } // if
       
  2574 
       
  2575     if (!isfail(ctx))
       
  2576     {
       
  2577         retval->warning_count = ctx->warning_count;
       
  2578         retval->warnings = build_errors(ctx, &ctx->warnings, ctx->warning_count);
       
  2579         if ((retval->warnings == NULL) && (retval->warning_count > 0))
       
  2580         {
       
  2581             MOJOSHADER_freeCompileData(retval);
       
  2582             return &MOJOSHADER_out_of_mem_compile_data;
       
  2583         } // if
       
  2584     } // if
       
  2585 
       
  2586     return retval;
       
  2587 } // build_compiledata
  2476 
  2588 
  2477 
  2589 
  2478 // API entry point...
  2590 // API entry point...
  2479 
  2591 
  2480 // !!! FIXME: move this (and a lot of other things) to mojoshader_ast.c.
  2592 // !!! FIXME: move this (and a lot of other things) to mojoshader_ast.c.
  2555 
  2667 
  2556     f(data, d);
  2668     f(data, d);
  2557 } // MOJOSHADER_freeAstData
  2669 } // MOJOSHADER_freeAstData
  2558 
  2670 
  2559 
  2671 
  2560 
       
  2561 const MOJOSHADER_compileData *MOJOSHADER_compile(const char *srcprofile,
  2672 const MOJOSHADER_compileData *MOJOSHADER_compile(const char *srcprofile,
  2562                                     const char *filename, const char *source,
  2673                                     const char *filename, const char *source,
  2563                                     unsigned int sourcelen,
  2674                                     unsigned int sourcelen,
  2564                                     const MOJOSHADER_preprocessorDefine *defs,
  2675                                     const MOJOSHADER_preprocessorDefine *defs,
  2565                                     unsigned int define_count,
  2676                                     unsigned int define_count,
  2566                                     MOJOSHADER_includeOpen include_open,
  2677                                     MOJOSHADER_includeOpen include_open,
  2567                                     MOJOSHADER_includeClose include_close,
  2678                                     MOJOSHADER_includeClose include_close,
  2568                                     MOJOSHADER_malloc m, MOJOSHADER_free f,
  2679                                     MOJOSHADER_malloc m, MOJOSHADER_free f,
  2569                                     void *d)
  2680                                     void *d)
  2570 {
  2681 {
  2571     Context *ctx = build_context(m, f, d);
  2682     // !!! FIXME: cut and paste from MOJOSHADER_parseAst().
  2572     if (!ctx)
  2683     MOJOSHADER_compileData *retval = NULL;
  2573         return NULL;  // !!! FIXME: report error.
  2684     Context *ctx = NULL;
  2574 
  2685 
  2575     parse_source(ctx, filename, source, sourcelen, defs, define_count,
  2686     if ( ((m == NULL) && (f != NULL)) || ((m != NULL) && (f == NULL)) )
  2576                  include_open, include_close);
  2687         return &MOJOSHADER_out_of_mem_compile_data;  // supply both or neither.
  2577 
  2688 
  2578     // !!! FIXME: check (ctx->ast != NULL), and maybe isfail().
  2689     ctx = build_context(m, f, d);
  2579 
  2690     if (ctx == NULL)
  2580     semantic_analysis(ctx);
  2691         return &MOJOSHADER_out_of_mem_compile_data;
       
  2692 
       
  2693     choose_src_profile(ctx, srcprofile);
       
  2694 
       
  2695     if (!isfail(ctx))
       
  2696     {
       
  2697         parse_source(ctx, filename, source, sourcelen, defs, define_count,
       
  2698                      include_open, include_close);
       
  2699     } // if
       
  2700 
       
  2701     if (!isfail(ctx))
       
  2702         semantic_analysis(ctx);
       
  2703 
       
  2704     if (isfail(ctx))
       
  2705         retval = (MOJOSHADER_compileData *) build_failed_compile(ctx);
       
  2706     else
       
  2707         retval = (MOJOSHADER_compileData *) build_compiledata(ctx);
  2581 
  2708 
  2582     destroy_context(ctx);
  2709     destroy_context(ctx);
  2583 
  2710     return retval;
  2584     // !!! FIXME: report success/error.
       
  2585     return NULL;
       
  2586 } // MOJOSHADER_compile
  2711 } // MOJOSHADER_compile
  2587 
  2712 
       
  2713 
       
  2714 void MOJOSHADER_freeCompileData(const MOJOSHADER_compileData *_data)
       
  2715 {
       
  2716     MOJOSHADER_compileData *data = (MOJOSHADER_compileData *) _data;
       
  2717     if ((data == NULL) || (data == &MOJOSHADER_out_of_mem_compile_data))
       
  2718         return;  // no-op.
       
  2719 
       
  2720     MOJOSHADER_free f = (data->free == NULL) ? MOJOSHADER_internal_free : data->free;
       
  2721     void *d = data->malloc_data;
       
  2722     int i;
       
  2723 
       
  2724     // we don't f(data->source_profile), because that's internal static data.
       
  2725 
       
  2726     // check for NULL in case of dumb free() impl.
       
  2727     if (data->errors != NULL)
       
  2728     {
       
  2729         for (i = 0; i < data->error_count; i++)
       
  2730         {
       
  2731             if (data->errors[i].error != NULL)
       
  2732                 f((void *) data->errors[i].error, d);
       
  2733             if (data->errors[i].filename != NULL)
       
  2734                 f((void *) data->errors[i].filename, d);
       
  2735         } // for
       
  2736         f((void *) data->errors, d);
       
  2737     } // if
       
  2738 
       
  2739     if (data->warnings != NULL)
       
  2740     {
       
  2741         for (i = 0; i < data->warning_count; i++)
       
  2742         {
       
  2743             if (data->warnings[i].error != NULL)
       
  2744                 f((void *) data->warnings[i].error, d);
       
  2745             if (data->warnings[i].filename != NULL)
       
  2746                 f((void *) data->warnings[i].filename, d);
       
  2747         } // for
       
  2748         f((void *) data->warnings, d);
       
  2749     } // if
       
  2750 
       
  2751     if (data->symbols != NULL)
       
  2752     {
       
  2753         for (i = 0; i < data->symbol_count; i++)
       
  2754         {
       
  2755             if (data->symbols[i].name != NULL)
       
  2756                 f((void *) data->symbols[i].name, d);
       
  2757             if (data->symbols[i].default_value != NULL)
       
  2758                 f((void *) data->symbols[i].default_value, d);
       
  2759         } // for
       
  2760         f((void *) data->symbols, d);
       
  2761     } // if
       
  2762 
       
  2763     if (data->output != NULL)
       
  2764         f((void *) data->output, d);
       
  2765 
       
  2766     f(data, d);
       
  2767 } // MOJOSHADER_freeCompileData
       
  2768 
  2588 // end of mojoshader_compiler.c ...
  2769 // end of mojoshader_compiler.c ...
  2589 
  2770