Exemple #1
0
void UnitEmitter::addTrivialPseudoMain() {
  initMain(0, 0);
  auto const mfe = getMain();
  emitOp(OpInt);
  emitInt64(1);
  emitOp(OpRetC);
  mfe->maxStackCells = 1;
  mfe->finish(bcPos(), false);
  recordFunction(mfe);

  TypedValue mainReturn;
  mainReturn.m_data.num = 1;
  mainReturn.m_type = KindOfInt64;
  m_mainReturn = mainReturn;
  m_mergeOnly = true;
}
Exemple #2
0
static void
emit(int c, const char *p1)
{
	char		ap        [PATH_MAX];
	SE;
	emitOp(c, realpath(p1, ap), 0);
	RE;
}
Exemple #3
0
std::unique_ptr<UnitEmitter>
createFatalUnit(StringData* filename, const MD5& md5, FatalOp /*op*/,
                StringData* err) {
  auto ue = std::make_unique<UnitEmitter>(md5);
  ue->m_filepath = filename;
  ue->initMain(1, 1);
  ue->emitOp(OpString);
  ue->emitInt32(ue->mergeLitstr(err));
  ue->emitOp(OpFatal);
  ue->emitByte(static_cast<uint8_t>(FatalOp::Runtime));
  FuncEmitter* fe = ue->getMain();
  fe->maxStackCells = 1;
  // XXX line numbers are bogus
  fe->finish(ue->bcPos(), false);
  ue->recordFunction(fe);
  return ue;
}
Exemple #4
0
int
unlink(const char *p)
{
	int		r;
	char		b         [PATH_MAX];
	char           *rp;
	static int      (*ounlink) (const char *)= 0;
	DP;
	R(unlink);
	rp = realpath(p, b);
	r = ounlink(p);
	if (!r)
		emitOp('d', rp, 0);
	DD;
	return r;
}
Exemple #5
0
int
renameat(int fd1, const char *p1, int fd2, const char *p2)
{
	int		r;
	D;
	if (fd1 != AT_FDCWD || fd2 != AT_FDCWD) {
		static int      (*orenameat) (const char *, const char *)= 0;
		R(renameat);
		r = orenameat(p1, p2);
		if (!r)
			emitOp('R', p2, p1);
	} else
		r = rename(p1, p2);
	DD;
	return r;
}
Exemple #6
0
int
openat64(int fd, const char *p, int f, mode_t m)
{
	int		r;
	DP;
	if (fd != AT_FDCWD) {
		static int      (*oopenat64) (int, const char *, int, mode_t)= 0;
		R(openat64);
		r = oopenat64(fd, p, f, m);
		if (r >= 0)
			emitOp(f & wmode ? 'W' : 'R', p, 0);
	} else
		r = open64(p, f, m);
	DD;
	return r;
}
Exemple #7
0
int
rename(const char *p1, const char *p2)
{
	int		r;
	char		b1        [PATH_MAX];
	char           *rp1 = realpath(p1, b1);
	static int      (*orename) (const char *, const char *)= 0;
	D;
	R(rename);
	r = orename(p1, p2);
	if (!r) {
		char		b2        [PATH_MAX];
		char           *rp2 = realpath(p2, b2);
		emitOp(rp1 ? 'm' : 'M', rp2, rp1);
	}
	DD;
	return r;
}
Exemple #8
0
int
unlinkat(int fd, const char *p, int f)
{
	int		r;
	DP;
	if (fd != AT_FDCWD) {
		static int      (*ounlinkat) (int fd, const char *p, int f);
		R(unlinkat);
		r = ounlinkat(fd, p, f);
		if (!r)
			emitOp('D', p, 0);
		assert(0);
	} else if (f & AT_REMOVEDIR)
		r = rmdir(p);
	else
		r = unlink(p);
	DD;
	return r;
}
Exemple #9
0
static void
fdemit(int c, int fd)
{
	char		ap        [PATH_MAX];
	int		ok;
	SE;
#ifdef F_GETPATH
	ok = -1 != fcntl(fd, F_GETPATH, ap);
#else
	{
		ssize_t		written;
		char		fdpath    [100];
		snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd);
		written = readlink(fdpath, ap, sizeof(ap));
		ok = written >= 0 && written < sizeof(ap);
		if (ok)
			ap[written] = 0;
	}
