<commit_before>/*******************************************************************************/
#include "WSLexer.h"

/*******************************************************************************/
WSLexer::WSLexer()
{
}

/*******************************************************************************/
WSLexer::~WSLexer()
{
}

/*******************************************************************************/
void WSLexer::Put_HttpRequest(const char* inHttpStr, const char* inHttpStrEnd)
{
	mpHttpStr		= inHttpStr;
	mpHttpStrEnd	= inHttpStrEnd  ? inHttpStrEnd
									: inHttpStr + strlen(inHttpStr);
	mpCurrChar		= mpHttpStr;

	mLine			= 1;
}

/*******************************************************************************/
bool WSLexer::GetNextToken(Token* outToken)
{
	outToken->Clear();

	if( mpCurrChar == mpHttpStrEnd)
	{
		if(flagBracketsOpen || flagQuotesOpen)
		{
			throw exception("Error WSLexer: Don't closed brackets or quotes");
		}
		return false; // end of string
	}

	bool flagLongWord = false;

	outToken->ps = mpCurrChar;

	do
	{
		switch(*mpCurrChar)
		{
			case 32: // " "
			{
				if( !flagLongWord)
				{
					outToken->mType = wsSpaceType;
					outToken->pe = mpCurrChar;
					mpCurrChar = mpCurrChar + 1; // I only work with UTF-8 char, it has a length of 1.
				}
				else
				{
					flagLongWord = false;
				}
			}break;

			case 42: // "*"
			case 43: // "+"
			case 46: // "."
			case 58: // ":"
			case 59: // ";"
			case 61: // "="
			{
				if( !flagLongWord)
				{
					outToken->mType = wsSymbolType;
					outToken->pe = mpCurrChar;
					mpCurrChar = mpCurrChar + 1;
				}
				else
				{
					flagLongWord = false;
				}
			}break;

			case 34: // ""
			{
				if( !flagLongWord )
				{
					outToken->mType = wsQuotesSymbolType;
					outToken->pe = mpCurrChar;
					mpCurrChar = mpCurrChar + 1;

					flagQuotesOpen = flagQuotesOpen ? false : true;
				}
				else
				{
					flagLongWord = false;
				}
			}break;

			case 28: // "("
			case 29: // ")"
			{
				if( !flagLongWord )
				{
					outToken->mType = wsBracketsSymbolType;
					outToken->pe = mpCurrChar;
					mpCurrChar = mpCurrChar + 1;

					flagBracketsOpen = flagBracketsOpen ? false : true;
				}
				else
				{
					flagLongWord = false;
				}
			}break;

			case 10: // "\n"
			case 13: // "\r"
			{
				if( !flagLongWord )
				{
					outToken->mType = wsNewLineSymbolType;
					outToken->pe = mpCurrChar;
					mpCurrChar = mpCurrChar + 1;

					// if the next symbol is not \n or \r, increase Token::mLen by 1
					if( !(*(mpCurrChar) == 10 || *(mpCurrChar) == 13) )
					{
						outToken->mLine += 1;
					}
				}
				else
				{
					flagLongWord = false;
				}
			}break;

			// All other symbol
			default:
			{
				outToken->mType = wsDefaultType;
				outToken->pe = mpCurrChar;
				mpCurrChar = mpCurrChar + 1;

				flagLongWord = true;
			}break;
		}
	}
	while(flagLongWord);

	outToken->mLen = (outToken->pe - outToken->ps) + 1;
	outToken->mPosition = (outToken->pe - mpHttpStr) + 1;

	return true;
}<commit_msg>fix WLexer pe + 1<commit_after>/*******************************************************************************/
#include "WSLexer.h"

/*******************************************************************************/
WSLexer::WSLexer()
{
}

/*******************************************************************************/
WSLexer::~WSLexer()
{
}

/*******************************************************************************/
void WSLexer::Put_HttpRequest(const char* inHttpStr, const char* inHttpStrEnd)
{
	mpHttpStr		= inHttpStr;
	mpHttpStrEnd	= inHttpStrEnd  ? inHttpStrEnd
									: inHttpStr + strlen(inHttpStr);
	mpCurrChar		= mpHttpStr;

	mLine			= 1;
}

/*******************************************************************************/
bool WSLexer::GetNextToken(Token* outToken)
{
	outToken->Clear();

	if( mpCurrChar == mpHttpStrEnd )
	{
		if(flagBracketsOpen || flagQuotesOpen)
		{
			throw exception("Error WSLexer: Don't closed brackets or quotes");
		}
		return false; // end of string
	}

	bool flagLongWord = false;

	outToken->ps = mpCurrChar;

	do
	{
		switch(*mpCurrChar)
		{
			case 32: // " "
			{
				if( !flagLongWord)
				{
					mpCurrChar = mpCurrChar + 1; // I only work with UTF-8 char, it has a length of 1.

					outToken->mType = wsSpaceType;
					outToken->pe = mpCurrChar;
				}
				else
				{
					flagLongWord = false;
				}
			}break;

			case 42: // "*"
			case 43: // "+"
			case 46: // "."
			case 58: // ":"
			case 59: // ";"
			case 61: // "="
			{
				if( !flagLongWord)
				{
					mpCurrChar = mpCurrChar + 1;

					outToken->mType = wsSymbolType;
					outToken->pe = mpCurrChar;
				}
				else
				{
					flagLongWord = false;
				}
			}break;

			case 34: // ""
			{
				if( !flagLongWord )
				{
					mpCurrChar = mpCurrChar + 1;

					outToken->mType = wsQuotesSymbolType;
					outToken->pe = mpCurrChar;

					flagQuotesOpen = flagQuotesOpen ? false : true;
				}
				else
				{
					flagLongWord = false;
				}
			}break;

			case 28: // "("
			case 29: // ")"
			{
				if( !flagLongWord )
				{
					mpCurrChar = mpCurrChar + 1;

					outToken->mType = wsBracketsSymbolType;
					outToken->pe = mpCurrChar;

					flagBracketsOpen = flagBracketsOpen ? false : true;
				}
				else
				{
					flagLongWord = false;
				}
			}break;

			case 10: // "\n"
			case 13: // "\r"
			{
				if( !flagLongWord )
				{
					mpCurrChar = mpCurrChar + 1;

					outToken->mType = wsNewLineSymbolType;
					outToken->pe = mpCurrChar;

					// if the next symbol is not \n or \r, increase Token::mLen by 1
					if( !(*(mpCurrChar) == 10 || *(mpCurrChar) == 13) )
					{
						outToken->mLine += 1;
					}
				}
				else
				{
					flagLongWord = false;
				}
			}break;

			// All other symbol
			default:
			{
				mpCurrChar = mpCurrChar + 1;

				outToken->mType = wsDefaultType;
				outToken->pe = mpCurrChar;

				flagLongWord = true;
			}break;
		}
	}
	while(flagLongWord);

	outToken->mLen = (outToken->pe - outToken->ps) + 1;
	outToken->mPosition = (outToken->pe - mpHttpStr) + 1;

	return true;
}<|endoftext|>


<commit_before>/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

#include "P_EventSystem.h"
#include "RegressionSM.h"

#define REGRESSION_SM_RETRY (100*HRTIME_MSECOND)

void RegressionSM::set_status(int astatus)
{
  ink_assert(astatus != REGRESSION_TEST_INPROGRESS);
  // INPROGRESS < NOT_RUN < PASSED < FAILED
  if (status != REGRESSION_TEST_FAILED) {
    if (status == REGRESSION_TEST_PASSED) {
      if (astatus != REGRESSION_TEST_NOT_RUN)
        status = astatus;
    } else {
      // INPROGRESS or NOT_RUN
      status = astatus;
    }
  } // else FAILED is FAILED
}

void RegressionSM::done(int astatus)
{
  if (pending_action) {
    pending_action->cancel();
    pending_action = 0;
  }
  set_status(astatus);
  if (pstatus) *pstatus = status;
  if (parent) parent->child_done(status);
}

void RegressionSM::run(int *apstatus)
{
  pstatus = apstatus;
  run();
}

void RegressionSM::xrun(RegressionSM *aparent)
{
  parent = aparent;
  parent->nwaiting++;
  run();
}

void RegressionSM::run_in(int *apstatus, ink_hrtime t)
{
  pstatus = apstatus;
  SET_HANDLER(&RegressionSM::regression_sm_start);
  eventProcessor.schedule_in(this, t);
}

void RegressionSM::child_done(int astatus)
{
  MUTEX_LOCK(l, mutex, this_ethread());
  ink_assert(nwaiting > 0);
  --nwaiting;
  set_status(astatus);
}

int RegressionSM::regression_sm_waiting(int /* event ATS_UNUSED */ , void *data)
{
  if (!nwaiting) {
    done(REGRESSION_TEST_NOT_RUN);
    delete this;
    return EVENT_DONE;
  }
  if (par || nwaiting > 1) {
    ((Event*)data)->schedule_in(REGRESSION_SM_RETRY);
    return EVENT_CONT;
  }
  run();
  return EVENT_DONE;
}

int RegressionSM::regression_sm_start(int /* event ATS_UNUSED */, void * /* data ATS_UNUSED */)
{
  run();
  return EVENT_CONT;
}

RegressionSM *r_sequential(RegressionTest *t, RegressionSM* sm, ...)
{
  RegressionSM *new_sm = new RegressionSM(t);
  va_list ap;
  va_start(ap, sm);
  new_sm->par = false;
  new_sm->rep = false;
  new_sm->ichild = 0;
  new_sm->nchildren = 0;
  new_sm->nwaiting = 0;
  while (0 != sm) {
    new_sm->children(new_sm->nchildren++) = sm;
    sm = va_arg(ap, RegressionSM*);
  }
  new_sm->n = new_sm->nchildren;
  va_end(ap);
  return new_sm;
}

RegressionSM *r_sequential(RegressionTest *t, int an, RegressionSM *sm)
{
  RegressionSM *new_sm = new RegressionSM(t);
  new_sm->par = false;
  new_sm->rep = true;
  new_sm->ichild = 0;
  new_sm->nchildren = 1;
  new_sm->children(0) = sm;
  new_sm->nwaiting = 0;
  new_sm->n = an;
  return new_sm;
}

RegressionSM *r_parallel(RegressionTest *t, RegressionSM *sm, ...)
{
  RegressionSM *new_sm = new RegressionSM(t);
  va_list ap;
  va_start(ap, sm);
  new_sm->par = true;
  new_sm->rep = false;
  new_sm->ichild = 0;
  new_sm->nchildren = 0;
  new_sm->nwaiting = 0;
  while (sm) {
    new_sm->children(new_sm->nchildren++) = sm;
    sm = va_arg(ap, RegressionSM*);
  }
  new_sm->n = new_sm->nchildren;
  va_end(ap);
  return new_sm;
}

RegressionSM *r_parallel(RegressionTest *t, int an, RegressionSM *sm)
{
  RegressionSM *new_sm = new RegressionSM(t);
  new_sm->par = true;
  new_sm->rep = true;
  new_sm->ichild = 0;
  new_sm->nchildren = 1;
  new_sm->children(0) = sm;
  new_sm->nwaiting = 0;
  new_sm->n = an;
  return new_sm;
}

