Beispiel #1
0
void
test_map_push() {
  {
    std::map<std::string, std::string> my_map{
      {"a", "1"}, {"b", "2"}, {"c", "3"}};

    lua_raii L;

    primer::push(L, my_map);
    CHECK_STACK(L, 1);
    test_top_type(L, LUA_TTABLE, __LINE__);

    lua_pushnil(L);
    int counter = 0;
    while (lua_next(L, 1)) {
      ++counter;
      TEST(lua_isstring(L, 2), "expected a string key");
      std::string key = lua_tostring(L, 2);
      TEST(lua_isstring(L, 3), "expected a string val");
      std::string val = lua_tostring(L, 3);

      TEST_EQ(val, my_map[key]);
      my_map.erase(key);

      lua_pop(L, 1);
    }
    TEST_EQ(my_map.size(), 0);
    TEST_EQ(counter, 3);
  }

  {
    std::map<int, int> my_map{{'a', 1}, {'b', 2}, {'c', 3}};

    lua_raii L;

    primer::push(L, my_map);
    CHECK_STACK(L, 1);
    test_top_type(L, LUA_TTABLE, __LINE__);

    lua_pushnil(L);
    int counter = 0;
    while (lua_next(L, 1)) {
      ++counter;
      TEST(lua_isinteger(L, 2), "expected an int key");
      int key = lua_tointeger(L, 2);
      TEST(lua_isinteger(L, 3), "expected an int val");
      int val = lua_tointeger(L, 3);

      TEST_EQ(val, my_map[key]);
      my_map.erase(key);

      lua_pop(L, 1);
    }
    TEST_EQ(my_map.size(), 0);
    TEST_EQ(counter, 3);
  }
}
Beispiel #2
0
void CScriptTable::CloneTable_r( int srcTable,int trgTable )
{
    CHECK_STACK(L);
    int top = lua_gettop(L);
    lua_pushnil(L);  // first key
    while (lua_next(L, srcTable) != 0)
    {
        if (lua_type(L,-1) == LUA_TTABLE)
        {
            int srct = lua_gettop(L);

            lua_pushvalue(L, -2); // Push again index.
            lua_newtable(L);      // Make value.
            int trgt = lua_gettop(L);
            CloneTable_r( srct,trgt );
            lua_rawset(L, trgTable); // Set new table to trgtable.
        }
        else
        {
            // `key' is at index -2 and `value' at index -1
            lua_pushvalue(L, -2); // Push again index.
            lua_pushvalue(L, -2); // Push value.
            lua_rawset(L, trgTable);
        }
        lua_pop(L, 1); // pop value, leave index.
    }
    lua_settop(L, top); // Restore stack.
}
Beispiel #3
0
bool CScriptTable::Clone( IScriptTable *pSrcTable,bool bDeepCopy, bool bCopyByReference )
{
    CHECK_STACK(L);
    int top = lua_gettop(L);

    PushRef(pSrcTable);
    PushRef();

    int srcTable = top + 1;
    int trgTable = top + 2;

    if (bDeepCopy)
    {
        if ( bCopyByReference )
        {
            ReferenceTable_r( srcTable,trgTable );
        }
        else
        {
            CloneTable_r( srcTable,trgTable );
        }
    }
    else
    {
        CloneTable( srcTable,trgTable );
    }
    lua_settop(L, top); // Restore stack.

    return true;
}
void ActorStackPool_::clearThread()
{
	while (true)
	{
		{
			boost::unique_lock<boost::mutex> ul(_clearMutex);
			if (_exit)
			{
				break;
			}
			_clearWait = true;
			if (_clearVar.timed_wait(ul, boost::posix_time::seconds(STACK_MIN_CLEAR_CYCLE)))
			{
				break;
			}
			_clearWait = false;
		}
		size_t freeCount;
		goto _checkFree;
		do
		{
			{
				boost::unique_lock<boost::mutex> ul(_clearMutex);
				if (_exit)
				{
					break;
				}
				_clearWait = true;
				if (_clearVar.timed_wait(ul, boost::posix_time::millisec(100)))
				{
					break;
				}
				_clearWait = false;
			}
			_checkFree:;
			freeCount = 0;
			int extTick = get_tick_s();
			for (int i = 0; i < 256; i++)
			{
				_stackPool[i]._mutex.lock();
				if (!_stackPool[i]._pool.empty() && extTick - _stackPool[i]._pool.front()._tick >= STACK_MIN_CLEAR_CYCLE)
				{
					StackPck_ pck = _stackPool[i]._pool.front();
					_stackPool[i]._pool.pop_front();
					_stackPool[i]._mutex.unlock();

					CHECK_STACK(pck);
					free(((char*)pck._stack.sp) - pck._stack.size);
					_stackCount--;
					_stackTotalSize -= pck._stack.size;
					freeCount++;
				}
				else
				{
					_stackPool[i]._mutex.unlock();
				}
			}
		} while (freeCount);
	}
}
ActorStackPool_::~ActorStackPool_()
{
	{
		boost::lock_guard<boost::mutex> lg(_clearMutex);
		_exit = true;
		if (_clearWait)
		{
			_clearWait = false;
			_clearVar.notify_one();
		}
	}
	_clearThread.join();

	int ic = 0;
	vector<void*> tempPool;
	tempPool.resize(_stackCount);
	for (int i = 0; i < 256; i++)
	{
		boost::lock_guard<boost::mutex> lg1(_stackPool[i]._mutex);
		while (!_stackPool[i]._pool.empty())
		{
			StackPck_ pck = _stackPool[i]._pool.back();
			_stackPool[i]._pool.pop_back();
			tempPool[ic++] = ((char*)pck._stack.sp) - pck._stack.size;
			CHECK_STACK(pck);
			_stackCount--;
		}
	}
	assert(0 == _stackCount);
	sort(tempPool.begin(), tempPool.end());
	for (int j = 0; j < (int)tempPool.size(); j++)
	{
		free(tempPool[j]);
	}
}
StackPck_ ActorStackPool_::getStack( size_t size )
{
	assert(size && size % 4096 == 0 && size <= 1024*1024);
	{
		stack_pool_pck& pool = _actorStackPool->_stackPool[size/4096-1];
		pool._mutex.lock();
		if (!pool._pool.empty())
		{
			StackPck_ r = pool._pool.back();
			pool._pool.pop_back();
			pool._mutex.unlock();
			r._tick = 0;
			CHECK_STACK(r);
			return r;
		}
		pool._mutex.unlock();
	}
	_actorStackPool->_stackCount++;
	_actorStackPool->_stackTotalSize += size;
	StackPck_ r;
	r._tick = 0;
	r._stack.size = size;
	r._stack.sp = ((char*)malloc(size))+size;
	if (r._stack.sp)
	{
		return r;
	}
	throw std::shared_ptr<string>(new string("Actor栈内存不足"));
}
Beispiel #7
0
*/	REBINT Cmp_Block(REBVAL *sval, REBVAL *tval, REBFLG is_case)
/*
**		Compare two blocks and return the difference of the first
**		non-matching value.
**
***********************************************************************/
{
	REBVAL	*s = VAL_BLK_DATA(sval);
	REBVAL	*t = VAL_BLK_DATA(tval);
	REBINT	diff;

	CHECK_STACK(&s);

	if ((VAL_SERIES(sval)==VAL_SERIES(tval))&&
	 (VAL_INDEX(sval)==VAL_INDEX(tval)))
		 return 0;

	while (!IS_END(s) && (VAL_TYPE(s) == VAL_TYPE(t) ||
					(IS_NUMBER(s) && IS_NUMBER(t)))) {
		if ((diff = Cmp_Value(s, t, is_case)) != 0)
			return diff;
		s++, t++;
	}
	return VAL_TYPE(s) - VAL_TYPE(t);
}
Beispiel #8
0
void CScriptTable::ReferenceTable_r( int srcTable,int trgTable )
{
    CHECK_STACK(L);
    int top = lua_gettop(L);

    lua_newtable(L);																	// push new meta table
    lua_pushlstring(L, "__index", strlen("__index"));	// push __index
    lua_pushvalue(L, srcTable);												// push src table
    lua_rawset(L, -3);																// meta.__index==src table
    lua_setmetatable(L,trgTable);											// set meta table

    lua_pushnil(L);  // first key
    while (lua_next(L, srcTable) != 0)
    {
        if (lua_type(L,-1) == LUA_TTABLE)
        {
            int srct = lua_gettop(L);
            lua_pushvalue(L, -2); // Push again index.
            lua_newtable(L);      // Make value.
            int trgt = lua_gettop(L);
            ReferenceTable_r( srct,trgt );
            lua_rawset(L, trgTable); // Set new table to trgtable.
        }
        lua_pop(L, 1); // pop value, leave index.
    }
    lua_settop(L, top); // Restore stack.
}
Beispiel #9
0
void
test_userdata() {
  lua_raii L;

  // Install base library
  luaL_requiref(L, "", luaopen_base, 1);
  lua_pop(L, 1); // remove lib

  CHECK_STACK(L, 0);

  const char * const script =
    ""
    "obj = ...                                      \n"
    "assert(1 == obj('asdf'))                       \n"
    "assert(2 == obj('jkl;'))                       \n"
    "assert(3 == obj('awad'))                       \n"
    "assert(4 == obj('waka'))                       \n"
    "local d = obj:dump()                           \n"
    "assert(4 == #d)                                \n"
    "assert('asdf' == d[1])                         \n"
    "assert('jkl;' == d[2])                         \n"
    "assert('awad' == d[3])                         \n"
    "assert('waka' == d[4])                         \n";

  primer::push_udata<userdata_test>(L);
  TEST_EXPECTED(try_load_script(L, script));
  lua_pushvalue(L, 1);

  CHECK_STACK(L, 3);

  auto result = primer::fcn_call_no_ret(L, 1);
  TEST_EXPECTED(result);

  CHECK_STACK(L, 1);

  TEST(primer::test_udata<userdata_test>(L, 1),
       "did not recover userdata from stack");

  auto ref = primer::read<userdata_test &>(L, 1);
  TEST_EXPECTED(ref);

  TEST_EQ(ref->list.size(), 4);
  TEST_EQ(ref->list[0], "asdf");
  TEST_EQ(ref->list[1], "jkl;");
  TEST_EQ(ref->list[2], "awad");
  TEST_EQ(ref->list[3], "waka");
}
Beispiel #10
0
void CScriptTable::SetAtAny( int nIndex,const ScriptAnyValue &any )
{
    CHECK_STACK(L);
    PushRef();
    m_pSS->PushAny(any);
    lua_rawseti(L,-2,nIndex);
    lua_pop(L, 1); // Pop table.
}
void DuktapeContext::set(JNIEnv *env, jstring name, jobject object, jobjectArray methods) {
  CHECK_STACK(m_context);
  duk_push_global_object(m_context);
  const JString instanceName(env, name);
  if (duk_has_prop_string(m_context, -1, instanceName)) {
    duk_pop(m_context);
    queueIllegalArgumentException(env,
       "A global object called " + instanceName.str() + " already exists");
    return;
  }
  const duk_idx_t objIndex = duk_require_normalize_index(m_context, duk_push_object(m_context));

  // Hook up a finalizer to decrement the refcount and clean up our JavaMethods.
  duk_push_c_function(m_context, javaObjectFinalizer, 1);
  duk_set_finalizer(m_context, objIndex);

  const jsize numMethods = env->GetArrayLength(methods);
  for (jsize i = 0; i < numMethods; ++i) {
    jobject method = env->GetObjectArrayElement(methods, i);

    const jmethodID getName =
        env->GetMethodID(env->GetObjectClass(method), "getName", "()Ljava/lang/String;");
    const JString methodName(env, static_cast<jstring>(env->CallObjectMethod(method, getName)));

    std::unique_ptr<JavaMethod> javaMethod;
    try {
      javaMethod.reset(new JavaMethod(m_javaValues, env, method));
    } catch (const std::invalid_argument& e) {
      queueIllegalArgumentException(env, "In bound method \"" +
          instanceName.str() + "." + methodName.str() + "\": " + e.what());
      // Pop the object being bound and the duktape global object.
      duk_pop_2(m_context);
      return;
    }

    // Use VARARGS here to allow us to manually validate that the proper number of arguments are
    // given in the call.  If we specify the actual number of arguments needed, Duktape will try to
    // be helpful by discarding extra or providing missing arguments. That's not quite what we want.
    // See http://duktape.org/api.html#duk_push_c_function for details.
    const duk_idx_t func = duk_push_c_function(m_context, javaMethodHandler, DUK_VARARGS);
    duk_push_pointer(m_context, javaMethod.release());
    duk_put_prop_string(m_context, func, JAVA_METHOD_PROP_NAME);

    // Add this method to the bound object.
    duk_put_prop_string(m_context, objIndex, methodName);
  }

  // Keep a reference in JavaScript to the object being bound.
  duk_push_pointer(m_context, env->NewGlobalRef(object));
  duk_put_prop_string(m_context, objIndex, JAVA_THIS_PROP_NAME);

  // Make our bound Java object a property of the Duktape global object (so it's a JS global).
  duk_put_prop_string(m_context, -2, instanceName);
  // Pop the Duktape global object off the stack.
  duk_pop(m_context);
}
Beispiel #12
0
int CScriptTable::Count()
{
    CHECK_STACK(L);

    PushRef();
    int count = luaL_getn(L,-1);
    lua_pop(L, 1);

    return count;
}
Beispiel #13
0
void CScriptTable::SetValueAny( const char *sKey,const ScriptAnyValue &any,bool bChain )
{
    CHECK_STACK(L);
    int top = lua_gettop(L);

    ScriptAnyValue oldValue;
    if ( lua_getmetatable( L, -1 ) )	// if there is no metatable nothing is pushed
    {
        lua_pop( L, 1 );	// pop the metatable - we only care that it exists, not about the value
        if ( GetValueAny( sKey, oldValue, bChain) && oldValue == any )
            return;
    }

    if (!bChain)
        PushRef();

    assert(sKey);
    size_t len = strlen(sKey);

    if (any.type == ANY_TVECTOR)
    {
        // Check if we can reuse Vec3 value already in the table.
        lua_pushlstring(L, sKey, len);
        lua_gettable(L,-2);
        int luatype = lua_type(L,-1);
        if (luatype == LUA_TTABLE)
        {
            lua_pushlstring(L,"x", 1);
            lua_gettable(L,-2);
            bool bXIsNumber = lua_isnumber(L,-1) != 0;
            lua_pop(L,1); // pop x value.
            if (bXIsNumber)
            {
                // Assume its a vector, just fill it with new vector values.
                lua_pushlstring(L,"x", 1);
                lua_pushnumber(L, any.vec3.x);
                lua_settable(L,-3);
                lua_pushlstring(L,"y", 1);
                lua_pushnumber(L, any.vec3.y);
                lua_settable(L,-3);
                lua_pushlstring(L,"z", 1);
                lua_pushnumber(L, any.vec3.z);
                lua_settable(L,-3);

                lua_settop(L,top);
                return;
            }
        }
        lua_pop(L,1); // pop key value.
    }
    lua_pushlstring(L, sKey, len);
    m_pSS->PushAny(any);
    lua_settable(L, -3);
    lua_settop(L,top);
}
Beispiel #14
0
void
test_std_function() {
  lua_raii L;

  //[ primer_example_std_function
  std::function<primer::result(lua_State * L, int x, int y)> f =
    [](lua_State * L, int x, int y) -> primer::result {
    if (y == x) { return primer::error{"bad input"}; }
    lua_pushinteger(L, x - y);
    return 1;
  };

  primer::push_std_function(L, std::move(f));
  //]

  CHECK_STACK(L, 1);

  {
    lua_pushvalue(L, 1);

    lua_pushinteger(L, 3);
    lua_pushinteger(L, 2);

    auto result = primer::fcn_call_one_ret(L, 2);
    CHECK_STACK(L, 1);
    TEST_EXPECTED(result);
    auto maybe_int = result->as<int>();
    CHECK_STACK(L, 1);
    TEST_EXPECTED(maybe_int);
    TEST_EQ(*maybe_int, 1);
  }

  {
    lua_pushvalue(L, 1);
    lua_pushinteger(L, 4);
    lua_pushinteger(L, 4);

    auto result = primer::fcn_call_one_ret(L, 2);
    CHECK_STACK(L, 1);
    TEST(!result, "expected failure");
  }
}
Beispiel #15
0
bool CScriptTable::GetAtAny( int nIndex,ScriptAnyValue &any )
{
    CHECK_STACK(L);
    bool res = false;
    PushRef();
    lua_rawgeti(L,-1,nIndex);
    res = m_pSS->PopAny(any);
    lua_pop(L, 1); // Pop table.

    return res;
}
Beispiel #16
0
void CScriptTable::SetMetatable( IScriptTable *pMetatable )
{
    CHECK_STACK(L);
    //////////////////////////////////////////////////////////////////////////
    // Set metatable for this script object.
    //////////////////////////////////////////////////////////////////////////
    PushRef(); // -2
    PushRef(pMetatable); // -1
    lua_setmetatable(L,-2);
    lua_pop(L,1); // pop table
}
Beispiel #17
0
void
kthread_start(void (*func)(void*), void* arg)
{
	extern long _etext, _stext;
	
	CHECK_STACK();
	if ( ((unsigned long)func > (unsigned long)&_etext)
	     || ((unsigned long)func < (unsigned long)&_stext) ) {
		panic("XXX: bad kthread addr: %p\n", func);
	}
	func(arg);
}
Beispiel #18
0
bool CScriptTable::GetValueAny( const char *sKey,ScriptAnyValue &any,bool bChain )
{
    CHECK_STACK(L);
    int top = lua_gettop(L);
    if (!bChain)
        PushRef();
    bool res = false;
    lua_pushstring(L, sKey);
    lua_gettable(L, -2);
    res = m_pSS->PopAny(any);
    lua_settop(L,top);
    return res;
}
Beispiel #19
0
void
test_userdata_two() {
  lua_raii L;

  // Install base library
  luaL_requiref(L, "", luaopen_base, 1);
  lua_pop(L, 1); // remove lib

  // Install vec2 ctor
  lua_pushcfunction(L, PRIMER_ADAPT(&vec2_ctor));
  lua_setglobal(L, "vec2");

  CHECK_STACK(L, 0);

  const char * const script =
    ""
    "local v1 = vec2(1, 1)                          \n"
    "_ = v1 + vec2(3, 4)                            \n"
    "local x,y = v1:dump()                          \n"
    "assert(x == 4)                                 \n"
    "assert(y == 5)                                 \n"
    "assert(v1:norm() == 41)                        \n"
    "_ = v1 + - vec2(3, 4)                          \n"
    "assert(v1:norm() == 2)                         \n"
    "_ = v1 - vec2(3, 3)                            \n"
    "assert(v1:norm() == 8)                         \n"
    "assert(v1 < vec2(5, 5))                        \n";

  TEST_EXPECTED(try_load_script(L, script));

  CHECK_STACK(L, 1);

  auto result = primer::fcn_call_no_ret(L, 0);
  TEST_EXPECTED(result);

  CHECK_STACK(L, 0);
}
Beispiel #20
0
void CScriptTable::Delegate( IScriptTable *pMetatable )
{
    if (!pMetatable)
        return;

    CHECK_STACK(L);

    PushRef(pMetatable);
    lua_pushstring(L,"__index"); // push key.
    PushRef(pMetatable);
    lua_rawset(L,-3); // sets metatable.__index = metatable
    lua_pop(L,1); // pop metatable from stack.

    SetMetatable( pMetatable );
}
Beispiel #21
0
void CScriptTable::CloneTable( int srcTable,int trgTable )
{
    CHECK_STACK(L);
    int top = lua_gettop(L);
    lua_pushnil(L);  // first key
    while (lua_next(L, srcTable) != 0)
    {
        // `key' is at index -2 and `value' at index -1
        lua_pushvalue(L, -2); // Push again index.
        lua_pushvalue(L, -2); // Push value.
        lua_rawset(L, trgTable);
        lua_pop(L, 1); // pop value, leave index.
    }
    lua_settop(L, top); // Restore stack.
}
Beispiel #22
0
bool CScriptTable::AddFunction( const SUserFunctionDesc &fd )
{
    CHECK_STACK(L);

    assert( fd.pFunctor || fd.pUserDataFunc != 0 );

    // Make function signature.
    char sFuncSignature[256];
    if (fd.sGlobalName[0] != 0)
        sprintf( sFuncSignature,"%s.%s(%s)",fd.sGlobalName,fd.sFunctionName,fd.sFunctionParams );
    else
        sprintf( sFuncSignature,"%s.%s(%s)",fd.sGlobalName,fd.sFunctionName,fd.sFunctionParams );

    PushRef();
    lua_pushstring(L, fd.sFunctionName);

    int8 nParamIdOffset = fd.nParamIdOffset;
    if (fd.pFunctor)
    {
        int nDataSize = sizeof(fd.pFunctor) + strlen(sFuncSignature) + 1 + 1;

        // Store functor in first upvalue.
        unsigned char *pBuffer = (unsigned char*)lua_newuserdata(L, nDataSize);
        memcpy( pBuffer, &fd.pFunctor, sizeof(fd.pFunctor));
        memcpy( pBuffer+sizeof(fd.pFunctor), &nParamIdOffset, 1 );
        memcpy( pBuffer+sizeof(fd.pFunctor)+1, sFuncSignature, strlen(sFuncSignature)+1 );
        lua_pushcclosure( L,StdCFunction,1 );
    }
    else
    {
        assert( fd.pDataBuffer != NULL && fd.nDataSize > 0 );
        UserDataFunction function = fd.pUserDataFunc;
        int nSize = fd.nDataSize;
        int nTotalSize = sizeof(function) + sizeof(int) + nSize + strlen(sFuncSignature) + 1 + 1;
        // Store functor in first upvalue.
        unsigned char *pBuffer = (unsigned char*)lua_newuserdata(L, nTotalSize );
        memcpy( pBuffer, &function, sizeof(function) );
        memcpy( pBuffer+sizeof(function), &nSize, sizeof(nSize) );
        memcpy( pBuffer+sizeof(function)+sizeof(nSize), fd.pDataBuffer, nSize );
        memcpy( pBuffer+sizeof(function)+sizeof(nSize)+nSize, &nParamIdOffset, 1 );
        memcpy( pBuffer+sizeof(function)+sizeof(nSize)+nSize+1, sFuncSignature, strlen(sFuncSignature)+1 );
        lua_pushcclosure( L,StdCUserDataFunction,1 );
    }

    lua_rawset(L, -3);
    lua_pop(L,1); // pop table.
    return true;
}
Beispiel #23
0
void CScriptTable::Clear()
{
    CHECK_STACK(L);

    PushRef();
    int trgTable = lua_gettop(L);

    lua_pushnil(L);  // first key
    while (lua_next(L, trgTable) != 0)
    {
        lua_pop(L, 1); // pop value, leave index.
        lua_pushvalue(L, -1); // Push again index.
        lua_pushnil(L);
        lua_rawset(L,trgTable);
    }
    assert(lua_istable(L,-1));
    lua_pop(L, 1);
}
jobject JavaScriptObject::call(JNIEnv* env, jobject method, jobjectArray args) const {
    CHECK_STACK(m_context);
    if (m_instance == nullptr) {
        queueDuktapeException(env, "JavaScript object " + m_name + " has been garbage collected");
        return nullptr;
    }

    const auto methodIter = m_methods.find(env->FromReflectedMethod(method));
    if (methodIter != m_methods.end()) {
        return methodIter->second(env, m_context, m_instance, args);
    }

    // Failed to find the method in our map - should be impossible!
    const jclass methodClass = env->GetObjectClass(method);
    const jmethodID getName = env->GetMethodID(methodClass, "getName", "()Ljava/lang/String;");
    const JString methodName(env, static_cast<jstring>(env->CallObjectMethod(method, getName)));
    queueDuktapeException(env, "Could not find method " + m_name + "." + methodName.str());
    return nullptr;
}
Beispiel #25
0
void
test_set_push() {
  lua_raii L;

  std::set<std::string> s{"a", "k", "q", "j"};

  primer::push(L, s);

  CHECK_STACK(L, 1);
  test_top_type(L, LUA_TTABLE, __LINE__);

  lua_getfield(L, 1, "a");
  test_top_type(L, LUA_TBOOLEAN, __LINE__);
  TEST_EQ(true, lua_toboolean(L, 2));
  lua_pop(L, 1);

  lua_getfield(L, 1, "k");
  test_top_type(L, LUA_TBOOLEAN, __LINE__);
  TEST_EQ(true, lua_toboolean(L, 2));
  lua_pop(L, 1);

  lua_getfield(L, 1, "q");
  test_top_type(L, LUA_TBOOLEAN, __LINE__);
  TEST_EQ(true, lua_toboolean(L, 2));
  lua_pop(L, 1);

  lua_getfield(L, 1, "j");
  test_top_type(L, LUA_TBOOLEAN, __LINE__);
  TEST_EQ(true, lua_toboolean(L, 2));
  lua_pop(L, 1);

  lua_getfield(L, 1, "p");
  test_top_type(L, LUA_TNIL, __LINE__);
  lua_pop(L, 1);

  lua_getfield(L, 1, "b");
  test_top_type(L, LUA_TNIL, __LINE__);
  lua_pop(L, 1);

  lua_getfield(L, 1, "c");
  test_top_type(L, LUA_TNIL, __LINE__);
  lua_pop(L, 1);
}
jobject DuktapeContext::evaluate(JNIEnv* env, jstring code, jstring fname) const {
  CHECK_STACK(m_context);
  const JString sourceCode(env, code);
  const JString fileName(env, fname);

  if (eval_string_with_filename(m_context, sourceCode, fileName) != DUK_EXEC_SUCCESS) {
    queueJavaExceptionForDuktapeError(env, m_context);
    return nullptr;
  }

  const int supportedTypeMask = DUK_TYPE_MASK_BOOLEAN | DUK_TYPE_MASK_NUMBER | DUK_TYPE_MASK_STRING;
  if (duk_check_type_mask(m_context, -1, supportedTypeMask)) {
    // The result is a supported scalar type - return it.
    return m_objectType->pop(m_context, env, false).l;
  } else if (duk_is_array(m_context, -1)) {
    return m_objectType->popArray(m_context, env, 1, false, false);
  } else {
    // The result is an unsupported type, undefined, or null.
    duk_pop(m_context);
    return nullptr;
  }
}
Beispiel #27
0
ScriptVarType CScriptTable::GetAtType(int nIdx)
{
    CHECK_STACK(L);
    ScriptVarType svtRetVal=svtNull;
    PushRef();

    if (luaL_getn(L, -1) < nIdx)
    {
        lua_pop(L, 1);
        return svtNull;
    }

    lua_rawgeti(L, -1, nIdx);

    switch (lua_type(L, -1))
    {
    case LUA_TNIL:
        svtRetVal=svtNull;
        break;
    case LUA_TBOOLEAN:
        svtRetVal=svtBool;
        break;
    case LUA_TNUMBER:
        svtRetVal=svtNumber;
        break;
    case LUA_TSTRING:
        svtRetVal=svtString;
        break;
    case LUA_TTABLE:
        svtRetVal=svtObject;
        break;
    case LUA_TFUNCTION:
        svtRetVal=svtFunction;
        break;
    }

    lua_pop(L, 2);
    return svtRetVal;
}
Beispiel #28
0
void
test_array_push() {
  lua_raii L;

  std::array<int, 4> arr{{5, 6, 7, 8}};

  primer::push(L, arr);
  CHECK_STACK(L, 1);
  test_top_type(L, LUA_TTABLE, __LINE__);

  std::size_t n = lua_rawlen(L, -1);
  TEST_EQ(n, arr.size());

  lua_rawgeti(L, 1, 1);
  TEST(lua_isinteger(L, -1), "not an integer");
  TEST_EQ(lua_tointeger(L, -1), 5);
  lua_pop(L, 1);

  lua_rawgeti(L, 1, 2);
  TEST(lua_isinteger(L, -1), "not an integer");
  TEST_EQ(lua_tointeger(L, -1), 6);
  lua_pop(L, 1);

  lua_rawgeti(L, 1, 3);
  TEST(lua_isinteger(L, -1), "not an integer");
  TEST_EQ(lua_tointeger(L, -1), 7);
  lua_pop(L, 1);

  lua_rawgeti(L, 1, 4);
  TEST(lua_isinteger(L, -1), "not an integer");
  TEST_EQ(lua_tointeger(L, -1), 8);
  lua_pop(L, 1);

  lua_rawgeti(L, 1, 5);
  TEST(lua_isnil(L, -1), "expected nil");
  lua_pop(L, 1);
}
Beispiel #29
0
ScriptVarType CScriptTable::GetValueType( const char *sKey )
{
    CHECK_STACK(L);
    ScriptVarType type=svtNull;

    PushRef();
    lua_pushstring(L, sKey);
    lua_gettable(L, -2);
    int luatype = lua_type(L,-1);
    switch (luatype)
    {
    case LUA_TNIL:
        type = svtNull;
        break;
    case LUA_TBOOLEAN:
        type = svtBool;
        break;
    case LUA_TNUMBER:
        type = svtNumber;
        break;
    case LUA_TSTRING:
        type = svtString;
        break;
    case LUA_TFUNCTION:
        type = svtFunction;
        break;
    case LUA_TLIGHTUSERDATA:
        type = svtPointer;
        break;
    case LUA_TTABLE:
        type = svtObject;
        break;
    }
    lua_pop(L, 2); // Pop value and table.
    return type;
}
int main(int argc, char **argv) {
  grpc_test_init(argc, argv);
  grpc_init();
  int errors = 0;

  // tests with a minimal stack
  grpc_arg minimal_stack_arg = {.type = GRPC_ARG_INTEGER,
                                .key = GRPC_ARG_MINIMAL_STACK,
                                .value.integer = 1};
  grpc_channel_args minimal_stack_args = {.num_args = 1,
                                          .args = &minimal_stack_arg};
  errors += CHECK_STACK("unknown", &minimal_stack_args,
                        GRPC_CLIENT_DIRECT_CHANNEL, "connected", NULL);
  errors += CHECK_STACK("unknown", &minimal_stack_args, GRPC_CLIENT_SUBCHANNEL,
                        "connected", NULL);
  errors += CHECK_STACK("unknown", &minimal_stack_args, GRPC_SERVER_CHANNEL,
                        "server", "connected", NULL);
  errors +=
      CHECK_STACK("chttp2", &minimal_stack_args, GRPC_CLIENT_DIRECT_CHANNEL,
                  "http-client", "connected", NULL);
  errors += CHECK_STACK("chttp2", &minimal_stack_args, GRPC_CLIENT_SUBCHANNEL,
                        "http-client", "connected", NULL);
  errors += CHECK_STACK("chttp2", &minimal_stack_args, GRPC_SERVER_CHANNEL,
                        "server", "http-server", "connected", NULL);
  errors += CHECK_STACK(NULL, &minimal_stack_args, GRPC_CLIENT_CHANNEL,
                        "client-channel", NULL);

  // tests with a default stack
  errors += CHECK_STACK("unknown", NULL, GRPC_CLIENT_DIRECT_CHANNEL,
                        "message_size", "deadline", "connected", NULL);
  errors += CHECK_STACK("unknown", NULL, GRPC_CLIENT_SUBCHANNEL, "message_size",
                        "connected", NULL);
  errors += CHECK_STACK("unknown", NULL, GRPC_SERVER_CHANNEL, "server",
                        "message_size", "deadline", "connected", NULL);
  errors +=
      CHECK_STACK("chttp2", NULL, GRPC_CLIENT_DIRECT_CHANNEL, "message_size",
                  "deadline", "http-client", "compress", "connected", NULL);
  errors += CHECK_STACK("chttp2", NULL, GRPC_CLIENT_SUBCHANNEL, "message_size",
                        "http-client", "compress", "connected", NULL);
  errors +=
      CHECK_STACK("chttp2", NULL, GRPC_SERVER_CHANNEL, "server", "message_size",
                  "deadline", "http-server", "compress", "connected", NULL);
  errors +=
      CHECK_STACK(NULL, NULL, GRPC_CLIENT_CHANNEL, "client-channel", NULL);

  GPR_ASSERT(errors == 0);
  grpc_shutdown();
  return 0;
}

