示例#1
0
  PrimitiveTypeMapCache() {
    // if we create the TypeMap as a static function member, the constructor
    // is guarantueed to be called by only one thread (see C++11 standard sec 6.7)
    // while all other threads wait for completion. Thus no manual synchronization
    // is needed for the initialization.

    // create all type mappers

    /* convert primitive types */

    #define CONVERT_NUMBER(NAME, TYPE, PRED, CONV)                              \
     {                                                                          \
      func_t f = [](const Local<Value>& val)                                    \
        -> std::tuple<size_t, void*, cl_int> {                                  \
        if (!val->PRED()){                                                      \
         return std::tuple<size_t, void*,cl_int>(0, NULL, CL_INVALID_ARG_VALUE);\
        }                                                                       \
        void* ptr_data = new TYPE;                                              \
        size_t ptr_size = sizeof(TYPE);                                         \
        *((TYPE *)ptr_data) = val->CONV();                                      \
        return std::tuple<size_t, void*,cl_int>(ptr_size, ptr_data, 0);         \
      };                                                                        \
      m_converters[NAME] = f;                                                   \
     }

    CONVERT_NUMBER("char", cl_char, IsInt32, ToInt32()->Value);
    CONVERT_NUMBER("uchar", cl_uchar, IsInt32, ToUint32()->Value);
    CONVERT_NUMBER("short", cl_short, IsInt32, ToInt32()->Value);
    CONVERT_NUMBER("ushort", cl_ushort, IsInt32, ToUint32()->Value);
    CONVERT_NUMBER("int", cl_int , IsInt32, ToInt32()->Value);
    CONVERT_NUMBER("uint", cl_uint, IsInt32, ToUint32()->Value);
    CONVERT_NUMBER("long", cl_long, IsNumber, ToInteger()->Value);
    CONVERT_NUMBER("ulong", cl_ulong, IsNumber, ToInteger()->Value);
    CONVERT_NUMBER("float", cl_float, IsNumber, NumberValue);
    CONVERT_NUMBER("double", cl_double, IsNumber, NumberValue);
    CONVERT_NUMBER("half", cl_half, IsNumber, NumberValue);

    #undef CONVERT_NUMBER


    /* convert vector types (e.g. float4, int16, etc) */

    #define CONVERT_VECT(NAME, TYPE, I, PRED, COND)                             \
      {                                                                         \
       func_t f = [](const Local<Value>& val)                                   \
          -> std::tuple<size_t, void*, cl_int> {                                \
        if (!val->IsArray()) {                                                  \
          /*THROW_ERR(CL_INVALID_ARG_VALUE);  */                                \
          return std::tuple<size_t,void*,cl_int>(0, NULL, CL_INVALID_ARG_VALUE);\
        }                                                                       \
        Local<Array> arr = Local<Array>::Cast(val);                             \
        if (arr->Length() != I) {                                               \
          /*THROW_ERR(CL_INVALID_ARG_SIZE);*/                                   \
          return std::tuple<size_t,void*,cl_int>(0, NULL, CL_INVALID_ARG_SIZE); \
        }                                                                       \
        TYPE * vvc = new TYPE[I];                                               \
        size_t ptr_size = sizeof(TYPE) * I;                                     \
        void* ptr_data = vvc;                                                   \
        for (unsigned int i = 0; i < I; ++ i) {                                 \
          if (!arr->Get(i)->PRED()) {                                           \
            /*THROW_ERR(CL_INVALID_ARG_VALUE);*/                                \
            /*THROW_ERR(CL_INVALID_ARG_VALUE);*/                                \
          return std::tuple<size_t,void*,cl_int>(0, NULL, CL_INVALID_ARG_VALUE);\
          }                                                                     \
          vvc[i] = arr->Get(i)->COND();                                         \
        }                                                                       \
        return std::tuple<size_t,void*,cl_int>(ptr_size, ptr_data, 0);          \
      };                                                                        \
      m_converters["NAME ## I"] = f;                                            \
      }

    #define CONVERT_VECTS(NAME, TYPE, PRED, COND) \
      CONVERT_VECT(NAME, TYPE, 2, PRED, COND);\
      CONVERT_VECT(NAME, TYPE, 3, PRED, COND);\
      CONVERT_VECT(NAME, TYPE, 4, PRED, COND);\
      CONVERT_VECT(NAME, TYPE, 8, PRED, COND);\
      CONVERT_VECT(MAME, TYPE, 16, PRED, COND);

    CONVERT_VECTS("char", cl_char, IsInt32, ToInt32()->Value);
    CONVERT_VECTS("uchar", cl_uchar, IsInt32, ToUint32()->Value);
    CONVERT_VECTS("short", cl_short, IsInt32, ToInt32()->Value);
    CONVERT_VECTS("ushort", cl_ushort, IsInt32, ToUint32()->Value);
    CONVERT_VECTS("int", cl_int, IsInt32, ToInt32()->Value);
    CONVERT_VECTS("uint", cl_uint, IsInt32, ToUint32()->Value);
    CONVERT_VECTS("long", cl_long, IsNumber, ToInteger()->Value);
    CONVERT_VECTS("ulong", cl_ulong, IsNumber, ToInteger()->Value);
    CONVERT_VECTS("float", cl_float, IsNumber, NumberValue);
    CONVERT_VECTS("double", cl_double, IsNumber, NumberValue);
    CONVERT_VECTS("half", cl_half, IsNumber, NumberValue);

    #undef CONVERT_VECT
    #undef CONVERT_VECTS

    // add boolean conversion
    m_converters["bool"] = [](const Local<Value>& val) {
        size_t ptr_size = sizeof(cl_bool);
        void* ptr_data = new cl_bool;
        *((cl_bool *)ptr_data) = val->BooleanValue() ? 1 : 0;
        return std::tuple<size_t,void*,cl_int>(ptr_size, ptr_data, 0);
    };
  }