void RegressionSM::run()
{
  // TODO: Why introduce another scope here?
  {
    MUTEX_TRY_LOCK(l, mutex, this_ethread());
    if (!l || nwaiting > 1)
      goto Lretry;
    RegressionSM *x = 0;
    while (ichild < n) {
      if (!rep)
        x = children[ichild];
      else {
        if (ichild != n-1)
          x = children[(intptr_t)0]->clone();
        else
          x = children[(intptr_t)0];
      }
      if (!ichild) nwaiting++;
      x->xrun(this);
      ichild++;
      if (!par && nwaiting > 1)
        goto Lretry;
    }
  }
  nwaiting--;
  if (!nwaiting) {
    done(REGRESSION_TEST_NOT_RUN);
    delete this;
    return;
  }
Lretry:
  SET_HANDLER(&RegressionSM::regression_sm_waiting);
  pending_action = eventProcessor.schedule_in(this, REGRESSION_SM_RETRY);
}

RegressionSM::RegressionSM(const RegressionSM &ao)
{
  RegressionSM &o = *(RegressionSM*)&ao;
  t = o.t;
  status = o.status;
  pstatus = o.pstatus;
  parent = &o;
  nwaiting = o.nwaiting;
  nchildren = o.nchildren;
  for (intptr_t i = 0; i < nchildren; i++)
    children(i) = o.children[i]->clone();
  n = o.n;
  ichild = o.ichild;
  par = o.par;
  rep = o.rep;
  pending_action = o.pending_action;
  ink_assert(status == REGRESSION_TEST_INPROGRESS);
  ink_assert(nwaiting == 0);
  ink_assert(ichild == 0);
  mutex = new_ProxyMutex();
}

struct ReRegressionSM: public RegressionSM
{
  virtual void run() {
    if (time(NULL) < 1) { // example test
      rprintf(t,"impossible");
      done(REGRESSION_TEST_FAILED);
    } else
      done(REGRESSION_TEST_PASSED);
  }
  ReRegressionSM(RegressionTest *at) : RegressionSM(at) {}
  virtual RegressionSM *clone() { return new ReRegressionSM(*this); }
  ReRegressionSM(const ReRegressionSM &o) {
    t = o.t;
  }
};

REGRESSION_TEST(RegressionSM)(RegressionTest *t, int /* atype ATS_UNUSED */, int *pstatus)
{
  r_sequential(t, r_parallel(t, new ReRegressionSM(t), new ReRegressionSM(t), NULL_PTR),
               r_sequential(t, new ReRegressionSM(t), new ReRegressionSM(t), NULL_PTR),
               r_parallel(t, 3, new ReRegressionSM(t)), r_sequential(t, 3, new ReRegressionSM(t)),
               r_parallel(t, r_sequential(t, 2, new ReRegressionSM(t)),
                          r_parallel(t, 2, new ReRegressionSM(t)), NULL_PTR),
               NULL_PTR)->run(pstatus);
}
<commit_msg>TS-1475: Fix memory leak in regression tests. Coverity #1022150<commit_after>/** @file

  A brief file description

  @section license License

  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
 */

#include "P_EventSystem.h"
#include "RegressionSM.h"

#define REGRESSION_SM_RETRY (100*HRTIME_MSECOND)

void RegressionSM::set_status(int astatus)
{
  ink_assert(astatus != REGRESSION_TEST_INPROGRESS);
  // INPROGRESS < NOT_RUN < PASSED < FAILED
  if (status != REGRESSION_TEST_FAILED) {
    if (status == REGRESSION_TEST_PASSED) {
      if (astatus != REGRESSION_TEST_NOT_RUN)
        status = astatus;
    } else {
      // INPROGRESS or NOT_RUN
      status = astatus;
    }
  } // else FAILED is FAILED
}

void RegressionSM::done(int astatus)
{
  if (pending_action) {
    pending_action->cancel();
    pending_action = 0;
  }
  set_status(astatus);
  if (pstatus) *pstatus = status;
  if (parent) parent->child_done(status);
}

void RegressionSM::run(int *apstatus)
{
  pstatus = apstatus;
  run();
}

void RegressionSM::xrun(RegressionSM *aparent)
{
  parent = aparent;
  parent->nwaiting++;
  run();
}

void RegressionSM::run_in(int *apstatus, ink_hrtime t)
{
  pstatus = apstatus;
  SET_HANDLER(&RegressionSM::regression_sm_start);
  eventProcessor.schedule_in(this, t);
}

void RegressionSM::child_done(int astatus)
{
  MUTEX_LOCK(l, mutex, this_ethread());
  ink_assert(nwaiting > 0);
  --nwaiting;
  set_status(astatus);
}

int RegressionSM::regression_sm_waiting(int /* event ATS_UNUSED */ , void *data)
{
  if (!nwaiting) {
    done(REGRESSION_TEST_NOT_RUN);
    delete this;
    return EVENT_DONE;
  }
  if (par || nwaiting > 1) {
    ((Event*)data)->schedule_in(REGRESSION_SM_RETRY);
    return EVENT_CONT;
  }
  run();
  return EVENT_DONE;
}

int RegressionSM::regression_sm_start(int /* event ATS_UNUSED */, void * /* data ATS_UNUSED */)
{
  run();
  return EVENT_CONT;
}

RegressionSM *r_sequential(RegressionTest *t, RegressionSM* sm, ...)
{
  RegressionSM *new_sm = new RegressionSM(t);
  va_list ap;
  va_start(ap, sm);
  new_sm->par = false;
  new_sm->rep = false;
  new_sm->ichild = 0;
  new_sm->nchildren = 0;
  new_sm->nwaiting = 0;
  while (0 != sm) {
    new_sm->children(new_sm->nchildren++) = sm;
    sm = va_arg(ap, RegressionSM*);
  }
  new_sm->n = new_sm->nchildren;
  va_end(ap);
  return new_sm;
}

RegressionSM *r_sequential(RegressionTest *t, int an, RegressionSM *sm)
{
  RegressionSM *new_sm = new RegressionSM(t);
  new_sm->par = false;
  new_sm->rep = true;
  new_sm->ichild = 0;
  new_sm->nchildren = 1;
  new_sm->children(0) = sm;
  new_sm->nwaiting = 0;
  new_sm->n = an;
  return new_sm;
}

RegressionSM *r_parallel(RegressionTest *t, RegressionSM *sm, ...)
{
  RegressionSM *new_sm = new RegressionSM(t);
  va_list ap;
  va_start(ap, sm);
  new_sm->par = true;
  new_sm->rep = false;
  new_sm->ichild = 0;
  new_sm->nchildren = 0;
  new_sm->nwaiting = 0;
  while (sm) {
    new_sm->children(new_sm->nchildren++) = sm;
    sm = va_arg(ap, RegressionSM*);
  }
  new_sm->n = new_sm->nchildren;
  va_end(ap);
  return new_sm;
}

RegressionSM *r_parallel(RegressionTest *t, int an, RegressionSM *sm)
{
  RegressionSM *new_sm = new RegressionSM(t);
  new_sm->par = true;
  new_sm->rep = true;
  new_sm->ichild = 0;
  new_sm->nchildren = 1;
  new_sm->children(0) = sm;
  new_sm->nwaiting = 0;
  new_sm->n = an;
  return new_sm;
}

void RegressionSM::run()
{
  // TODO: Why introduce another scope here?
  {
    MUTEX_TRY_LOCK(l, mutex, this_ethread());
    if (!l || nwaiting > 1)
      goto Lretry;
    RegressionSM *x = 0;
    while (ichild < n) {
      if (!rep)
        x = children[ichild];
      else {
        if (ichild != n-1)
          x = children[(intptr_t)0]->clone();
        else
          x = children[(intptr_t)0];
      }
      if (!ichild) nwaiting++;
      x->xrun(this);
      ichild++;
      if (!par && nwaiting > 1)
        goto Lretry;
    }
  }
  nwaiting--;
  if (!nwaiting) {
    done(REGRESSION_TEST_NOT_RUN);
    delete this;
    return;
  }
Lretry:
  SET_HANDLER(&RegressionSM::regression_sm_waiting);
  pending_action = eventProcessor.schedule_in(this, REGRESSION_SM_RETRY);
}

RegressionSM::RegressionSM(const RegressionSM &ao)
{
  RegressionSM &o = *(RegressionSM*)&ao;
  t = o.t;
  status = o.status;
  pstatus = o.pstatus;
  parent = &o;
  nwaiting = o.nwaiting;
  nchildren = o.nchildren;
  for (intptr_t i = 0; i < nchildren; i++)
    children(i) = o.children[i]->clone();
  n = o.n;
  ichild = o.ichild;
  par = o.par;
  rep = o.rep;
  pending_action = o.pending_action;
  ink_assert(status == REGRESSION_TEST_INPROGRESS);
  ink_assert(nwaiting == 0);
  ink_assert(ichild == 0);
  mutex = new_ProxyMutex();
}

struct ReRegressionSM: public RegressionSM
{
  virtual void run() {
    if (time(NULL) < 1) { // example test
      rprintf(t,"impossible");
      done(REGRESSION_TEST_FAILED);
    } else
      done(REGRESSION_TEST_PASSED);
  }
  ReRegressionSM(RegressionTest *at) : RegressionSM(at) {}
  virtual RegressionSM *clone() { return new ReRegressionSM(*this); }
  ReRegressionSM(const ReRegressionSM &o) {
    t = o.t;
  }
};