/*******************************************************************************
 * End of tests definitions, start of test infrastructure
 */

static int check_stack(const char *file, int line, const char *transport_name,
                       grpc_channel_args *init_args,
                       grpc_channel_stack_type channel_stack_type, ...) {
  // create dummy channel stack
  grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create();
  grpc_transport_vtable fake_transport_vtable = {.name = transport_name};
  grpc_transport fake_transport = {.vtable = &fake_transport_vtable};
  grpc_channel_stack_builder_set_target(builder, "foo.test.google.fr");
  grpc_channel_args *channel_args = grpc_channel_args_copy(init_args);
  if (transport_name != NULL) {
    grpc_channel_stack_builder_set_transport(builder, &fake_transport);
  }
  {
    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
    grpc_channel_stack_builder_set_channel_arguments(&exec_ctx, builder,
                                                     channel_args);
    GPR_ASSERT(
        grpc_channel_init_create_stack(&exec_ctx, builder, channel_stack_type));
    grpc_exec_ctx_finish(&exec_ctx);
  }

  // build up our expectation list
  gpr_strvec v;
  gpr_strvec_init(&v);
  va_list args;
  va_start(args, channel_stack_type);
  for (;;) {
    char *a = va_arg(args, char *);
    if (a == NULL) break;
    if (v.count != 0) gpr_strvec_add(&v, gpr_strdup(", "));
    gpr_strvec_add(&v, gpr_strdup(a));
  }
  va_end(args);
  char *expect = gpr_strvec_flatten(&v, NULL);
  gpr_strvec_destroy(&v);

  // build up our "got" list
  gpr_strvec_init(&v);
  grpc_channel_stack_builder_iterator *it =
      grpc_channel_stack_builder_create_iterator_at_first(builder);
  while (grpc_channel_stack_builder_move_next(it)) {
    const char *name = grpc_channel_stack_builder_iterator_filter_name(it);
    if (name == NULL) continue;
    if (v.count != 0) gpr_strvec_add(&v, gpr_strdup(", "));
    gpr_strvec_add(&v, gpr_strdup(name));
  }
  char *got = gpr_strvec_flatten(&v, NULL);
  gpr_strvec_destroy(&v);
  grpc_channel_stack_builder_iterator_destroy(it);

  // figure out result, log if there's an error
  int result = 0;
  if (0 != strcmp(got, expect)) {
    gpr_strvec_init(&v);
    gpr_strvec_add(&v, gpr_strdup("{"));
    for (size_t i = 0; i < channel_args->num_args; i++) {
      if (i > 0) gpr_strvec_add(&v, gpr_strdup(", "));
      gpr_strvec_add(&v, gpr_strdup(channel_args->args[i].key));
      gpr_strvec_add(&v, gpr_strdup("="));
      switch (channel_args->args[i].type) {
        case GRPC_ARG_INTEGER: {
          char *tmp;
          gpr_asprintf(&tmp, "%d", channel_args->args[i].value.integer);
          gpr_strvec_add(&v, tmp);
          break;
        }
        case GRPC_ARG_STRING:
          gpr_strvec_add(&v, gpr_strdup(channel_args->args[i].value.string));
          break;
        case GRPC_ARG_POINTER: {
          char *tmp;
          gpr_asprintf(&tmp, "%p", channel_args->args[i].value.pointer.p);
          gpr_strvec_add(&v, tmp);
          break;
        }
      }
    }
    gpr_strvec_add(&v, gpr_strdup("}"));
    char *args_str = gpr_strvec_flatten(&v, NULL);
    gpr_strvec_destroy(&v);

    gpr_log(file, line, GPR_LOG_SEVERITY_ERROR,
            "**************************************************");
    gpr_log(file, line, GPR_LOG_SEVERITY_ERROR,
            "FAILED transport=%s; stack_type=%s; channel_args=%s:",
            transport_name, grpc_channel_stack_type_string(channel_stack_type),
            args_str);
    gpr_log(file, line, GPR_LOG_SEVERITY_ERROR, "EXPECTED: %s", expect);
    gpr_log(file, line, GPR_LOG_SEVERITY_ERROR, "GOT:      %s", got);
    result = 1;

    gpr_free(args_str);
  }

  gpr_free(got);
  gpr_free(expect);

  {
    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
    grpc_channel_stack_builder_destroy(&exec_ctx, builder);
    grpc_channel_args_destroy(&exec_ctx, channel_args);
    grpc_exec_ctx_finish(&exec_ctx);
  }

  return result;
}