示例#2
0
文件: api.c 项目: emonkak/cereja
static int
parse_item(lua_State* L, const char** p_format, va_list* p_va,
           int value_index, BOOL in_tablep, BOOL* p_optionalp)
{
	const char* format = *p_format;

L_RETRY:
	format = STRSKIP(format, WHITESPACES);
	switch (*format) {
	default:
		lua_pushfstring(L, "format item `%c(%d)' is not valid",
		                SANITIZE_CHAR(*format), *format);
		return FAILURE;
	case 'n': CONVERT_NUMBER(L, *p_va, value_index, lua_Number); break;
	case 'b': CONVERT_NUMBER(L, *p_va, value_index, char); break;
	case 'h': CONVERT_NUMBER(L, *p_va, value_index, short); break;
	case 'i': CONVERT_NUMBER(L, *p_va, value_index, int); break;
	case 'l': CONVERT_NUMBER(L, *p_va, value_index, long); break;
	case 'B': CONVERT_NUMBER(L, *p_va, value_index, unsigned char); break;
	case 'H': CONVERT_NUMBER(L, *p_va, value_index, unsigned short); break;
	case 'I': CONVERT_NUMBER(L, *p_va, value_index, unsigned int); break;
	case 'L': CONVERT_NUMBER(L, *p_va, value_index, unsigned long); break;
	case 's':
		CHECK_TYPE(L, value_index, LUA_TSTRING);
		/* FALLTHRU */
	case 'z': {
		const char** string;
		size_t* length = NULL;

		string = va_arg(*p_va, const char**);
		if (*(format+1) == '#') {
			length = va_arg(*p_va, size_t*);
			format++;
		}

		if (lua_isstring(L, value_index)) {
			*string = lua_tolstring(L, value_index, length);
		} else if (!lua_toboolean(L, value_index)) {  /*nil-or-false?*/
			*string = NULL;
			if (length != NULL)
				*length = 0;
		} else {
			lua_pushfstring(L,
			  "type mismatch (expected %s/nil/false, but got %s)",
			  lua_typename(L, LUA_TSTRING),
			  luaL_typename(L, value_index));
			return FAILURE;
		}
		} break;
	case 'Q': {
		BOOL* p_boolean;

		p_boolean = va_arg(*p_va, BOOL*);
		*p_boolean = lua_toboolean(L, value_index);
		} break;
	case 'u': /* FALLTHRU */
	case 'U': {
		void** userdata;

		CHECK_TYPE(L, value_index,
		           ((*format == 'U') ? LUA_TUSERDATA
		                             : LUA_TLIGHTUSERDATA));
		userdata = va_arg(*p_va, void**);
		*userdata = lua_touserdata(L, value_index);
		} break;
	case 'O': {
		int* index;

		if (in_tablep) {
			lua_pushstring(L,
			  "format item `O' is not available in `{...}");
			return FAILURE;
		}

		if (*(format+1) == '/') {
			int type;

			switch (*(format+2)) {
			default:
				lua_pushfstring(L,
				  "type `%c(%d)' for `O/<type>' is not valid",
				  SANITIZE_CHAR(*(format+2)), *(format+2));
				return FAILURE;
			case 'N': type = LUA_TNIL; break;
			case 'n': type = LUA_TNUMBER; break;
			case 's': type = LUA_TSTRING; break;
			case 'f': type = LUA_TFUNCTION; break;
			case 'Q': type = LUA_TBOOLEAN; break;
			case 'u': type = LUA_TLIGHTUSERDATA; break;
			case 'U': type = LUA_TUSERDATA; break;
			case 't': type = LUA_TTABLE; break;
			case 'T': type = LUA_TTHREAD; break;
			}
			CHECK_TYPE(L, value_index, type);
			format += 2;
		}

		index = va_arg(*p_va, int*);
		*index = value_index;
		} break;
	case '{':
		CHECK_TYPE(L, value_index, LUA_TTABLE);
		format++;
		if (parse_table(L, &format, p_va, value_index) != SUCCESS)
			return FAILURE;
		break;
	case '|':
		if (in_tablep) {
			lua_pushstring(L,
			  "optional argument `|' is not available in `{...}");
			return FAILURE;
		}
		*p_optionalp = TRUE;
		format++;
		goto L_RETRY;
	}