REGRESSION_TEST(RegressionSM)(RegressionTest *t, int /* atype ATS_UNUSED */, int *pstatus)
{
  RegressionSM *top_sm = r_sequential(t, r_parallel(t, new ReRegressionSM(t), new ReRegressionSM(t), NULL_PTR),
               r_sequential(t, new ReRegressionSM(t), new ReRegressionSM(t), NULL_PTR),
               r_parallel(t, 3, new ReRegressionSM(t)), r_sequential(t, 3, new ReRegressionSM(t)),
               r_parallel(t, r_sequential(t, 2, new ReRegressionSM(t)),
                          r_parallel(t, 2, new ReRegressionSM(t)), NULL_PTR),
               NULL_PTR);
  top_sm->run(pstatus);
  delete top_sm;
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>

// windows
//#pragma comment(lib, "gtestd.lib")

int main(int argc, char* argv[])
{
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>removed redundant MSVC code<commit_after>#include <gtest/gtest.h>

int main(int argc, char* argv[])
{
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "reflection.h"

#include "class_linker.h"
#include "jni_internal.h"
#include "object.h"
#include "object_utils.h"

#include "JniConstants.h" // Last to avoid problems with LOG redefinition.

namespace art {

Method* gBoolean_valueOf;
Method* gByte_valueOf;
Method* gCharacter_valueOf;
Method* gDouble_valueOf;
Method* gFloat_valueOf;
Method* gInteger_valueOf;
Method* gLong_valueOf;
Method* gShort_valueOf;

void InitBoxingMethods() {
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
  gBoolean_valueOf = class_linker->FindSystemClass("Ljava/lang/Boolean;")->FindDeclaredDirectMethod("valueOf", "(Z)Ljava/lang/Boolean;");
  gByte_valueOf = class_linker->FindSystemClass("Ljava/lang/Byte;")->FindDeclaredDirectMethod("valueOf", "(B)Ljava/lang/Byte;");
  gCharacter_valueOf = class_linker->FindSystemClass("Ljava/lang/Character;")->FindDeclaredDirectMethod("valueOf", "(C)Ljava/lang/Character;");
  gDouble_valueOf = class_linker->FindSystemClass("Ljava/lang/Double;")->FindDeclaredDirectMethod("valueOf", "(D)Ljava/lang/Double;");
  gFloat_valueOf = class_linker->FindSystemClass("Ljava/lang/Float;")->FindDeclaredDirectMethod("valueOf", "(F)Ljava/lang/Float;");
  gInteger_valueOf = class_linker->FindSystemClass("Ljava/lang/Integer;")->FindDeclaredDirectMethod("valueOf", "(I)Ljava/lang/Integer;");
  gLong_valueOf = class_linker->FindSystemClass("Ljava/lang/Long;")->FindDeclaredDirectMethod("valueOf", "(J)Ljava/lang/Long;");
  gShort_valueOf = class_linker->FindSystemClass("Ljava/lang/Short;")->FindDeclaredDirectMethod("valueOf", "(S)Ljava/lang/Short;");
}

jobject InvokeMethod(JNIEnv* env, jobject javaMethod, jobject javaReceiver, jobject javaArgs) {
  Thread* self = Thread::Current();
  ScopedThreadStateChange tsc(self, kRunnable);

  jmethodID mid = env->FromReflectedMethod(javaMethod);
  Method* m = reinterpret_cast<Method*>(mid);

  Class* declaring_class = m->GetDeclaringClass();
  if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(declaring_class, true, true)) {
    return NULL;
  }

  Object* receiver = NULL;
  if (!m->IsStatic()) {
    // Check that the receiver is non-null and an instance of the field's declaring class.
    receiver = Decode<Object*>(env, javaReceiver);
    if (!VerifyObjectInClass(env, receiver, declaring_class)) {
      return NULL;
    }

    // Find the actual implementation of the virtual method.
    m = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(m);
    mid = reinterpret_cast<jmethodID>(m);
  }

  // Get our arrays of arguments and their types, and check they're the same size.
  ObjectArray<Object>* objects = Decode<ObjectArray<Object>*>(env, javaArgs);
  MethodHelper mh(m);
  const DexFile::TypeList* classes = mh.GetParameterTypeList();
  uint32_t classes_size = classes == NULL ? 0 : classes->Size();
  uint32_t arg_count = (objects != NULL) ? objects->GetLength() : 0;
  if (arg_count != classes_size) {
    self->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
        "wrong number of arguments; expected %d, got %d",
        classes_size, arg_count);
    return NULL;
  }

  // Translate javaArgs to a jvalue[].
  UniquePtr<jvalue[]> args(new jvalue[arg_count]);
  JValue* decoded_args = reinterpret_cast<JValue*>(args.get());
  for (uint32_t i = 0; i < arg_count; ++i) {
    Object* arg = objects->Get(i);
    Class* dst_class = mh.GetClassFromTypeIdx(classes->GetTypeItem(i).type_idx_);
    if (dst_class->IsPrimitive() || (arg != NULL && !arg->InstanceOf(dst_class))) {
      // We want to actually unbox primitives, but only reuse the error reporting for reference types.
      if (!UnboxPrimitiveForArgument(arg, dst_class, decoded_args[i], m, i)) {
        return NULL;
      }
    } else {
      // We already tested that these types are compatible.
      args[i].l = AddLocalReference<jobject>(env, arg);
    }
  }

  // Invoke the method.
  JValue value(InvokeWithJValues(env, javaReceiver, mid, args.get()));

  // Wrap any exception with "Ljava/lang/reflect/InvocationTargetException;" and return early.
  if (self->IsExceptionPending()) {
    jthrowable th = env->ExceptionOccurred();
    env->ExceptionClear();
    jclass exception_class = env->FindClass("java/lang/reflect/InvocationTargetException");
    jmethodID mid = env->GetMethodID(exception_class, "<init>", "(Ljava/lang/Throwable;)V");
    jobject exception_instance = env->NewObject(exception_class, mid, th);
    env->Throw(reinterpret_cast<jthrowable>(exception_instance));
    return NULL;
  }

  // Box if necessary and return.
  BoxPrimitive(mh.GetReturnType()->GetPrimitiveType(), value);
  return AddLocalReference<jobject>(env, value.GetL());
}

bool VerifyObjectInClass(JNIEnv* env, Object* o, Class* c) {
  const char* exception = NULL;
  if (o == NULL) {
    exception = "java/lang/NullPointerException";
  } else if (!o->InstanceOf(c)) {
    exception = "java/lang/IllegalArgumentException";
  }
  if (exception != NULL) {
    std::string expected_class_name(PrettyDescriptor(c));
    std::string actual_class_name(PrettyTypeOf(o));
    jniThrowExceptionFmt(env, exception, "expected receiver of type %s, but got %s",
                         expected_class_name.c_str(), actual_class_name.c_str());
    return false;
  }
  return true;
}

bool ConvertPrimitiveValue(Primitive::Type srcType, Primitive::Type dstType,
                           const JValue& src, JValue& dst) {
  CHECK(srcType != Primitive::kPrimNot && dstType != Primitive::kPrimNot);
  switch (dstType) {
  case Primitive::kPrimBoolean:
    if (srcType == Primitive::kPrimBoolean) {
      dst.SetZ(src.GetZ());
      return true;
    }
    break;
  case Primitive::kPrimChar:
    if (srcType == Primitive::kPrimChar) {
      dst.SetC(src.GetC());
      return true;
    }
    break;
  case Primitive::kPrimByte:
    if (srcType == Primitive::kPrimByte) {
      dst.SetB(src.GetB());
      return true;
    }
    break;
  case Primitive::kPrimShort:
    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimShort) {
      dst.SetS(src.GetI());
      return true;
    }
    break;
  case Primitive::kPrimInt:
    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
        srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
      dst.SetI(src.GetI());
      return true;
    }
    break;
  case Primitive::kPrimLong:
    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
        srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
      dst.SetJ(src.GetI());
      return true;
    } else if (srcType == Primitive::kPrimLong) {
      dst.SetJ(src.GetJ());
      return true;
    }
    break;
  case Primitive::kPrimFloat:
    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
        srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
      dst.SetF(src.GetI());
      return true;
    } else if (srcType == Primitive::kPrimLong) {
      dst.SetF(src.GetJ());
      return true;
    } else if (srcType == Primitive::kPrimFloat) {
      dst.SetF(src.GetF());
      return true;
    }
    break;
  case Primitive::kPrimDouble:
    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
        srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
      dst.SetD(src.GetI());
      return true;
    } else if (srcType == Primitive::kPrimLong) {
      dst.SetD(src.GetJ());
      return true;
    } else if (srcType == Primitive::kPrimFloat) {
      dst.SetD(src.GetF());
      return true;
    } else if (srcType == Primitive::kPrimDouble) {
      dst.SetJ(src.GetJ());
      return true;
    }
    break;
  default:
    break;
  }
  Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
                                        "invalid primitive conversion from %s to %s",
                                        PrettyDescriptor(srcType).c_str(),
                                        PrettyDescriptor(dstType).c_str());
  return false;
}

void BoxPrimitive(Primitive::Type src_class, JValue& value) {
  if (src_class == Primitive::kPrimNot) {
    return;
  }

  Method* m = NULL;
  switch (src_class) {
  case Primitive::kPrimBoolean:
    m = gBoolean_valueOf;
    break;
  case Primitive::kPrimByte:
    m = gByte_valueOf;
    break;
  case Primitive::kPrimChar:
    m = gCharacter_valueOf;
    break;
  case Primitive::kPrimDouble:
    m = gDouble_valueOf;
    break;
  case Primitive::kPrimFloat:
    m = gFloat_valueOf;
    break;
  case Primitive::kPrimInt:
    m = gInteger_valueOf;
    break;
  case Primitive::kPrimLong:
    m = gLong_valueOf;
    break;
  case Primitive::kPrimShort:
    m = gShort_valueOf;
    break;
  case Primitive::kPrimVoid:
    // There's no such thing as a void field, and void methods invoked via reflection return null.
    value.SetL(NULL);
    return;
  default:
    LOG(FATAL) << static_cast<int>(src_class);
  }

  Thread* self = Thread::Current();
  ScopedThreadStateChange tsc(self, kRunnable);
  JValue args[1] = { value };
  m->Invoke(self, NULL, args, &value);
}

static std::string UnboxingFailureKind(Method* m, int index, Field* f) {
  if (m != NULL && index != -1) {
    ++index; // Humans count from 1.
    return StringPrintf("method %s argument %d", PrettyMethod(m, false).c_str(), index);
  }
  if (f != NULL) {
    return "field " + PrettyField(f, false);
  }
  return "result";
}

static bool UnboxPrimitive(Object* o, Class* dst_class, JValue& unboxed_value, Method* m, int index, Field* f) {
  if (!dst_class->IsPrimitive()) {
    if (o != NULL && !o->InstanceOf(dst_class)) {
      Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
                                            "%s has type %s, got %s",
                                            UnboxingFailureKind(m, index, f).c_str(),
                                            PrettyDescriptor(dst_class).c_str(),
                                            PrettyTypeOf(o).c_str());
      return false;
    }
    unboxed_value.SetL(o);
    return true;
  } else if (dst_class->GetPrimitiveType() == Primitive::kPrimVoid) {
    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
                                          "can't unbox %s to void",
                                          UnboxingFailureKind(m, index, f).c_str());
    return false;
  }

  if (o == NULL) {
    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
                                          "%s has type %s, got null",
                                          UnboxingFailureKind(m, index, f).c_str(),
                                          PrettyDescriptor(dst_class).c_str());
    return false;
  }

  JValue boxed_value;
  std::string src_descriptor(ClassHelper(o->GetClass()).GetDescriptor());
  Class* src_class = NULL;
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
  Field* primitive_field = o->GetClass()->GetIFields()->Get(0);
  if (src_descriptor == "Ljava/lang/Boolean;") {
    src_class = class_linker->FindPrimitiveClass('Z');
    boxed_value.SetZ(primitive_field->GetBoolean(o));
  } else if (src_descriptor == "Ljava/lang/Byte;") {
    src_class = class_linker->FindPrimitiveClass('B');
    boxed_value.SetB(primitive_field->GetByte(o));
  } else if (src_descriptor == "Ljava/lang/Character;") {
    src_class = class_linker->FindPrimitiveClass('C');
    boxed_value.SetC(primitive_field->GetChar(o));
  } else if (src_descriptor == "Ljava/lang/Float;") {
    src_class = class_linker->FindPrimitiveClass('F');
    boxed_value.SetF(primitive_field->GetFloat(o));
  } else if (src_descriptor == "Ljava/lang/Double;") {
    src_class = class_linker->FindPrimitiveClass('D');
    boxed_value.SetD(primitive_field->GetDouble(o));
  } else if (src_descriptor == "Ljava/lang/Integer;") {
    src_class = class_linker->FindPrimitiveClass('I');
    boxed_value.SetI(primitive_field->GetInt(o));
  } else if (src_descriptor == "Ljava/lang/Long;") {
    src_class = class_linker->FindPrimitiveClass('J');
    boxed_value.SetJ(primitive_field->GetLong(o));
  } else if (src_descriptor == "Ljava/lang/Short;") {
    src_class = class_linker->FindPrimitiveClass('S');
    boxed_value.SetS(primitive_field->GetShort(o));
  } else {
    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
                                          "%s has type %s, got %s",
                                          UnboxingFailureKind(m, index, f).c_str(),
                                          PrettyDescriptor(dst_class).c_str(),
                                          PrettyDescriptor(src_descriptor.c_str()).c_str());
    return false;
  }

  return ConvertPrimitiveValue(src_class->GetPrimitiveType(), dst_class->GetPrimitiveType(),
                               boxed_value, unboxed_value);
}