#endif
	emitOp(c, ok ? ap : 0, 0);
	RE;
}
Exemple #10
0
void Parser::emitOp(Ast &ast) {
	Ast copy = ast;
	emitOp(std::move(copy));
}
Exemple #11
0
void Parser::emitOp(Op op, double d) {
	Ast &&ast = Ast::create(op);
	ast.d = d;
	emitOp(ast);
}
Exemple #12
0
void Parser::emitOp(Op op, int i) {
	Ast &&ast = Ast::create(op);
	ast.i = i;
	emitOp(ast);
}
Exemple #13
0
int Parser::parse() {
	std::stack<Token> stack;
	ast.op = OP_HLT;
	ast.i = 0;
	lastTokenId = TOK_NONE;
	lastOp = -1;
	tok = scanner.getNextToken();
	while (tok.id != TOK_EOF) {
		bool expectUnary = lastTokenId == TOK_LPAREN
			|| lastTokenId == TOK_NONE
			|| canBePrefix(lastTokenId)
			|| canBeInfix(lastTokenId);
		bool expectExpr = lastTokenId == TOK_NONE
			|| lastTokenId == TOK_LPAREN
			|| canBePrefix(lastTokenId)
			|| canBeInfix(lastTokenId);
		switch (tok.id) {

			default:
				raiseError("unknown token");
				return 1;

			case TOK_ERROR:
				raiseError(tok.err);
				return 1;

			case TOK_PLUS:
				if (expectUnary)
					tok.id = TOK_UN_PLUS;
				else
					tok.id = TOK_OP_ADD;
				continue;

			case TOK_MINUS:
				if (expectUnary)
					tok.id = TOK_UN_NEG;
				else
					tok.id = TOK_OP_SUB;
				continue;

			case TOK_ARG:
				if (canBeValue(lastTokenId)) {
					raiseError("unexpected primary value");
					return 1;
				}
				if (tok.i > UCHAR_MAX) {
					raiseError("argument number out of range");
					return 1;
				}
				emitOp(OP_ARG, (unsigned char)(tok.i));
				break;

			case TOK_LIT:
				if (canBeValue(lastTokenId)) {
					raiseError("unexpected primary value");
					return 1;
				}
				emitOp(OP_CONST, tok.d);
				break;

			case TOK_F_PI:
				if (canBeValue(lastTokenId)) {
					raiseError("unexpected primary value");
					return 1;
				}
				emitOp(OP_PI);
				break;

			case TOK_F_E:
				if (canBeValue(lastTokenId)) {
					raiseError("unexpected primary value");
					return 1;
				}
				emitOp(OP_E);
				break;

			case TOK_UN_PLUS:
				// unary plus is a noop
				break;

			case TOK_LPAREN:
				if (!canBeFunction(lastTokenId) && !expectExpr) {
					raiseError("unexpected open parenthesis");
					return 1;
				}
				stack.push(tok);
				break;

			case TOK_F_SQRT:
			case TOK_F_SIN:
			case TOK_F_COS:
			case TOK_F_TAN:
			case TOK_F_ASIN:
			case TOK_F_ACOS:
			case TOK_F_ATAN:
			case TOK_F_SINH:
			case TOK_F_COSH:
			case TOK_F_TANH:
			case TOK_F_ASINH:
			case TOK_F_ACOSH:
			case TOK_F_ATANH:
			case TOK_F_EXP:
			case TOK_F_LOG:
			case TOK_F_ERF:
			case TOK_F_ERFC:
			case TOK_F_ABS:
			case TOK_F_FLOOR:
			case TOK_F_CEIL:
			case TOK_F_ROUND:
			case TOK_F_TRUNC:
			case TOK_F_POW:
			case TOK_UN_NEG:
				if (canBeValue(lastTokenId)) {
					raiseError("unexpected prefix operator");
					return 1;
				}
				stack.push(tok);
				break;

			case TOK_COMMA:
				while (stack.size() > 0 && stack.top().id != TOK_LPAREN) {
					emitOp(getOperator(stack.top().id));
					stack.pop();
				}
				if (stack.size() <= 0 || stack.top().id != TOK_LPAREN) {
					raiseError("misplaced comma");
					return 1;
				}
				break;

			case TOK_RPAREN:
				while (stack.size() > 0 && stack.top().id != TOK_LPAREN) {
					emitOp(getOperator(stack.top().id));
					stack.pop();
				}
				if (stack.size() <= 0 || stack.top().id != TOK_LPAREN) {
					raiseError("mismatched parenthesis");
					return 1;
				}
				stack.pop();
				while (stack.size() > 0 && canBePrefix(stack.top().id)) {
					emitOp(getOperator(stack.top().id));
					stack.pop();
				}
				break;

			case TOK_OP_ADD:
			case TOK_OP_SUB:
			case TOK_OP_MUL:
			case TOK_OP_DIV:
			case TOK_OP_POW:
				if (!canBeValue(lastTokenId)) {
					raiseError("unexpected operator");
					return 1;
				}
				while (stack.size() > 0 && canBeOperation(stack.top().id)) {
					if (isRightAssociative(tok.id)) {
						if (getPrecedence(tok.id) < getPrecedence(stack.top().id)) {
							emitOp(getOperator(stack.top().id));
							stack.pop();
						} else
							break;
					} else {
						if (getPrecedence(tok.id) <= getPrecedence(stack.top().id)) {
							emitOp(getOperator(stack.top().id));
							stack.pop();
						} else
							break;
					}
				}
				stack.push(tok);
				break;
		}

		lastTokenId = tok.id;
		tok = scanner.getNextToken();
	}

	if (!canBeValue(lastTokenId)) {
		raiseError("unexpected program end");
		return 1;
	}

	while (stack.size() > 0) {
		if (stack.top().id == TOK_LPAREN || stack.top().id == TOK_RPAREN) {
			raiseError("mismatched parenthesis");
			return 1;
		} else {
			emitOp(getOperator(stack.top().id));
			stack.pop();
		}
	}
	return 0;
}
Exemple #14
0
Bytecode::Bytecode() : size(0) {
    emitOp(FRAME);
    emitOp(INVK);
    emitReference(getLabel("main"));
    emitOp(EXIT);
}