Beispiel #1
0
/**
 * Compile one arithmetic operation COLOR&ALPHA pair into TGSI instructions.
 */
static void
compile_instruction(struct st_translate *t,
                    const struct atifs_instruction *inst)
{
   unsigned optype;

   for (optype = 0; optype < 2; optype++) { /* color, alpha */
      const struct instruction_desc *desc;
      struct ureg_dst dst[1];
      struct ureg_src args[3]; /* arguments for the main operation */
      unsigned arg;
      unsigned dstreg = inst->DstReg[optype].Index - GL_REG_0_ATI;

      if (!inst->Opcode[optype])
         continue;

      desc = &inst_desc[inst->Opcode[optype] - GL_MOV_ATI];

      /* prepare the arguments */
      for (arg = 0; arg < desc->arg_count; arg++) {
         if (arg >= inst->ArgCount[optype]) {
            _mesa_warning(0, "Using 0 for missing argument %d of %s\n",
                          arg, desc->name);
            args[arg] = ureg_imm1f(t->ureg, 0.0f);
         } else {
            args[arg] = prepare_argument(t, arg,
                                         &inst->SrcReg[optype][arg]);
         }
      }

      /* prepare dst */
      dst[0] = get_temp(t, dstreg);

      if (optype) {
         dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_W);
      } else {
         GLuint dstMask = inst->DstReg[optype].dstMask;
         if (dstMask == GL_NONE) {
            dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XYZ);
         } else {
            dst[0] = ureg_writemask(dst[0], dstMask); /* the enum values match */
         }
      }

      /* emit the main instruction */
      emit_arith_inst(t, desc, dst, args, arg);

      emit_dstmod(t, *dst, inst->DstReg[optype].dstMod);

      t->regs_written[t->current_pass][dstreg] = true;
   }
}
void
WrapperCreator::create_function_wrapper(Class* _class, Function* function)
{
    if(function->type == Function::DESTRUCTOR)
        assert(false);

    std::string ns_prefix;
    if(selected_namespace != "")
        ns_prefix = selected_namespace + "::";
    if(function->type == Function::CONSTRUCTOR)
        function->name = "constructor";

    out << "static int ";
    if(_class != 0) {
        out << _class->name << "_";
    }
    out << function->name << "_wrapper(HSQUIRRELVM vm)\n"
        << "{\n";
    // avoid warning...
    if(_class == 0 && function->parameters.empty() 
            && function->return_type.is_void()
            && function->type != Function::CONSTRUCTOR) {
        out << ind << "(void) vm;\n";
    }
    
    // retrieve pointer to class instance
    if(_class != 0 && function->type != Function::CONSTRUCTOR) {
        out << ind << ns_prefix <<  _class->name << "* _this;\n";
        out << ind << "if(SQ_FAILED(sq_getinstanceup(vm, 1, reinterpret_cast<SQUserPointer*> (&_this), 0))) {\n";
        out << ind << ind << "sq_throwerror(vm, _SC(\"'" << function->name << "' called without instance\"));\n";
        out << ind << ind << "return SQ_ERROR;\n";
        out << ind << "}\n";
    }

    // custom function?
    if(function->custom) {
        if(function->type != Function::FUNCTION)
            throw std::runtime_error(
                    "custom not allow constructor+destructor yet");
        if(function->return_type.atomic_type != &BasicType::INT)
            throw std::runtime_error("custom function has to return int");
        if(function->parameters.size() != 1)
            throw std::runtime_error(
                    "custom function must have 1 HSQUIRRELVM parameter");

        out << ind << "return ";
        if(_class != 0)
            out << "_this->";
        else
            out << ns_prefix;
        out << function->name << "(vm);\n";
        out << "}\n";
        out << "\n";
        return;
    }
    
    // declare and retrieve arguments
    int i = 0;
    int arg_offset = 2;
    for(std::vector<Parameter>::iterator p = function->parameters.begin();
            p != function->parameters.end(); ++p) {
        if(i == 0 && p->type.atomic_type == HSQUIRRELVMType::instance()) {
            out << ind << "HSQUIRRELVM arg0 = vm;\n";
            arg_offset--;
        } else {
            char argname[64];
            snprintf(argname, sizeof(argname), "arg%d", i);
            prepare_argument(p->type, i + arg_offset, argname);
        }
        ++i;
    }
    
    // call function
    out << ind << "\n";
    out << ind << "try {\n";
    out << ind << ind;
    if(!function->return_type.is_void()) {
        function->return_type.write_c_type(out);
        out << " return_value = ";
    }
    if(_class != 0) {
        if(function->type == Function::CONSTRUCTOR) {
            out << ns_prefix << _class->name << "* _this = new " << ns_prefix;
        } else {
            out << "_this->";
        }
    } else {
        out << ns_prefix;
    }
    if(function->type == Function::CONSTRUCTOR) {
        out << _class->name << "(";
    } else {
        out << function->name << "(";
    }
    for(size_t i = 0; i < function->parameters.size(); ++i) {
        if(i != 0)
            out << ", ";
        out << "arg" << i;
    }
    out << ");\n";
    if(function->type == Function::CONSTRUCTOR) {
        out << ind << "if(SQ_FAILED(sq_setinstanceup(vm, 1, _this))) {\n";
        out << ind << ind << "sq_throwerror(vm, _SC(\"Couldn't setup instance of '" << _class->name << "' class\"));\n";
        out << ind << ind << "return SQ_ERROR;\n";
        out << ind << "}\n";
        out << ind << "sq_setreleasehook(vm, 1, " 
            << _class->name << "_release_hook);\n";
    }
    out << ind << "\n";
    // push return value back on stack and return
    if(function->suspend) {
        if(!function->return_type.is_void()) {
            std::stringstream msg;
            msg << "Function '" << function->name << "' declared as suspend"
                << " but has a return value.";
            throw std::runtime_error(msg.str());
        }
        out << ind << ind << "return sq_suspendvm(vm);\n";
    } else if(function->return_type.is_void()) {
        out << ind << ind << "return 0;\n";
    } else {
        push_to_stack(function->return_type, "return_value");
        out << ind << ind << "return 1;\n";
    }

    out << ind << "\n";
    out << ind << "} catch(std::exception& e) {\n";
    out << ind << ind << "sq_throwerror(vm, e.what());\n";
    out << ind << ind << "return SQ_ERROR;\n";
    out << ind << "} catch(...) {\n";
    out << ind << ind << "sq_throwerror(vm, _SC(\"Unexpected exception while executing function '" << function->name << "'\"));\n";
    out << ind << ind << "return SQ_ERROR;\n";
    out << ind << "}\n";
    out << ind << "\n";
    
    out << "}\n";
    out << "\n";
}