bool UnboxPrimitiveForArgument(Object* o, Class* dst_class, JValue& unboxed_value, Method* m, size_t index) {
  CHECK(m != NULL);
  return UnboxPrimitive(o, dst_class, unboxed_value, m, index, NULL);
}

bool UnboxPrimitiveForField(Object* o, Class* dst_class, JValue& unboxed_value, Field* f) {
  CHECK(f != NULL);
  return UnboxPrimitive(o, dst_class, unboxed_value, NULL, -1, f);
}

bool UnboxPrimitiveForResult(Object* o, Class* dst_class, JValue& unboxed_value) {
  return UnboxPrimitive(o, dst_class, unboxed_value, NULL, -1, NULL);
}

}  // namespace art
<commit_msg>am 37f7775b: Slightly clearer reflection.<commit_after>/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "reflection.h"

#include "class_linker.h"
#include "jni_internal.h"
#include "object.h"
#include "object_utils.h"

#include "JniConstants.h" // Last to avoid problems with LOG redefinition.

namespace art {

Method* gBoolean_valueOf;
Method* gByte_valueOf;
Method* gCharacter_valueOf;
Method* gDouble_valueOf;
Method* gFloat_valueOf;
Method* gInteger_valueOf;
Method* gLong_valueOf;
Method* gShort_valueOf;

void InitBoxingMethods() {
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
  gBoolean_valueOf = class_linker->FindSystemClass("Ljava/lang/Boolean;")->FindDeclaredDirectMethod("valueOf", "(Z)Ljava/lang/Boolean;");
  gByte_valueOf = class_linker->FindSystemClass("Ljava/lang/Byte;")->FindDeclaredDirectMethod("valueOf", "(B)Ljava/lang/Byte;");
  gCharacter_valueOf = class_linker->FindSystemClass("Ljava/lang/Character;")->FindDeclaredDirectMethod("valueOf", "(C)Ljava/lang/Character;");
  gDouble_valueOf = class_linker->FindSystemClass("Ljava/lang/Double;")->FindDeclaredDirectMethod("valueOf", "(D)Ljava/lang/Double;");
  gFloat_valueOf = class_linker->FindSystemClass("Ljava/lang/Float;")->FindDeclaredDirectMethod("valueOf", "(F)Ljava/lang/Float;");
  gInteger_valueOf = class_linker->FindSystemClass("Ljava/lang/Integer;")->FindDeclaredDirectMethod("valueOf", "(I)Ljava/lang/Integer;");
  gLong_valueOf = class_linker->FindSystemClass("Ljava/lang/Long;")->FindDeclaredDirectMethod("valueOf", "(J)Ljava/lang/Long;");
  gShort_valueOf = class_linker->FindSystemClass("Ljava/lang/Short;")->FindDeclaredDirectMethod("valueOf", "(S)Ljava/lang/Short;");
}

jobject InvokeMethod(JNIEnv* env, jobject javaMethod, jobject javaReceiver, jobject javaArgs) {
  Thread* self = Thread::Current();
  ScopedThreadStateChange tsc(self, kRunnable);

  jmethodID mid = env->FromReflectedMethod(javaMethod);
  Method* m = reinterpret_cast<Method*>(mid);

  Class* declaring_class = m->GetDeclaringClass();
  if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(declaring_class, true, true)) {
    return NULL;
  }

  Object* receiver = NULL;
  if (!m->IsStatic()) {
    // Check that the receiver is non-null and an instance of the field's declaring class.
    receiver = Decode<Object*>(env, javaReceiver);
    if (!VerifyObjectInClass(env, receiver, declaring_class)) {
      return NULL;
    }

    // Find the actual implementation of the virtual method.
    m = receiver->GetClass()->FindVirtualMethodForVirtualOrInterface(m);
    mid = reinterpret_cast<jmethodID>(m);
  }

  // Get our arrays of arguments and their types, and check they're the same size.
  ObjectArray<Object>* objects = Decode<ObjectArray<Object>*>(env, javaArgs);
  MethodHelper mh(m);
  const DexFile::TypeList* classes = mh.GetParameterTypeList();
  uint32_t classes_size = classes == NULL ? 0 : classes->Size();
  uint32_t arg_count = (objects != NULL) ? objects->GetLength() : 0;
  if (arg_count != classes_size) {
    self->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
        "wrong number of arguments; expected %d, got %d",
        classes_size, arg_count);
    return NULL;
  }

  // Translate javaArgs to a jvalue[].
  UniquePtr<jvalue[]> args(new jvalue[arg_count]);
  JValue* decoded_args = reinterpret_cast<JValue*>(args.get());
  for (uint32_t i = 0; i < arg_count; ++i) {
    Object* arg = objects->Get(i);
    Class* dst_class = mh.GetClassFromTypeIdx(classes->GetTypeItem(i).type_idx_);
    if (!UnboxPrimitiveForArgument(arg, dst_class, decoded_args[i], m, i)) {
      return NULL;
    }
    if (!dst_class->IsPrimitive()) {
      args[i].l = AddLocalReference<jobject>(env, arg);
    }
  }

  // Invoke the method.
  JValue value(InvokeWithJValues(env, javaReceiver, mid, args.get()));

  // Wrap any exception with "Ljava/lang/reflect/InvocationTargetException;" and return early.
  if (self->IsExceptionPending()) {
    jthrowable th = env->ExceptionOccurred();
    env->ExceptionClear();
    jclass exception_class = env->FindClass("java/lang/reflect/InvocationTargetException");
    jmethodID mid = env->GetMethodID(exception_class, "<init>", "(Ljava/lang/Throwable;)V");
    jobject exception_instance = env->NewObject(exception_class, mid, th);
    env->Throw(reinterpret_cast<jthrowable>(exception_instance));
    return NULL;
  }

  // Box if necessary and return.
  BoxPrimitive(mh.GetReturnType()->GetPrimitiveType(), value);
  return AddLocalReference<jobject>(env, value.GetL());
}

bool VerifyObjectInClass(JNIEnv* env, Object* o, Class* c) {
  const char* exception = NULL;
  if (o == NULL) {
    exception = "java/lang/NullPointerException";
  } else if (!o->InstanceOf(c)) {
    exception = "java/lang/IllegalArgumentException";
  }
  if (exception != NULL) {
    std::string expected_class_name(PrettyDescriptor(c));
    std::string actual_class_name(PrettyTypeOf(o));
    jniThrowExceptionFmt(env, exception, "expected receiver of type %s, but got %s",
                         expected_class_name.c_str(), actual_class_name.c_str());
    return false;
  }
  return true;
}

bool ConvertPrimitiveValue(Primitive::Type srcType, Primitive::Type dstType,
                           const JValue& src, JValue& dst) {
  CHECK(srcType != Primitive::kPrimNot && dstType != Primitive::kPrimNot);
  switch (dstType) {
  case Primitive::kPrimBoolean:
    if (srcType == Primitive::kPrimBoolean) {
      dst.SetZ(src.GetZ());
      return true;
    }
    break;
  case Primitive::kPrimChar:
    if (srcType == Primitive::kPrimChar) {
      dst.SetC(src.GetC());
      return true;
    }
    break;
  case Primitive::kPrimByte:
    if (srcType == Primitive::kPrimByte) {
      dst.SetB(src.GetB());
      return true;
    }
    break;
  case Primitive::kPrimShort:
    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimShort) {
      dst.SetS(src.GetI());
      return true;
    }
    break;
  case Primitive::kPrimInt:
    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
        srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
      dst.SetI(src.GetI());
      return true;
    }
    break;
  case Primitive::kPrimLong:
    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
        srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
      dst.SetJ(src.GetI());
      return true;
    } else if (srcType == Primitive::kPrimLong) {
      dst.SetJ(src.GetJ());
      return true;
    }
    break;
  case Primitive::kPrimFloat:
    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
        srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
      dst.SetF(src.GetI());
      return true;
    } else if (srcType == Primitive::kPrimLong) {
      dst.SetF(src.GetJ());
      return true;
    } else if (srcType == Primitive::kPrimFloat) {
      dst.SetF(src.GetF());
      return true;
    }
    break;
  case Primitive::kPrimDouble:
    if (srcType == Primitive::kPrimByte || srcType == Primitive::kPrimChar ||
        srcType == Primitive::kPrimShort || srcType == Primitive::kPrimInt) {
      dst.SetD(src.GetI());
      return true;
    } else if (srcType == Primitive::kPrimLong) {
      dst.SetD(src.GetJ());
      return true;
    } else if (srcType == Primitive::kPrimFloat) {
      dst.SetD(src.GetF());
      return true;
    } else if (srcType == Primitive::kPrimDouble) {
      dst.SetJ(src.GetJ());
      return true;
    }
    break;
  default:
    break;
  }
  Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
                                        "invalid primitive conversion from %s to %s",
                                        PrettyDescriptor(srcType).c_str(),
                                        PrettyDescriptor(dstType).c_str());
  return false;
}

void BoxPrimitive(Primitive::Type src_class, JValue& value) {
  if (src_class == Primitive::kPrimNot) {
    return;
  }

  Method* m = NULL;
  switch (src_class) {
  case Primitive::kPrimBoolean:
    m = gBoolean_valueOf;
    break;
  case Primitive::kPrimByte:
    m = gByte_valueOf;
    break;
  case Primitive::kPrimChar:
    m = gCharacter_valueOf;
    break;
  case Primitive::kPrimDouble:
    m = gDouble_valueOf;
    break;
  case Primitive::kPrimFloat:
    m = gFloat_valueOf;
    break;
  case Primitive::kPrimInt:
    m = gInteger_valueOf;
    break;
  case Primitive::kPrimLong:
    m = gLong_valueOf;
    break;
  case Primitive::kPrimShort:
    m = gShort_valueOf;
    break;
  case Primitive::kPrimVoid:
    // There's no such thing as a void field, and void methods invoked via reflection return null.
    value.SetL(NULL);
    return;
  default:
    LOG(FATAL) << static_cast<int>(src_class);
  }

  Thread* self = Thread::Current();
  ScopedThreadStateChange tsc(self, kRunnable);
  JValue args[1] = { value };
  m->Invoke(self, NULL, args, &value);
}

static std::string UnboxingFailureKind(Method* m, int index, Field* f) {
  if (m != NULL && index != -1) {
    ++index; // Humans count from 1.
    return StringPrintf("method %s argument %d", PrettyMethod(m, false).c_str(), index);
  }
  if (f != NULL) {
    return "field " + PrettyField(f, false);
  }
  return "result";
}

