mojoshader.c
changeset 1180 8abc040525ed
parent 1179 6dd73a80629b
child 1181 b873f3b0f838
equal deleted inserted replaced
1179:6dd73a80629b 1180:8abc040525ed
   560         item->regnum = regnum;
   560         item->regnum = regnum;
   561         item->usage = MOJOSHADER_USAGE_UNKNOWN;
   561         item->usage = MOJOSHADER_USAGE_UNKNOWN;
   562         item->index = 0;
   562         item->index = 0;
   563         item->writemask = 0;
   563         item->writemask = 0;
   564         item->misc = 0;
   564         item->misc = 0;
       
   565         item->written = 0;
   565         item->array = NULL;
   566         item->array = NULL;
   566         item->next = prev->next;
   567         item->next = prev->next;
   567         prev->next = item;
   568         prev->next = item;
   568     } // if
   569     } // if
   569 
   570 
  9737     //  it must always be called in a loop_. So we'll just pass our loop
  9738     //  it must always be called in a loop_. So we'll just pass our loop
  9738     //  variable as a function parameter in those cases.
  9739     //  variable as a function parameter in those cases.
  9739 
  9740 
  9740     const int current_usage = (ctx->loops > 0) ? 1 : -1;
  9741     const int current_usage = (ctx->loops > 0) ? 1 : -1;
  9741     RegisterList *reg = reglist_find(&ctx->used_registers, REG_TYPE_LABEL, regnum);
  9742     RegisterList *reg = reglist_find(&ctx->used_registers, REG_TYPE_LABEL, regnum);
  9742     assert(reg != NULL);
  9743 
  9743 
  9744     if (reg == NULL)
  9744     if (reg->misc == 0)
  9745         fail(ctx, "Invalid label for CALL");
       
  9746     else if (reg->misc == 0)
  9745         reg->misc = current_usage;
  9747         reg->misc = current_usage;
  9746     else if (reg->misc != current_usage)
  9748     else if (reg->misc != current_usage)
  9747     {
  9749     {
  9748         if (current_usage == 1)
  9750         if (current_usage == 1)
  9749             fail(ctx, "CALL to this label must be wrapped in LOOP/ENDLOOP");
  9751             fail(ctx, "CALL to this label must be wrapped in LOOP/ENDLOOP");
 10440 } // parse_ctab_string
 10442 } // parse_ctab_string
 10441 
 10443 
 10442 
 10444 
 10443 static int parse_ctab_typeinfo(Context *ctx, const uint8 *start,
 10445 static int parse_ctab_typeinfo(Context *ctx, const uint8 *start,
 10444                                const uint32 bytes, const uint32 pos,
 10446                                const uint32 bytes, const uint32 pos,
 10445                                MOJOSHADER_symbolTypeInfo *info)
 10447                                MOJOSHADER_symbolTypeInfo *info,
 10446 {
 10448                                const int depth)
 10447     if ((pos + 16) >= bytes)
 10449 {
       
 10450     if ((bytes <= pos) || ((bytes - pos) < 16))
 10448         return 0;  // corrupt CTAB.
 10451         return 0;  // corrupt CTAB.
 10449 
 10452 
 10450     const uint16 *typeptr = (const uint16 *) (start + pos);
 10453     const uint16 *typeptr = (const uint16 *) (start + pos);
 10451 
 10454 
 10452     info->parameter_class = (MOJOSHADER_symbolClass) SWAP16(typeptr[0]);
 10455     info->parameter_class = (MOJOSHADER_symbolClass) SWAP16(typeptr[0]);
 10453     info->parameter_type = (MOJOSHADER_symbolType) SWAP16(typeptr[1]);
 10456     info->parameter_type = (MOJOSHADER_symbolType) SWAP16(typeptr[1]);
 10454     info->rows = (unsigned int) SWAP16(typeptr[2]);
 10457     info->rows = (unsigned int) SWAP16(typeptr[2]);
 10455     info->columns = (unsigned int) SWAP16(typeptr[3]);
 10458     info->columns = (unsigned int) SWAP16(typeptr[3]);
 10456     info->elements = (unsigned int) SWAP16(typeptr[4]);
 10459     info->elements = (unsigned int) SWAP16(typeptr[4]);
 10457     info->member_count = (unsigned int) SWAP16(typeptr[5]);
 10460 
 10458 
 10461     if (info->parameter_class >= MOJOSHADER_SYMCLASS_TOTAL)
 10459     if ((pos + 16 + (info->member_count * 8)) >= bytes)
 10462     {
       
 10463         failf(ctx, "Unknown parameter class (0x%X)", info->parameter_class);
       
 10464         info->parameter_class = MOJOSHADER_SYMCLASS_SCALAR;
       
 10465     } // if
       
 10466 
       
 10467     if (info->parameter_type >= MOJOSHADER_SYMTYPE_TOTAL)
       
 10468     {
       
 10469         failf(ctx, "Unknown parameter type (0x%X)", info->parameter_type);
       
 10470         info->parameter_type = MOJOSHADER_SYMTYPE_INT;
       
 10471     } // if
       
 10472 
       
 10473     const unsigned int member_count = (unsigned int) SWAP16(typeptr[5]);
       
 10474     info->member_count = 0;
       
 10475     info->members = NULL;
       
 10476 
       
 10477     if ((pos + 16 + (member_count * 8)) >= bytes)
 10460         return 0;  // corrupt CTAB.
 10478         return 0;  // corrupt CTAB.
 10461 
 10479 
 10462     if (info->member_count == 0)
 10480     if (member_count > 0)
 10463         info->members = NULL;
 10481     {
 10464     else
 10482         if (depth > 300)  // make sure we aren't in an infinite loop here.
 10465     {
 10483         {
 10466         const size_t len = sizeof (MOJOSHADER_symbolStructMember) *
 10484             fail(ctx, "Possible infinite loop in CTAB structure.");
 10467                             info->member_count;
 10485             return 0;
       
 10486         } // if
       
 10487 
       
 10488         const size_t len = sizeof (MOJOSHADER_symbolStructMember) * member_count;
 10468         info->members = (MOJOSHADER_symbolStructMember *) Malloc(ctx, len);
 10489         info->members = (MOJOSHADER_symbolStructMember *) Malloc(ctx, len);
 10469         if (info->members == NULL)
 10490         if (info->members == NULL)
 10470             return 1;  // we'll check ctx->out_of_memory later.
 10491             return 1;  // we'll check ctx->out_of_memory later.
 10471         memset(info->members, '\0', len);
 10492         memset(info->members, '\0', len);
       
 10493         info->member_count = member_count;
 10472     } // else
 10494     } // else
 10473 
 10495 
 10474     unsigned int i;
 10496     unsigned int i;
 10475     const uint32 *member = (const uint32 *) (start + typeptr[6]);
 10497     const uint32 *member = (const uint32 *) (start + typeptr[6]);
 10476     for (i = 0; i < info->member_count; i++)
 10498     for (i = 0; i < member_count; i++)
 10477     {
 10499     {
 10478         MOJOSHADER_symbolStructMember *mbr = &info->members[i];
 10500         MOJOSHADER_symbolStructMember *mbr = &info->members[i];
 10479         const uint32 name = SWAP32(member[0]);
 10501         const uint32 name = SWAP32(member[0]);
 10480         const uint32 memberinfopos = SWAP32(member[1]);
 10502         const uint32 memberinfopos = SWAP32(member[1]);
 10481         member += 2;
 10503         member += 2;
 10484             return 0;  // info->members will be free()'d elsewhere.
 10506             return 0;  // info->members will be free()'d elsewhere.
 10485 
 10507 
 10486         mbr->name = StrDup(ctx, (const char *) (start + name));
 10508         mbr->name = StrDup(ctx, (const char *) (start + name));
 10487         if (mbr->name == NULL)
 10509         if (mbr->name == NULL)
 10488             return 1;  // we'll check ctx->out_of_memory later.
 10510             return 1;  // we'll check ctx->out_of_memory later.
 10489         if (!parse_ctab_typeinfo(ctx, start, bytes, memberinfopos, &mbr->info))
 10511         if (!parse_ctab_typeinfo(ctx, start, bytes, memberinfopos, &mbr->info, depth + 1))
 10490             return 0;
 10512             return 0;
 10491         if (ctx->out_of_memory)
 10513         if (ctx->out_of_memory)
 10492             return 1;  // drop out now.
 10514             return 1;  // drop out now.
 10493     } // for
 10515     } // for
 10494 
 10516 
 10507 {
 10529 {
 10508     const uint32 id = SWAP32(tokens[1]);
 10530     const uint32 id = SWAP32(tokens[1]);
 10509     if (id != CTAB_ID)
 10531     if (id != CTAB_ID)
 10510         return;  // not the constant table.
 10532         return;  // not the constant table.
 10511 
 10533 
 10512     assert(ctab->have_ctab == 0);  // !!! FIXME: can you have more than one?
 10534     if (ctab->have_ctab)  // !!! FIXME: can you have more than one?
       
 10535     {
       
 10536         fail(ctx, "Shader has multiple CTAB sections");
       
 10537         return;
       
 10538     } // if
       
 10539 
 10513     ctab->have_ctab = 1;
 10540     ctab->have_ctab = 1;
 10514 
 10541 
 10515     const uint8 *start = (uint8 *) &tokens[2];
 10542     const uint8 *start = (uint8 *) &tokens[2];
 10516 
 10543 
 10517     if (bytes < 32)
 10544     if (bytes < 32)
 10527     const uint32 constantinfo = SWAP32(tokens[6]);
 10554     const uint32 constantinfo = SWAP32(tokens[6]);
 10528     const uint32 target = SWAP32(tokens[8]);
 10555     const uint32 target = SWAP32(tokens[8]);
 10529 
 10556 
 10530     if (size != CTAB_SIZE)
 10557     if (size != CTAB_SIZE)
 10531         goto corrupt_ctab;
 10558         goto corrupt_ctab;
       
 10559     else if (constants > 1000000)  // sanity check.
       
 10560         goto corrupt_ctab;
 10532 
 10561 
 10533     if (version != okay_version) goto corrupt_ctab;
 10562     if (version != okay_version) goto corrupt_ctab;
 10534     if (creator >= bytes) goto corrupt_ctab;
 10563     if (creator >= bytes) goto corrupt_ctab;
 10535     if ((constantinfo + (constants * CINFO_SIZE)) >= bytes) goto corrupt_ctab;
 10564     if (constantinfo >= bytes) goto corrupt_ctab;
       
 10565     if ((bytes - constantinfo) < (constants * CINFO_SIZE)) goto corrupt_ctab;
 10536     if (target >= bytes) goto corrupt_ctab;
 10566     if (target >= bytes) goto corrupt_ctab;
 10537     if (!parse_ctab_string(start, bytes, target)) goto corrupt_ctab;
 10567     if (!parse_ctab_string(start, bytes, target)) goto corrupt_ctab;
 10538     // !!! FIXME: check that (start+target) points to "ps_3_0", etc.
 10568     // !!! FIXME: check that (start+target) points to "ps_3_0", etc.
 10539 
 10569 
       
 10570     ctab->symbols = NULL;
       
 10571     if (constants > 0)
       
 10572     {
       
 10573         ctab->symbols = (MOJOSHADER_symbol *) Malloc(ctx, sizeof (MOJOSHADER_symbol) * constants);
       
 10574         if (ctab->symbols == NULL)
       
 10575             return;
       
 10576         memset(ctab->symbols, '\0', sizeof (MOJOSHADER_symbol) * constants);
       
 10577     } // if
 10540     ctab->symbol_count = constants;
 10578     ctab->symbol_count = constants;
 10541     ctab->symbols = (MOJOSHADER_symbol *) Malloc(ctx, sizeof (MOJOSHADER_symbol) * constants);
       
 10542     if (ctab->symbols == NULL)
       
 10543         return;
       
 10544     memset(ctab->symbols, '\0', sizeof (MOJOSHADER_symbol) * constants);
       
 10545 
 10579 
 10546     uint32 i = 0;
 10580     uint32 i = 0;
 10547     for (i = 0; i < constants; i++)
 10581     for (i = 0; i < constants; i++)
 10548     {
 10582     {
 10549         const uint8 *ptr = start + constantinfo + (i * CINFO_SIZE);
 10583         const uint8 *ptr = start + constantinfo + (i * CINFO_SIZE);
 10592         MOJOSHADER_symbol *sym = &ctab->symbols[i];
 10626         MOJOSHADER_symbol *sym = &ctab->symbols[i];
 10593         sym->name = namecpy;
 10627         sym->name = namecpy;
 10594         sym->register_set = (MOJOSHADER_symbolRegisterSet) regset;
 10628         sym->register_set = (MOJOSHADER_symbolRegisterSet) regset;
 10595         sym->register_index = (unsigned int) regidx;
 10629         sym->register_index = (unsigned int) regidx;
 10596         sym->register_count = (unsigned int) regcnt;
 10630         sym->register_count = (unsigned int) regcnt;
 10597         if (!parse_ctab_typeinfo(ctx, start, bytes, typeinf, &sym->info))
 10631         if (!parse_ctab_typeinfo(ctx, start, bytes, typeinf, &sym->info, 0))
 10598             goto corrupt_ctab;  // sym->name will get free()'d later.
 10632             goto corrupt_ctab;  // sym->name will get free()'d later.
 10599         else if (ctx->out_of_memory)
 10633         else if (ctx->out_of_memory)
 10600             return;  // just bail now.
 10634             return;  // just bail now.
 10601     } // for
 10635     } // for
 10602 
 10636