static bool UnboxPrimitive(Object* o, Class* dst_class, JValue& unboxed_value, Method* m, int index, Field* f) {
  if (!dst_class->IsPrimitive()) {
    if (o != NULL && !o->InstanceOf(dst_class)) {
      Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
                                            "%s has type %s, got %s",
                                            UnboxingFailureKind(m, index, f).c_str(),
                                            PrettyDescriptor(dst_class).c_str(),
                                            PrettyTypeOf(o).c_str());
      return false;
    }
    unboxed_value.SetL(o);
    return true;
  } else if (dst_class->GetPrimitiveType() == Primitive::kPrimVoid) {
    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
                                          "can't unbox %s to void",
                                          UnboxingFailureKind(m, index, f).c_str());
    return false;
  }

  if (o == NULL) {
    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
                                          "%s has type %s, got null",
                                          UnboxingFailureKind(m, index, f).c_str(),
                                          PrettyDescriptor(dst_class).c_str());
    return false;
  }

  JValue boxed_value;
  std::string src_descriptor(ClassHelper(o->GetClass()).GetDescriptor());
  Class* src_class = NULL;
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
  Field* primitive_field = o->GetClass()->GetIFields()->Get(0);
  if (src_descriptor == "Ljava/lang/Boolean;") {
    src_class = class_linker->FindPrimitiveClass('Z');
    boxed_value.SetZ(primitive_field->GetBoolean(o));
  } else if (src_descriptor == "Ljava/lang/Byte;") {
    src_class = class_linker->FindPrimitiveClass('B');
    boxed_value.SetB(primitive_field->GetByte(o));
  } else if (src_descriptor == "Ljava/lang/Character;") {
    src_class = class_linker->FindPrimitiveClass('C');
    boxed_value.SetC(primitive_field->GetChar(o));
  } else if (src_descriptor == "Ljava/lang/Float;") {
    src_class = class_linker->FindPrimitiveClass('F');
    boxed_value.SetF(primitive_field->GetFloat(o));
  } else if (src_descriptor == "Ljava/lang/Double;") {
    src_class = class_linker->FindPrimitiveClass('D');
    boxed_value.SetD(primitive_field->GetDouble(o));
  } else if (src_descriptor == "Ljava/lang/Integer;") {
    src_class = class_linker->FindPrimitiveClass('I');
    boxed_value.SetI(primitive_field->GetInt(o));
  } else if (src_descriptor == "Ljava/lang/Long;") {
    src_class = class_linker->FindPrimitiveClass('J');
    boxed_value.SetJ(primitive_field->GetLong(o));
  } else if (src_descriptor == "Ljava/lang/Short;") {
    src_class = class_linker->FindPrimitiveClass('S');
    boxed_value.SetS(primitive_field->GetShort(o));
  } else {
    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
                                          "%s has type %s, got %s",
                                          UnboxingFailureKind(m, index, f).c_str(),
                                          PrettyDescriptor(dst_class).c_str(),
                                          PrettyDescriptor(src_descriptor.c_str()).c_str());
    return false;
  }

  return ConvertPrimitiveValue(src_class->GetPrimitiveType(), dst_class->GetPrimitiveType(),
                               boxed_value, unboxed_value);
}

bool UnboxPrimitiveForArgument(Object* o, Class* dst_class, JValue& unboxed_value, Method* m, size_t index) {
  CHECK(m != NULL);
  return UnboxPrimitive(o, dst_class, unboxed_value, m, index, NULL);
}

bool UnboxPrimitiveForField(Object* o, Class* dst_class, JValue& unboxed_value, Field* f) {
  CHECK(f != NULL);
  return UnboxPrimitive(o, dst_class, unboxed_value, NULL, -1, f);
}

bool UnboxPrimitiveForResult(Object* o, Class* dst_class, JValue& unboxed_value) {
  return UnboxPrimitive(o, dst_class, unboxed_value, NULL, -1, NULL);
}

}  // namespace art
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <arrayfire.h>
#include <af/dim4.hpp>
#include <af/traits.hpp>
#include <string>
#include <vector>
#include <iostream>
#include <testHelpers.hpp>

using std::string;
using std::cout;
using std::endl;
using std::vector;
using af::af_cfloat;
using af::af_cdouble;

template<typename T>
class Transpose : public ::testing::Test
{
    public:
        virtual void SetUp() {
            subMat2D.push_back({2,7,1});
            subMat2D.push_back({2,7,1});

            subMat3D.push_back({2,7,1});
            subMat3D.push_back({2,7,1});
            subMat3D.push_back(span);
        }
        vector<af_seq> subMat2D;
        vector<af_seq> subMat3D;
};

// create a list of types to be tested
typedef ::testing::Types<float, af_cfloat, double, af_cdouble, int, unsigned, char, unsigned char> TestTypes;

// register the type list
TYPED_TEST_CASE(Transpose, TestTypes);

template<typename T>
void trsTest(string pTestFile, bool isSubRef=false, const vector<af_seq> *seqv=nullptr)
{
    af::dim4            dims(1);
    vector<T>           in;
    vector<vector<T>>   tests;
    ReadTests<int, T>(pTestFile,dims,in,tests);

    af_array outArray   = 0;
    af_array inArray    = 0;
    T *outData;
    ASSERT_EQ(AF_SUCCESS, af_create_array(&inArray, &in.front(), dims.ndims(), dims.get(), (af_dtype) af::dtype_traits<T>::af_type));

    // check if the test is for indexed Array
    if (isSubRef) {
        af::dim4 newDims(dims[1]-4,dims[0]-4,dims[2],dims[3]);
        af_array subArray = 0;
        ASSERT_EQ(AF_SUCCESS, af_index(&subArray,inArray,seqv->size(),&seqv->front()));
        ASSERT_EQ(AF_SUCCESS, af_transpose(&outArray,subArray));
        // destroy the temporary indexed Array
        ASSERT_EQ(AF_SUCCESS, af_destroy_array(subArray));

        dim_type nElems;
        ASSERT_EQ(AF_SUCCESS, af_get_elements(&nElems,outArray));
        outData = new T[nElems];
    } else {
        ASSERT_EQ(AF_SUCCESS, af_transpose(&outArray,inArray));
        outData = new T[dims.elements()];
    }

    ASSERT_EQ(AF_SUCCESS, af_get_data_ptr((void*)outData, outArray));

    for (int testIter=0; testIter<tests.size(); ++testIter) {
        vector<T> currGoldBar   = tests[testIter];
        size_t nElems        = currGoldBar.size();
        for (size_t elIter=0; elIter<nElems; ++elIter) {
            ASSERT_EQ(currGoldBar[elIter],outData[elIter])<< "at: " << elIter<< std::endl;
        }
    }

    // cleanup
    delete[] outData;
    ASSERT_EQ(AF_SUCCESS, af_destroy_array(inArray));
    ASSERT_EQ(AF_SUCCESS, af_destroy_array(outArray));
}

TYPED_TEST(Transpose,Vector)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/vector.test"));
}

TYPED_TEST(Transpose,VectorBatch)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/vector_batch.test"));
}

TYPED_TEST(Transpose,Square)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/square.test"));
}

TYPED_TEST(Transpose,SquareBatch)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/square_batch.test"));
}

TYPED_TEST(Transpose,Rectangle)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/rectangle.test"));
}

TYPED_TEST(Transpose,RectangleBatch)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/rectangle_batch.test"));
}

TYPED_TEST(Transpose,SubRef)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/offset.test"),true,&(this->subMat2D));
}

TYPED_TEST(Transpose,SubRefBatch)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/offset_batch.test"),true,&(this->subMat3D));
}

TYPED_TEST(Transpose,InvalidArgs)
{
    af::dim4            dims(1);
    vector<TypeParam>           in;
    vector<vector<TypeParam>>   tests;
    ReadTests<int, TypeParam>(string(TEST_DIR"/transpose/square.test"),dims,in,tests);

    af_array inArray   = 0;
    af_array outArray  = 0;

    // square test file is 100x100 originally
    // usee new dimensions for this argument
    // unit test
    af::dim4 newDims(5,5,2,2);
    ASSERT_EQ(AF_SUCCESS, af_create_array(&inArray, &in.front(), newDims.ndims(), newDims.get(), (af_dtype) af::dtype_traits<TypeParam>::af_type));

    ASSERT_EQ(AF_ERR_ARG, af_transpose(&outArray,inArray));
}
<commit_msg>Fixing warnings in transpose tests<commit_after>#include <gtest/gtest.h>
#include <arrayfire.h>
#include <af/dim4.hpp>
#include <af/traits.hpp>
#include <string>
#include <vector>
#include <iostream>
#include <testHelpers.hpp>

using std::string;
using std::cout;
using std::endl;
using std::vector;
using af::af_cfloat;
using af::af_cdouble;

template<typename T>
class Transpose : public ::testing::Test
{
    public:
        virtual void SetUp() {
            subMat2D.push_back({2,7,1});
            subMat2D.push_back({2,7,1});

            subMat3D.push_back({2,7,1});
            subMat3D.push_back({2,7,1});
            subMat3D.push_back(span);
        }
        vector<af_seq> subMat2D;
        vector<af_seq> subMat3D;
};

// create a list of types to be tested
typedef ::testing::Types<float, af_cfloat, double, af_cdouble, int, unsigned, char, unsigned char> TestTypes;

// register the type list
TYPED_TEST_CASE(Transpose, TestTypes);

template<typename T>
void trsTest(string pTestFile, bool isSubRef=false, const vector<af_seq> *seqv=nullptr)
{
    af::dim4            dims(1);
    vector<T>           in;
    vector<vector<T>>   tests;
    ReadTests<int, T>(pTestFile,dims,in,tests);

    af_array outArray   = 0;
    af_array inArray    = 0;
    T *outData;
    ASSERT_EQ(AF_SUCCESS, af_create_array(&inArray, &in.front(), dims.ndims(), dims.get(), (af_dtype) af::dtype_traits<T>::af_type));

    // check if the test is for indexed Array
    if (isSubRef) {
        af::dim4 newDims(dims[1]-4,dims[0]-4,dims[2],dims[3]);
        af_array subArray = 0;
        ASSERT_EQ(AF_SUCCESS, af_index(&subArray,inArray,seqv->size(),&seqv->front()));
        ASSERT_EQ(AF_SUCCESS, af_transpose(&outArray,subArray));
        // destroy the temporary indexed Array
        ASSERT_EQ(AF_SUCCESS, af_destroy_array(subArray));

        dim_type nElems;
        ASSERT_EQ(AF_SUCCESS, af_get_elements(&nElems,outArray));
        outData = new T[nElems];
    } else {
        ASSERT_EQ(AF_SUCCESS, af_transpose(&outArray,inArray));
        outData = new T[dims.elements()];
    }

    ASSERT_EQ(AF_SUCCESS, af_get_data_ptr((void*)outData, outArray));

    for (size_t testIter=0; testIter<tests.size(); ++testIter) {
        vector<T> currGoldBar   = tests[testIter];
        size_t nElems        = currGoldBar.size();
        for (size_t elIter=0; elIter<nElems; ++elIter) {
            ASSERT_EQ(currGoldBar[elIter],outData[elIter])<< "at: " << elIter<< std::endl;
        }
    }

    // cleanup
    delete[] outData;
    ASSERT_EQ(AF_SUCCESS, af_destroy_array(inArray));
    ASSERT_EQ(AF_SUCCESS, af_destroy_array(outArray));
}

TYPED_TEST(Transpose,Vector)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/vector.test"));
}

TYPED_TEST(Transpose,VectorBatch)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/vector_batch.test"));
}

TYPED_TEST(Transpose,Square)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/square.test"));
}

TYPED_TEST(Transpose,SquareBatch)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/square_batch.test"));
}

TYPED_TEST(Transpose,Rectangle)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/rectangle.test"));
}

TYPED_TEST(Transpose,RectangleBatch)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/rectangle_batch.test"));
}

TYPED_TEST(Transpose,SubRef)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/offset.test"),true,&(this->subMat2D));
}

TYPED_TEST(Transpose,SubRefBatch)
{
    trsTest<TypeParam>(string(TEST_DIR"/transpose/offset_batch.test"),true,&(this->subMat3D));
}

TYPED_TEST(Transpose,InvalidArgs)
{
    af::dim4            dims(1);
    vector<TypeParam>           in;
    vector<vector<TypeParam>>   tests;
    ReadTests<int, TypeParam>(string(TEST_DIR"/transpose/square.test"),dims,in,tests);

    af_array inArray   = 0;
    af_array outArray  = 0;

    // square test file is 100x100 originally
    // usee new dimensions for this argument
    // unit test
    af::dim4 newDims(5,5,2,2);
    ASSERT_EQ(AF_SUCCESS, af_create_array(&inArray, &in.front(), newDims.ndims(), newDims.get(), (af_dtype) af::dtype_traits<TypeParam>::af_type));

    ASSERT_EQ(AF_ERR_ARG, af_transpose(&outArray,inArray));
}
<|endoftext|>


<commit_before>//===------------------------- unwind_06.cpp ------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <exception>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>

// Compile with -Os to get compiler uses float registers to hold float variables

__attribute__((noinline))
double get(int x) { return (double)x; }

double try1(bool v) {
  double a = get(0);
  double b = get(0);
  if (v) throw 10;
  return get(0)+a+b;
}

double try2(bool v) {
  double a = get(0);
  double b = get(0);
  double c = get(0);
  if (v) throw 10;
  return get(0)+a+b+c;
}

double try3(bool v) {
  double a = get(0);
  double b = get(0);
  double c = get(0);
  double d = get(0);
  if (v) throw 10;
  return get(0)+a+b+c+d;
}

double try4(bool v) {
  double a = get(0);
  double b = get(0);
  double c = get(0);
  double d = get(0);
  double e = get(0);
  if (v) throw 10;
  return get(0)+a+b+c+d+e;
}

double try5(bool v) {
  double a = get(0);
  double b = get(0);
  double c = get(0);
  double d = get(0);
  double e = get(0);
  double f = get(0);
  if (v) throw 10;
  return get(0)+a+b+c+d+e+f;
}

double try6(bool v) {
  double a = get(0);
  double b = get(0);
  double c = get(0);
  double d = get(0);
  double e = get(0);
  double f = get(0);
  double g = get(0);
  if (v) throw 10;
  return get(0)+a+b+c+d+e+f+g;
}

double try7(bool v) {
  double a = get(0);
  double b = get(0);
  double c = get(0);
  double d = get(0);
  double e = get(0);
  double f = get(0);
  double g = get(0);
  double h = get(0);
  if (v) throw 10;
  return get(0)+a+b+c+d+e+f+g;
}

double try8(bool v) {
  double a = get(0);
  double b = get(0);
  double c = get(0);
  double d = get(0);
  double e = get(0);
  double f = get(0);
  double g = get(0);
  double h = get(0);
  double i = get(0);
  if (v) throw 10;
  return get(0)+a+b+c+d+e+f+g+i;
}

double foo()
{
  double a = get(1);
  double b = get(2);
  double c = get(3);
  double d = get(4);
  double e = get(5);
  double f = get(6);
  double g = get(7);
  double h = get(8);
  try {
    try1(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  try {
    try2(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  try {
    try3(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  try {
    try4(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  try {
    try5(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  try {
    try6(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  try {
    try7(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  try {
    try8(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  return a+b+c+d+e+f+g+h;
}

int main()
{
  foo();
}
<commit_msg>Try harder to get the compiler to use float registers in different places to increase the chance of messing up any preserved registers.<commit_after>//===------------------------- unwind_06.cpp ------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <exception>
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>

// Compile with -Os to get compiler uses float registers to hold float variables

double get_(int x) { return (double)x; }

double (* volatile get)(int) = get_;

volatile int counter;

double try1(bool v) {
  double a = get(0);
  double b = get(1);
  for (counter = 100; counter; --counter)
    a += get(1) + b;
  if (v) throw 10;
  return get(0)+a+b;
}

double try2(bool v) {
  double a = get(0);
  double b = get(1);
  double c = get(2);
  for (counter = 100; counter; --counter)
    a += get(1) + b + c;
  if (v) throw 10;
  return get(0)+a+b+c;
}

double try3(bool v) {
  double a = get(0);
  double b = get(1);
  double c = get(2);
  double d = get(3);
  for (counter = 100; counter; --counter)
    a += get(1) + b + c + d;
  if (v) throw 10;
  return get(0)+a+b+c+d;
}

double try4(bool v) {
  double a = get(0);
  double b = get(0);
  double c = get(0);
  double d = get(0);
  double e = get(0);
  for (counter = 100; counter; --counter)
    a += get(1) + b+c+d+e;
  if (v) throw 10;
  return get(0)+a+b+c+d+e;
}

double try5(bool v) {
  double a = get(0);
  double b = get(0);
  double c = get(0);
  double d = get(0);
  double e = get(0);
  double f = get(0);
  for (counter = 100; counter; --counter)
    a += get(1) + b+c+d+e+f;
  if (v) throw 10;
  return get(0)+a+b+c+d+e+f;
}

double try6(bool v) {
  double a = get(0);
  double b = get(0);
  double c = get(0);
  double d = get(0);
  double e = get(0);
  double f = get(0);
  double g = get(0);
  for (counter = 100; counter; --counter)
    a += get(1) + b+c+d+e+f+g;
  if (v) throw 10;
  return get(0)+a+b+c+d+e+f+g;
}

double try7(bool v) {
  double a = get(0);
  double b = get(0);
  double c = get(0);
  double d = get(0);
  double e = get(0);
  double f = get(0);
  double g = get(0);
  double h = get(0);
  for (counter = 100; counter; --counter)
    a += get(1) + b+c+d+e+f+g;
  if (v) throw 10;
  return get(0)+a+b+c+d+e+f+g;
}

double try8(bool v) {
  double a = get(0);
  double b = get(0);
  double c = get(0);
  double d = get(0);
  double e = get(0);
  double f = get(0);
  double g = get(0);
  double h = get(0);
  double i = get(0);
  for (counter = 100; counter; --counter)
    a += get(1) + b+c+d+e+f+g+i;
  if (v) throw 10;
  return get(0)+a+b+c+d+e+f+g+i;
}

double foo()
{
  double a = get(1);
  double b = get(2);
  double c = get(3);
  double d = get(4);
  double e = get(5);
  double f = get(6);
  double g = get(7);
  double h = get(8);
  try {
    try1(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  try {
    try2(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  try {
    try3(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  try {
    try4(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  try {
    try5(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  try {
    try6(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  try {
    try7(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  try {
    try8(true);
  }
  catch (int e) {
  }
  assert(a == get(1));
  assert(b == get(2));
  assert(c == get(3));
  assert(d == get(4));
  assert(e == get(5));
  assert(f == get(6));
  assert(g == get(7));
  assert(h == get(8));

  return a+b+c+d+e+f+g+h;
}

int main()
{
  foo();
}
<|endoftext|>


<commit_before>/****************************************************************************
 *
 * Copyright (C) 2014 Flavio Fontana & Luis Rodrigues. All rights reserved.
 * Author: Flavio Fontana <fly.fontana@gmail.com>
 * Author: Luis Rodrigues <luis.rodrigues@terabee.com>

 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in
 * the documentation and/or other materials provided with the
 * distribution.
 * 3. Neither the name TerarangerOne nor the names of its contributors may be
 * used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

#include <string>

#include "terarangerone/terarangerone.h"

namespace terarangerone
{

TerarangerOne::TerarangerOne()
{
  // Get paramters
  ros::NodeHandle private_node_handle_("~");
  private_node_handle_.param("portname", portname_, std::string("/dev/ttyUSB0"));

  // Publishers
  range_publisher_ = nh_.advertise<sensor_msgs::Range>("terarangerone", 1);

  // Create serial port
  serial_port_ = new SerialPort();

  // Set callback function for the serial ports
  serial_data_callback_function_ = boost::bind(&TerarangerOne::serialDataCallback, this, _1);
  serial_port_->setSerialCallbackFunction(&serial_data_callback_function_);

  // Connect serial port
  if (!serial_port_->connect(portname_))
  {
    ros::shutdown();
    return;
  }

  // Output loaded parameters to console for double checking
  ROS_INFO("[%s] is up and running with the following parameters:", ros::this_node::getName().c_str());
  ROS_INFO("[%s] portname: %s",ros::this_node::getName().c_str(), portname_.c_str());

  // Set operation Mode
  setMode(BINARY_MODE);

  // Dynamic reconfigure
  dyn_param_server_callback_function_ = boost::bind(&TerarangerOne::dynParamCallback, this, _1, _2);
  dyn_param_server_.setCallback(dyn_param_server_callback_function_);
}

TerarangerOne::~TerarangerOne()
{
}

uint8_t TerarangerOne::crc8(uint8_t *p, uint8_t len)
{
  uint16_t i;
  uint16_t crc = 0x0;

  while (len--)
  {
    i = (crc ^ *p++) & 0xFF;
    crc = (crc_table[i] ^ (crc << 8)) & 0xFF;
  }
  return crc & 0xFF;
}

void TerarangerOne::serialDataCallback(uint8_t single_character)
{
  static uint8_t input_buffer[BUFFER_SIZE];
  static int buffer_ctr = 0;
  static int seq_ctr = 0;

  sensor_msgs::Range range_msg;
  range_msg.field_of_view = 0.0593;
  range_msg.max_range = 14.0;
  range_msg.min_range = 0.2;
  range_msg.radiation_type = sensor_msgs::Range::INFRARED;

  if (single_character != 'T' && buffer_ctr < 4)
  {
    // not begin of serial feed so add char to buffer
    input_buffer[buffer_ctr++] = single_character;
  }
  else if (single_character == 'T' && buffer_ctr == 4)
  {
    // end of feed, calculate
    int16_t crc = crc8(input_buffer, 3);

    if (crc == input_buffer[3])
    {
      int16_t range = input_buffer[1] << 8;
      range |= input_buffer[2];

      if (range < 14000 && range > 200)
      {
        range_msg.header.stamp = ros::Time::now();
        range_msg.header.seq = seq_ctr++;
        range_msg.range = range * 0.001; // convert to m
        range_publisher_.publish(range_msg);
      }
    }
    // reset
    buffer_ctr = 0;

    // clear struct
    bzero(&input_buffer, BUFFER_SIZE);
    // store T
    input_buffer[buffer_ctr++] = single_character;

  }
  else if (buffer_ctr >= 4)
  {
    buffer_ctr = 0;
  }
}

void TerarangerOne::setMode(char c)
{
  serial_port_->sendChar(c);
}

void TerarangerOne::dynParamCallback(const terarangerone::TerarangerOneConfig &config, uint32_t level)
{
  if (config.Speed == terarangerone::TerarangerOne_Fast)
  {
    setMode(FAST_MODE);
  }

  if (config.Speed == terarangerone::TerarangerOne_Precise)
  {
    setMode(PRECISE_MODE);
  }

  if (config.Environment == terarangerone::TerarangerOne_Indoor)
  {
    setMode(INDOOR_MODE);
  }

  if (config.Environment == terarangerone::TerarangerOne_Outdoor)
  {
    setMode(OUTDOOR_MODE);
  }
}

} // namespace terarangerone

int main(int argc, char **argv)
{
  ros::init(argc, argv, "terarangerone");
  terarangerone::TerarangerOne tera_bee;
  ros::spin();

  return 0;
}
<commit_msg>improved the parser, now every time we receive T character we reset the input_buffer<commit_after>/****************************************************************************
 *
 * Copyright (C) 2014 Flavio Fontana & Luis Rodrigues. All rights reserved.
 * Author: Flavio Fontana <fly.fontana@gmail.com>
 * Author: Luis Rodrigues <luis.rodrigues@terabee.com>

 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in
 * the documentation and/or other materials provided with the
 * distribution.
 * 3. Neither the name TerarangerOne nor the names of its contributors may be
 * used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************/

#include <string>

#include "terarangerone/terarangerone.h"

namespace terarangerone
{

TerarangerOne::TerarangerOne()
{
  // Get paramters
  ros::NodeHandle private_node_handle_("~");
  private_node_handle_.param("portname", portname_, std::string("/dev/ttyUSB0"));

  // Publishers
  range_publisher_ = nh_.advertise<sensor_msgs::Range>("terarangerone", 1);

  // Create serial port
  serial_port_ = new SerialPort();

  // Set callback function for the serial ports
  serial_data_callback_function_ = boost::bind(&TerarangerOne::serialDataCallback, this, _1);
  serial_port_->setSerialCallbackFunction(&serial_data_callback_function_);

  // Connect serial port
  if (!serial_port_->connect(portname_))
  {
    ros::shutdown();
    return;
  }

  // Output loaded parameters to console for double checking
  ROS_INFO("[%s] is up and running with the following parameters:", ros::this_node::getName().c_str());
  ROS_INFO("[%s] portname: %s", ros::this_node::getName().c_str(), portname_.c_str());

  // Set operation Mode
  setMode(BINARY_MODE);

  // Dynamic reconfigure
  dyn_param_server_callback_function_ = boost::bind(&TerarangerOne::dynParamCallback, this, _1, _2);
  dyn_param_server_.setCallback(dyn_param_server_callback_function_);
}

TerarangerOne::~TerarangerOne()
{
}

uint8_t TerarangerOne::crc8(uint8_t *p, uint8_t len)
{
  uint16_t i;
  uint16_t crc = 0x0;

  while (len--)
  {
    i = (crc ^ *p++) & 0xFF;
    crc = (crc_table[i] ^ (crc << 8)) & 0xFF;
  }
  return crc & 0xFF;
}

void TerarangerOne::serialDataCallback(uint8_t single_character)
{
  static uint8_t input_buffer[BUFFER_SIZE];
  static int buffer_ctr = 0;
  static int seq_ctr = 0;

  sensor_msgs::Range range_msg;
  range_msg.field_of_view = 0.0593;
  range_msg.max_range = 14.0;
  range_msg.min_range = 0.2;
  range_msg.radiation_type = sensor_msgs::Range::INFRARED;

// Debug Code to show the buffer
//  if (single_character == 'T')
//  {
//    ROS_INFO("TTTT single_character = %3d, buffer_ctr = %d |%3d|%3d|%3d|%3d|", single_character, buffer_ctr,
//             input_buffer[0], input_buffer[1], input_buffer[2], input_buffer[3]);
//  }
//  else
//  {
//    ROS_INFO("#### single_character = %3d, buffer_ctr = %d |%3d|%3d|%3d|%3d|", single_character, buffer_ctr,
//             input_buffer[0], input_buffer[1], input_buffer[2], input_buffer[3]);
//  }

  if (single_character != 'T' && buffer_ctr < 4)
  {
    // not begin of serial feed so add char to buffer
    input_buffer[buffer_ctr++] = single_character;
    return;
  }
  else if (single_character == 'T')
  {
    if (buffer_ctr == 4)
    {
      // end of feed, calculate
      int16_t crc = crc8(input_buffer, 3);

      if (crc == input_buffer[3])
      {
        int16_t range = input_buffer[1] << 8;
        range |= input_buffer[2];

        if (range < 14000 && range > 200)
        {
          range_msg.header.stamp = ros::Time::now();
          range_msg.header.seq = seq_ctr++;
          range_msg.range = range * 0.001; // convert to m
          range_publisher_.publish(range_msg);
        }
        ROS_DEBUG("[%s] all good %.3f m", ros::this_node::getName().c_str(), range_msg.range);
      }
      else
      {
        ROS_DEBUG("[%s] crc missmatch", ros::this_node::getName().c_str());
      }
    }
    else
    {
      ROS_DEBUG("[%s] reveived T but did not expect it, reset buffer without evaluating data",
               ros::this_node::getName().c_str());
    }
  }
  else
  {
    ROS_DEBUG("[%s] buffer_overflowed without receiving T, reset input_buffer", ros::this_node::getName().c_str());
  }
  // reset
  buffer_ctr = 0;

  // clear struct
  bzero(&input_buffer, BUFFER_SIZE);

  // store T
  input_buffer[buffer_ctr++] = 'T';
}

void TerarangerOne::setMode(char c)
{
  serial_port_->sendChar(c);
}

void TerarangerOne::dynParamCallback(const terarangerone::TerarangerOneConfig &config, uint32_t level)
{
  if (config.Speed == terarangerone::TerarangerOne_Fast)
  {
    setMode(FAST_MODE);
  }

  if (config.Speed == terarangerone::TerarangerOne_Precise)
  {
    setMode(PRECISE_MODE);
  }

  if (config.Environment == terarangerone::TerarangerOne_Indoor)
  {
    setMode(INDOOR_MODE);
  }

  if (config.Environment == terarangerone::TerarangerOne_Outdoor)
  {
    setMode(OUTDOOR_MODE);
  }
}

} // namespace terarangerone

int main(int argc, char **argv)
{
  ros::init(argc, argv, "terarangerone");
  terarangerone::TerarangerOne tera_bee;
  ros::spin();

  return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2020-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <chain.h>
#include <chainparams.h>
#include <pow.h>
#include <primitives/block.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <util/overflow.h>

#include <cstdint>
#include <optional>
#include <string>
#include <vector>

void initialize_pow()
{
    SelectParams(CBaseChainParams::MAIN);
}

FUZZ_TARGET_INIT(pow, initialize_pow)
{
    FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
    const Consensus::Params& consensus_params = Params().GetConsensus();
    std::vector<CBlockIndex> blocks;
    const uint32_t fixed_time = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
    const uint32_t fixed_bits = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
    LIMITED_WHILE(fuzzed_data_provider.remaining_bytes() > 0, 10000) {
        const std::optional<CBlockHeader> block_header = ConsumeDeserializable<CBlockHeader>(fuzzed_data_provider);
        if (!block_header) {
            continue;
        }
        CBlockIndex current_block{*block_header};
        {
            CBlockIndex* previous_block = blocks.empty() ? nullptr : &PickValue(fuzzed_data_provider, blocks);
            const int current_height = (previous_block != nullptr && previous_block->nHeight != std::numeric_limits<int>::max()) ? previous_block->nHeight + 1 : 0;
            if (fuzzed_data_provider.ConsumeBool()) {
                current_block.pprev = previous_block;
            }
            if (fuzzed_data_provider.ConsumeBool()) {
                current_block.nHeight = current_height;
            }
            if (fuzzed_data_provider.ConsumeBool()) {
                const uint32_t seconds = current_height * consensus_params.nPowTargetSpacing;
                if (!AdditionOverflow(fixed_time, seconds)) {
                    current_block.nTime = fixed_time + seconds;
                }
            }
            if (fuzzed_data_provider.ConsumeBool()) {
                current_block.nBits = fixed_bits;
            }
            if (fuzzed_data_provider.ConsumeBool()) {
                current_block.nChainWork = previous_block != nullptr ? previous_block->nChainWork + GetBlockProof(*previous_block) : arith_uint256{0};
            } else {
                current_block.nChainWork = ConsumeArithUInt256(fuzzed_data_provider);
            }
            blocks.push_back(current_block);
        }
        {
            (void)GetBlockProof(current_block);
            (void)CalculateNextWorkRequired(&current_block, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, std::numeric_limits<int64_t>::max()), consensus_params);
            if (current_block.nHeight != std::numeric_limits<int>::max() && current_block.nHeight - (consensus_params.DifficultyAdjustmentInterval() - 1) >= 0) {
                (void)GetNextWorkRequired(&current_block, &(*block_header), consensus_params);
            }
        }
        {
            const CBlockIndex* to = &PickValue(fuzzed_data_provider, blocks);
            const CBlockIndex* from = &PickValue(fuzzed_data_provider, blocks);
            const CBlockIndex* tip = &PickValue(fuzzed_data_provider, blocks);
            try {
                (void)GetBlockProofEquivalentTime(*to, *from, *tip, consensus_params);
            } catch (const uint_error&) {
            }
        }
        {
            const std::optional<uint256> hash = ConsumeDeserializable<uint256>(fuzzed_data_provider);
            if (hash) {
                (void)CheckProofOfWork(*hash, fuzzed_data_provider.ConsumeIntegral<unsigned int>(), consensus_params);
            }
        }
    }
}

FUZZ_TARGET_INIT(pow_transition, initialize_pow)
{
    FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
    const Consensus::Params& consensus_params{Params().GetConsensus()};
    std::vector<std::unique_ptr<CBlockIndex>> blocks;

    const uint32_t old_time{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
    const uint32_t new_time{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
    const int32_t version{fuzzed_data_provider.ConsumeIntegral<int32_t>()};
    uint32_t nbits{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};

    const arith_uint256 pow_limit = UintToArith256(consensus_params.powLimit);
    arith_uint256 old_target;
    old_target.SetCompact(nbits);
    if (old_target > pow_limit) {
        nbits = pow_limit.GetCompact();
    }
    // Create one difficulty adjustment period worth of headers
    for (int height = 0; height < consensus_params.DifficultyAdjustmentInterval(); ++height) {
        CBlockHeader header;
        header.nVersion = version;
        header.nTime = old_time;
        header.nBits = nbits;
        if (height == consensus_params.DifficultyAdjustmentInterval() - 1) {
            header.nTime = new_time;
        }
        auto current_block{std::make_unique<CBlockIndex>(header)};
        current_block->pprev = blocks.empty() ? nullptr : blocks.back().get();
        current_block->nHeight = height;
        blocks.emplace_back(std::move(current_block)).get();
    }
    auto last_block{blocks.back().get()};
    unsigned int new_nbits{GetNextWorkRequired(last_block, nullptr, consensus_params)};
    Assert(PermittedDifficultyTransition(consensus_params, last_block->nHeight + 1, last_block->nBits, new_nbits));
}
<commit_msg>fuzz: Remove no-op call to get()<commit_after>// Copyright (c) 2020-2021 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <chain.h>
#include <chainparams.h>
#include <pow.h>
#include <primitives/block.h>
#include <test/fuzz/FuzzedDataProvider.h>
#include <test/fuzz/fuzz.h>
#include <test/fuzz/util.h>
#include <util/overflow.h>

#include <cstdint>
#include <optional>
#include <string>
#include <vector>

void initialize_pow()
{
    SelectParams(CBaseChainParams::MAIN);
}

FUZZ_TARGET_INIT(pow, initialize_pow)
{
    FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
    const Consensus::Params& consensus_params = Params().GetConsensus();
    std::vector<CBlockIndex> blocks;
    const uint32_t fixed_time = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
    const uint32_t fixed_bits = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
    LIMITED_WHILE(fuzzed_data_provider.remaining_bytes() > 0, 10000) {
        const std::optional<CBlockHeader> block_header = ConsumeDeserializable<CBlockHeader>(fuzzed_data_provider);
        if (!block_header) {
            continue;
        }
        CBlockIndex current_block{*block_header};
        {
            CBlockIndex* previous_block = blocks.empty() ? nullptr : &PickValue(fuzzed_data_provider, blocks);
            const int current_height = (previous_block != nullptr && previous_block->nHeight != std::numeric_limits<int>::max()) ? previous_block->nHeight + 1 : 0;
            if (fuzzed_data_provider.ConsumeBool()) {
                current_block.pprev = previous_block;
            }
            if (fuzzed_data_provider.ConsumeBool()) {
                current_block.nHeight = current_height;
            }
            if (fuzzed_data_provider.ConsumeBool()) {
                const uint32_t seconds = current_height * consensus_params.nPowTargetSpacing;
                if (!AdditionOverflow(fixed_time, seconds)) {
                    current_block.nTime = fixed_time + seconds;
                }
            }
            if (fuzzed_data_provider.ConsumeBool()) {
                current_block.nBits = fixed_bits;
            }
            if (fuzzed_data_provider.ConsumeBool()) {
                current_block.nChainWork = previous_block != nullptr ? previous_block->nChainWork + GetBlockProof(*previous_block) : arith_uint256{0};
            } else {
                current_block.nChainWork = ConsumeArithUInt256(fuzzed_data_provider);
            }
            blocks.push_back(current_block);
        }
        {
            (void)GetBlockProof(current_block);
            (void)CalculateNextWorkRequired(&current_block, fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, std::numeric_limits<int64_t>::max()), consensus_params);
            if (current_block.nHeight != std::numeric_limits<int>::max() && current_block.nHeight - (consensus_params.DifficultyAdjustmentInterval() - 1) >= 0) {
                (void)GetNextWorkRequired(&current_block, &(*block_header), consensus_params);
            }
        }
        {
            const CBlockIndex* to = &PickValue(fuzzed_data_provider, blocks);
            const CBlockIndex* from = &PickValue(fuzzed_data_provider, blocks);
            const CBlockIndex* tip = &PickValue(fuzzed_data_provider, blocks);
            try {
                (void)GetBlockProofEquivalentTime(*to, *from, *tip, consensus_params);
            } catch (const uint_error&) {
            }
        }
        {
            const std::optional<uint256> hash = ConsumeDeserializable<uint256>(fuzzed_data_provider);
            if (hash) {
                (void)CheckProofOfWork(*hash, fuzzed_data_provider.ConsumeIntegral<unsigned int>(), consensus_params);
            }
        }
    }
}

FUZZ_TARGET_INIT(pow_transition, initialize_pow)
{
    FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size());
    const Consensus::Params& consensus_params{Params().GetConsensus()};
    std::vector<std::unique_ptr<CBlockIndex>> blocks;

    const uint32_t old_time{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
    const uint32_t new_time{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
    const int32_t version{fuzzed_data_provider.ConsumeIntegral<int32_t>()};
    uint32_t nbits{fuzzed_data_provider.ConsumeIntegral<uint32_t>()};

    const arith_uint256 pow_limit = UintToArith256(consensus_params.powLimit);
    arith_uint256 old_target;
    old_target.SetCompact(nbits);
    if (old_target > pow_limit) {
        nbits = pow_limit.GetCompact();
    }
    // Create one difficulty adjustment period worth of headers
    for (int height = 0; height < consensus_params.DifficultyAdjustmentInterval(); ++height) {
        CBlockHeader header;
        header.nVersion = version;
        header.nTime = old_time;
        header.nBits = nbits;
        if (height == consensus_params.DifficultyAdjustmentInterval() - 1) {
            header.nTime = new_time;
        }
        auto current_block{std::make_unique<CBlockIndex>(header)};
        current_block->pprev = blocks.empty() ? nullptr : blocks.back().get();
        current_block->nHeight = height;
        blocks.emplace_back(std::move(current_block));
    }
    auto last_block{blocks.back().get()};
    unsigned int new_nbits{GetNextWorkRequired(last_block, nullptr, consensus_params)};
    Assert(PermittedDifficultyTransition(consensus_params, last_block->nHeight + 1, last_block->nBits, new_nbits));
}
<|endoftext|>


<commit_before>#include "rtl_platform.h"

#include <dlfcn.h>
#include <map>

#ifdef __APPLE__
#define SO_SUFFIX ".dylib"
#else
#define SO_SUFFIX ".so"
#endif

static std::map<std::string, void *> g_Libraries;

static void *get_library_handle(const std::string &library)
{
    auto i = g_Libraries.find(library);
    if (i == g_Libraries.end()) {
        std::string libname = library + SO_SUFFIX;
        void *lib = dlopen(libname.c_str(), RTLD_LAZY);
        if (lib == nullptr) {
            return NULL;
        }
        i = g_Libraries.insert(std::make_pair(library, lib)).first;
    }
    return i->second;
}

void_function_t rtl_external_function(const std::string &library, const std::string &function, std::string &exception)
{
    void *lib = get_library_handle(library);
    if (lib == NULL) {
        exception = "LibraryNotFound";
        return nullptr;
    }
    void (*fp)() = reinterpret_cast<void (*)()>(dlsym(lib, function.c_str()));
    if (fp == NULL) {
        exception = "FunctionNotFound";
        return nullptr;
    }
    return fp;
}
<commit_msg>show more dynamic loading info on error<commit_after>#include "rtl_platform.h"

#include <dlfcn.h>
#include <map>

#ifdef __APPLE__
#define SO_SUFFIX ".dylib"
#else
#define SO_SUFFIX ".so"
#endif

static std::map<std::string, void *> g_Libraries;

static void *get_library_handle(const std::string &library)
{
    auto i = g_Libraries.find(library);
    if (i == g_Libraries.end()) {
        std::string libname = library + SO_SUFFIX;
        void *lib = dlopen(libname.c_str(), RTLD_LAZY);
        if (lib == nullptr) {
            // TODO: fill in exception info
            fprintf(stderr, "%s\n", dlerror());
            return NULL;
        }
        i = g_Libraries.insert(std::make_pair(library, lib)).first;
    }
    return i->second;
}

void_function_t rtl_external_function(const std::string &library, const std::string &function, std::string &exception)
{
    void *lib = get_library_handle(library);
    if (lib == NULL) {
        exception = "LibraryNotFound";
        return nullptr;
    }
    void (*fp)() = reinterpret_cast<void (*)()>(dlsym(lib, function.c_str()));
    if (fp == NULL) {
        exception = "FunctionNotFound";
        return nullptr;
    }
    return fp;
}
<|endoftext|>


<commit_before>#include "gtest/gtest.h"
#include "map/Tile.h"
#include "actor/Actor.h"

TEST(TileTest, WallTileIsOpaque)
{
	Tile t1 = WallTile;

	EXPECT_FALSE(t1.isTransparent());
}

TEST(TileTest, WallTileIsInpassable)
{
	Tile t1 = WallTile;

	EXPECT_FALSE(t1.isPassable());
}

TEST(TileTest, FloorTileIsTransparent)
{
	Tile t1 = FloorTile;

	EXPECT_TRUE(t1.isTransparent());
}

TEST(TileTest, FloorTileIsPassable)
{
	Tile t1 = FloorTile;

	EXPECT_TRUE(t1.isPassable());
}

TEST(TileTest, ClosedDoorTileIsOpaque)
{
	Tile t1 = ClosedDoorTile;

	EXPECT_FALSE(t1.isTransparent());
}

TEST(TileTest, ClosedDoorTileIsInpassable)
{
	Tile t1 = ClosedDoorTile;

	EXPECT_FALSE(t1.isPassable());
}

TEST(TileTest, OpenDoorTileIsTransparent)
{
	Tile t1 = OpenDoorTile;

	EXPECT_TRUE(t1.isTransparent());
}

TEST(TileTest, OpenDoorTileIsPassable)
{
	Tile t1 = OpenDoorTile;

	EXPECT_TRUE(t1.isPassable());
}

TEST(TileTest, FloorEqualsFloor)
{
	Tile floor = FloorTile;
	Tile wall = FloorTile;

	EXPECT_TRUE(floor == wall);
}

TEST(TileTest, FloorDoesNotEqualWall)
{
	Tile floor = FloorTile;
	Tile wall = WallTile;

	EXPECT_TRUE(floor != wall);
}

TEST(TileTest, TileDisplaysActor)
{
	Actor actor('@', "TestActor", 0x00);
	Tile floor = FloorTile;

	EXPECT_EQ('.', floor.getDisplay());

	floor.addActor(&actor);

	EXPECT_EQ('@', floor.getDisplay());

	floor.removeActor();

	EXPECT_EQ('.', floor.getDisplay());
}

TEST(TileTest, TileIsOccupied)
{
	Actor actor('@', "TestActor", 0x00);
	Tile floor = FloorTile;

	EXPECT_FALSE(floor.isOccupied());

	floor.addActor(&actor);

	EXPECT_TRUE(floor.isOccupied());

	floor.removeActor();

	EXPECT_FALSE(floor.isOccupied());
}

<commit_msg>Remove Actor-related Tile tests<commit_after>#include "gtest/gtest.h"
#include "map/Tile.h"

TEST(TileTest, WallTileIsOpaque)
{
	Tile t1 = WallTile;

	EXPECT_FALSE(t1.isTransparent());
}

TEST(TileTest, WallTileIsInpassable)
{
	Tile t1 = WallTile;

	EXPECT_FALSE(t1.isPassable());
}

TEST(TileTest, FloorTileIsTransparent)
{
	Tile t1 = FloorTile;

	EXPECT_TRUE(t1.isTransparent());
}

TEST(TileTest, FloorTileIsPassable)
{
	Tile t1 = FloorTile;

	EXPECT_TRUE(t1.isPassable());
}

TEST(TileTest, ClosedDoorTileIsOpaque)
{
	Tile t1 = ClosedDoorTile;

	EXPECT_FALSE(t1.isTransparent());
}

TEST(TileTest, ClosedDoorTileIsInpassable)
{
	Tile t1 = ClosedDoorTile;

	EXPECT_FALSE(t1.isPassable());
}

TEST(TileTest, OpenDoorTileIsTransparent)
{
	Tile t1 = OpenDoorTile;

	EXPECT_TRUE(t1.isTransparent());
}

TEST(TileTest, OpenDoorTileIsPassable)
{
	Tile t1 = OpenDoorTile;

	EXPECT_TRUE(t1.isPassable());
}

TEST(TileTest, FloorEqualsFloor)
{
	Tile floor = FloorTile;
	Tile wall = FloorTile;

	EXPECT_TRUE(floor == wall);
}

TEST(TileTest, FloorDoesNotEqualWall)
{
	Tile floor = FloorTile;
	Tile wall = WallTile;

	EXPECT_TRUE(floor != wall);
}

<|endoftext|>


<commit_before>/* This file is part of VoltDB.
 * Copyright (C) 2008-2015 VoltDB Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>

int main (int argc, char **argv) {
    CppUnit::TextUi::TestRunner runner;
    CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();
    runner.addTest( registry.makeTest() );
    return runner.run( "" );
}

<commit_msg>Make cpptest main return 0 for SUCCESS.<commit_after>/* This file is part of VoltDB.
 * Copyright (C) 2008-2015 VoltDB Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>

int main (int argc, char **argv) {
    CppUnit::TextUi::TestRunner runner;
    CppUnit::TestFactoryRegistry &registry = CppUnit::TestFactoryRegistry::getRegistry();
    runner.addTest( registry.makeTest() );
    return !runner.run( "" );
}

<|endoftext|>